Wed Jan 8 2020 09:50:20

Asterisk developer's documentation


sig_pri.c File Reference

PRI signaling module. More...

#include "asterisk.h"
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/say.h"
#include "asterisk/manager.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/cli.h"
#include "asterisk/transcap.h"
#include "asterisk/features.h"
#include "asterisk/aoc.h"
#include "sig_pri.h"

Go to the source code of this file.

Data Structures

struct  sig_pri_cc_agent_prv
 
struct  sig_pri_cc_monitor_instance
 
struct  xfer_rsp_data
 

Macros

#define DCHAN_AVAILABLE   (DCHAN_NOTINALARM | DCHAN_UP)
 
#define DCHAN_NOTINALARM   (1 << 0)
 
#define DCHAN_UP   (1 << 1)
 
#define FORCE_RESTART_UNAVAIL_CHANS   1
 
#define PRI_CHANNEL(p)   ((p) & 0xff)
 
#define PRI_CIS_CALL   (1 << 17) /* Call is using the D channel only. */
 
#define PRI_EXPLICIT   (1 << 16)
 
#define PRI_HELD_CALL   (1 << 18)
 
#define PRI_SPAN(p)   (((p) >> 8) & 0xff)
 
#define SIG_PRI_SC_HEADER   "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
 
#define SIG_PRI_SC_LINE   "%4d %4d %-4s %-4s %-10s %-4s %s"
 

Typedefs

typedef void(* xfer_rsp_callback )(void *data, int is_successful)
 Protocol callback to indicate if transfer will happen. More...
 

Enumerations

enum  SIG_PRI_CALL_OPT_ARGS { OPT_ARG_KEYPAD = 0, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE }
 
enum  SIG_PRI_CALL_OPT_FLAGS { OPT_KEYPAD = (1 << 0), OPT_REVERSE_CHARGE = (1 << 1), OPT_AOC_REQUEST = (1 << 2) }
 

Functions

static void apply_plan_to_existing_number (char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
 
static void apply_plan_to_number (char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
 
static unsigned char ast_pri_pack_hex_char (char c)
 
static int ast_pri_pack_hex_string (unsigned char *dst, char *src, int maxlen)
 
static int ast_to_pri_char_set (enum AST_PARTY_CHAR_SET ast_char_set)
 
static int ast_to_pri_presentation (int ast_presentation)
 
static int ast_to_pri_reason (enum AST_REDIRECTING_REASON ast_reason)
 
static void build_status (char *s, size_t len, int status, int active)
 
static int detect_aoc_e_subcmd (const struct pri_subcommands *subcmds)
 
static char * dialplan2str (int dialplan)
 
static void * do_idle_thread (void *v_pvt)
 
static int pri_active_dchan_index (struct sig_pri_span *pri)
 
static void pri_check_restart (struct sig_pri_span *pri)
 
static void * pri_dchannel (void *vpri)
 
void pri_event_alarm (struct sig_pri_span *pri, int index, int before_start_pri)
 
void pri_event_noalarm (struct sig_pri_span *pri, int index, int before_start_pri)
 
static void pri_find_dchan (struct sig_pri_span *pri)
 
static int pri_find_empty_chan (struct sig_pri_span *pri, int backwards)
 
static int pri_find_empty_nobch (struct sig_pri_span *pri)
 
static int pri_find_fixup_principle (struct sig_pri_span *pri, int channel, q931_call *call)
 
static int pri_find_principle (struct sig_pri_span *pri, int channel, q931_call *call)
 
static int pri_find_principle_by_call (struct sig_pri_span *pri, q931_call *call)
 
static int pri_fixup_principle (struct sig_pri_span *pri, int principle, q931_call *call)
 
static int pri_grab (struct sig_pri_chan *p, struct sig_pri_span *pri)
 
int pri_is_up (struct sig_pri_span *pri)
 
int pri_maintenance_bservice (struct pri *pri, struct sig_pri_chan *p, int changestatus)
 
static const char * pri_order (int level)
 
static void pri_queue_control (struct sig_pri_span *pri, int chanpos, int subclass)
 
static void pri_queue_frame (struct sig_pri_span *pri, int chanpos, struct ast_frame *frame)
 
static void pri_rel (struct sig_pri_span *pri)
 
int pri_send_callrerouting_facility_exec (struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
 
int pri_send_keypad_facility_exec (struct sig_pri_chan *p, const char *digits)
 
static void * pri_ss_thread (void *data)
 
static enum AST_PARTY_CHAR_SET pri_to_ast_char_set (int pri_char_set)
 
static int pri_to_ast_presentation (int pri_presentation)
 
static enum AST_REDIRECTING_REASON pri_to_ast_reason (int pri_reason)
 
static unsigned int PVT_TO_CHANNEL (struct sig_pri_chan *p)
 
static char * redirectingreason2str (int redirectingreason)
 
static void sig_pri_ami_channel_event (struct sig_pri_chan *p)
 
int sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast)
 
static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast (enum PRI_AOC_CHARGED_ITEM value)
 
static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri (enum PRI_AOC_CHARGED_ITEM value)
 
static void sig_pri_aoc_d_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 
static void sig_pri_aoc_d_from_pri (const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough)
 
static void sig_pri_aoc_e_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 
static void sig_pri_aoc_e_from_pri (const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
 
static int sig_pri_aoc_multiplier_from_ast (enum ast_aoc_currency_multiplier mult)
 
static int sig_pri_aoc_multiplier_from_pri (const int mult)
 
static void sig_pri_aoc_request_from_pri (const struct pri_subcmd_aoc_request *aoc_request, struct sig_pri_chan *pvt, q931_call *call)
 
static void sig_pri_aoc_s_from_ast (struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 
static void sig_pri_aoc_s_from_pri (const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough)
 
static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast (enum PRI_AOC_TIME_SCALE value)
 
static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri (enum ast_aoc_time_scale value)
 
static int sig_pri_attempt_transfer (struct sig_pri_span *pri, q931_call *call_1_pri, int call_1_held, q931_call *call_2_pri, int call_2_held, xfer_rsp_callback rsp_callback, void *data)
 
int sig_pri_available (struct sig_pri_chan **pvt, int is_specific_channel)
 
static int sig_pri_available_check (struct sig_pri_chan *pvt)
 
int sig_pri_call (struct sig_pri_chan *p, struct ast_channel *ast, char *rdest, int timeout, int layer1)
 
static const char * sig_pri_call_level2str (enum sig_pri_call_level level)
 
int sig_pri_cc_agent_callee_available (struct ast_cc_agent *agent)
 Alert the caller that it is time to try recalling. More...
 
static int sig_pri_cc_agent_cmp_cc_id (void *obj, void *arg, int flags)
 
void sig_pri_cc_agent_destructor (struct ast_cc_agent *agent)
 Destroy private data on the agent. More...
 
int sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
 PRI CC agent initialization. More...
 
int sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent)
 Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line. More...
 
void sig_pri_cc_agent_req_rsp (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
 Response to a CC request. More...
 
int sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent)
 Begin monitoring a busy device. More...
 
int sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
 Start the offer timer. More...
 
int sig_pri_cc_agent_status_req (struct ast_cc_agent *agent)
 Request the status of the agent's device. More...
 
int sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
 Stop the offer timer. More...
 
int sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent)
 Request for an agent's phone to stop ringing. More...
 
static int sig_pri_cc_available (struct sig_pri_span *pri, int chanpos, long cc_id, enum ast_cc_service_type service)
 
static void sig_pri_cc_generic_check (struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service)
 
static void sig_pri_cc_link_canceled (struct sig_pri_span *pri, long cc_id, int is_agent)
 
int sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
 Cancel the running available timer. More...
 
static int sig_pri_cc_monitor_cmp_cc_id (void *obj, void *arg, int flags)
 
void sig_pri_cc_monitor_destructor (void *monitor_pvt)
 Destroy PRI private data on the monitor. More...
 
static int sig_pri_cc_monitor_instance_cmp_fn (void *obj, void *arg, int flags)
 
static void sig_pri_cc_monitor_instance_destroy (void *data)
 
static int sig_pri_cc_monitor_instance_hash_fn (const void *obj, const int flags)
 
static struct
sig_pri_cc_monitor_instance
sig_pri_cc_monitor_instance_init (int core_id, struct sig_pri_span *pri, long cc_id, const char *device_name)
 
int sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
 Request CCSS. More...
 
int sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate)
 Status response to an ast_cc_monitor_status_request(). More...
 
int sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor)
 Suspend monitoring. More...
 
int sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
 Unsuspend monitoring. More...
 
void sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm)
 Notify new alarm status. More...
 
void sig_pri_chan_delete (struct sig_pri_chan *doomed)
 Delete the sig_pri private channel structure. More...
 
struct sig_pri_chansig_pri_chan_new (void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
 
void sig_pri_cli_show_channels (int fd, struct sig_pri_span *pri)
 
void sig_pri_cli_show_channels_header (int fd)
 
void sig_pri_cli_show_span (int fd, int *dchannels, struct sig_pri_span *pri)
 
void sig_pri_cli_show_spans (int fd, int span, struct sig_pri_span *pri)
 
static int sig_pri_cmp_pri_chans (const void *left, const void *right)
 
static struct sig_pri_chansig_pri_cw_available (struct sig_pri_span *pri)
 
void sig_pri_dial_complete (struct sig_pri_chan *pvt, struct ast_channel *ast)
 DTMF dial string complete. More...
 
static void sig_pri_dial_digits (struct sig_pri_chan *p, const char *dial_string)
 
int sig_pri_digit_begin (struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
 
static void sig_pri_dsp_reset_and_flush_digits (struct sig_pri_chan *p)
 
static void sig_pri_event_party_id (struct ast_str **msg, const char *prefix, struct ast_party_id *party)
 
void sig_pri_extract_called_num_subaddr (struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
 Extract the called number and subaddress from the dial string. More...
 
static struct ast_cc_agentsig_pri_find_cc_agent_by_cc_id (struct sig_pri_span *pri, long cc_id)
 
static struct
sig_pri_cc_monitor_instance
sig_pri_find_cc_monitor_by_cc_id (struct sig_pri_span *pri, long cc_id)
 
void sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
 
static void sig_pri_fixup_chans (struct sig_pri_chan *old_chan, struct sig_pri_chan *new_chan)
 
static const char * sig_pri_get_orig_dialstring (struct sig_pri_chan *p)
 
static void sig_pri_handle_cis_subcmds (struct sig_pri_span *pri, int event_id, const struct pri_subcommands *subcmds, q931_call *call_rsp)
 
static void sig_pri_handle_dchan_exception (struct sig_pri_span *pri, int index)
 
static int sig_pri_handle_hold (struct sig_pri_span *pri, pri_event *ev)
 
static void sig_pri_handle_retrieve (struct sig_pri_span *pri, pri_event *ev)
 
static void sig_pri_handle_subcmds (struct sig_pri_span *pri, int chanpos, int event_id, int channel, const struct pri_subcommands *subcmds, q931_call *call_rsp)
 
int sig_pri_hangup (struct sig_pri_chan *p, struct ast_channel *ast)
 
int sig_pri_indicate (struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
 
static void sig_pri_init_config (struct sig_pri_chan *pvt, struct sig_pri_span *pri)
 
void sig_pri_init_pri (struct sig_pri_span *pri)
 
int sig_pri_is_alarm_ignored (struct sig_pri_span *pri)
 Determine if layer 1 alarms are ignored. More...
 
int sig_pri_is_chan_available (struct sig_pri_chan *pvt)
 Determine if a private channel structure is available. More...
 
static int sig_pri_is_chan_in_use (struct sig_pri_chan *pvt)
 
static int sig_pri_is_cis_call (int channel)
 
static void sig_pri_kill_call (struct sig_pri_span *pri, q931_call *call, int cause)
 
int sig_pri_load (const char *cc_type_name)
 Load the sig_pri submodule. More...
 
static void sig_pri_lock_owner (struct sig_pri_span *pri, int chanpos)
 
static void sig_pri_lock_private (struct sig_pri_chan *p)
 
static void sig_pri_make_cc_dialstring (struct sig_pri_chan *p, char *buf, size_t buf_size)
 
static void sig_pri_mcid_event (struct sig_pri_span *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner)
 
static int sig_pri_msn_match (const char *msn_patterns, const char *exten)
 
static void sig_pri_mwi_cache_update (struct sig_pri_span *pri)
 
static void sig_pri_mwi_event_cb (const struct ast_event *event, void *userdata)
 
static struct ast_channelsig_pri_new_ast_channel (struct sig_pri_chan *p, int state, enum sig_pri_law law, 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)
 
struct ast_channelsig_pri_request (struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
 
static void sig_pri_send_aoce_termination_request (struct sig_pri_span *pri, int chanpos, unsigned int ms)
 
static void sig_pri_send_mwi_indication (struct sig_pri_span *pri, const char *mbox_number, const char *mbox_context, int num_messages)
 
void sig_pri_set_alarm (struct sig_pri_chan *p, int in_alarm)
 
static void sig_pri_set_caller_id (struct sig_pri_chan *p)
 
static void sig_pri_set_dialing (struct sig_pri_chan *p, int is_dialing)
 
static void sig_pri_set_digital (struct sig_pri_chan *p, int is_digital)
 
static void sig_pri_set_dnid (struct sig_pri_chan *p, const char *dnid)
 
static int sig_pri_set_echocanceller (struct sig_pri_chan *p, int enable)
 
static void sig_pri_set_outgoing (struct sig_pri_chan *p, int is_outgoing)
 
static void sig_pri_set_rdnis (struct sig_pri_chan *p, const char *rdnis)
 
static void sig_pri_set_subaddress (struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress)
 
static void sig_pri_sort_pri_chans (struct sig_pri_span *pri)
 
static void sig_pri_span_devstate_changed (struct sig_pri_span *pri)
 
int sig_pri_start_pri (struct sig_pri_span *pri)
 
void sig_pri_stop_pri (struct sig_pri_span *pri)
 Stop PRI span. More...
 
static void sig_pri_transfer_rsp (void *data, int is_successful)
 
void sig_pri_unload (void)
 Unload the sig_pri submodule. More...
 
static void sig_pri_unlock_private (struct sig_pri_chan *p)
 

Variables

static int pri_gendigittimeout = 8000
 
static int pri_matchdigittimeout = 3000
 
static struct ast_app_option sig_pri_call_opts [128] = { [ 'K' ] = { .flag = OPT_KEYPAD , .arg_index = OPT_ARG_KEYPAD + 1 }, [ 'R' ] = { .flag = OPT_REVERSE_CHARGE }, [ 'A' ] = { .flag = OPT_AOC_REQUEST , .arg_index = OPT_ARG_AOC_REQUEST + 1 }, }
 
static struct ao2_containersig_pri_cc_monitors
 
static const char * sig_pri_cc_type_name
 

Detailed Description

PRI signaling module.

Author
Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com

Definition in file sig_pri.c.

Macro Definition Documentation

#define DCHAN_AVAILABLE   (DCHAN_NOTINALARM | DCHAN_UP)

Definition at line 119 of file sig_pri.c.

Referenced by pri_find_dchan(), and pri_is_up().

#define DCHAN_NOTINALARM   (1 << 0)

Definition at line 108 of file sig_pri.c.

Referenced by build_status(), pri_event_alarm(), and pri_event_noalarm().

#define DCHAN_UP   (1 << 1)

Definition at line 109 of file sig_pri.c.

Referenced by build_status(), pri_dchannel(), and pri_event_alarm().

#define FORCE_RESTART_UNAVAIL_CHANS   1

Define to make always pick a channel if allowed. Useful for testing channel shifting.

Define to force a RESTART on a channel that returns a cause code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44). If the cause is because of a stuck channel on the peer and the channel is always the next channel we pick for an outgoing call then this can help.

Definition at line 75 of file sig_pri.c.

#define PRI_CHANNEL (   p)    ((p) & 0xff)
#define PRI_CIS_CALL   (1 << 17) /* Call is using the D channel only. */

Definition at line 115 of file sig_pri.c.

Referenced by sig_pri_is_cis_call().

#define PRI_EXPLICIT   (1 << 16)

Definition at line 114 of file sig_pri.c.

Referenced by pri_find_principle(), and PVT_TO_CHANNEL().

#define PRI_HELD_CALL   (1 << 18)

Definition at line 116 of file sig_pri.c.

Referenced by pri_find_principle(), and sig_pri_handle_retrieve().

#define PRI_SPAN (   p)    (((p) >> 8) & 0xff)
#define SIG_PRI_SC_HEADER   "%-4s %4s %-4s %-4s %-10s %-4s %s\n"

Definition at line 7958 of file sig_pri.c.

Referenced by sig_pri_cli_show_channels_header().

#define SIG_PRI_SC_LINE   "%4d %4d %-4s %-4s %-10s %-4s %s"

Definition at line 7959 of file sig_pri.c.

Referenced by sig_pri_cli_show_channels().

Typedef Documentation

typedef void(* xfer_rsp_callback)(void *data, int is_successful)

Protocol callback to indicate if transfer will happen.

Since
1.8
Parameters
dataCallback user data pointer
is_successfulTRUE if the transfer will happen.
Returns
Nothing

Definition at line 2325 of file sig_pri.c.

Enumeration Type Documentation

Enumerator
OPT_ARG_KEYPAD 
OPT_ARG_AOC_REQUEST 
OPT_ARG_ARRAY_SIZE 

Definition at line 6626 of file sig_pri.c.

6626  {
6627  OPT_ARG_KEYPAD = 0,
6629 
6630  /* note: this entry _MUST_ be the last one in the enum */
6632 };
Enumerator
OPT_KEYPAD 
OPT_REVERSE_CHARGE 
OPT_AOC_REQUEST 

Definition at line 6621 of file sig_pri.c.

6621  {
6622  OPT_KEYPAD = (1 << 0),
6623  OPT_REVERSE_CHARGE = (1 << 1), /* Collect call */
6624  OPT_AOC_REQUEST = (1 << 2), /* AOC Request */
6625 };

Function Documentation

static void apply_plan_to_existing_number ( char *  buf,
size_t  size,
const struct sig_pri_span pri,
const char *  number,
int  plan 
)
static

Definition at line 1670 of file sig_pri.c.

References apply_plan_to_number(), and ast_strlen_zero().

Referenced by pri_dchannel(), and sig_pri_party_number_convert().

1671 {
1672  /* Make sure a number exists so the prefix isn't placed on an empty string. */
1673  if (ast_strlen_zero(number)) {
1674  if (size) {
1675  *buf = '\0';
1676  }
1677  return;
1678  }
1679  apply_plan_to_number(buf, size, pri, number, plan);
1680 }
Number structure.
Definition: app_followme.c:109
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static void apply_plan_to_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
Definition: sig_pri.c:1634
static void apply_plan_to_number ( char *  buf,
size_t  size,
const struct sig_pri_span pri,
const char *  number,
int  plan 
)
static

Definition at line 1634 of file sig_pri.c.

References sig_pri_span::internationalprefix, sig_pri_span::localprefix, sig_pri_span::nationalprefix, sig_pri_span::privateprefix, and sig_pri_span::unknownprefix.

Referenced by apply_plan_to_existing_number().

1635 {
1636  switch (plan) {
1637  case PRI_INTERNATIONAL_ISDN: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
1638  snprintf(buf, size, "%s%s", pri->internationalprefix, number);
1639  break;
1640  case PRI_NATIONAL_ISDN: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
1641  snprintf(buf, size, "%s%s", pri->nationalprefix, number);
1642  break;
1643  case PRI_LOCAL_ISDN: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
1644  snprintf(buf, size, "%s%s", pri->localprefix, number);
1645  break;
1646  case PRI_PRIVATE: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
1647  snprintf(buf, size, "%s%s", pri->privateprefix, number);
1648  break;
1649  case PRI_UNKNOWN: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
1650  snprintf(buf, size, "%s%s", pri->unknownprefix, number);
1651  break;
1652  default: /* other Q.931 dialplan => don't twiddle with callingnum */
1653  snprintf(buf, size, "%s", number);
1654  break;
1655  }
1656 }
char nationalprefix[10]
Definition: sig_pri.h:407
char localprefix[20]
Definition: sig_pri.h:408
Number structure.
Definition: app_followme.c:109
char unknownprefix[20]
Definition: sig_pri.h:410
char internationalprefix[10]
Definition: sig_pri.h:406
char privateprefix[20]
Definition: sig_pri.h:409
static unsigned char ast_pri_pack_hex_char ( char  c)
static

Definition at line 696 of file sig_pri.c.

Referenced by ast_pri_pack_hex_string().

697 {
698  unsigned char res;
699 
700  if (c < '0') {
701  res = 0;
702  } else if (c < ('9' + 1)) {
703  res = c - '0';
704  } else if (c < 'A') {
705  res = 0;
706  } else if (c < ('F' + 1)) {
707  res = c - 'A' + 10;
708  } else if (c < 'a') {
709  res = 0;
710  } else if (c < ('f' + 1)) {
711  res = c - 'a' + 10;
712  } else {
713  res = 0;
714  }
715  return res;
716 }
static int ast_pri_pack_hex_string ( unsigned char *  dst,
char *  src,
int  maxlen 
)
static

Definition at line 735 of file sig_pri.c.

References ast_pri_pack_hex_char(), and len().

Referenced by sig_pri_party_subaddress_from_ast().

736 {
737  int res = 0;
738  int len = strlen(src);
739 
740  if (len > (2 * maxlen)) {
741  len = 2 * maxlen;
742  }
743 
744  res = len / 2 + len % 2;
745 
746  while (len > 1) {
747  *dst = ast_pri_pack_hex_char(*src) << 4;
748  src++;
749  *dst |= ast_pri_pack_hex_char(*src);
750  dst++, src++;
751  len -= 2;
752  }
753  if (len) { /* 1 left */
754  *dst = ast_pri_pack_hex_char(*src) << 4;
755  }
756  return res;
757 }
static unsigned char ast_pri_pack_hex_char(char c)
Definition: sig_pri.c:696
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int ast_to_pri_char_set ( enum AST_PARTY_CHAR_SET  ast_char_set)
static

Definition at line 597 of file sig_pri.c.

References AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, AST_PARTY_CHAR_SET_ISO8859_1, AST_PARTY_CHAR_SET_ISO8859_2, AST_PARTY_CHAR_SET_ISO8859_3, AST_PARTY_CHAR_SET_ISO8859_4, AST_PARTY_CHAR_SET_ISO8859_5, AST_PARTY_CHAR_SET_ISO8859_7, AST_PARTY_CHAR_SET_UNKNOWN, and AST_PARTY_CHAR_SET_WITHDRAWN.

Referenced by sig_pri_party_name_from_ast().

598 {
599  int pri_char_set;
600 
601  switch (ast_char_set) {
602  default:
604  pri_char_set = PRI_CHAR_SET_UNKNOWN;
605  break;
607  pri_char_set = PRI_CHAR_SET_ISO8859_1;
608  break;
610  pri_char_set = PRI_CHAR_SET_WITHDRAWN;
611  break;
613  pri_char_set = PRI_CHAR_SET_ISO8859_2;
614  break;
616  pri_char_set = PRI_CHAR_SET_ISO8859_3;
617  break;
619  pri_char_set = PRI_CHAR_SET_ISO8859_4;
620  break;
622  pri_char_set = PRI_CHAR_SET_ISO8859_5;
623  break;
625  pri_char_set = PRI_CHAR_SET_ISO8859_7;
626  break;
628  pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
629  break;
631  pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
632  break;
633  }
634 
635  return pri_char_set;
636 }
static int ast_to_pri_presentation ( int  ast_presentation)
static

Definition at line 492 of file sig_pri.c.

References AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.

Referenced by sig_pri_party_name_from_ast(), and sig_pri_party_number_from_ast().

493 {
494  int pri_presentation;
495 
496  switch (ast_presentation) {
498  pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
499  break;
501  pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
502  break;
504  pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
505  break;
507  pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
508  break;
509 
511  pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
512  break;
514  pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
515  break;
517  pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
518  break;
520  pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
521  break;
522 
527  pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
528  break;
529 
530  default:
531  pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
532  break;
533  }
534 
535  return pri_presentation;
536 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326
static int ast_to_pri_reason ( enum AST_REDIRECTING_REASON  ast_reason)
static

Definition at line 402 of file sig_pri.c.

References AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, and AST_REDIRECTING_REASON_USER_BUSY.

Referenced by sig_pri_redirecting_update().

403 {
404  int pri_reason;
405 
406  switch (ast_reason) {
408  pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
409  break;
411  pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
412  break;
414  pri_reason = PRI_REDIR_UNCONDITIONAL;
415  break;
417  pri_reason = PRI_REDIR_DEFLECTION;
418  break;
420  default:
421  pri_reason = PRI_REDIR_UNKNOWN;
422  break;
423  }
424 
425  return pri_reason;
426 }
static void build_status ( char *  s,
size_t  len,
int  status,
int  active 
)
static

Definition at line 8007 of file sig_pri.c.

References DCHAN_NOTINALARM, and DCHAN_UP.

Referenced by sig_pri_cli_show_span(), and sig_pri_cli_show_spans().

8008 {
8009  if (!s || len < 1) {
8010  return;
8011  }
8012  s[0] = '\0';
8013  if (!(status & DCHAN_NOTINALARM))
8014  strncat(s, "In Alarm, ", len - strlen(s) - 1);
8015  if (status & DCHAN_UP)
8016  strncat(s, "Up", len - strlen(s) - 1);
8017  else
8018  strncat(s, "Down", len - strlen(s) - 1);
8019  if (active)
8020  strncat(s, ", Active", len - strlen(s) - 1);
8021  else
8022  strncat(s, ", Standby", len - strlen(s) - 1);
8023  s[len - 1] = '\0';
8024 }
#define DCHAN_NOTINALARM
Definition: sig_pri.c:108
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define DCHAN_UP
Definition: sig_pri.c:109
jack_status_t status
Definition: app_jack.c:143
static int detect_aoc_e_subcmd ( const struct pri_subcommands *  subcmds)
static

Definition at line 4070 of file sig_pri.c.

Referenced by pri_dchannel().

4071 {
4072  int i;
4073 
4074  if (!subcmds) {
4075  return 0;
4076  }
4077  for (i = 0; i < subcmds->counter_subcmd; ++i) {
4078  const struct pri_subcommand *subcmd = &subcmds->subcmd[i];
4079  if (subcmd->cmd == PRI_SUBCMD_AOC_E) {
4080  return 1;
4081  }
4082  }
4083  return 0;
4084 }
static char* dialplan2str ( int  dialplan)
static

Definition at line 1614 of file sig_pri.c.

Referenced by sig_pri_call().

1615 {
1616  if (dialplan == -1) {
1617  return("Dynamically set dialplan in ISDN");
1618  }
1619  return (pri_plan2str(dialplan));
1620 }
static void* do_idle_thread ( void *  v_pvt)
static

Definition at line 1834 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_remaining_ms(), ast_tvnow(), ast_verb, ast_waitfor(), sig_pri_chan::channel, ast_channel::context, ast_channel::exten, f, ast_frame::frametype, sig_pri_span::idlecontext, sig_pri_span::idledial, sig_pri_span::idleext, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, sig_pri_chan::owner, sig_pri_chan::pri, ast_channel::priority, and ast_frame::subclass.

Referenced by pri_dchannel().

1835 {
1836  struct sig_pri_chan *pvt = v_pvt;
1837  struct ast_channel *chan = pvt->owner;
1838  struct ast_frame *f;
1839  char ex[80];
1840  /* Wait up to 30 seconds for an answer */
1841  int timeout_ms = 30000;
1842  int ms;
1843  struct timeval start;
1844 
1845  ast_verb(3, "Initiating idle call on channel %s\n", chan->name);
1846  snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
1847  if (ast_call(chan, ex, 0)) {
1848  ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
1849  ast_hangup(chan);
1850  return NULL;
1851  }
1852  start = ast_tvnow();
1853  while ((ms = ast_remaining_ms(start, timeout_ms))) {
1854  if (ast_waitfor(chan, ms) <= 0) {
1855  break;
1856  }
1857 
1858  f = ast_read(chan);
1859  if (!f) {
1860  /* Got hangup */
1861  break;
1862  }
1863  if (f->frametype == AST_FRAME_CONTROL) {
1864  switch (f->subclass.integer) {
1865  case AST_CONTROL_ANSWER:
1866  /* Launch the PBX */
1867  ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
1868  ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
1869  chan->priority = 1;
1870  ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
1871  ast_pbx_run(chan);
1872  /* It's already hungup, return immediately */
1873  return NULL;
1874  case AST_CONTROL_BUSY:
1875  ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name);
1876  break;
1878  ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name);
1879  break;
1880  };
1881  }
1882  ast_frfree(f);
1883  }
1884  /* Hangup the channel since nothing happend */
1885  ast_hangup(chan);
1886  return NULL;
1887 }
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
Main Channel structure associated with a channel.
Definition: channel.h:742
int priority
Definition: channel.h:841
char idleext[AST_MAX_EXTENSION]
Definition: sig_pri.h:429
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
char idlecontext[AST_MAX_CONTEXT]
Definition: sig_pri.h:430
struct ast_channel * owner
Definition: sig_pri.h:294
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_verb(level,...)
Definition: logger.h:243
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:1615
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char idledial[AST_MAX_EXTENSION]
Definition: sig_pri.h:431
static struct ast_format f[]
Definition: format_g726.c:181
int ast_call(struct ast_channel *chan, char *addr, int timeout)
Make a call.
Definition: channel.c:5761
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
Data structure associated with a single frame of data.
Definition: frame.h:142
struct sig_pri_span * pri
Definition: sig_pri.h:296
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int channel
Definition: sig_pri.h:234
static int pri_active_dchan_index ( struct sig_pri_span pri)
static

Definition at line 1054 of file sig_pri.c.

References ast_log(), sig_pri_span::dchans, LOG_WARNING, sig_pri_span::pri, and SIG_PRI_NUM_DCHANS.

Referenced by pri_find_principle().

1055 {
1056  int x;
1057 
1058  for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
1059  if ((pri->dchans[x] == pri->pri))
1060  return x;
1061  }
1062 
1063  ast_log(LOG_WARNING, "No active dchan found!\n");
1064  return -1;
1065 }
#define LOG_WARNING
Definition: logger.h:144
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
struct pri * pri
Definition: sig_pri.h:481
static void pri_check_restart ( struct sig_pri_span pri)
static

Definition at line 1692 of file sig_pri.c.

References ast_log(), sig_pri_chan::channel, sig_pri_span::lastreset, LOG_NOTICE, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_span::pri, PVT_TO_CHANNEL(), sig_pri_span::pvts, sig_pri_span::resetpos, sig_pri_chan::resetting, sig_pri_span::resetting, sig_pri_chan::service_status, sig_pri_is_chan_in_use(), SIG_PRI_RESET_ACTIVE, sig_pri_span_devstate_changed(), sig_pri_span::span, SRVST_FAREND, and SRVST_NEAREND.

Referenced by pri_dchannel().

1693 {
1694 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1695  unsigned why;
1696 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
1697 
1698  for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) {
1699  if (!pri->pvts[pri->resetpos]
1700  || pri->pvts[pri->resetpos]->no_b_channel
1701  || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) {
1702  continue;
1703  }
1704 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1705  why = pri->pvts[pri->resetpos]->service_status;
1706  if (why) {
1708  "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
1709  pri->span, pri->pvts[pri->resetpos]->channel,
1710  (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
1711  continue;
1712  }
1713 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
1714  break;
1715  }
1716  if (pri->resetpos < pri->numchans) {
1717  /* Mark the channel as resetting and restart it */
1719  pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
1720  } else {
1721  pri->resetting = 0;
1722  time(&pri->lastreset);
1724  }
1725 }
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:302
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
unsigned service_status
Active SRVST_DBKEY out-of-service status value.
Definition: sig_pri.h:308
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
The channel is being RESTARTed.
Definition: sig_pri.h:111
time_t lastreset
Definition: sig_pri.h:496
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int resetpos
Definition: sig_pri.h:473
static int sig_pri_is_chan_in_use(struct sig_pri_chan *pvt)
Definition: sig_pri.c:1146
int numchans
Definition: sig_pri.h:492
int resetting
Definition: sig_pri.h:472
#define SRVST_NEAREND
SRVST_NEAREND is used to indicate that the near end was put out-of-service.
Definition: sig_pri.h:212
struct pri * pri
Definition: sig_pri.h:481
int channel
Definition: sig_pri.h:234
#define SRVST_FAREND
SRVST_FAREND is used to indicate that the far end was taken out-of-service.
Definition: sig_pri.h:214
static void* pri_dchannel ( void *  vpri)
static

Definition at line 4596 of file sig_pri.c.

References ast_channel::_softhangup, ast_channel::_state, sig_pri_chan::allocated, sig_pri_span::allow_call_waiting_calls, sig_pri_chan::alreadyhungup, sig_pri_span::aoce_delayhangup, sig_pri_span::append_msn_to_user_tag, apply_plan_to_existing_number(), ast_atomic_fetchadd_int(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_USER_BUSY, AST_CC_CCBS, AST_CC_CCNR, ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_db_del(), ast_db_put(), ast_debug, ast_exists_extension(), AST_FRAME_DTMF, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_party_subaddress_free(), ast_party_subaddress_init(), ast_pbx_start(), ast_pthread_create_background, ast_pthread_create_detached, ast_setstate(), ast_shrink_phone_number(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_BUSY, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), AST_TRANS_CAP_DIGITAL, ast_tv(), ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_verb, ast_verbose(), sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_chan::callingpres, sig_pri_chan::channel, 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, sig_pri_chan::context, dahdi_db, DAHDI_OVERLAPDIAL_INCOMING, DAHDI_OVERLAPDIAL_OUTGOING, ast_channel::data, DCHAN_UP, sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::debug, sig_pri_chan::deferred_digits, detect_aoc_e_subcmd(), sig_pri_chan::dialdest, ast_channel::dialed, sig_pri_chan::digital, sig_pri_span::discardremoteholdretrieval, do_idle_thread(), errno, sig_pri_chan::exten, sig_pri_span::fds, ast_channel::hangupcause, HAVE_PRI_SETUP_ACK_INBAND, sig_pri_span::hold_disconnect_transfer, sig_pri_chan::holding_aoce, ast_party_caller::id, sig_pri_span::idlecontext, sig_pri_span::idledial, sig_pri_span::idleext, sig_pri_chan::immediate, sig_pri_span::inband_on_proceeding, sig_pri_span::inband_on_setup_ack, sig_pri_span::initial_user_tag, sig_pri_chan::is_call_waiting, sig_pri_chan::isidlecall, sig_pri_chan::keypad_digits, sig_pri_span::lastreset, len(), sig_pri_span::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sig_pri_chan::logicalspan, sig_pri_span::minidle, sig_pri_span::minunused, sig_pri_span::msn_list, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_span::no_d_channels, sig_pri_chan::no_dialed_digits, sig_pri_span::nodetype, sig_pri_span::num_call_waiting_calls, ast_party_dialed::number, sig_pri_span::numchans, sig_pri_chan::outgoing, sig_pri_span::overlapdial, sig_pri_chan::owner, pbx_builtin_setvar_helper(), ast_party_dialed::plan, sig_pri_chan::pri, sig_pri_span::pri, PRI_CHANNEL, pri_check_restart(), pri_find_dchan(), pri_find_empty_chan(), pri_find_empty_nobch(), pri_find_fixup_principle(), pri_find_principle(), pri_find_principle_by_call(), pri_fixup_principle(), pri_is_up(), pri_order(), pri_queue_control(), pri_queue_frame(), PRI_SPAN, pri_ss_thread(), sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), sig_pri_span::pvts, redirectingreason2str(), sig_pri_span::resetinterval, sig_pri_span::resetpos, sig_pri_chan::resetting, sig_pri_span::resetting, sig_pri_chan::reverse_charging_indication, S_OR, sig_pri_chan::service_status, sig_pri_span::sig, SIG_BRI_PTMP, SIG_PRI_ALAW, sig_pri_attempt_transfer(), SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_cc_generic_check(), SIG_PRI_DEFLAW, sig_pri_dial_digits(), sig_pri_handle_cis_subcmds(), sig_pri_handle_dchan_exception(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_handle_subcmds(), sig_pri_init_config(), sig_pri_is_chan_available(), sig_pri_is_cis_call(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_msn_match(), sig_pri_new_ast_channel(), SIG_PRI_NUM_DCHANS, sig_pri_open_media(), sig_pri_request(), SIG_PRI_RESET_ACTIVE, SIG_PRI_RESET_IDLE, SIG_PRI_RESET_NO_ACK, sig_pri_send_aoce_termination_request(), sig_pri_set_alarm(), sig_pri_set_caller_id(), sig_pri_set_dialing(), sig_pri_set_dnid(), sig_pri_set_echocanceller(), sig_pri_set_rdnis(), sig_pri_set_subaddress(), sig_pri_span_devstate_changed(), SIG_PRI_ULAW, sig_pri_unlock_private(), sig_pri_span::span, SRVST_DBKEY, SRVST_FAREND, SRVST_NEAREND, SRVST_TYPE_OOS, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_dialed::subaddress, sig_pri_span::switchtype, tv, sig_pri_chan::use_callerid, and sig_pri_chan::user_tag.

Referenced by sig_pri_start_pri().

4597 {
4598  struct sig_pri_span *pri = vpri;
4599  pri_event *e;
4600  struct pollfd fds[SIG_PRI_NUM_DCHANS];
4601  int res;
4602  int chanpos = 0;
4603  int x;
4604  enum sig_pri_law law;
4605  struct ast_channel *c;
4606  struct timeval tv, lowest, *next;
4607  int doidling=0;
4608  char *cc;
4609  time_t t;
4610  int i, which=-1;
4611  int numdchans;
4612  pthread_t threadid;
4613  char ani2str[6];
4614  char plancallingnum[AST_MAX_EXTENSION];
4615  char plancallingani[AST_MAX_EXTENSION];
4616  char calledtonstr[10];
4617  struct timeval lastidle = { 0, 0 };
4618  pthread_t p;
4619  struct ast_channel *idle;
4620  char idlen[80];
4621  int nextidle = -1;
4622  int haveidles;
4623  int activeidles;
4624  unsigned int len;
4625 
4626  gettimeofday(&lastidle, NULL);
4627  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
4628 
4629  if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
4630  /* Need to do idle dialing, check to be sure though */
4631  cc = strchr(pri->idleext, '@');
4632  if (cc) {
4633  *cc = '\0';
4634  cc++;
4635  ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
4636 #if 0
4637  /* Extensions may not be loaded yet */
4638  if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
4639  ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
4640  else
4641 #endif
4642  doidling = 1;
4643  } else
4644  ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
4645  }
4646  for (;;) {
4647  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
4648  if (!pri->dchans[i])
4649  break;
4650  fds[i].fd = pri->fds[i];
4651  fds[i].events = POLLIN | POLLPRI;
4652  fds[i].revents = 0;
4653  }
4654  numdchans = i;
4655  time(&t);
4656  ast_mutex_lock(&pri->lock);
4657  if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) {
4658  if (pri->resetting && pri_is_up(pri)) {
4659  if (pri->resetpos < 0) {
4660  pri_check_restart(pri);
4661  if (pri->resetting) {
4663  }
4664  }
4665  } else {
4666  if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) {
4667  pri->resetting = 1;
4668  pri->resetpos = -1;
4669  }
4670  }
4671  }
4672  /* Look for any idle channels if appropriate */
4673  if (doidling && pri_is_up(pri)) {
4674  nextidle = -1;
4675  haveidles = 0;
4676  activeidles = 0;
4677  for (x = pri->numchans; x >= 0; x--) {
4678  if (pri->pvts[x] && !pri->pvts[x]->no_b_channel) {
4679  if (sig_pri_is_chan_available(pri->pvts[x])) {
4680  if (haveidles < pri->minunused) {
4681  haveidles++;
4682  } else {
4683  nextidle = x;
4684  break;
4685  }
4686  } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
4687  activeidles++;
4688  }
4689  }
4690  }
4691  if (nextidle > -1) {
4692  if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
4693  /* Don't create a new idle call more than once per second */
4694  snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
4695  pri->pvts[nextidle]->allocated = 1;
4696  /*
4697  * Release the PRI lock while we create the channel so other
4698  * threads can send D channel messages.
4699  */
4700  ast_mutex_unlock(&pri->lock);
4701  /*
4702  * We already have the B channel reserved for this call. We
4703  * just need to make sure that sig_pri_hangup() has completed
4704  * cleaning up before continuing.
4705  */
4706  sig_pri_lock_private(pri->pvts[nextidle]);
4707  sig_pri_unlock_private(pri->pvts[nextidle]);
4708  idle = sig_pri_request(pri->pvts[nextidle], SIG_PRI_ULAW, NULL, 0);
4709  ast_mutex_lock(&pri->lock);
4710  if (idle) {
4711  pri->pvts[nextidle]->isidlecall = 1;
4712  if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) {
4713  ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
4714  ast_mutex_unlock(&pri->lock);
4715  ast_hangup(idle);
4716  ast_mutex_lock(&pri->lock);
4717  }
4718  } else {
4719  pri->pvts[nextidle]->allocated = 0;
4720  ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
4721  }
4722  gettimeofday(&lastidle, NULL);
4723  }
4724  } else if ((haveidles < pri->minunused) &&
4725  (activeidles > pri->minidle)) {
4726  /* Mark something for hangup if there is something
4727  that can be hungup */
4728  for (x = pri->numchans; x >= 0; x--) {
4729  /* find a candidate channel */
4730  if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
4732  haveidles++;
4733  /* Stop if we have enough idle channels or
4734  can't spare any more active idle ones */
4735  if ((haveidles >= pri->minunused) ||
4736  (activeidles <= pri->minidle))
4737  break;
4738  }
4739  }
4740  }
4741  }
4742  /* Start with reasonable max */
4743  if (doidling || pri->resetting) {
4744  /*
4745  * Make sure we stop at least once per second if we're
4746  * monitoring idle channels
4747  */
4748  lowest = ast_tv(1, 0);
4749  } else {
4750  /* Don't poll for more than 60 seconds */
4751  lowest = ast_tv(60, 0);
4752  }
4753  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
4754  if (!pri->dchans[i]) {
4755  /* We scanned all D channels on this span. */
4756  break;
4757  }
4758  next = pri_schedule_next(pri->dchans[i]);
4759  if (next) {
4760  /* We need relative time here */
4761  tv = ast_tvsub(*next, ast_tvnow());
4762  if (tv.tv_sec < 0) {
4763  /*
4764  * A timer has already expired.
4765  * By definition zero time is the lowest so we can quit early.
4766  */
4767  lowest = ast_tv(0, 0);
4768  break;
4769  }
4770  if (ast_tvcmp(tv, lowest) < 0) {
4771  lowest = tv;
4772  }
4773  }
4774  }
4775  ast_mutex_unlock(&pri->lock);
4776 
4777  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
4778  pthread_testcancel();
4779  e = NULL;
4780  res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
4781  pthread_testcancel();
4782  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
4783 
4784  ast_mutex_lock(&pri->lock);
4785  if (!res) {
4786  for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
4787  if (!pri->dchans[which])
4788  break;
4789  /* Just a timeout, run the scheduler */
4790  e = pri_schedule_run(pri->dchans[which]);
4791  if (e)
4792  break;
4793  }
4794  } else if (res > -1) {
4795  for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
4796  if (!pri->dchans[which])
4797  break;
4798  if (fds[which].revents & POLLPRI) {
4799  sig_pri_handle_dchan_exception(pri, which);
4800  } else if (fds[which].revents & POLLIN) {
4801  e = pri_check_event(pri->dchans[which]);
4802  }
4803  if (e)
4804  break;
4805  }
4806  } else if (errno != EINTR)
4807  ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
4808 
4809  if (e) {
4810  if (pri->debug) {
4811  ast_verbose("Span %d: Processing event %s\n",
4812  pri->span, pri_event2str(e->e));
4813  }
4814 
4815  if (e->e != PRI_EVENT_DCHAN_DOWN) {
4816  if (!(pri->dchanavail[which] & DCHAN_UP)) {
4817  ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
4818  }
4819  pri->dchanavail[which] |= DCHAN_UP;
4820  } else {
4821  if (pri->dchanavail[which] & DCHAN_UP) {
4822  ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
4823  }
4824  pri->dchanavail[which] &= ~DCHAN_UP;
4825  }
4826 
4827  if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
4828  /* Must be an NFAS group that has the secondary dchan active */
4829  pri->pri = pri->dchans[which];
4830 
4831  switch (e->e) {
4832  case PRI_EVENT_DCHAN_UP:
4833  pri->no_d_channels = 0;
4834  if (!pri->pri) {
4835  pri_find_dchan(pri);
4836  }
4837 
4838  /* Note presense of D-channel */
4839  time(&pri->lastreset);
4840 
4841  /* Restart in 5 seconds */
4842  if (pri->resetinterval > -1) {
4843  pri->lastreset -= pri->resetinterval;
4844  pri->lastreset += 5;
4845  }
4846  /* Take the channels from inalarm condition */
4847  pri->resetting = 0;
4848  for (i = 0; i < pri->numchans; i++) {
4849  if (pri->pvts[i]) {
4850  sig_pri_set_alarm(pri->pvts[i], 0);
4851  }
4852  }
4854  break;
4855  case PRI_EVENT_DCHAN_DOWN:
4856  pri_find_dchan(pri);
4857  if (!pri_is_up(pri)) {
4858  if (pri->sig == SIG_BRI_PTMP) {
4859  /*
4860  * For PTMP connections with non-persistent layer 2 we want to
4861  * *not* declare inalarm unless there actually is an alarm.
4862  */
4863  break;
4864  }
4865  /* Hangup active channels and put them in alarm mode */
4866  pri->resetting = 0;
4867  for (i = 0; i < pri->numchans; i++) {
4868  struct sig_pri_chan *p = pri->pvts[i];
4869 
4870  if (p) {
4871  if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
4872  /* T309 is not enabled : destroy calls when alarm occurs */
4873  if (p->call) {
4874  pri_destroycall(p->pri->pri, p->call);
4875  p->call = NULL;
4876  }
4877  if (p->owner)
4879  }
4880  sig_pri_set_alarm(p, 1);
4881  }
4882  }
4884  }
4885  break;
4886  case PRI_EVENT_RESTART:
4887  if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
4888  chanpos = pri_find_principle(pri, e->restart.channel, NULL);
4889  if (chanpos < 0)
4891  "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
4892  pri->span, PRI_SPAN(e->restart.channel),
4893  PRI_CHANNEL(e->restart.channel));
4894  else {
4895  int skipit = 0;
4896 #if defined(HAVE_PRI_SERVICE_MESSAGES)
4897  unsigned why;
4898 
4899  why = pri->pvts[chanpos]->service_status;
4900  if (why) {
4902  "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
4903  pri->span, PRI_SPAN(e->restart.channel),
4904  PRI_CHANNEL(e->restart.channel),
4905  (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
4906  skipit = 1;
4907  }
4908 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
4909  sig_pri_lock_private(pri->pvts[chanpos]);
4910  if (!skipit) {
4911  ast_verb(3, "Span %d: Channel %d/%d restarted\n", pri->span,
4912  PRI_SPAN(e->restart.channel),
4913  PRI_CHANNEL(e->restart.channel));
4914  if (pri->pvts[chanpos]->call) {
4915  pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
4916  pri->pvts[chanpos]->call = NULL;
4917  }
4918  }
4919  /* Force soft hangup if appropriate */
4920  if (pri->pvts[chanpos]->owner)
4921  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
4922  sig_pri_unlock_private(pri->pvts[chanpos]);
4923  }
4924  } else {
4925  ast_verb(3, "Restart requested on entire span %d\n", pri->span);
4926  for (x = 0; x < pri->numchans; x++)
4927  if (pri->pvts[x]) {
4928  sig_pri_lock_private(pri->pvts[x]);
4929  if (pri->pvts[x]->call) {
4930  pri_destroycall(pri->pri, pri->pvts[x]->call);
4931  pri->pvts[x]->call = NULL;
4932  }
4933  if (pri->pvts[x]->owner)
4935  sig_pri_unlock_private(pri->pvts[x]);
4936  }
4937  }
4939  break;
4940  case PRI_EVENT_KEYPAD_DIGIT:
4941  if (sig_pri_is_cis_call(e->digit.channel)) {
4942  sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds,
4943  e->digit.call);
4944  break;
4945  }
4946  chanpos = pri_find_principle_by_call(pri, e->digit.call);
4947  if (chanpos < 0) {
4949  "Span %d: Received keypad digits for unknown call.\n", pri->span);
4950  break;
4951  }
4952  sig_pri_lock_private(pri->pvts[chanpos]);
4953  sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.channel,
4954  e->digit.subcmds, e->digit.call);
4955  /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
4957  && pri->pvts[chanpos]->owner) {
4958  /* how to do that */
4959  int digitlen = strlen(e->digit.digits);
4960  int i;
4961 
4962  for (i = 0; i < digitlen; i++) {
4963  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], };
4964 
4965  pri_queue_frame(pri, chanpos, &f);
4966  }
4967  }
4968  sig_pri_unlock_private(pri->pvts[chanpos]);
4969  break;
4970 
4971  case PRI_EVENT_INFO_RECEIVED:
4972  if (sig_pri_is_cis_call(e->ring.channel)) {
4973  sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
4974  e->ring.call);
4975  break;
4976  }
4977  chanpos = pri_find_principle_by_call(pri, e->ring.call);
4978  if (chanpos < 0) {
4980  "Span %d: Received INFORMATION for unknown call.\n", pri->span);
4981  break;
4982  }
4983  sig_pri_lock_private(pri->pvts[chanpos]);
4984  sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
4985  e->ring.subcmds, e->ring.call);
4986  /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
4988  && pri->pvts[chanpos]->owner) {
4989  /* how to do that */
4990  int digitlen = strlen(e->ring.callednum);
4991  int i;
4992 
4993  for (i = 0; i < digitlen; i++) {
4994  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], };
4995 
4996  pri_queue_frame(pri, chanpos, &f);
4997  }
4998  }
4999  sig_pri_unlock_private(pri->pvts[chanpos]);
5000  break;
5001 #if defined(HAVE_PRI_SERVICE_MESSAGES)
5002  case PRI_EVENT_SERVICE:
5003  chanpos = pri_find_principle(pri, e->service.channel, NULL);
5004  if (chanpos < 0) {
5005  ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n",
5006  e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
5007  } else {
5008  char db_chan_name[20];
5009  char db_answer[5];
5010  int ch;
5011  unsigned *why;
5012 
5013  ch = pri->pvts[chanpos]->channel;
5014  snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch);
5015  why = &pri->pvts[chanpos]->service_status;
5016  switch (e->service.changestatus) {
5017  case 0: /* in-service */
5018  /* Far end wants to be in service now. */
5019  ast_db_del(db_chan_name, SRVST_DBKEY);
5020  *why &= ~SRVST_FAREND;
5021  if (*why) {
5022  snprintf(db_answer, sizeof(db_answer), "%s:%u",
5023  SRVST_TYPE_OOS, *why);
5024  ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
5025  } else {
5027  }
5028  break;
5029  case 2: /* out-of-service */
5030  /* Far end wants to be out-of-service now. */
5031  ast_db_del(db_chan_name, SRVST_DBKEY);
5032  *why |= SRVST_FAREND;
5033  snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS,
5034  *why);
5035  ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
5037  break;
5038  default:
5039  ast_log(LOG_ERROR, "Huh? changestatus is: %d\n", e->service.changestatus);
5040  break;
5041  }
5042  ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
5043  PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus);
5044  }
5045  break;
5046  case PRI_EVENT_SERVICE_ACK:
5047  chanpos = pri_find_principle(pri, e->service_ack.channel, NULL);
5048  if (chanpos < 0) {
5049  ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
5050  e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
5051  } else {
5052  ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
5053  PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus);
5054  }
5055  break;
5056 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
5057  case PRI_EVENT_RING:
5058  if (!ast_strlen_zero(pri->msn_list)
5059  && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) {
5060  /* The call is not for us so ignore it. */
5061  ast_verb(3,
5062  "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
5063  e->ring.callednum, pri->span, pri->msn_list);
5064  pri_destroycall(pri->pri, e->ring.call);
5065  break;
5066  }
5067  if (sig_pri_is_cis_call(e->ring.channel)) {
5068  sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
5069  e->ring.call);
5070  break;
5071  }
5072  chanpos = pri_find_principle_by_call(pri, e->ring.call);
5073  if (-1 < chanpos) {
5074  /* Libpri has already filtered out duplicate SETUPs. */
5076  "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
5077  pri->span, e->ring.call);
5078  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5079  break;
5080  }
5081  if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
5082  /* Any channel requested. */
5083  chanpos = pri_find_empty_chan(pri, 1);
5084  } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
5085  /* No channel specified. */
5086 #if defined(HAVE_PRI_CALL_WAITING)
5087  if (!pri->allow_call_waiting_calls)
5088 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5089  {
5090  /* We will not accept incoming call waiting calls. */
5091  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5092  break;
5093  }
5094 #if defined(HAVE_PRI_CALL_WAITING)
5095  chanpos = pri_find_empty_nobch(pri);
5096  if (chanpos < 0) {
5097  /* We could not find/create a call interface. */
5098  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5099  break;
5100  }
5101  /* Setup the call interface to use. */
5102  sig_pri_init_config(pri->pvts[chanpos], pri);
5103 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5104  } else {
5105  /* A channel is specified. */
5106  chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
5107  if (chanpos < 0) {
5109  "Span %d: SETUP on unconfigured channel %d/%d\n",
5110  pri->span, PRI_SPAN(e->ring.channel),
5111  PRI_CHANNEL(e->ring.channel));
5112  } else {
5113  switch (pri->pvts[chanpos]->resetting) {
5114  case SIG_PRI_RESET_IDLE:
5115  break;
5116  case SIG_PRI_RESET_ACTIVE:
5117  /*
5118  * The peer may have lost the expected ack or not received the
5119  * RESTART yet.
5120  */
5121  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_NO_ACK;
5122  break;
5123  case SIG_PRI_RESET_NO_ACK:
5124  /* The peer likely is not going to ack the RESTART. */
5125  ast_debug(1,
5126  "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
5127  pri->span, PRI_SPAN(e->ring.channel),
5128  PRI_CHANNEL(e->ring.channel));
5129 
5130  /* Assume we got the ack. */
5131  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
5132  if (pri->resetting) {
5133  /* Go on to the next idle channel to RESTART. */
5134  pri_check_restart(pri);
5135  }
5136  break;
5137  }
5138  if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
5139  /* This is where we handle initial glare */
5140  ast_debug(1,
5141  "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
5142  pri->span, PRI_SPAN(e->ring.channel),
5143  PRI_CHANNEL(e->ring.channel));
5144  chanpos = -1;
5145  }
5146  }
5147 #if defined(ALWAYS_PICK_CHANNEL)
5148  if (e->ring.flexible) {
5149  chanpos = -1;
5150  }
5151 #endif /* defined(ALWAYS_PICK_CHANNEL) */
5152  if (chanpos < 0 && e->ring.flexible) {
5153  /* We can try to pick another channel. */
5154  chanpos = pri_find_empty_chan(pri, 1);
5155  }
5156  }
5157  if (chanpos < 0) {
5158  if (e->ring.flexible) {
5159  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5160  } else {
5161  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5162  }
5163  break;
5164  }
5165 
5166  sig_pri_lock_private(pri->pvts[chanpos]);
5167 
5168  /* Mark channel as in use so noone else will steal it. */
5169  pri->pvts[chanpos]->call = e->ring.call;
5170 
5171  /* Use plancallingnum as a scratch buffer since it is initialized next. */
5172  apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
5173  e->ring.redirectingnum, e->ring.callingplanrdnis);
5174  sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum);
5175 
5176  /* Setup caller-id info */
5177  apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
5178  e->ring.callingnum, e->ring.callingplan);
5179  pri->pvts[chanpos]->cid_ani2 = 0;
5180  if (pri->pvts[chanpos]->use_callerid) {
5181  ast_shrink_phone_number(plancallingnum);
5182  ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
5183 #ifdef PRI_ANI
5184  apply_plan_to_existing_number(plancallingani, sizeof(plancallingani),
5185  pri, e->ring.callingani, e->ring.callingplanani);
5186  ast_shrink_phone_number(plancallingani);
5187  ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani,
5188  sizeof(pri->pvts[chanpos]->cid_ani));
5189 #endif
5190  pri->pvts[chanpos]->cid_subaddr[0] = '\0';
5191 #if defined(HAVE_PRI_SUBADDR)
5192  if (e->ring.calling.subaddress.valid) {
5193  struct ast_party_subaddress calling_subaddress;
5194 
5195  ast_party_subaddress_init(&calling_subaddress);
5196  sig_pri_set_subaddress(&calling_subaddress,
5197  &e->ring.calling.subaddress);
5198  if (calling_subaddress.str) {
5199  ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
5200  calling_subaddress.str,
5201  sizeof(pri->pvts[chanpos]->cid_subaddr));
5202  }
5203  ast_party_subaddress_free(&calling_subaddress);
5204  }
5205 #endif /* defined(HAVE_PRI_SUBADDR) */
5206  ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
5207  pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
5208  pri->pvts[chanpos]->callingpres = e->ring.callingpres;
5209  if (e->ring.ani2 >= 0) {
5210  pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
5211  }
5212  } else {
5213  pri->pvts[chanpos]->cid_num[0] = '\0';
5214  pri->pvts[chanpos]->cid_subaddr[0] = '\0';
5215  pri->pvts[chanpos]->cid_ani[0] = '\0';
5216  pri->pvts[chanpos]->cid_name[0] = '\0';
5217  pri->pvts[chanpos]->cid_ton = 0;
5218  pri->pvts[chanpos]->callingpres = 0;
5219  }
5220 
5221  /* Setup the user tag for party id's from this device for this call. */
5222  if (pri->append_msn_to_user_tag) {
5223  snprintf(pri->pvts[chanpos]->user_tag,
5224  sizeof(pri->pvts[chanpos]->user_tag), "%s_%s",
5225  pri->initial_user_tag,
5226  pri->nodetype == PRI_NETWORK
5227  ? plancallingnum : e->ring.callednum);
5228  } else {
5229  ast_copy_string(pri->pvts[chanpos]->user_tag,
5230  pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag));
5231  }
5232 
5233  sig_pri_set_caller_id(pri->pvts[chanpos]);
5234 
5235  /* Set DNID on all incoming calls -- even immediate */
5236  sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum);
5237 
5238  /* If immediate=yes go to s|1 */
5239  if (pri->pvts[chanpos]->immediate) {
5240  ast_verb(3, "Going to extension s|1 because of immediate=yes\n");
5241  pri->pvts[chanpos]->exten[0] = 's';
5242  pri->pvts[chanpos]->exten[1] = '\0';
5243  }
5244  /* Get called number */
5245  else if (!ast_strlen_zero(e->ring.callednum)) {
5246  ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
5247  } else if (pri->overlapdial)
5248  pri->pvts[chanpos]->exten[0] = '\0';
5249  else {
5250  /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */
5251  pri->pvts[chanpos]->exten[0] = 's';
5252  pri->pvts[chanpos]->exten[1] = '\0';
5253  }
5254  /* No number yet, but received "sending complete"? */
5255  if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
5256  ast_verb(3, "Going to extension s|1 because of Complete received\n");
5257  pri->pvts[chanpos]->exten[0] = 's';
5258  pri->pvts[chanpos]->exten[1] = '\0';
5259  }
5260 
5261  /* Make sure extension exists (or in overlap dial mode, can exist) */
5262  if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
5263  ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
5264  int could_match_more;
5265  int need_dialtone;
5266 
5267  /* Select audio companding mode. */
5268  switch (e->ring.layer1) {
5269  case PRI_LAYER_1_ALAW:
5270  law = SIG_PRI_ALAW;
5271  break;
5272  case PRI_LAYER_1_ULAW:
5273  law = SIG_PRI_ULAW;
5274  break;
5275  default:
5276  /* This is a data call to us. */
5277  law = SIG_PRI_DEFLAW;
5278  break;
5279  }
5280 
5281  could_match_more = !e->ring.complete
5283  && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context,
5284  pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num);
5285 
5286  need_dialtone = could_match_more
5287  /*
5288  * Must explicitly check the digital capability this
5289  * way instead of checking the pvt->digital flag
5290  * because the flag hasn't been set yet.
5291  */
5292  && !(e->ring.ctype & AST_TRANS_CAP_DIGITAL)
5293  && !pri->pvts[chanpos]->no_b_channel
5294  && (!strlen(pri->pvts[chanpos]->exten)
5295  || ast_ignore_pattern(pri->pvts[chanpos]->context,
5296  pri->pvts[chanpos]->exten));
5297 
5298  if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
5299  /* Just announce proceeding */
5301  pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
5302  } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
5303  pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
5304  pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
5305  } else {
5306  pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
5307 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
5308  pri_setup_ack(pri->pri, e->ring.call,
5309  PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, need_dialtone);
5310 #else /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
5311  pri_need_more_info(pri->pri, e->ring.call,
5312  PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
5313 #endif /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
5314  }
5315 
5316  /* Start PBX */
5317  if (could_match_more) {
5318  /*
5319  * Release the PRI lock while we create the channel so other
5320  * threads can send D channel messages. We must also release
5321  * the private lock to prevent deadlock while creating the
5322  * channel.
5323  */
5324  sig_pri_unlock_private(pri->pvts[chanpos]);
5325  ast_mutex_unlock(&pri->lock);
5326  c = sig_pri_new_ast_channel(pri->pvts[chanpos],
5327  AST_STATE_RESERVED, law, e->ring.ctype,
5328  pri->pvts[chanpos]->exten, NULL);
5329  ast_mutex_lock(&pri->lock);
5330  sig_pri_lock_private(pri->pvts[chanpos]);
5331  if (c) {
5332 #if defined(HAVE_PRI_SUBADDR)
5333  if (e->ring.calling.subaddress.valid) {
5334  /* Set Calling Subaddress */
5335  sig_pri_lock_owner(pri, chanpos);
5337  &pri->pvts[chanpos]->owner->caller.id.subaddress,
5338  &e->ring.calling.subaddress);
5339  if (!e->ring.calling.subaddress.type
5340  && !ast_strlen_zero(
5341  (char *) e->ring.calling.subaddress.data)) {
5342  /* NSAP */
5343  pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
5344  (char *) e->ring.calling.subaddress.data);
5345  }
5346  ast_channel_unlock(c);
5347  }
5348  if (e->ring.called_subaddress.valid) {
5349  /* Set Called Subaddress */
5350  sig_pri_lock_owner(pri, chanpos);
5352  &pri->pvts[chanpos]->owner->dialed.subaddress,
5353  &e->ring.called_subaddress);
5354  if (!e->ring.called_subaddress.type
5355  && !ast_strlen_zero(
5356  (char *) e->ring.called_subaddress.data)) {
5357  /* NSAP */
5358  pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
5359  (char *) e->ring.called_subaddress.data);
5360  }
5361  ast_channel_unlock(c);
5362  }
5363 #else
5364  if (!ast_strlen_zero(e->ring.callingsubaddr)) {
5365  pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
5366  }
5367 #endif /* !defined(HAVE_PRI_SUBADDR) */
5368  if (e->ring.ani2 >= 0) {
5369  snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
5370  pbx_builtin_setvar_helper(c, "ANI2", ani2str);
5371  }
5372 
5373 #ifdef SUPPORT_USERUSER
5374  if (!ast_strlen_zero(e->ring.useruserinfo)) {
5375  pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
5376  }
5377 #endif
5378 
5379  snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
5380  pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
5381  ast_channel_lock(c);
5382  c->dialed.number.plan = e->ring.calledplan;
5383  ast_channel_unlock(c);
5384 
5385  if (e->ring.redirectingreason >= 0) {
5386  /* This is now just a status variable. Use REDIRECTING() dialplan function. */
5387  pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
5388  }
5389 #if defined(HAVE_PRI_REVERSE_CHARGE)
5390  pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
5391 #endif
5392 #if defined(HAVE_PRI_SETUP_KEYPAD)
5393  ast_copy_string(pri->pvts[chanpos]->keypad_digits,
5394  e->ring.keypad_digits,
5395  sizeof(pri->pvts[chanpos]->keypad_digits));
5396 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
5397 
5398  sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
5399  e->ring.subcmds, e->ring.call);
5400 
5401 #if !defined(HAVE_PRI_SETUP_ACK_INBAND)
5402  if (need_dialtone) {
5403  /* Indicate that we are providing dialtone. */
5404  pri->pvts[chanpos]->progress = 1;/* No need to send plain PROGRESS again. */
5405 #ifdef HAVE_PRI_PROG_W_CAUSE
5406  pri_progress_with_cause(pri->pri, e->ring.call,
5407  PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, -1);/* no cause at all */
5408 #else
5409  pri_progress(pri->pri, e->ring.call,
5410  PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
5411 #endif
5412  }
5413 #endif /* !defined(HAVE_PRI_SETUP_ACK_INBAND) */
5414  }
5415  if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
5416  ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
5417  plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
5418  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
5419  } else {
5420  ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
5421  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
5422  if (c) {
5423  /* Avoid deadlock while destroying channel */
5424  sig_pri_unlock_private(pri->pvts[chanpos]);
5425  ast_mutex_unlock(&pri->lock);
5426  ast_hangup(c);
5427  ast_mutex_lock(&pri->lock);
5428  } else {
5429  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
5430  pri->pvts[chanpos]->call = NULL;
5431  sig_pri_unlock_private(pri->pvts[chanpos]);
5433  }
5434  break;
5435  }
5436  } else {
5437  /*
5438  * Release the PRI lock while we create the channel so other
5439  * threads can send D channel messages. We must also release
5440  * the private lock to prevent deadlock while creating the
5441  * channel.
5442  */
5443  sig_pri_unlock_private(pri->pvts[chanpos]);
5444  ast_mutex_unlock(&pri->lock);
5445  c = sig_pri_new_ast_channel(pri->pvts[chanpos],
5446  AST_STATE_RING, law, e->ring.ctype,
5447  pri->pvts[chanpos]->exten, NULL);
5448  ast_mutex_lock(&pri->lock);
5449  sig_pri_lock_private(pri->pvts[chanpos]);
5450  if (c) {
5451  /*
5452  * It is reasonably safe to set the following
5453  * channel variables while the PRI and DAHDI private
5454  * structures are locked. The PBX has not been
5455  * started yet and it is unlikely that any other task
5456  * will do anything with the channel we have just
5457  * created.
5458  */
5459 #if defined(HAVE_PRI_SUBADDR)
5460  if (e->ring.calling.subaddress.valid) {
5461  /* Set Calling Subaddress */
5462  sig_pri_lock_owner(pri, chanpos);
5464  &pri->pvts[chanpos]->owner->caller.id.subaddress,
5465  &e->ring.calling.subaddress);
5466  if (!e->ring.calling.subaddress.type
5467  && !ast_strlen_zero(
5468  (char *) e->ring.calling.subaddress.data)) {
5469  /* NSAP */
5470  pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
5471  (char *) e->ring.calling.subaddress.data);
5472  }
5473  ast_channel_unlock(c);
5474  }
5475  if (e->ring.called_subaddress.valid) {
5476  /* Set Called Subaddress */
5477  sig_pri_lock_owner(pri, chanpos);
5479  &pri->pvts[chanpos]->owner->dialed.subaddress,
5480  &e->ring.called_subaddress);
5481  if (!e->ring.called_subaddress.type
5482  && !ast_strlen_zero(
5483  (char *) e->ring.called_subaddress.data)) {
5484  /* NSAP */
5485  pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
5486  (char *) e->ring.called_subaddress.data);
5487  }
5488  ast_channel_unlock(c);
5489  }
5490 #else
5491  if (!ast_strlen_zero(e->ring.callingsubaddr)) {
5492  pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
5493  }
5494 #endif /* !defined(HAVE_PRI_SUBADDR) */
5495  if (e->ring.ani2 >= 0) {
5496  snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
5497  pbx_builtin_setvar_helper(c, "ANI2", ani2str);
5498  }
5499 
5500 #ifdef SUPPORT_USERUSER
5501  if (!ast_strlen_zero(e->ring.useruserinfo)) {
5502  pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
5503  }
5504 #endif
5505 
5506  if (e->ring.redirectingreason >= 0) {
5507  /* This is now just a status variable. Use REDIRECTING() dialplan function. */
5508  pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
5509  }
5510 #if defined(HAVE_PRI_REVERSE_CHARGE)
5511  pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
5512 #endif
5513 #if defined(HAVE_PRI_SETUP_KEYPAD)
5514  ast_copy_string(pri->pvts[chanpos]->keypad_digits,
5515  e->ring.keypad_digits,
5516  sizeof(pri->pvts[chanpos]->keypad_digits));
5517 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
5518 
5519  snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
5520  pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
5521  ast_channel_lock(c);
5522  c->dialed.number.plan = e->ring.calledplan;
5523  ast_channel_unlock(c);
5524 
5525  sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.channel,
5526  e->ring.subcmds, e->ring.call);
5527  }
5528  if (c && !ast_pbx_start(c)) {
5529  ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
5530  plancallingnum, pri->pvts[chanpos]->exten,
5531  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
5532  sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
5533  } else {
5534  ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
5535  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
5536  if (c) {
5537  /* Avoid deadlock while destroying channel */
5538  sig_pri_unlock_private(pri->pvts[chanpos]);
5539  ast_mutex_unlock(&pri->lock);
5540  ast_hangup(c);
5541  ast_mutex_lock(&pri->lock);
5542  } else {
5543  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
5544  pri->pvts[chanpos]->call = NULL;
5545  sig_pri_unlock_private(pri->pvts[chanpos]);
5547  }
5548  break;
5549  }
5550  }
5551  } else {
5552  ast_verb(3,
5553  "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
5554  pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context,
5555  pri->pvts[chanpos]->cid_num);
5556  pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
5557  pri->pvts[chanpos]->call = NULL;
5558  pri->pvts[chanpos]->exten[0] = '\0';
5559  sig_pri_unlock_private(pri->pvts[chanpos]);
5561  break;
5562  }
5563  sig_pri_unlock_private(pri->pvts[chanpos]);
5564  break;
5565  case PRI_EVENT_RINGING:
5566  if (sig_pri_is_cis_call(e->ringing.channel)) {
5567  sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
5568  e->ringing.call);
5569  break;
5570  }
5571  chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
5572  e->ringing.call);
5573  if (chanpos < 0) {
5574  break;
5575  }
5576  sig_pri_lock_private(pri->pvts[chanpos]);
5577 
5578  sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.channel,
5579  e->ringing.subcmds, e->ringing.call);
5580  sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR);
5581  sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
5582  sig_pri_lock_owner(pri, chanpos);
5583  if (pri->pvts[chanpos]->owner) {
5584  ast_setstate(pri->pvts[chanpos]->owner, AST_STATE_RINGING);
5585  ast_channel_unlock(pri->pvts[chanpos]->owner);
5586  }
5587  pri_queue_control(pri, chanpos, AST_CONTROL_RINGING);
5588  if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_ALERTING) {
5589  pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
5590  }
5591 
5592  if (!pri->pvts[chanpos]->progress
5593  && !pri->pvts[chanpos]->no_b_channel
5594 #ifdef PRI_PROGRESS_MASK
5595  && (e->ringing.progressmask
5596  & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
5597 #else
5598  && e->ringing.progress == 8
5599 #endif
5600  ) {
5601  /* Bring voice path up */
5602  pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
5603  pri->pvts[chanpos]->progress = 1;
5604  sig_pri_set_dialing(pri->pvts[chanpos], 0);
5605  sig_pri_open_media(pri->pvts[chanpos]);
5606  }
5607 
5608 #ifdef SUPPORT_USERUSER
5609  if (!ast_strlen_zero(e->ringing.useruserinfo)) {
5610  struct ast_channel *owner;
5611 
5612  sig_pri_lock_owner(pri, chanpos);
5613  owner = pri->pvts[chanpos]->owner;
5614  if (owner) {
5615  pbx_builtin_setvar_helper(owner, "USERUSERINFO",
5616  e->ringing.useruserinfo);
5617  ast_channel_unlock(owner);
5618  }
5619  }
5620 #endif
5621 
5622  sig_pri_unlock_private(pri->pvts[chanpos]);
5623  break;
5624  case PRI_EVENT_PROGRESS:
5625  if (sig_pri_is_cis_call(e->proceeding.channel)) {
5626  sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
5627  e->proceeding.call);
5628  break;
5629  }
5630  chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
5631  e->proceeding.call);
5632  if (chanpos < 0) {
5633  break;
5634  }
5635  sig_pri_lock_private(pri->pvts[chanpos]);
5636  sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
5637  e->proceeding.subcmds, e->proceeding.call);
5638 
5639  if (e->proceeding.cause > -1) {
5640  ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
5641 
5642  /* Work around broken, out of spec USER_BUSY cause in a progress message */
5643  if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
5644  if (pri->pvts[chanpos]->owner) {
5645  ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
5646 
5647  pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
5648  pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
5649  }
5650  }
5651  }
5652 
5653  if (!pri->pvts[chanpos]->progress
5654  && !pri->pvts[chanpos]->no_b_channel
5655 #ifdef PRI_PROGRESS_MASK
5656  && (e->proceeding.progressmask
5657  & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
5658 #else
5659  && e->proceeding.progress == 8
5660 #endif
5661  ) {
5662  /* Bring voice path up */
5663  ast_debug(1,
5664  "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
5665  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
5666  pri->span);
5667  pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
5668  pri->pvts[chanpos]->progress = 1;
5669  sig_pri_set_dialing(pri->pvts[chanpos], 0);
5670  sig_pri_open_media(pri->pvts[chanpos]);
5671  }
5672  sig_pri_unlock_private(pri->pvts[chanpos]);
5673  break;
5674  case PRI_EVENT_PROCEEDING:
5675  if (sig_pri_is_cis_call(e->proceeding.channel)) {
5676  sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
5677  e->proceeding.call);
5678  break;
5679  }
5680  chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
5681  e->proceeding.call);
5682  if (chanpos < 0) {
5683  break;
5684  }
5685  sig_pri_lock_private(pri->pvts[chanpos]);
5686  sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
5687  e->proceeding.subcmds, e->proceeding.call);
5688  if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
5690  ast_debug(1,
5691  "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
5692  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
5693  pri->span);
5695  }
5696  if (!pri->pvts[chanpos]->progress
5697  && !pri->pvts[chanpos]->no_b_channel
5698 #ifdef PRI_PROGRESS_MASK
5699  /*
5700  * We only care about PRI_PROG_INBAND_AVAILABLE to open the
5701  * voice path.
5702  *
5703  * We explicitly DO NOT want to check PRI_PROG_CALL_NOT_E2E_ISDN
5704  * because it will mess up ISDN to SIP interoperability for
5705  * the ALERTING message.
5706  */
5707  && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
5708 #else
5709  && e->proceeding.progress == 8
5710 #endif
5711  ) {
5712  /* Bring voice path up */
5713  pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
5714  pri->pvts[chanpos]->progress = 1;
5715  sig_pri_set_dialing(pri->pvts[chanpos], 0);
5716  sig_pri_open_media(pri->pvts[chanpos]);
5717  } else if (pri->inband_on_proceeding) {
5718  /*
5719  * XXX This is to accomodate a broken switch that sends a
5720  * PROCEEDING without any progress indication ie for
5721  * inband audio. This should be part of the conditional
5722  * test above to bring the voice path up.
5723  */
5724  sig_pri_set_dialing(pri->pvts[chanpos], 0);
5725  }
5726  sig_pri_unlock_private(pri->pvts[chanpos]);
5727  break;
5728  case PRI_EVENT_FACILITY:
5729  if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
5730  /* Event came in on the dummy channel or a CIS call. */
5731 #if defined(HAVE_PRI_CALL_REROUTING)
5732  sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
5733  e->facility.subcall);
5734 #else
5735  sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
5736  e->facility.call);
5737 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */
5738  break;
5739  }
5740  chanpos = pri_find_principle_by_call(pri, e->facility.call);
5741  if (chanpos < 0) {
5742  ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n",
5743  pri->span);
5744  break;
5745  }
5746  sig_pri_lock_private(pri->pvts[chanpos]);
5747 #if defined(HAVE_PRI_CALL_REROUTING)
5748  sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
5749  e->facility.subcmds, e->facility.subcall);
5750 #else
5751  sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.channel,
5752  e->facility.subcmds, e->facility.call);
5753 #endif /* !defined(HAVE_PRI_CALL_REROUTING) */
5754  sig_pri_unlock_private(pri->pvts[chanpos]);
5755  break;
5756  case PRI_EVENT_ANSWER:
5757  if (sig_pri_is_cis_call(e->answer.channel)) {
5758 #if defined(HAVE_PRI_CALL_WAITING)
5759  /* Call is CIS so do normal CONNECT_ACKNOWLEDGE. */
5760  pri_connect_ack(pri->pri, e->answer.call, 0);
5761 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5762  sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
5763  e->answer.call);
5764  break;
5765  }
5766  chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
5767  if (chanpos < 0) {
5768  break;
5769  }
5770 #if defined(HAVE_PRI_CALL_WAITING)
5771  if (pri->pvts[chanpos]->is_call_waiting) {
5772  if (pri->pvts[chanpos]->no_b_channel) {
5773  int new_chanpos;
5774 
5775  /*
5776  * Need to find a free channel now or
5777  * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION.
5778  */
5779  new_chanpos = pri_find_empty_chan(pri, 1);
5780  if (0 <= new_chanpos) {
5781  new_chanpos = pri_fixup_principle(pri, new_chanpos,
5782  e->answer.call);
5783  }
5784  if (new_chanpos < 0) {
5785  /*
5786  * Either no channel was available or someone stole
5787  * the channel!
5788  */
5789  ast_verb(3,
5790  "Span %d: Channel not available for call waiting call.\n",
5791  pri->span);
5792  sig_pri_lock_private(pri->pvts[chanpos]);
5793  sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
5794  e->answer.subcmds, e->answer.call);
5795  sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
5796  sig_pri_lock_owner(pri, chanpos);
5797  if (pri->pvts[chanpos]->owner) {
5798  pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION;
5799  switch (pri->pvts[chanpos]->owner->_state) {
5800  case AST_STATE_BUSY:
5801  case AST_STATE_UP:
5803  break;
5804  default:
5806  break;
5807  }
5808  ast_channel_unlock(pri->pvts[chanpos]->owner);
5809  } else {
5810  pri->pvts[chanpos]->is_call_waiting = 0;
5812  pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5813  pri->pvts[chanpos]->call = NULL;
5814  }
5815  sig_pri_unlock_private(pri->pvts[chanpos]);
5817  break;
5818  }
5819  chanpos = new_chanpos;
5820  }
5821  pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos]));
5823  } else {
5824  /* Call is normal so do normal CONNECT_ACKNOWLEDGE. */
5825  pri_connect_ack(pri->pri, e->answer.call, 0);
5826  }
5827 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5828  sig_pri_lock_private(pri->pvts[chanpos]);
5829 
5830 #if defined(HAVE_PRI_CALL_WAITING)
5831  if (pri->pvts[chanpos]->is_call_waiting) {
5832  pri->pvts[chanpos]->is_call_waiting = 0;
5834  }
5835 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5836  sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
5837  e->answer.subcmds, e->answer.call);
5838  if (!ast_strlen_zero(pri->pvts[chanpos]->deferred_digits)) {
5839  /* We have some 'w' deferred digits to dial now. */
5840  ast_verb(3,
5841  "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
5842  pri->span, pri->pvts[chanpos]->logicalspan,
5843  pri->pvts[chanpos]->prioffset,
5844  pri->pvts[chanpos]->deferred_digits);
5845  if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
5847  }
5848  sig_pri_dial_digits(pri->pvts[chanpos],
5849  pri->pvts[chanpos]->deferred_digits);
5850  } else {
5851  if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
5852  pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
5853  }
5854  sig_pri_open_media(pri->pvts[chanpos]);
5855  pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER);
5856  sig_pri_set_dialing(pri->pvts[chanpos], 0);
5857  /* Enable echo cancellation if it's not on already */
5858  sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
5859  }
5860 
5861 #ifdef SUPPORT_USERUSER
5862  if (!ast_strlen_zero(e->answer.useruserinfo)) {
5863  struct ast_channel *owner;
5864 
5865  sig_pri_lock_owner(pri, chanpos);
5866  owner = pri->pvts[chanpos]->owner;
5867  if (owner) {
5868  pbx_builtin_setvar_helper(owner, "USERUSERINFO",
5869  e->answer.useruserinfo);
5870  ast_channel_unlock(owner);
5871  }
5872  }
5873 #endif
5874 
5875  sig_pri_unlock_private(pri->pvts[chanpos]);
5876  break;
5877 #if defined(HAVE_PRI_CALL_WAITING)
5878  case PRI_EVENT_CONNECT_ACK:
5879  if (sig_pri_is_cis_call(e->connect_ack.channel)) {
5880  sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
5881  e->connect_ack.call);
5882  break;
5883  }
5884  chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
5885  e->connect_ack.call);
5886  if (chanpos < 0) {
5887  break;
5888  }
5889 
5890  sig_pri_lock_private(pri->pvts[chanpos]);
5891  sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.channel,
5892  e->connect_ack.subcmds, e->connect_ack.call);
5893  sig_pri_open_media(pri->pvts[chanpos]);
5894  sig_pri_unlock_private(pri->pvts[chanpos]);
5896  break;
5897 #endif /* defined(HAVE_PRI_CALL_WAITING) */
5898  case PRI_EVENT_HANGUP:
5899  if (sig_pri_is_cis_call(e->hangup.channel)) {
5900  sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
5901  e->hangup.call);
5902  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
5903  break;
5904  }
5905  chanpos = pri_find_principle_by_call(pri, e->hangup.call);
5906  if (chanpos < 0) {
5907  /*
5908  * Continue hanging up the call even though
5909  * we do not remember it (if we ever did).
5910  */
5911  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
5912  break;
5913  }
5914  sig_pri_lock_private(pri->pvts[chanpos]);
5915  sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
5916  e->hangup.subcmds, e->hangup.call);
5917  switch (e->hangup.cause) {
5918  case PRI_CAUSE_INVALID_CALL_REFERENCE:
5919  /*
5920  * The peer denies the existence of this call so we must
5921  * continue hanging it up and forget about it.
5922  */
5923  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
5924  pri->pvts[chanpos]->call = NULL;
5925  break;
5926  default:
5927  break;
5928  }
5929  if (!pri->pvts[chanpos]->alreadyhungup) {
5930  /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
5931  pri->pvts[chanpos]->alreadyhungup = 1;
5932  switch (e->hangup.cause) {
5933  case PRI_CAUSE_USER_BUSY:
5934  case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
5935  sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
5936  break;
5937  default:
5938  break;
5939  }
5940  if (pri->pvts[chanpos]->owner) {
5941  int do_hangup = 0;
5942 
5943  /* Queue a BUSY instead of a hangup if our cause is appropriate */
5944  pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
5945  switch (pri->pvts[chanpos]->owner->_state) {
5946  case AST_STATE_BUSY:
5947  case AST_STATE_UP:
5948  do_hangup = 1;
5949  break;
5950  default:
5951  if (!pri->pvts[chanpos]->outgoing) {
5952  /*
5953  * The incoming call leg hung up before getting
5954  * connected so just hangup the call.
5955  */
5956  do_hangup = 1;
5957  break;
5958  }
5959  switch (e->hangup.cause) {
5960  case PRI_CAUSE_USER_BUSY:
5961  pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
5962  break;
5963  case PRI_CAUSE_CALL_REJECTED:
5964  case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
5965  case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
5966  case PRI_CAUSE_SWITCH_CONGESTION:
5967  case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
5968  case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
5970  break;
5971  default:
5972  do_hangup = 1;
5973  break;
5974  }
5975  break;
5976  }
5977 
5978  if (do_hangup) {
5979 #if defined(HAVE_PRI_AOC_EVENTS)
5980  if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
5981  /* If a AOC-E msg was sent during the release, we must use a
5982  * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */
5983  pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
5984  } else {
5985  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
5986  }
5987 #else
5988  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
5989 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
5990  }
5991  } else {
5992  /*
5993  * Continue hanging up the call even though
5994  * we do not have an owner.
5995  */
5996  pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
5997  pri->pvts[chanpos]->call = NULL;
5998  }
5999  ast_verb(3, "Span %d: Channel %d/%d got hangup, cause %d\n",
6000  pri->span, pri->pvts[chanpos]->logicalspan,
6001  pri->pvts[chanpos]->prioffset, e->hangup.cause);
6002  } else {
6003  /* Continue hanging up the call. */
6004  pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
6005  pri->pvts[chanpos]->call = NULL;
6006  }
6007 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
6008  if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
6009  && pri->sig != SIG_BRI_PTMP && !pri->resetting
6010  && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
6011  ast_verb(3,
6012  "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
6013  pri->span, pri->pvts[chanpos]->logicalspan,
6014  pri->pvts[chanpos]->prioffset);
6015  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
6016  pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
6017  }
6018 #endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
6019  if (e->hangup.aoc_units > -1)
6020  ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
6021  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
6022 
6023 #ifdef SUPPORT_USERUSER
6024  if (!ast_strlen_zero(e->hangup.useruserinfo)) {
6025  struct ast_channel *owner;
6026 
6027  sig_pri_lock_owner(pri, chanpos);
6028  owner = pri->pvts[chanpos]->owner;
6029  if (owner) {
6030  pbx_builtin_setvar_helper(owner, "USERUSERINFO",
6031  e->hangup.useruserinfo);
6032  ast_channel_unlock(owner);
6033  }
6034  }
6035 #endif
6036 
6037  sig_pri_unlock_private(pri->pvts[chanpos]);
6039  break;
6040  case PRI_EVENT_HANGUP_REQ:
6041  if (sig_pri_is_cis_call(e->hangup.channel)) {
6042  sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
6043  e->hangup.call);
6044  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
6045  break;
6046  }
6047  chanpos = pri_find_principle_by_call(pri, e->hangup.call);
6048  if (chanpos < 0) {
6049  /*
6050  * Continue hanging up the call even though
6051  * we do not remember it (if we ever did).
6052  */
6053  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
6054  break;
6055  }
6056  sig_pri_lock_private(pri->pvts[chanpos]);
6057  sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.channel,
6058  e->hangup.subcmds, e->hangup.call);
6059 #if defined(HAVE_PRI_CALL_HOLD)
6060  if (e->hangup.call_active && e->hangup.call_held
6061  && pri->hold_disconnect_transfer) {
6062  /* We are to transfer the call instead of simply hanging up. */
6063  sig_pri_unlock_private(pri->pvts[chanpos]);
6064  if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
6065  e->hangup.call_active, 0, NULL, NULL)) {
6066  break;
6067  }
6068  sig_pri_lock_private(pri->pvts[chanpos]);
6069  }
6070 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6071  switch (e->hangup.cause) {
6072  case PRI_CAUSE_USER_BUSY:
6073  case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
6074  sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
6075  break;
6076  case PRI_CAUSE_INVALID_CALL_REFERENCE:
6077  /*
6078  * The peer denies the existence of this call so we must
6079  * continue hanging it up and forget about it. We should not
6080  * get this cause here, but for completeness we will handle it
6081  * anyway.
6082  */
6083  pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
6084  pri->pvts[chanpos]->call = NULL;
6085  break;
6086  default:
6087  break;
6088  }
6089  if (pri->pvts[chanpos]->owner) {
6090  int do_hangup = 0;
6091 
6092  pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
6093  switch (pri->pvts[chanpos]->owner->_state) {
6094  case AST_STATE_BUSY:
6095  case AST_STATE_UP:
6096  do_hangup = 1;
6097  break;
6098  default:
6099  if (!pri->pvts[chanpos]->outgoing) {
6100  /*
6101  * The incoming call leg hung up before getting
6102  * connected so just hangup the call.
6103  */
6104  do_hangup = 1;
6105  break;
6106  }
6107  switch (e->hangup.cause) {
6108  case PRI_CAUSE_USER_BUSY:
6109  pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
6110  break;
6111  case PRI_CAUSE_CALL_REJECTED:
6112  case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
6113  case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
6114  case PRI_CAUSE_SWITCH_CONGESTION:
6115  case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
6116  case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
6118  break;
6119  default:
6120  do_hangup = 1;
6121  break;
6122  }
6123  break;
6124  }
6125 
6126  if (do_hangup) {
6127 #if defined(HAVE_PRI_AOC_EVENTS)
6128  if (!pri->pvts[chanpos]->holding_aoce
6129  && pri->aoce_delayhangup
6130  && ast_bridged_channel(pri->pvts[chanpos]->owner)) {
6132  pri_get_timer(pri->pri, PRI_TIMER_T305) / 2);
6133  } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
6134  /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame
6135  * to guarantee that frame gets read before hangup */
6136  pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
6137  } else {
6138  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
6139  }
6140 #else
6141  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
6142 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
6143  }
6144  ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n",
6145  pri->span, pri->pvts[chanpos]->logicalspan,
6146  pri->pvts[chanpos]->prioffset, e->hangup.cause);
6147  } else {
6148  /*
6149  * Continue hanging up the call even though
6150  * we do not have an owner.
6151  */
6152  pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
6153  pri->pvts[chanpos]->call = NULL;
6154  }
6155 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
6156  if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
6157  && pri->sig != SIG_BRI_PTMP && !pri->resetting
6158  && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
6159  ast_verb(3,
6160  "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
6161  pri->span, pri->pvts[chanpos]->logicalspan,
6162  pri->pvts[chanpos]->prioffset);
6163  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
6164  pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
6165  }
6166 #endif /* defined(FORCE_RESTART_UNAVAIL_CHANS) */
6167 
6168 #ifdef SUPPORT_USERUSER
6169  if (!ast_strlen_zero(e->hangup.useruserinfo)) {
6170  struct ast_channel *owner;
6171 
6172  sig_pri_lock_owner(pri, chanpos);
6173  owner = pri->pvts[chanpos]->owner;
6174  if (owner) {
6175  pbx_builtin_setvar_helper(owner, "USERUSERINFO",
6176  e->hangup.useruserinfo);
6177  ast_channel_unlock(owner);
6178  }
6179  }
6180 #endif
6181 
6182  sig_pri_unlock_private(pri->pvts[chanpos]);
6184  break;
6185  case PRI_EVENT_HANGUP_ACK:
6186  if (sig_pri_is_cis_call(e->hangup.channel)) {
6187  sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
6188  e->hangup.call);
6189  break;
6190  }
6191  chanpos = pri_find_principle_by_call(pri, e->hangup.call);
6192  if (chanpos < 0) {
6193  break;
6194  }
6195  sig_pri_lock_private(pri->pvts[chanpos]);
6196  pri->pvts[chanpos]->call = NULL;
6197  if (pri->pvts[chanpos]->owner) {
6198  ast_verb(3, "Span %d: Channel %d/%d got hangup ACK\n", pri->span,
6199  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset);
6200  }
6201 #ifdef SUPPORT_USERUSER
6202  if (!ast_strlen_zero(e->hangup.useruserinfo)) {
6203  struct ast_channel *owner;
6204 
6205  sig_pri_lock_owner(pri, chanpos);
6206  owner = pri->pvts[chanpos]->owner;
6207  if (owner) {
6208  pbx_builtin_setvar_helper(owner, "USERUSERINFO",
6209  e->hangup.useruserinfo);
6210  ast_channel_unlock(owner);
6211  }
6212  }
6213 #endif
6214  sig_pri_unlock_private(pri->pvts[chanpos]);
6216  break;
6217  case PRI_EVENT_CONFIG_ERR:
6218  ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
6219  break;
6220  case PRI_EVENT_RESTART_ACK:
6221  chanpos = pri_find_principle(pri, e->restartack.channel, NULL);
6222  if (chanpos < 0) {
6223  /* Sometime switches (e.g. I421 / British Telecom) don't give us the
6224  channel number, so we have to figure it out... This must be why
6225  everybody resets exactly a channel at a time. */
6226  for (x = 0; x < pri->numchans; x++) {
6227  if (pri->pvts[x]
6228  && pri->pvts[x]->resetting != SIG_PRI_RESET_IDLE) {
6229  chanpos = x;
6230  sig_pri_lock_private(pri->pvts[chanpos]);
6231  ast_debug(1,
6232  "Span %d: Assuming restart ack is for channel %d/%d\n",
6233  pri->span, pri->pvts[chanpos]->logicalspan,
6234  pri->pvts[chanpos]->prioffset);
6235  if (pri->pvts[chanpos]->owner) {
6237  "Span %d: Got restart ack on channel %d/%d with owner\n",
6238  pri->span, pri->pvts[chanpos]->logicalspan,
6239  pri->pvts[chanpos]->prioffset);
6240  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
6241  }
6242  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
6243  ast_verb(3,
6244  "Span %d: Channel %d/%d successfully restarted\n",
6245  pri->span, pri->pvts[chanpos]->logicalspan,
6246  pri->pvts[chanpos]->prioffset);
6247  sig_pri_unlock_private(pri->pvts[chanpos]);
6248  if (pri->resetting)
6249  pri_check_restart(pri);
6250  break;
6251  }
6252  }
6253  if (chanpos < 0) {
6255  "Span %d: Restart ACK on strange channel %d/%d\n",
6256  pri->span, PRI_SPAN(e->restartack.channel),
6257  PRI_CHANNEL(e->restartack.channel));
6258  }
6259  } else {
6260  sig_pri_lock_private(pri->pvts[chanpos]);
6261  if (pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
6262  /* The channel is not in the resetting state. */
6263  ast_debug(1,
6264  "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
6265  pri->span, pri->pvts[chanpos]->logicalspan,
6266  pri->pvts[chanpos]->prioffset);
6267  sig_pri_unlock_private(pri->pvts[chanpos]);
6268  break;
6269  }
6270  if (pri->pvts[chanpos]->owner) {
6272  "Span %d: Got restart ack on channel %d/%d with owner\n",
6273  pri->span, pri->pvts[chanpos]->logicalspan,
6274  pri->pvts[chanpos]->prioffset);
6275  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
6276  }
6277  pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
6278  ast_verb(3,
6279  "Span %d: Channel %d/%d successfully restarted\n",
6280  pri->span, pri->pvts[chanpos]->logicalspan,
6281  pri->pvts[chanpos]->prioffset);
6282  sig_pri_unlock_private(pri->pvts[chanpos]);
6283  if (pri->resetting)
6284  pri_check_restart(pri);
6285  }
6286  break;
6287  case PRI_EVENT_SETUP_ACK:
6288  if (sig_pri_is_cis_call(e->setup_ack.channel)) {
6289  sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
6290  e->setup_ack.call);
6291  break;
6292  }
6293  chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
6294  e->setup_ack.call);
6295  if (chanpos < 0) {
6296  break;
6297  }
6298  sig_pri_lock_private(pri->pvts[chanpos]);
6299  sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.channel,
6300  e->setup_ack.subcmds, e->setup_ack.call);
6301  if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
6302  pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
6303  }
6304 
6305  /* Send any queued digits */
6306  len = strlen(pri->pvts[chanpos]->dialdest);
6307  for (x = 0; x < len; ++x) {
6308  ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
6309  pri_information(pri->pri, pri->pvts[chanpos]->call,
6310  pri->pvts[chanpos]->dialdest[x]);
6311  }
6312 
6313  if (!pri->pvts[chanpos]->progress
6315  && !pri->pvts[chanpos]->digital
6316  && !pri->pvts[chanpos]->no_b_channel
6317 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
6318  /*
6319  * We only care about PRI_PROG_INBAND_AVAILABLE to open the
6320  * voice path.
6321  *
6322  * We explicitly DO NOT want to check PRI_PROG_CALL_NOT_E2E_ISDN
6323  * because it will mess up ISDN to SIP interoperability for
6324  * the ALERTING message.
6325  *
6326  * Q.931 Section 5.1.3 says that in scenarios with overlap
6327  * dialing where no called digits are received and the tone
6328  * option requires dialtone, the switch MAY send an inband
6329  * progress indication ie to indicate dialtone presence in
6330  * the SETUP ACKNOWLEDGE. Therefore, if we did not send any
6331  * digits with the SETUP then we must assume that dialtone
6332  * is present and open the voice path. Fortunately when
6333  * interoperating with SIP, we should be sending digits.
6334  */
6335  && ((e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
6336  || pri->inband_on_setup_ack
6337  || pri->pvts[chanpos]->no_dialed_digits)
6338 #endif /* defined(HAVE_PRI_SETUP_ACK_INBAND) */
6339  ) {
6340  /*
6341  * Call has a channel.
6342  * Indicate for overlap dialing that dialtone may be present.
6343  */
6344  pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
6345  pri->pvts[chanpos]->progress = 1;/* Claim to have seen inband-information */
6346  sig_pri_set_dialing(pri->pvts[chanpos], 0);
6347  sig_pri_open_media(pri->pvts[chanpos]);
6348  }
6349  sig_pri_unlock_private(pri->pvts[chanpos]);
6350  break;
6351  case PRI_EVENT_NOTIFY:
6352  if (sig_pri_is_cis_call(e->notify.channel)) {
6353 #if defined(HAVE_PRI_CALL_HOLD)
6354  sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
6355  e->notify.call);
6356 #else
6357  sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL);
6358 #endif /* !defined(HAVE_PRI_CALL_HOLD) */
6359  break;
6360  }
6361 #if defined(HAVE_PRI_CALL_HOLD)
6362  chanpos = pri_find_principle_by_call(pri, e->notify.call);
6363  if (chanpos < 0) {
6364  ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n",
6365  pri->span);
6366  break;
6367  }
6368 #else
6369  /*
6370  * This version of libpri does not supply a call pointer for
6371  * this message. We are just going to have to trust that the
6372  * correct principle is found.
6373  */
6374  chanpos = pri_find_principle(pri, e->notify.channel, NULL);
6375  if (chanpos < 0) {
6376  ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
6377  PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
6378  break;
6379  }
6380 #endif /* !defined(HAVE_PRI_CALL_HOLD) */
6381  sig_pri_lock_private(pri->pvts[chanpos]);
6382 #if defined(HAVE_PRI_CALL_HOLD)
6383  sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
6384  e->notify.subcmds, e->notify.call);
6385 #else
6386  sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.channel,
6387  e->notify.subcmds, NULL);
6388 #endif /* !defined(HAVE_PRI_CALL_HOLD) */
6389  switch (e->notify.info) {
6390  case PRI_NOTIFY_REMOTE_HOLD:
6391  if (!pri->discardremoteholdretrieval) {
6392  pri_queue_control(pri, chanpos, AST_CONTROL_HOLD);
6393  }
6394  break;
6395  case PRI_NOTIFY_REMOTE_RETRIEVAL:
6396  if (!pri->discardremoteholdretrieval) {
6397  pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
6398  }
6399  break;
6400  }
6401  sig_pri_unlock_private(pri->pvts[chanpos]);
6402  break;
6403 #if defined(HAVE_PRI_CALL_HOLD)
6404  case PRI_EVENT_HOLD:
6405  /* We should not be getting any CIS calls with this message type. */
6406  if (sig_pri_handle_hold(pri, e)) {
6407  pri_hold_rej(pri->pri, e->hold.call,
6408  PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
6409  } else {
6410  pri_hold_ack(pri->pri, e->hold.call);
6411  }
6412  break;
6413 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6414 #if defined(HAVE_PRI_CALL_HOLD)
6415  case PRI_EVENT_HOLD_ACK:
6416  ast_debug(1, "Event: HOLD_ACK\n");
6417  break;
6418 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6419 #if defined(HAVE_PRI_CALL_HOLD)
6420  case PRI_EVENT_HOLD_REJ:
6421  ast_debug(1, "Event: HOLD_REJ\n");
6422  break;
6423 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6424 #if defined(HAVE_PRI_CALL_HOLD)
6425  case PRI_EVENT_RETRIEVE:
6426  /* We should not be getting any CIS calls with this message type. */
6427  sig_pri_handle_retrieve(pri, e);
6428  break;
6429 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6430 #if defined(HAVE_PRI_CALL_HOLD)
6431  case PRI_EVENT_RETRIEVE_ACK:
6432  ast_debug(1, "Event: RETRIEVE_ACK\n");
6433  break;
6434 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6435 #if defined(HAVE_PRI_CALL_HOLD)
6436  case PRI_EVENT_RETRIEVE_REJ:
6437  ast_debug(1, "Event: RETRIEVE_REJ\n");
6438  break;
6439 #endif /* defined(HAVE_PRI_CALL_HOLD) */
6440  default:
6441  ast_debug(1, "Event: %d\n", e->e);
6442  break;
6443  }
6444  }
6445  ast_mutex_unlock(&pri->lock);
6446  }
6447  /* Never reached */
6448  return NULL;
6449 }
int cid_ton
Definition: sig_pri.h:238
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
static void sig_pri_handle_dchan_exception(struct sig_pri_span *pri, int index)
Definition: sig_pri.c:158
int nodetype
Definition: sig_pri.h:434
long resetinterval
Definition: sig_pri.h:411
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:5420
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:197
Main Channel structure associated with a channel.
Definition: channel.h:742
int logicalspan
Definition: sig_pri.h:304
unsigned int alreadyhungup
Definition: sig_pri.h:266
static int detect_aoc_e_subcmd(const struct pri_subcommands *subcmds)
Definition: sig_pri.c:4070
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:338
static void * pri_ss_thread(void *data)
Definition: sig_pri.c:1889
char keypad_digits[AST_MAX_EXTENSION]
Keypad digits that came in with the SETUP message.
Definition: sig_pri.h:253
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int reverse_charging_indication
Reverse charging indication.
Definition: sig_pri.h:321
static const char dahdi_db[]
The AstDB family.
Definition: sig_pri.h:219
int callingpres
Definition: sig_pri.h:239
static char * redirectingreason2str(int redirectingreason)
Definition: sig_pri.c:1598
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
#define SIG_BRI_PTMP
Definition: chan_dahdi.c:366
unsigned int use_callerid
Definition: sig_pri.h:229
char idleext[AST_MAX_EXTENSION]
Definition: sig_pri.h:429
unsigned int hold_disconnect_transfer
TRUE if held calls are transferred on disconnect.
Definition: sig_pri.h:382
#define PRI_SPAN(p)
Definition: sig_pri.c:113
unsigned int allow_call_waiting_calls
TRUE if we will allow incoming ISDN call waiting calls.
Definition: sig_pri.h:391
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_channel * sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
Definition: sig_pri.c:1013
q931_call * call
Definition: sig_pri.h:297
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define AST_FRAME_DTMF
Definition: frame.h:128
unsigned int progress
Definition: sig_pri.h:268
char idlecontext[AST_MAX_CONTEXT]
Definition: sig_pri.h:430
#define SRVST_TYPE_OOS
The out-of-service SERVICE state.
Definition: sig_pri.h:204
static void sig_pri_dial_digits(struct sig_pri_chan *p, const char *dial_string)
Definition: sig_pri.c:228
struct ast_channel * owner
Definition: sig_pri.h:294
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)
Definition: sig_pri.c:2347
char cid_ani[AST_MAX_EXTENSION]
Definition: sig_pri.h:243
static void pri_check_restart(struct sig_pri_span *pri)
Definition: sig_pri.c:1692
#define HAVE_PRI_SETUP_ACK_INBAND
Definition: autoconfig.h:612
int minidle
Definition: sig_pri.h:433
unsigned int aoce_delayhangup
Definition: sig_pri.h:371
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:8650
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:302
#define DAHDI_OVERLAPDIAL_OUTGOING
Definition: sig_pri.h:196
unsigned int isidlecall
Definition: sig_pri.h:267
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
static void sig_pri_set_dnid(struct sig_pri_chan *p, const char *dnid)
Definition: sig_pri.c:306
The channel is not being RESTARTed.
Definition: sig_pri.h:106
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static const char * pri_order(int level)
Definition: sig_pri.c:1037
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
Definition: sig_pri.c:187
#define ast_mutex_lock(a)
Definition: lock.h:155
static void sig_pri_init_config(struct sig_pri_chan *pvt, struct sig_pri_span *pri)
Definition: sig_pri.c:1740
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
int switchtype
Definition: sig_pri.h:435
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
const char * data
Definition: channel.h:755
unsigned service_status
Active SRVST_DBKEY out-of-service status value.
Definition: sig_pri.h:308
unsigned int inband_on_setup_ack
Definition: sig_pri.h:401
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static void sig_pri_handle_retrieve(struct sig_pri_span *pri, pri_event *ev)
Definition: sig_pri.c:4542
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)
Definition: sig_pri.c:4107
#define ast_verb(level,...)
Definition: logger.h:243
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:5415
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
ast_mutex_t lock
Definition: sig_pri.h:495
unsigned int no_d_channels
Definition: sig_pri.h:477
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
Definition: sig_pri.c:1239
static void pri_find_dchan(struct sig_pri_span *pri)
Definition: sig_pri.c:1067
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static int sig_pri_msn_match(const char *msn_patterns, const char *exten)
Definition: sig_pri.c:2144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void sig_pri_open_media(struct sig_pri_chan *p)
Definition: sig_pri.c:984
static int pri_find_fixup_principle(struct sig_pri_span *pri, int channel, q931_call *call)
Definition: sig_pri.c:1570
unsigned int inband_on_proceeding
Definition: sig_pri.h:403
sig_pri_law
Definition: sig_pri.h:80
struct ast_party_dialed::@155 number
Dialed/Called number.
char dialdest[256]
Definition: sig_pri.h:250
#define SRVST_DBKEY
Persistent Service State.
Definition: sig_pri.h:202
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
Destroy the party subaddress contents.
Definition: channel.c:2081
static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
Definition: sig_pri.c:1397
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
static void sig_pri_set_subaddress(struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress)
Definition: sig_pri.c:650
#define AST_MAX_EXTENSION
Definition: channel.h:135
static void apply_plan_to_existing_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
Definition: sig_pri.c:1670
The channel is being RESTARTed.
Definition: sig_pri.h:111
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
unsigned int holding_aoce
Definition: sig_pri.h:263
int overlapdial
Definition: sig_pri.h:358
static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
Definition: sig_pri.c:1265
static void sig_pri_handle_cis_subcmds(struct sig_pri_span *pri, int event_id, const struct pri_subcommands *subcmds, q931_call *call_rsp)
Definition: sig_pri.c:3851
int pri_is_up(struct sig_pri_span *pri)
Definition: sig_pri.c:1027
int fds[AST_MAX_FDS]
Definition: channel.h:829
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
#define LOG_ERROR
Definition: logger.h:155
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:120
int minunused
Definition: sig_pri.h:432
time_t lastreset
Definition: sig_pri.h:496
static int pri_find_empty_nobch(struct sig_pri_span *pri)
Definition: sig_pri.c:1811
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_channel_state _state
Definition: channel.h:839
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
const ast_string_field name
Definition: channel.h:787
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void pri_queue_frame(struct sig_pri_span *pri, int chanpos, struct ast_frame *frame)
Definition: sig_pri.c:1216
int _softhangup
Definition: channel.h:832
static void sig_pri_send_aoce_termination_request(struct sig_pri_span *pri, int chanpos, unsigned int ms)
Definition: sig_pri.c:3774
char idledial[AST_MAX_EXTENSION]
Definition: sig_pri.h:431
unsigned int immediate
Definition: sig_pri.h:226
#define LOG_NOTICE
Definition: logger.h:133
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
char exten[AST_MAX_EXTENSION]
Definition: sig_pri.h:246
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
int resetpos
Definition: sig_pri.h:473
unsigned int append_msn_to_user_tag
Definition: sig_pri.h:399
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:427
static void sig_pri_set_rdnis(struct sig_pri_chan *p, const char *rdnis)
Definition: sig_pri.c:323
static struct ast_format f[]
Definition: format_g726.c:181
char cid_subaddr[AST_MAX_EXTENSION]
Definition: sig_pri.h:241
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
char cid_num[AST_MAX_EXTENSION]
Definition: sig_pri.h:240
static int pri_find_empty_chan(struct sig_pri_span *pri, int backwards)
Definition: sig_pri.c:1771
char msn_list[AST_MAX_EXTENSION]
Definition: sig_pri.h:428
struct ast_party_subaddress subaddress
Dialed/Called subaddress.
Definition: channel.h:341
char deferred_digits[AST_MAX_EXTENSION]
Definition: sig_pri.h:256
static void sig_pri_set_caller_id(struct sig_pri_chan *p)
Definition: sig_pri.c:262
int numchans
Definition: sig_pri.h:492
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
Definition: sig_pri.c:164
static int pri_find_principle(struct sig_pri_span *pri, int channel, q931_call *call)
Definition: sig_pri.c:1330
int resetting
Definition: sig_pri.h:472
unsigned int is_call_waiting
TRUE if this is a call waiting call.
Definition: sig_pri.h:287
static void * do_idle_thread(void *v_pvt)
Definition: sig_pri.c:1834
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: db.c:365
int cid_ani2
Definition: sig_pri.h:237
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Peer may not be sending the expected RESTART ACKNOWLEDGE.
Definition: sig_pri.h:122
static int sig_pri_handle_hold(struct sig_pri_span *pri, pri_event *ev)
Definition: sig_pri.c:4460
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
Definition: channel.c:2034
int num_call_waiting_calls
Number of outstanding call waiting calls.
Definition: sig_pri.h:467
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
unsigned int digital
Definition: sig_pri.h:282
int discardremoteholdretrieval
Definition: sig_pri.h:360
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
Data structure associated with a single frame of data.
Definition: frame.h:142
int hangupcause
Definition: channel.h:849
struct sig_pri_span * pri
Definition: sig_pri.h:296
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: db.c:260
struct timeval tv
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
int prioffset
Definition: sig_pri.h:303
Information needed to specify a subaddress in a call.
Definition: channel.h:257
static int sig_pri_set_echocanceller(struct sig_pri_chan *p, int enable)
Definition: sig_pri.c:921
unsigned int outgoing
Definition: sig_pri.h:281
static void sig_pri_cc_generic_check(struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service)
Definition: sig_pri.c:2752
#define PRI_CHANNEL(p)
Definition: sig_pri.c:112
#define DCHAN_UP
Definition: sig_pri.c:109
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:948
char cid_name[AST_MAX_EXTENSION]
Definition: sig_pri.h:242
static struct ast_channel * sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, enum sig_pri_law law, int transfercapability, char *exten, const struct ast_channel *requestor)
Definition: sig_pri.c:943
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:280
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:231
unsigned int no_dialed_digits
Definition: sig_pri.h:291
#define SRVST_NEAREND
SRVST_NEAREND is used to indicate that the near end was put out-of-service.
Definition: sig_pri.h:212
struct pri * pri
Definition: sig_pri.h:481
#define AST_TRANS_CAP_DIGITAL
Definition: transcap.h:35
int channel
Definition: sig_pri.h:234
int fds[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:367
static int sig_pri_is_cis_call(int channel)
Definition: sig_pri.c:3829
#define ast_mutex_unlock(a)
Definition: lock.h:156
#define SRVST_FAREND
SRVST_FAREND is used to indicate that the far end was taken out-of-service.
Definition: sig_pri.h:214
void pri_event_alarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

Definition at line 2014 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().

2015 {
2016  pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
2017  if (!before_start_pri) {
2018  pri_find_dchan(pri);
2019  }
2020 }
#define DCHAN_NOTINALARM
Definition: sig_pri.c:108
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
static void pri_find_dchan(struct sig_pri_span *pri)
Definition: sig_pri.c:1067
#define DCHAN_UP
Definition: sig_pri.c:109
void pri_event_noalarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

Definition at line 2022 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().

2023 {
2024  pri->dchanavail[index] |= DCHAN_NOTINALARM;
2025  if (!before_start_pri)
2026  pri_restart(pri->dchans[index]);
2027 }
#define DCHAN_NOTINALARM
Definition: sig_pri.c:108
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
static void pri_find_dchan ( struct sig_pri_span pri)
static

Definition at line 1067 of file sig_pri.c.

References ast_log(), DCHAN_AVAILABLE, sig_pri_span::dchans, sig_pri_span::fds, LOG_NOTICE, LOG_WARNING, sig_pri_span::no_d_channels, sig_pri_span::pri, pri_order(), sig_pri_span::sig, SIG_BRI_PTMP, SIG_PRI_NUM_DCHANS, and sig_pri_span::span.

Referenced by pri_dchannel(), and pri_event_alarm().

1068 {
1069  struct pri *old;
1070  int oldslot = -1;
1071  int newslot = -1;
1072  int idx;
1073 
1074  old = pri->pri;
1075  for (idx = 0; idx < SIG_PRI_NUM_DCHANS; ++idx) {
1076  if (!pri->dchans[idx]) {
1077  /* No more D channels defined on the span. */
1078  break;
1079  }
1080  if (pri->dchans[idx] == old) {
1081  oldslot = idx;
1082  }
1083  if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
1084  newslot = idx;
1085  }
1086  }
1087  /* At this point, idx is a count of how many D-channels are defined on the span. */
1088 
1089  if (1 < idx) {
1090  /* We have several D-channels defined on the span. (NFAS PRI setup) */
1091  if (newslot < 0) {
1092  /* No D-channels available. Default to the primary D-channel. */
1093  newslot = 0;
1094 
1095  if (!pri->no_d_channels) {
1096  pri->no_d_channels = 1;
1097  if (old && oldslot != newslot) {
1099  "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
1100  pri->span, pri_order(oldslot), pri_order(newslot));
1101  } else {
1102  ast_log(LOG_WARNING, "Span %d: No D-channels up!\n", pri->span);
1103  }
1104  }
1105  } else {
1106  pri->no_d_channels = 0;
1107  }
1108  if (old && oldslot != newslot) {
1110  "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
1111  pri_order(oldslot), pri->fds[oldslot],
1112  pri_order(newslot), pri->fds[newslot]);
1113  }
1114  } else {
1115  if (newslot < 0) {
1116  /* The only D-channel is not up. */
1117  newslot = 0;
1118 
1119  if (!pri->no_d_channels) {
1120  pri->no_d_channels = 1;
1121 
1122  /*
1123  * This is annoying to see on non-persistent layer 2
1124  * connections. Let's not complain in that case.
1125  */
1126  if (pri->sig != SIG_BRI_PTMP) {
1127  ast_log(LOG_WARNING, "Span %d: D-channel is down!\n", pri->span);
1128  }
1129  }
1130  } else {
1131  pri->no_d_channels = 0;
1132  }
1133  }
1134  pri->pri = pri->dchans[newslot];
1135 }
#define SIG_BRI_PTMP
Definition: chan_dahdi.c:366
#define LOG_WARNING
Definition: logger.h:144
static const char * pri_order(int level)
Definition: sig_pri.c:1037
unsigned int no_d_channels
Definition: sig_pri.h:477
#define DCHAN_AVAILABLE
Definition: sig_pri.c:119
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
struct pri * pri
Definition: sig_pri.h:481
int fds[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:367
static int pri_find_empty_chan ( struct sig_pri_span pri,
int  backwards 
)
static

Definition at line 1771 of file sig_pri.c.

References ast_debug, sig_pri_chan::logicalspan, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::prioffset, sig_pri_span::pvts, and sig_pri_is_chan_available().

Referenced by pri_dchannel(), and sig_pri_handle_retrieve().

1772 {
1773  int x;
1774  if (backwards)
1775  x = pri->numchans;
1776  else
1777  x = 0;
1778  for (;;) {
1779  if (backwards && (x < 0))
1780  break;
1781  if (!backwards && (x >= pri->numchans))
1782  break;
1783  if (pri->pvts[x]
1784  && !pri->pvts[x]->no_b_channel
1785  && sig_pri_is_chan_available(pri->pvts[x])) {
1786  ast_debug(1, "Found empty available channel %d/%d\n",
1787  pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
1788  return x;
1789  }
1790  if (backwards)
1791  x--;
1792  else
1793  x++;
1794  }
1795  return -1;
1796 }
int logicalspan
Definition: sig_pri.h:304
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
int numchans
Definition: sig_pri.h:492
int prioffset
Definition: sig_pri.h:303
static int pri_find_empty_nobch ( struct sig_pri_span pri)
static

Definition at line 1811 of file sig_pri.c.

References ast_debug, sig_pri_span::calls, sig_pri_callback::new_nobch_intf, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_span::pvts, and sig_pri_is_chan_available().

Referenced by pri_dchannel(), sig_pri_cw_available(), and sig_pri_handle_hold().

1812 {
1813  int idx;
1814 
1815  for (idx = 0; idx < pri->numchans; ++idx) {
1816  if (pri->pvts[idx]
1817  && pri->pvts[idx]->no_b_channel
1818  && sig_pri_is_chan_available(pri->pvts[idx])) {
1819  ast_debug(1, "Found empty available no B channel interface\n");
1820  return idx;
1821  }
1822  }
1823 
1824  /* Need to create a new interface. */
1825  if (pri->calls->new_nobch_intf) {
1826  idx = pri->calls->new_nobch_intf(pri);
1827  } else {
1828  idx = -1;
1829  }
1830  return idx;
1831 }
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
struct sig_pri_callback * calls
Definition: sig_pri.h:497
int(*const new_nobch_intf)(struct sig_pri_span *pri)
Definition: sig_pri.h:158
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
int numchans
Definition: sig_pri.h:492
static int pri_find_fixup_principle ( struct sig_pri_span pri,
int  channel,
q931_call *  call 
)
static

Definition at line 1570 of file sig_pri.c.

References ast_log(), LOG_WARNING, PRI_CHANNEL, pri_find_principle(), pri_fixup_principle(), PRI_SPAN, sig_pri_kill_call(), and sig_pri_span::span.

Referenced by pri_dchannel().

1571 {
1572  int chanpos;
1573 
1574  chanpos = pri_find_principle(pri, channel, call);
1575  if (chanpos < 0) {
1576  ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n",
1577  pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1578  sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
1579  return -1;
1580  }
1581  chanpos = pri_fixup_principle(pri, chanpos, call);
1582  if (chanpos < 0) {
1583  ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n",
1584  pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1585  /*
1586  * Using Q.931 section 5.2.3.1 b) as the reason for picking
1587  * PRI_CAUSE_CHANNEL_UNACCEPTABLE. Receiving a
1588  * PRI_CAUSE_REQUESTED_CHAN_UNAVAIL would cause us to restart
1589  * that channel (which is not specified by Q.931) and kill some
1590  * other call which would be bad.
1591  */
1592  sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
1593  return -1;
1594  }
1595  return chanpos;
1596 }
#define PRI_SPAN(p)
Definition: sig_pri.c:113
#define LOG_WARNING
Definition: logger.h:144
static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
Definition: sig_pri.c:1397
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void sig_pri_kill_call(struct sig_pri_span *pri, q931_call *call, int cause)
Definition: sig_pri.c:1295
static int pri_find_principle(struct sig_pri_span *pri, int channel, q931_call *call)
Definition: sig_pri.c:1330
#define PRI_CHANNEL(p)
Definition: sig_pri.c:112
static int pri_find_principle ( struct sig_pri_span pri,
int  channel,
q931_call *  call 
)
static

Definition at line 1330 of file sig_pri.c.

References sig_pri_chan::call, sig_pri_span::dchan_logical_span, sig_pri_chan::logicalspan, sig_pri_chan::no_b_channel, sig_pri_span::numchans, pri_active_dchan_index(), PRI_CHANNEL, PRI_EXPLICIT, PRI_HELD_CALL, PRI_SPAN, sig_pri_chan::prioffset, and sig_pri_span::pvts.

Referenced by pri_dchannel(), pri_find_fixup_principle(), and sig_pri_handle_retrieve().

1331 {
1332  int x;
1333  int span;
1334  int principle;
1335  int prioffset;
1336 
1337  if (channel < 0) {
1338  /* Channel is not picked yet. */
1339  return -1;
1340  }
1341 
1342  prioffset = PRI_CHANNEL(channel);
1343  if (!prioffset || (channel & PRI_HELD_CALL)) {
1344  if (!call) {
1345  /* Cannot find a call waiting call or held call without a call. */
1346  return -1;
1347  }
1348  principle = -1;
1349  for (x = 0; x < pri->numchans; ++x) {
1350  if (pri->pvts[x]
1351  && pri->pvts[x]->call == call) {
1352  principle = x;
1353  break;
1354  }
1355  }
1356  return principle;
1357  }
1358 
1359  span = PRI_SPAN(channel);
1360  if (!(channel & PRI_EXPLICIT)) {
1361  int index;
1362 
1363  index = pri_active_dchan_index(pri);
1364  if (index == -1) {
1365  return -1;
1366  }
1367  span = pri->dchan_logical_span[index];
1368  }
1369 
1370  principle = -1;
1371  for (x = 0; x < pri->numchans; x++) {
1372  if (pri->pvts[x]
1373  && pri->pvts[x]->prioffset == prioffset
1374  && pri->pvts[x]->logicalspan == span
1375  && !pri->pvts[x]->no_b_channel) {
1376  principle = x;
1377  break;
1378  }
1379  }
1380 
1381  return principle;
1382 }
int dchan_logical_span[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:366
int logicalspan
Definition: sig_pri.h:304
#define PRI_SPAN(p)
Definition: sig_pri.c:113
q931_call * call
Definition: sig_pri.h:297
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define PRI_EXPLICIT
Definition: sig_pri.c:114
static int pri_active_dchan_index(struct sig_pri_span *pri)
Definition: sig_pri.c:1054
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define PRI_HELD_CALL
Definition: sig_pri.c:116
int numchans
Definition: sig_pri.h:492
int prioffset
Definition: sig_pri.h:303
#define PRI_CHANNEL(p)
Definition: sig_pri.c:112
static int pri_find_principle_by_call ( struct sig_pri_span pri,
q931_call *  call 
)
static

Definition at line 1265 of file sig_pri.c.

References sig_pri_chan::call, sig_pri_span::numchans, and sig_pri_span::pvts.

Referenced by pri_dchannel(), sig_pri_attempt_transfer(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), and sig_pri_kill_call().

1266 {
1267  int idx;
1268 
1269  if (!call) {
1270  /* Cannot find a call without a call. */
1271  return -1;
1272  }
1273  for (idx = 0; idx < pri->numchans; ++idx) {
1274  if (pri->pvts[idx] && pri->pvts[idx]->call == call) {
1275  /* Found the principle */
1276  return idx;
1277  }
1278  }
1279  return -1;
1280 }
q931_call * call
Definition: sig_pri.h:297
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
int numchans
Definition: sig_pri.h:492
static int pri_fixup_principle ( struct sig_pri_span pri,
int  principle,
q931_call *  call 
)
static

Definition at line 1397 of file sig_pri.c.

References sig_pri_chan::allocated, sig_pri_chan::alreadyhungup, sig_pri_chan::aoc_e, sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_channel_unlock, ast_log(), ast_verb, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::channel, sig_pri_chan::context, sig_pri_chan::deferred_digits, sig_pri_chan::digital, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, sig_pri_chan::holding_aoce, sig_pri_chan::immediate, sig_pri_chan::is_call_waiting, sig_pri_chan::isidlecall, sig_pri_chan::keypad_digits, LOG_WARNING, sig_pri_chan::logicalspan, sig_pri_chan::mastertrunkgroup, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::no_dialed_digits, sig_pri_span::numchans, sig_pri_chan::outgoing, sig_pri_chan::owner, sig_pri_chan::priexclusive, sig_pri_chan::priindication_oob, sig_pri_chan::progress, sig_pri_span::pvts, sig_pri_chan::reverse_charging_indication, sig_pri_ami_channel_event(), SIG_PRI_CALL_LEVEL_IDLE, sig_pri_fixup_chans(), sig_pri_is_chan_available(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_open_media(), sig_pri_unlock_private(), sig_pri_chan::stripmsd, sig_pri_chan::use_callerid, sig_pri_chan::use_callingpres, sig_pri_chan::user_tag, and sig_pri_chan::waiting_for_aoce.

Referenced by pri_dchannel(), pri_find_fixup_principle(), sig_pri_handle_hold(), and sig_pri_handle_retrieve().

1398 {
1399  int x;
1400 
1401  if (principle < 0 || pri->numchans <= principle) {
1402  /* Out of rannge */
1403  return -1;
1404  }
1405  if (!call) {
1406  /* No call */
1407  return principle;
1408  }
1409  if (pri->pvts[principle] && pri->pvts[principle]->call == call) {
1410  /* Call is already on the specified principle. */
1411  return principle;
1412  }
1413 
1414  /* Find the old principle location. */
1415  for (x = 0; x < pri->numchans; x++) {
1416  struct sig_pri_chan *new_chan;
1417  struct sig_pri_chan *old_chan;
1418 
1419  if (!pri->pvts[x] || pri->pvts[x]->call != call) {
1420  continue;
1421  }
1422 
1423  /* Found our call */
1424  new_chan = pri->pvts[principle];
1425  old_chan = pri->pvts[x];
1426 
1427  /* Get locks to safely move to the new private structure. */
1428  sig_pri_lock_private(old_chan);
1429  sig_pri_lock_owner(pri, x);
1430  sig_pri_lock_private(new_chan);
1431 
1432  ast_verb(3, "Moving call (%s) from channel %d to %d.\n",
1433  old_chan->owner ? old_chan->owner->name : "",
1434  old_chan->channel, new_chan->channel);
1435  if (!sig_pri_is_chan_available(new_chan)) {
1437  "Can't move call (%s) from channel %d to %d. It is already in use.\n",
1438  old_chan->owner ? old_chan->owner->name : "",
1439  old_chan->channel, new_chan->channel);
1440  sig_pri_unlock_private(new_chan);
1441  if (old_chan->owner) {
1442  ast_channel_unlock(old_chan->owner);
1443  }
1444  sig_pri_unlock_private(old_chan);
1445  return -1;
1446  }
1447 
1448  sig_pri_fixup_chans(old_chan, new_chan);
1449 
1450  /* Fix it all up now */
1451  new_chan->owner = old_chan->owner;
1452  old_chan->owner = NULL;
1453 
1454  new_chan->call = old_chan->call;
1455  old_chan->call = NULL;
1456 
1457  /* Transfer flags from the old channel. */
1458 #if defined(HAVE_PRI_AOC_EVENTS)
1460  new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
1461  new_chan->holding_aoce = old_chan->holding_aoce;
1462 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
1463  new_chan->alreadyhungup = old_chan->alreadyhungup;
1464  new_chan->isidlecall = old_chan->isidlecall;
1465  new_chan->progress = old_chan->progress;
1466  new_chan->allocated = old_chan->allocated;
1467  new_chan->outgoing = old_chan->outgoing;
1468  new_chan->digital = old_chan->digital;
1469 #if defined(HAVE_PRI_CALL_WAITING)
1470  new_chan->is_call_waiting = old_chan->is_call_waiting;
1471 #endif /* defined(HAVE_PRI_CALL_WAITING) */
1472 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
1473  new_chan->no_dialed_digits = old_chan->no_dialed_digits;
1474 #endif /* defined(HAVE_PRI_SETUP_ACK_INBAND) */
1475 
1476 #if defined(HAVE_PRI_AOC_EVENTS)
1477  old_chan->aoc_s_request_invoke_id_valid = 0;
1478  old_chan->waiting_for_aoce = 0;
1479  old_chan->holding_aoce = 0;
1480 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
1481  old_chan->alreadyhungup = 0;
1482  old_chan->isidlecall = 0;
1483  old_chan->progress = 0;
1484  old_chan->allocated = 0;
1485  old_chan->outgoing = 0;
1486  old_chan->digital = 0;
1487 #if defined(HAVE_PRI_CALL_WAITING)
1488  old_chan->is_call_waiting = 0;
1489 #endif /* defined(HAVE_PRI_CALL_WAITING) */
1490 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
1491  old_chan->no_dialed_digits = 0;
1492 #endif /* defined(HAVE_PRI_SETUP_ACK_INBAND) */
1493 
1494  /* More stuff to transfer to the new channel. */
1495  new_chan->call_level = old_chan->call_level;
1496  old_chan->call_level = SIG_PRI_CALL_LEVEL_IDLE;
1497 #if defined(HAVE_PRI_REVERSE_CHARGE)
1499 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */
1500 #if defined(HAVE_PRI_SETUP_KEYPAD)
1501  strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
1502 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
1503  strcpy(new_chan->deferred_digits, old_chan->deferred_digits);
1504 #if defined(HAVE_PRI_AOC_EVENTS)
1505  new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
1506  new_chan->aoc_e = old_chan->aoc_e;
1507 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
1508  strcpy(new_chan->user_tag, old_chan->user_tag);
1509 
1510  if (new_chan->no_b_channel) {
1511  /* Copy the real channel configuration to the no B channel interface. */
1512  new_chan->hidecallerid = old_chan->hidecallerid;
1513  new_chan->hidecalleridname = old_chan->hidecalleridname;
1514  new_chan->immediate = old_chan->immediate;
1515  new_chan->priexclusive = old_chan->priexclusive;
1516  new_chan->priindication_oob = old_chan->priindication_oob;
1517  new_chan->use_callerid = old_chan->use_callerid;
1518  new_chan->use_callingpres = old_chan->use_callingpres;
1519  new_chan->stripmsd = old_chan->stripmsd;
1520  strcpy(new_chan->context, old_chan->context);
1521  strcpy(new_chan->mohinterpret, old_chan->mohinterpret);
1522 
1523  /* Become a member of the old channel span/trunk-group. */
1524  new_chan->logicalspan = old_chan->logicalspan;
1525  new_chan->mastertrunkgroup = old_chan->mastertrunkgroup;
1526  } else if (old_chan->no_b_channel) {
1527  /*
1528  * We are transitioning from a held/call-waiting channel to a
1529  * real channel so we need to make sure that the media path is
1530  * open. (Needed especially if the channel is natively
1531  * bridged.)
1532  */
1533  sig_pri_open_media(new_chan);
1534  }
1535 
1536  if (new_chan->owner) {
1537  sig_pri_ami_channel_event(new_chan);
1538  }
1539 
1540  sig_pri_unlock_private(old_chan);
1541  if (new_chan->owner) {
1542  ast_channel_unlock(new_chan->owner);
1543  }
1544  sig_pri_unlock_private(new_chan);
1545 
1546  return principle;
1547  }
1548  ast_verb(3, "Call specified, but not found.\n");
1549  return -1;
1550 }
int aoc_s_request_invoke_id
Definition: sig_pri.h:260
static void sig_pri_fixup_chans(struct sig_pri_chan *old_chan, struct sig_pri_chan *new_chan)
Definition: sig_pri.c:929
int logicalspan
Definition: sig_pri.h:304
unsigned int alreadyhungup
Definition: sig_pri.h:266
unsigned int priexclusive
Definition: sig_pri.h:227
char keypad_digits[AST_MAX_EXTENSION]
Keypad digits that came in with the SETUP message.
Definition: sig_pri.h:253
int reverse_charging_indication
Reverse charging indication.
Definition: sig_pri.h:321
unsigned int use_callingpres
Definition: sig_pri.h:230
unsigned int priindication_oob
Definition: sig_pri.h:228
unsigned int use_callerid
Definition: sig_pri.h:229
#define LOG_WARNING
Definition: logger.h:144
q931_call * call
Definition: sig_pri.h:297
unsigned int progress
Definition: sig_pri.h:268
struct ast_channel * owner
Definition: sig_pri.h:294
unsigned int aoc_s_request_invoke_id_valid
Definition: sig_pri.h:261
unsigned int isidlecall
Definition: sig_pri.h:267
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define ast_verb(level,...)
Definition: logger.h:243
int mastertrunkgroup
Definition: sig_pri.h:305
static void sig_pri_open_media(struct sig_pri_chan *p)
Definition: sig_pri.c:984
int stripmsd
Definition: sig_pri.h:233
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
struct pri_subcmd_aoc_e aoc_e
Definition: sig_pri.h:259
unsigned int holding_aoce
Definition: sig_pri.h:263
const ast_string_field name
Definition: channel.h:787
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
unsigned int immediate
Definition: sig_pri.h:226
#define ast_channel_unlock(chan)
Definition: channel.h:2467
unsigned int hidecalleridname
Definition: sig_pri.h:225
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
char deferred_digits[AST_MAX_EXTENSION]
Definition: sig_pri.h:256
int numchans
Definition: sig_pri.h:492
static void sig_pri_ami_channel_event(struct sig_pri_chan *p)
Definition: sig_pri.c:1006
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
unsigned int hidecallerid
Definition: sig_pri.h:224
unsigned int is_call_waiting
TRUE if this is a call waiting call.
Definition: sig_pri.h:287
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
unsigned int digital
Definition: sig_pri.h:282
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
unsigned int outgoing
Definition: sig_pri.h:281
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:280
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:231
unsigned int no_dialed_digits
Definition: sig_pri.h:291
unsigned int waiting_for_aoce
Definition: sig_pri.h:262
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:232
int channel
Definition: sig_pri.h:234
static int pri_grab ( struct sig_pri_chan p,
struct sig_pri_span pri 
)
inlinestatic

Definition at line 342 of file sig_pri.c.

References ast_mutex_trylock, AST_PTHREADT_NULL, sig_pri_span::lock, sig_pri_span::master, sig_pri_lock_private(), and sig_pri_unlock_private().

Referenced by pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), pri_ss_thread(), sig_pri_answer(), sig_pri_call(), sig_pri_chan_alarm_notify(), sig_pri_digit_begin(), sig_pri_hangup(), and sig_pri_indicate().

343 {
344  /* Grab the lock first */
345  while (ast_mutex_trylock(&pri->lock)) {
346  /* Avoid deadlock */
348  sched_yield();
350  }
351  /* Then break the poll */
352  if (pri->master != AST_PTHREADT_NULL) {
353  pthread_kill(pri->master, SIGURG);
354  }
355  return 0;
356 }
ast_mutex_t lock
Definition: sig_pri.h:495
#define ast_mutex_trylock(a)
Definition: lock.h:157
#define AST_PTHREADT_NULL
Definition: lock.h:65
pthread_t master
Definition: sig_pri.h:494
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
int pri_is_up ( struct sig_pri_span pri)

Definition at line 1027 of file sig_pri.c.

References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.

Referenced by pri_dchannel().

1028 {
1029  int x;
1030  for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
1031  if (pri->dchanavail[x] == DCHAN_AVAILABLE)
1032  return 1;
1033  }
1034  return 0;
1035 }
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
#define DCHAN_AVAILABLE
Definition: sig_pri.c:119
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
int pri_maintenance_bservice ( struct pri *  pri,
struct sig_pri_chan p,
int  changestatus 
)

Definition at line 8109 of file sig_pri.c.

References sig_pri_chan::channel, PRI_SPAN, and PVT_TO_CHANNEL().

Referenced by handle_pri_service_generic().

8110 {
8111  int channel = PVT_TO_CHANNEL(p);
8112  int span = PRI_SPAN(channel);
8113 
8114  return pri_maintenance_service(pri, span, channel, changestatus);
8115 }
#define PRI_SPAN(p)
Definition: sig_pri.c:113
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
struct sig_pri_span * pri
Definition: sig_pri.h:296
int channel
Definition: sig_pri.h:234
static const char* pri_order ( int  level)
static

Definition at line 1037 of file sig_pri.c.

Referenced by pri_dchannel(), pri_find_dchan(), and sig_pri_cli_show_span().

1038 {
1039  switch (level) {
1040  case 0:
1041  return "Primary";
1042  case 1:
1043  return "Secondary";
1044  case 2:
1045  return "Tertiary";
1046  case 3:
1047  return "Quaternary";
1048  default:
1049  return "<Unknown>";
1050  }
1051 }
static void pri_queue_control ( struct sig_pri_span pri,
int  chanpos,
int  subclass 
)
static

Definition at line 1239 of file sig_pri.c.

References AST_FRAME_CONTROL, sig_pri_chan::calls, sig_pri_chan::chan_pvt, ast_frame_subclass::integer, pri_queue_frame(), sig_pri_span::pvts, sig_pri_callback::queue_control, and ast_frame::subclass.

Referenced by pri_dchannel(), sig_pri_handle_retrieve(), and sig_pri_kill_call().

1240 {
1241  struct ast_frame f = {AST_FRAME_CONTROL, };
1242  struct sig_pri_chan *p = pri->pvts[chanpos];
1243 
1244  if (p->calls->queue_control) {
1245  p->calls->queue_control(p->chan_pvt, subclass);
1246  }
1247 
1248  f.subclass.integer = subclass;
1249  pri_queue_frame(pri, chanpos, &f);
1250 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const queue_control)(void *pvt, int subclass)
Definition: sig_pri.h:157
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
static void pri_queue_frame(struct sig_pri_span *pri, int chanpos, struct ast_frame *frame)
Definition: sig_pri.c:1216
static struct ast_format f[]
Definition: format_g726.c:181
Data structure associated with a single frame of data.
Definition: frame.h:142
static void pri_queue_frame ( struct sig_pri_span pri,
int  chanpos,
struct ast_frame frame 
)
static

Definition at line 1216 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_dchannel(), and pri_queue_control().

1217 {
1218  sig_pri_lock_owner(pri, chanpos);
1219  if (pri->pvts[chanpos]->owner) {
1220  ast_queue_frame(pri->pvts[chanpos]->owner, frame);
1221  ast_channel_unlock(pri->pvts[chanpos]->owner);
1222  }
1223 }
struct ast_channel * owner
Definition: sig_pri.h:294
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
static void pri_rel ( struct sig_pri_span pri)
inlinestatic
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 8087 of file sig_pri.c.

References ast_log(), sig_pri_chan::call, LOG_DEBUG, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_lock_private(), and sig_pri_unlock_private().

Referenced by dahdi_send_callrerouting_facility_exec().

8088 {
8089  int res;
8090 
8092 
8093  if (!p->pri || !p->call) {
8094  ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
8096  return -1;
8097  }
8098 
8099  pri_grab(p, p->pri);
8100  res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
8101  pri_rel(p->pri);
8102 
8104 
8105  return res;
8106 }
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
q931_call * call
Definition: sig_pri.h:297
#define LOG_DEBUG
Definition: logger.h:122
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
int pri_send_keypad_facility_exec ( struct sig_pri_chan p,
const char *  digits 
)

Definition at line 8068 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().

8069 {
8071 
8072  if (!p->pri || !p->call) {
8073  ast_debug(1, "Unable to find pri or call on channel!\n");
8075  return -1;
8076  }
8077 
8078  pri_grab(p, p->pri);
8079  pri_keypad_facility(p->pri->pri, p->call, digits);
8080  pri_rel(p->pri);
8081 
8083 
8084  return 0;
8085 }
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
q931_call * call
Definition: sig_pri.h:297
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
static void* pri_ss_thread ( void *  data)
static

Definition at line 1889 of file sig_pri.c.

References sig_pri_span::append_msn_to_user_tag, AST_CAUSE_UNALLOCATED, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_pbx_run(), ast_setstate(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_verb, ast_waitfordigit(), sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_chan::cid_num, ast_channel::context, DAHDI_OVERLAPDIAL_INCOMING, ast_channel::dialed, exten, sig_pri_chan::exten, ast_channel::exten, ast_channel::hangupcause, ast_party_caller::id, sig_pri_span::initial_user_tag, len(), sig_pri_span::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, sig_pri_span::nodetype, ast_party_dialed::number, sig_pri_span::overlapdial, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pri, pri_gendigittimeout, pri_grab(), pri_matchdigittimeout, pri_rel(), PVT_TO_CHANNEL(), SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_dsp_reset_and_flush_digits(), sig_pri_lock_private(), sig_pri_play_tone(), sig_pri_set_echocanceller(), sig_pri_span_devstate_changed(), SIG_PRI_TONE_DIALTONE, sig_pri_unlock_private(), ast_party_dialed::str, ast_party_id::tag, ast_channel::tech_pvt, and sig_pri_chan::user_tag.

Referenced by pri_dchannel().

1890 {
1891  struct sig_pri_chan *p = data;
1892  struct ast_channel *chan = p->owner;
1893  char exten[AST_MAX_EXTENSION];
1894  int res;
1895  int len;
1896  int timeout;
1897 
1898  if (!chan) {
1899  /* We lost the owner before we could get started. */
1900  return NULL;
1901  }
1902 
1903  /*
1904  * In the bizarre case where the channel has become a zombie before we
1905  * even get started here, abort safely.
1906  */
1907  if (!chan->tech_pvt) {
1908  ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
1909  ast_hangup(chan);
1910  return NULL;
1911  }
1912 
1913  ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
1914 
1916 
1917  /* Now loop looking for an extension */
1918  ast_copy_string(exten, p->exten, sizeof(exten));
1919  len = strlen(exten);
1920  res = 0;
1921  while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
1922  if (len && !ast_ignore_pattern(chan->context, exten))
1923  sig_pri_play_tone(p, -1);
1924  else
1926  if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
1927  timeout = pri_matchdigittimeout;
1928  else
1929  timeout = pri_gendigittimeout;
1930  res = ast_waitfordigit(chan, timeout);
1931  if (res < 0) {
1932  ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
1933  ast_hangup(chan);
1934  return NULL;
1935  } else if (res) {
1936  exten[len++] = res;
1937  exten[len] = '\0';
1938  } else
1939  break;
1940  }
1941  /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
1942  if (ast_strlen_zero(exten)) {
1943  ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n");
1944  exten[0] = 's';
1945  exten[1] = '\0';
1946  } else {
1947  ast_free(chan->dialed.number.str);
1948  chan->dialed.number.str = ast_strdup(exten);
1949 
1950  if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) {
1951  /*
1952  * Update the user tag for party id's from this device for this call
1953  * now that we have a complete MSN from the network.
1954  */
1955  snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
1956  exten);
1957  ast_free(chan->caller.id.tag);
1958  chan->caller.id.tag = ast_strdup(p->user_tag);
1959  }
1960  }
1961  sig_pri_play_tone(p, -1);
1962  if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
1963  /* Start the real PBX */
1964  ast_copy_string(chan->exten, exten, sizeof(chan->exten));
1966 #if defined(JIRA_ASTERISK_15594)
1967  /*
1968  * Conditionaled out this code to effectively revert the JIRA
1969  * ASTERISK-15594 change. It breaks overlap dialing through
1970  * Asterisk. There is not enough information available at this
1971  * point to know if dialing is complete. The
1972  * ast_exists_extension(), ast_matchmore_extension(), and
1973  * ast_canmatch_extension() calls are not adequate to detect a
1974  * dial through extension pattern of "_9!".
1975  *
1976  * Workaround is to use the dialplan Proceeding() application
1977  * early on non-dial through extensions.
1978  */
1980  && !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
1982  if (p->pri->pri) {
1983  pri_grab(p, p->pri);
1986  }
1987  pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0);
1988  pri_rel(p->pri);
1989  }
1991  }
1992 #endif /* defined(JIRA_ASTERISK_15594) */
1993 
1996  res = ast_pbx_run(chan);
1997  if (res) {
1998  ast_log(LOG_WARNING, "PBX exited non-zero!\n");
1999  }
2000  } else {
2001  ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
2003  ast_hangup(chan);
2004  p->exten[0] = '\0';
2005  /* Since we send release complete here, we won't get one */
2006  p->call = NULL;
2007  ast_mutex_lock(&p->pri->lock);
2009  ast_mutex_unlock(&p->pri->lock);
2010  }
2011  return NULL;
2012 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
int nodetype
Definition: sig_pri.h:434
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:5420
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:197
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
static void sig_pri_dsp_reset_and_flush_digits(struct sig_pri_chan *p)
Definition: sig_pri.c:914
#define ast_strdup(a)
Definition: astmm.h:109
void * tech_pvt
Definition: channel.h:744
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
static int sig_pri_play_tone(struct sig_pri_chan *p, enum sig_pri_tone tone)
Definition: sig_pri.c:935
q931_call * call
Definition: sig_pri.h:297
struct ast_channel * owner
Definition: sig_pri.h:294
static int pri_gendigittimeout
Definition: sig_pri.c:106
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:8650
#define ast_mutex_lock(a)
Definition: lock.h:155
#define LOG_DEBUG
Definition: logger.h:122
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
#define ast_verb(level,...)
Definition: logger.h:243
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
ast_mutex_t lock
Definition: sig_pri.h:495
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
struct ast_party_dialed::@155 number
Dialed/Called number.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
#define AST_MAX_EXTENSION
Definition: channel.h:135
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
int overlapdial
Definition: sig_pri.h:358
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char exten[AST_MAX_EXTENSION]
Definition: sig_pri.h:246
#define ast_free(a)
Definition: astmm.h:97
unsigned int append_msn_to_user_tag
Definition: sig_pri.h:399
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:427
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
char cid_num[AST_MAX_EXTENSION]
Definition: sig_pri.h:240
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
int hangupcause
Definition: channel.h:849
struct sig_pri_span * pri
Definition: sig_pri.h:296
static int pri_matchdigittimeout
Definition: sig_pri.c:104
static int sig_pri_set_echocanceller(struct sig_pri_chan *p, int enable)
Definition: sig_pri.c:921
struct pri * pri
Definition: sig_pri.h:481
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_mutex_unlock(a)
Definition: lock.h:156
static enum AST_PARTY_CHAR_SET pri_to_ast_char_set ( int  pri_char_set)
static

Definition at line 547 of file sig_pri.c.

References AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, AST_PARTY_CHAR_SET_ISO8859_1, AST_PARTY_CHAR_SET_ISO8859_2, AST_PARTY_CHAR_SET_ISO8859_3, AST_PARTY_CHAR_SET_ISO8859_4, AST_PARTY_CHAR_SET_ISO8859_5, AST_PARTY_CHAR_SET_ISO8859_7, AST_PARTY_CHAR_SET_UNKNOWN, and AST_PARTY_CHAR_SET_WITHDRAWN.

Referenced by sig_pri_party_name_convert().

548 {
549  enum AST_PARTY_CHAR_SET ast_char_set;
550 
551  switch (pri_char_set) {
552  default:
553  case PRI_CHAR_SET_UNKNOWN:
554  ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN;
555  break;
556  case PRI_CHAR_SET_ISO8859_1:
557  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1;
558  break;
559  case PRI_CHAR_SET_WITHDRAWN:
560  ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN;
561  break;
562  case PRI_CHAR_SET_ISO8859_2:
563  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2;
564  break;
565  case PRI_CHAR_SET_ISO8859_3:
566  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3;
567  break;
568  case PRI_CHAR_SET_ISO8859_4:
569  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4;
570  break;
571  case PRI_CHAR_SET_ISO8859_5:
572  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5;
573  break;
574  case PRI_CHAR_SET_ISO8859_7:
575  ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7;
576  break;
577  case PRI_CHAR_SET_ISO10646_BMPSTRING:
579  break;
580  case PRI_CHAR_SET_ISO10646_UTF_8STRING:
582  break;
583  }
584 
585  return ast_char_set;
586 }
AST_PARTY_CHAR_SET
Definition: channel.h:192
static int pri_to_ast_presentation ( int  pri_presentation)
static

Definition at line 437 of file sig_pri.c.

References AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.

Referenced by sig_pri_party_name_convert(), and sig_pri_party_number_convert().

438 {
439  int ast_presentation;
440 
441  switch (pri_presentation) {
442  case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
444  break;
445  case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
447  break;
448  case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
450  break;
451  case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
452  ast_presentation = AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER;
453  break;
454 
455  case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
457  break;
458  case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
460  break;
461  case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
463  break;
464  case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
465  ast_presentation = AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER;
466  break;
467 
468  case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
469  case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
470  case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
471  case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
472  ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE;
473  break;
474 
475  default:
477  break;
478  }
479 
480  return ast_presentation;
481 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_NUMBER_NOT_AVAILABLE
Definition: callerid.h:353
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319
#define AST_PRES_ALLOWED
Definition: callerid.h:324
static enum AST_REDIRECTING_REASON pri_to_ast_reason ( int  pri_reason)
static

Definition at line 367 of file sig_pri.c.

References AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, and AST_REDIRECTING_REASON_USER_BUSY.

Referenced by sig_pri_redirecting_convert().

368 {
369  enum AST_REDIRECTING_REASON ast_reason;
370 
371  switch (pri_reason) {
372  case PRI_REDIR_FORWARD_ON_BUSY:
374  break;
375  case PRI_REDIR_FORWARD_ON_NO_REPLY:
377  break;
378  case PRI_REDIR_DEFLECTION:
380  break;
381  case PRI_REDIR_UNCONDITIONAL:
383  break;
384  case PRI_REDIR_UNKNOWN:
385  default:
386  ast_reason = AST_REDIRECTING_REASON_UNKNOWN;
387  break;
388  }
389 
390  return ast_reason;
391 }
AST_REDIRECTING_REASON
redirecting reason codes.
Definition: callerid.h:390
static unsigned int PVT_TO_CHANNEL ( struct sig_pri_chan p)
static

Definition at line 149 of file sig_pri.c.

References ast_debug, sig_pri_chan::logicalspan, sig_pri_chan::mastertrunkgroup, PRI_EXPLICIT, and sig_pri_chan::prioffset.

Referenced by pri_check_restart(), pri_dchannel(), pri_maintenance_bservice(), pri_ss_thread(), sig_pri_call(), sig_pri_handle_retrieve(), and sig_pri_indicate().

150 {
151  int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->mastertrunkgroup ? PRI_EXPLICIT : 0));
152  ast_debug(5, "prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
153  p->prioffset, p->mastertrunkgroup, p->logicalspan, res);
154 
155  return res;
156 }
int logicalspan
Definition: sig_pri.h:304
int mastertrunkgroup
Definition: sig_pri.h:305
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define PRI_EXPLICIT
Definition: sig_pri.c:114
int prioffset
Definition: sig_pri.h:303
static char* redirectingreason2str ( int  redirectingreason)
static

Definition at line 1598 of file sig_pri.c.

Referenced by pri_dchannel().

1599 {
1600  switch (redirectingreason) {
1601  case 0:
1602  return "UNKNOWN";
1603  case 1:
1604  return "BUSY";
1605  case 2:
1606  return "NO_REPLY";
1607  case 0xF:
1608  return "UNCONDITIONAL";
1609  default:
1610  return "NOREDIRECT";
1611  }
1612 }
static void sig_pri_ami_channel_event ( struct sig_pri_chan p)
static

Definition at line 1006 of file sig_pri.c.

References sig_pri_callback::ami_channel_event, sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_chan::owner.

Referenced by pri_fixup_principle().

1007 {
1008  if (p->calls->ami_channel_event) {
1009  p->calls->ami_channel_event(p->chan_pvt, p->owner);
1010  }
1011 }
struct ast_channel * owner
Definition: sig_pri.h:294
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const ami_channel_event)(void *pvt, struct ast_channel *chan)
Post an AMI B channel association event.
Definition: sig_pri.h:175
int sig_pri_answer ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 7317 of file sig_pri.c.

References sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_setstate(), AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::digital, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_open_media(), and sig_pri_set_dialing().

Referenced by dahdi_answer().

7318 {
7319  int res;
7320 
7321  /* Send a pri acknowledge */
7322  pri_grab(p, p->pri);
7323 #if defined(HAVE_PRI_AOC_EVENTS)
7325  /* if AOC-S was requested and the invoke id is still present on answer. That means
7326  * no AOC-S rate list was provided, so send a NULL response which will indicate that
7327  * AOC-S is not available */
7328  pri_aoc_s_request_response_send(p->pri->pri, p->call,
7329  p->aoc_s_request_invoke_id, NULL);
7331  }
7332 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
7335  }
7336  sig_pri_set_dialing(p, 0);
7337  sig_pri_open_media(p);
7338  res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
7339  pri_rel(p->pri);
7340  ast_setstate(ast, AST_STATE_UP);
7341  return res;
7342 }
int aoc_s_request_invoke_id
Definition: sig_pri.h:260
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
q931_call * call
Definition: sig_pri.h:297
unsigned int aoc_s_request_invoke_id_valid
Definition: sig_pri.h:261
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
static void sig_pri_open_media(struct sig_pri_chan *p)
Definition: sig_pri.c:984
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
Definition: sig_pri.c:164
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
unsigned int digital
Definition: sig_pri.h:282
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast ( enum PRI_AOC_CHARGED_ITEM  value)
static

Definition at line 2918 of file sig_pri.c.

References AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, and AST_AOC_CHARGED_ITEM_USER_USER_INFO.

Referenced by sig_pri_aoc_s_from_pri().

2919 {
2920  switch (value) {
2921  case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
2922  return AST_AOC_CHARGED_ITEM_NA;
2923  case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
2925  case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
2927  case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
2929  case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
2931  case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
2933  case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
2935  }
2936  return AST_AOC_CHARGED_ITEM_NA;
2937 }
int value
Definition: syslog.c:39
static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri ( enum PRI_AOC_CHARGED_ITEM  value)
static

Definition at line 2886 of file sig_pri.c.

References AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, and AST_AOC_CHARGED_ITEM_USER_USER_INFO.

Referenced by sig_pri_aoc_s_from_ast().

2887 {
2888  switch (value) {
2890  return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
2892  return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
2894  return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
2896  return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
2898  return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
2900  return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
2902  return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
2903  }
2904  return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
2905 }
int value
Definition: syslog.c:39
static void sig_pri_aoc_d_from_ast ( struct sig_pri_chan pvt,
struct ast_aoc_decoded decoded 
)
static

Definition at line 3574 of file sig_pri.c.

References ast_aoc_unit_entry::amount, ARRAY_LEN, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_get_billing_id(), ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier(), ast_aoc_get_currency_name(), ast_aoc_get_total_type(), ast_aoc_get_unit_count(), ast_aoc_get_unit_info(), AST_AOC_TOTAL, ast_copy_string(), ast_strlen_zero(), sig_pri_chan::call, sig_pri_chan::pri, sig_pri_span::pri, sig_pri_aoc_multiplier_from_ast(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.

Referenced by sig_pri_indicate().

3575 {
3576  struct pri_subcmd_aoc_d aoc_d = { 0, };
3577 
3578  aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0;
3579 
3580  switch (ast_aoc_get_billing_id(decoded)) {
3582  aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
3583  break;
3585  aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
3586  break;
3588  aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
3589  break;
3590  case AST_AOC_BILLING_NA:
3591  default:
3592  aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
3593  break;
3594  }
3595 
3596  switch (ast_aoc_get_charge_type(decoded)) {
3597  case AST_AOC_CHARGE_FREE:
3598  aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
3599  break;
3601  {
3602  const char *currency_name = ast_aoc_get_currency_name(decoded);
3603  aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
3604  aoc_d.recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
3605  aoc_d.recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
3606  if (!ast_strlen_zero(currency_name)) {
3607  ast_copy_string(aoc_d.recorded.money.currency, currency_name, sizeof(aoc_d.recorded.money.currency));
3608  }
3609  }
3610  break;
3611  case AST_AOC_CHARGE_UNIT:
3612  {
3613  const struct ast_aoc_unit_entry *entry;
3614  int i;
3615  aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
3616  for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
3617  if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_d.recorded.unit.item)) {
3618  if (entry->valid_amount) {
3619  aoc_d.recorded.unit.item[i].number = entry->amount;
3620  } else {
3621  aoc_d.recorded.unit.item[i].number = -1;
3622  }
3623  if (entry->valid_type) {
3624  aoc_d.recorded.unit.item[i].type = entry->type;
3625  } else {
3626  aoc_d.recorded.unit.item[i].type = -1;
3627  }
3628  aoc_d.recorded.unit.num_items++;
3629  } else {
3630  break;
3631  }
3632  }
3633  }
3634  break;
3635  case AST_AOC_CHARGE_NA:
3636  default:
3637  aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3638  break;
3639  }
3640 
3641  pri_aoc_d_send(pvt->pri->pri, pvt->call, &aoc_d);
3642 }
char valid_amount
Definition: aoc.h:179
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
q931_call * call
Definition: sig_pri.h:297
unsigned int type
Definition: aoc.h:182
enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded)
get the type of total for a AOC-D message
Definition: aoc.c:783
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
Definition: aoc.c:809
enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded)
get the billing id for AOC-D and AOC-E messages
Definition: aoc.c:904
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
Definition: aoc.c:841
char valid_type
Definition: aoc.h:181
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
Definition: aoc.c:766
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int sig_pri_aoc_multiplier_from_ast(enum ast_aoc_currency_multiplier mult)
Definition: sig_pri.c:2948
struct sig_pri_span * pri
Definition: sig_pri.h:296
enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded)
get the currency multiplier for AOC-D and AOC-E messages
Definition: aoc.c:814
Definition: aoc.h:178
struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
Definition: aoc.c:879
unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded)
get the number of unit entries for AOC-D and AOC-E messages
Definition: aoc.c:888
unsigned int amount
Definition: aoc.h:180
struct pri * pri
Definition: sig_pri.h:481
static void sig_pri_aoc_d_from_pri ( const struct pri_subcmd_aoc_d *  aoc_d,
struct ast_channel owner,
int  passthrough 
)
static

Definition at line 3247 of file sig_pri.c.

References ast_aoc_add_unit_entry(), AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_manager_event(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), ast_aoc_set_total_type(), AST_AOC_SUBTOTAL, AST_AOC_TOTAL, AST_CONTROL_AOC, ast_debug, ast_queue_control_data(), sig_pri_aoc_multiplier_from_pri(), and type.

Referenced by sig_pri_handle_subcmds().

3248 {
3249  struct ast_aoc_decoded *decoded = NULL;
3250  struct ast_aoc_encoded *encoded = NULL;
3251  size_t encoded_size = 0;
3253 
3254  if (!owner || !aoc_d) {
3255  return;
3256  }
3257 
3258  switch (aoc_d->charge) {
3259  case PRI_AOC_DE_CHARGE_CURRENCY:
3260  type = AST_AOC_CHARGE_CURRENCY;
3261  break;
3262  case PRI_AOC_DE_CHARGE_UNITS:
3263  type = AST_AOC_CHARGE_UNIT;
3264  break;
3265  case PRI_AOC_DE_CHARGE_FREE:
3266  type = AST_AOC_CHARGE_FREE;
3267  break;
3268  default:
3269  type = AST_AOC_CHARGE_NA;
3270  break;
3271  }
3272 
3273  if (!(decoded = ast_aoc_create(AST_AOC_D, type, 0))) {
3274  return;
3275  }
3276 
3277  switch (aoc_d->billing_accumulation) {
3278  default:
3279  ast_debug(1, "AOC-D billing accumulation has unknown value: %d\n",
3280  aoc_d->billing_accumulation);
3281  /* Fall through */
3282  case 0:/* subTotal */
3284  break;
3285  case 1:/* total */
3287  break;
3288  }
3289 
3290  switch (aoc_d->billing_id) {
3291  case PRI_AOC_D_BILLING_ID_NORMAL:
3293  break;
3294  case PRI_AOC_D_BILLING_ID_REVERSE:
3296  break;
3297  case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
3299  break;
3300  case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
3301  default:
3303  break;
3304  }
3305 
3306  switch (aoc_d->charge) {
3307  case PRI_AOC_DE_CHARGE_CURRENCY:
3308  ast_aoc_set_currency_info(decoded,
3309  aoc_d->recorded.money.amount.cost,
3310  sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
3311  aoc_d->recorded.money.currency);
3312  break;
3313  case PRI_AOC_DE_CHARGE_UNITS:
3314  {
3315  int i;
3316  for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
3317  /* if type or number are negative, then they are not present */
3318  ast_aoc_add_unit_entry(decoded,
3319  (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
3320  aoc_d->recorded.unit.item[i].number,
3321  (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
3322  aoc_d->recorded.unit.item[i].type);
3323  }
3324  }
3325  break;
3326  }
3327 
3328  if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
3329  ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
3330  }
3331 
3332  ast_aoc_manager_event(decoded, owner);
3333 
3334  ast_aoc_destroy_decoded(decoded);
3335  ast_aoc_destroy_encoded(encoded);
3336 }
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition: aoc.c:846
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
Definition: aoc.c:1512
static int sig_pri_aoc_multiplier_from_pri(const int mult)
Definition: sig_pri.c:2979
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:519
ast_aoc_charge_type
Definition: aoc.h:69
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition: aoc.c:893
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
Definition: aoc.c:776
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
static const char type[]
Definition: chan_nbs.c:57
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:145
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1608
Definition: aoc.h:65
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition: aoc.c:788
static void sig_pri_aoc_e_from_ast ( struct sig_pri_chan pvt,
struct ast_aoc_decoded decoded 
)
static

Definition at line 3657 of file sig_pri.c.

References ast_aoc_unit_entry::amount, sig_pri_chan::aoc_e, ARRAY_LEN, AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, AST_AOC_CHARGING_ASSOCIATION_ID, AST_AOC_CHARGING_ASSOCIATION_NA, AST_AOC_CHARGING_ASSOCIATION_NUMBER, ast_aoc_get_association_info(), ast_aoc_get_billing_id(), ast_aoc_get_charge_type(), ast_aoc_get_currency_amount(), ast_aoc_get_currency_multiplier(), ast_aoc_get_currency_name(), ast_aoc_get_unit_count(), ast_aoc_get_unit_info(), ast_copy_string(), ast_strlen_zero(), ast_aoc_charging_association::charge, ast_aoc_charging_association::charging_type, sig_pri_chan::holding_aoce, ast_aoc_charging_association::id, ast_aoc_charging_association_number::number, ast_aoc_charging_association::number, ast_aoc_charging_association_number::plan, sig_pri_aoc_multiplier_from_ast(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.

Referenced by sig_pri_indicate().

3658 {
3659  struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
3660  const struct ast_aoc_charging_association *ca = ast_aoc_get_association_info(decoded);
3661 
3662  memset(aoc_e, 0, sizeof(*aoc_e));
3663  pvt->holding_aoce = 1;
3664 
3665  switch (ca->charging_type) {
3667  aoc_e->associated.charge.number.valid = 1;
3668  ast_copy_string(aoc_e->associated.charge.number.str,
3669  ca->charge.number.number,
3670  sizeof(aoc_e->associated.charge.number.str));
3671  aoc_e->associated.charge.number.plan = ca->charge.number.plan;
3672  aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
3673  break;
3675  aoc_e->associated.charge.id = ca->charge.id;
3676  aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
3677  break;
3679  default:
3680  break;
3681  }
3682 
3683  switch (ast_aoc_get_billing_id(decoded)) {
3685  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
3686  break;
3688  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
3689  break;
3691  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
3692  break;
3694  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
3695  break;
3697  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
3698  break;
3700  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
3701  break;
3703  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
3704  break;
3706  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
3707  break;
3708  case AST_AOC_BILLING_NA:
3709  default:
3710  aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
3711  break;
3712  }
3713 
3714  switch (ast_aoc_get_charge_type(decoded)) {
3715  case AST_AOC_CHARGE_FREE:
3716  aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
3717  break;
3719  {
3720  const char *currency_name = ast_aoc_get_currency_name(decoded);
3721  aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
3722  aoc_e->recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
3723  aoc_e->recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
3724  if (!ast_strlen_zero(currency_name)) {
3725  ast_copy_string(aoc_e->recorded.money.currency, currency_name, sizeof(aoc_e->recorded.money.currency));
3726  }
3727  }
3728  break;
3729  case AST_AOC_CHARGE_UNIT:
3730  {
3731  const struct ast_aoc_unit_entry *entry;
3732  int i;
3733  aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
3734  for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
3735  if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_e->recorded.unit.item)) {
3736  if (entry->valid_amount) {
3737  aoc_e->recorded.unit.item[i].number = entry->amount;
3738  } else {
3739  aoc_e->recorded.unit.item[i].number = -1;
3740  }
3741  if (entry->valid_type) {
3742  aoc_e->recorded.unit.item[i].type = entry->type;
3743  } else {
3744  aoc_e->recorded.unit.item[i].type = -1;
3745  }
3746  aoc_e->recorded.unit.num_items++;
3747  }
3748  }
3749  }
3750  break;
3751  case AST_AOC_CHARGE_NA:
3752  default:
3753  aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3754  break;
3755  }
3756 }
char valid_amount
Definition: aoc.h:179
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
unsigned int type
Definition: aoc.h:182
struct ast_aoc_charging_association_number number
Definition: aoc.h:197
struct ast_aoc_charging_association * ast_aoc_get_association_info(struct ast_aoc_decoded *decoded)
get the charging association info for AOC-E messages
Definition: aoc.c:920
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct pri_subcmd_aoc_e aoc_e
Definition: sig_pri.h:259
unsigned int holding_aoce
Definition: sig_pri.h:263
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
Definition: aoc.c:809
enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded)
get the billing id for AOC-D and AOC-E messages
Definition: aoc.c:904
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
Definition: aoc.c:841
char valid_type
Definition: aoc.h:181
union ast_aoc_charging_association::@142 charge
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
Definition: aoc.c:766
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int sig_pri_aoc_multiplier_from_ast(enum ast_aoc_currency_multiplier mult)
Definition: sig_pri.c:2948
enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded)
get the currency multiplier for AOC-D and AOC-E messages
Definition: aoc.c:814
Definition: aoc.h:178
struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
Definition: aoc.c:879
unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded)
get the number of unit entries for AOC-D and AOC-E messages
Definition: aoc.c:888
unsigned int amount
Definition: aoc.h:180
static void sig_pri_aoc_e_from_pri ( const struct pri_subcmd_aoc_e *  aoc_e,
struct ast_channel owner,
int  passthrough 
)
static

Definition at line 3356 of file sig_pri.c.

References ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), AST_AOC_E, ast_aoc_encode(), ast_aoc_manager_event(), ast_aoc_set_association_id(), ast_aoc_set_association_number(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), AST_CONTROL_AOC, ast_queue_control_data(), sig_pri_aoc_multiplier_from_pri(), and type.

Referenced by sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().

3357 {
3358  struct ast_aoc_decoded *decoded = NULL;
3359  struct ast_aoc_encoded *encoded = NULL;
3360  size_t encoded_size = 0;
3362 
3363  if (!aoc_e) {
3364  return;
3365  }
3366 
3367  switch (aoc_e->charge) {
3368  case PRI_AOC_DE_CHARGE_CURRENCY:
3369  type = AST_AOC_CHARGE_CURRENCY;
3370  break;
3371  case PRI_AOC_DE_CHARGE_UNITS:
3372  type = AST_AOC_CHARGE_UNIT;
3373  break;
3374  case PRI_AOC_DE_CHARGE_FREE:
3375  type = AST_AOC_CHARGE_FREE;
3376  break;
3377  default:
3378  type = AST_AOC_CHARGE_NA;
3379  break;
3380  }
3381 
3382  if (!(decoded = ast_aoc_create(AST_AOC_E, type, 0))) {
3383  return;
3384  }
3385 
3386  switch (aoc_e->associated.charging_type) {
3387  case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
3388  if (!aoc_e->associated.charge.number.valid) {
3389  break;
3390  }
3391  ast_aoc_set_association_number(decoded, aoc_e->associated.charge.number.str, aoc_e->associated.charge.number.plan);
3392  break;
3393  case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
3394  ast_aoc_set_association_id(decoded, aoc_e->associated.charge.id);
3395  break;
3396  default:
3397  break;
3398  }
3399 
3400  switch (aoc_e->billing_id) {
3401  case PRI_AOC_E_BILLING_ID_NORMAL:
3403  break;
3404  case PRI_AOC_E_BILLING_ID_REVERSE:
3406  break;
3407  case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
3409  break;
3410  case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
3412  break;
3413  case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
3415  break;
3416  case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
3418  break;
3419  case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
3421  break;
3422  case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
3424  break;
3425  case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
3426  default:
3428  break;
3429  }
3430 
3431  switch (aoc_e->charge) {
3432  case PRI_AOC_DE_CHARGE_CURRENCY:
3433  ast_aoc_set_currency_info(decoded,
3434  aoc_e->recorded.money.amount.cost,
3435  sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
3436  aoc_e->recorded.money.currency);
3437  break;
3438  case PRI_AOC_DE_CHARGE_UNITS:
3439  {
3440  int i;
3441  for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
3442  /* if type or number are negative, then they are not present */
3443  ast_aoc_add_unit_entry(decoded,
3444  (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
3445  aoc_e->recorded.unit.item[i].number,
3446  (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
3447  aoc_e->recorded.unit.item[i].type);
3448  }
3449  }
3450  }
3451 
3452  if (passthrough && owner && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
3453  ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
3454  }
3455 
3456  ast_aoc_manager_event(decoded, owner);
3457 
3458  ast_aoc_destroy_decoded(decoded);
3459  ast_aoc_destroy_encoded(encoded);
3460 }
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition: aoc.c:846
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
Definition: aoc.c:1512
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging accociation number for an AOC-E message
Definition: aoc.c:925
static int sig_pri_aoc_multiplier_from_pri(const int mult)
Definition: sig_pri.c:2979
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:519
ast_aoc_charge_type
Definition: aoc.h:69
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition: aoc.c:893
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
static const char type[]
Definition: chan_nbs.c:57
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:145
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1608
Definition: aoc.h:66
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
Definition: aoc.c:909
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition: aoc.c:788
static int sig_pri_aoc_multiplier_from_ast ( enum ast_aoc_currency_multiplier  mult)
static

Definition at line 2948 of file sig_pri.c.

References AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, and AST_AOC_MULT_THOUSAND.

Referenced by sig_pri_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), and sig_pri_aoc_s_from_ast().

2949 {
2950  switch (mult) {
2952  return PRI_AOC_MULTIPLIER_THOUSANDTH;
2954  return PRI_AOC_MULTIPLIER_HUNDREDTH;
2955  case AST_AOC_MULT_ONETENTH:
2956  return PRI_AOC_MULTIPLIER_TENTH;
2957  case AST_AOC_MULT_ONE:
2958  return PRI_AOC_MULTIPLIER_ONE;
2959  case AST_AOC_MULT_TEN:
2960  return PRI_AOC_MULTIPLIER_TEN;
2961  case AST_AOC_MULT_HUNDRED:
2962  return PRI_AOC_MULTIPLIER_HUNDRED;
2963  case AST_AOC_MULT_THOUSAND:
2964  return PRI_AOC_MULTIPLIER_THOUSAND;
2965  default:
2966  return PRI_AOC_MULTIPLIER_ONE;
2967  }
2968 }
static int sig_pri_aoc_multiplier_from_pri ( const int  mult)
static

Definition at line 2979 of file sig_pri.c.

References AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, and AST_AOC_MULT_THOUSAND.

Referenced by sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), and sig_pri_aoc_s_from_pri().

2980 {
2981  switch (mult) {
2982  case PRI_AOC_MULTIPLIER_THOUSANDTH:
2984  case PRI_AOC_MULTIPLIER_HUNDREDTH:
2986  case PRI_AOC_MULTIPLIER_TENTH:
2987  return AST_AOC_MULT_ONETENTH;
2988  case PRI_AOC_MULTIPLIER_ONE:
2989  return AST_AOC_MULT_ONE;
2990  case PRI_AOC_MULTIPLIER_TEN:
2991  return AST_AOC_MULT_TEN;
2992  case PRI_AOC_MULTIPLIER_HUNDRED:
2993  return AST_AOC_MULT_HUNDRED;
2994  case PRI_AOC_MULTIPLIER_THOUSAND:
2995  return AST_AOC_MULT_THOUSAND;
2996  default:
2997  return AST_AOC_MULT_ONE;
2998  }
2999 }
static void sig_pri_aoc_request_from_pri ( const struct pri_subcmd_aoc_request *  aoc_request,
struct sig_pri_chan pvt,
q931_call *  call 
)
static

Definition at line 3176 of file sig_pri.c.

References sig_pri_span::aoc_passthrough_flag, sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, sig_pri_chan::pri, sig_pri_span::pri, SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, and SIG_PRI_AOC_GRANT_S.

Referenced by sig_pri_handle_subcmds().

3177 {
3178  int request;
3179 
3180  if (!aoc_request) {
3181  return;
3182  }
3183 
3184  request = aoc_request->charging_request;
3185 
3186  if (request & PRI_AOC_REQUEST_S) {
3188  /* An AOC-S response must come from the other side, so save off this invoke_id
3189  * and see if an AOC-S message comes in before the call is answered. */
3190  pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
3192 
3193  } else {
3194  pri_aoc_s_request_response_send(pvt->pri->pri,
3195  call,
3196  aoc_request->invoke_id,
3197  NULL);
3198  }
3199  }
3200 
3201  if (request & PRI_AOC_REQUEST_D) {
3203  pri_aoc_de_request_response_send(pvt->pri->pri,
3204  call,
3205  PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3206  aoc_request->invoke_id);
3207  } else {
3208  pri_aoc_de_request_response_send(pvt->pri->pri,
3209  call,
3210  PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3211  aoc_request->invoke_id);
3212  }
3213  }
3214 
3215  if (request & PRI_AOC_REQUEST_E) {
3217  pri_aoc_de_request_response_send(pvt->pri->pri,
3218  call,
3219  PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3220  aoc_request->invoke_id);
3221  } else {
3222  pri_aoc_de_request_response_send(pvt->pri->pri,
3223  call,
3224  PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3225  aoc_request->invoke_id);
3226  }
3227  }
3228 }
int aoc_s_request_invoke_id
Definition: sig_pri.h:260
unsigned int aoc_s_request_invoke_id_valid
Definition: sig_pri.h:261
#define SIG_PRI_AOC_GRANT_S
Definition: sig_pri.h:66
struct sig_pri_span * pri
Definition: sig_pri.h:296
#define SIG_PRI_AOC_GRANT_E
Definition: sig_pri.h:68
int aoc_passthrough_flag
Definition: sig_pri.h:370
#define SIG_PRI_AOC_GRANT_D
Definition: sig_pri.h:67
struct pri * pri
Definition: sig_pri.h:481
static void sig_pri_aoc_s_from_ast ( struct sig_pri_chan pvt,
struct ast_aoc_decoded decoded 
)
static

Definition at line 3475 of file sig_pri.c.

References ast_aoc_duration_rate::amount, ast_aoc_volume_rate::amount, ast_aoc_flat_rate::amount, sig_pri_chan::aoc_s_request_invoke_id, sig_pri_chan::aoc_s_request_invoke_id_valid, AST_AOC_RATE_TYPE_DURATION, AST_AOC_RATE_TYPE_FLAT, AST_AOC_RATE_TYPE_FREE, AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING, AST_AOC_RATE_TYPE_NA, AST_AOC_RATE_TYPE_SPECIAL_CODE, AST_AOC_RATE_TYPE_VOLUME, ast_aoc_s_get_count(), ast_aoc_s_get_rate_info(), ast_copy_string(), ast_strlen_zero(), sig_pri_chan::call, ast_aoc_s_entry::charged_item, ast_aoc_duration_rate::charging_type, ast_aoc_duration_rate::currency_name, ast_aoc_volume_rate::currency_name, ast_aoc_flat_rate::currency_name, ast_aoc_s_entry::duration, ast_aoc_s_entry::flat, ast_aoc_duration_rate::granularity_time, ast_aoc_duration_rate::granularity_time_scale, ast_aoc_duration_rate::multiplier, ast_aoc_volume_rate::multiplier, ast_aoc_flat_rate::multiplier, sig_pri_chan::pri, sig_pri_span::pri, ast_aoc_s_entry::rate, ast_aoc_s_entry::rate_type, sig_pri_aoc_charged_item_to_pri(), sig_pri_aoc_multiplier_from_ast(), sig_pri_aoc_scale_to_pri(), ast_aoc_s_entry::special_code, ast_aoc_duration_rate::time, ast_aoc_duration_rate::time_scale, ast_aoc_s_entry::volume, and ast_aoc_volume_rate::volume_unit.

Referenced by sig_pri_indicate().

3476 {
3477  struct pri_subcmd_aoc_s aoc_s = { 0, };
3478  const struct ast_aoc_s_entry *entry;
3479  int idx;
3480 
3481  for (idx = 0; idx < ast_aoc_s_get_count(decoded); idx++) {
3482  if (!(entry = ast_aoc_s_get_rate_info(decoded, idx))) {
3483  break;
3484  }
3485 
3486  aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->charged_item);
3487 
3488  switch (entry->rate_type) {
3490  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
3491  aoc_s.item[idx].rate.duration.amount.cost = entry->rate.duration.amount;
3492  aoc_s.item[idx].rate.duration.amount.multiplier =
3494  aoc_s.item[idx].rate.duration.time.length = entry->rate.duration.time;
3495  aoc_s.item[idx].rate.duration.time.scale =
3497  aoc_s.item[idx].rate.duration.granularity.length = entry->rate.duration.granularity_time;
3498  aoc_s.item[idx].rate.duration.granularity.scale =
3500  aoc_s.item[idx].rate.duration.charging_type = entry->rate.duration.charging_type;
3501 
3502  if (!ast_strlen_zero(entry->rate.duration.currency_name)) {
3503  ast_copy_string(aoc_s.item[idx].rate.duration.currency,
3504  entry->rate.duration.currency_name,
3505  sizeof(aoc_s.item[idx].rate.duration.currency));
3506  }
3507  break;
3509  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
3510  aoc_s.item[idx].rate.flat.amount.cost = entry->rate.flat.amount;
3511  aoc_s.item[idx].rate.flat.amount.multiplier =
3513 
3514  if (!ast_strlen_zero(entry->rate.flat.currency_name)) {
3515  ast_copy_string(aoc_s.item[idx].rate.flat.currency,
3516  entry->rate.flat.currency_name,
3517  sizeof(aoc_s.item[idx].rate.flat.currency));
3518  }
3519  break;
3521  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
3522  aoc_s.item[idx].rate.volume.unit = entry->rate.volume.volume_unit;
3523  aoc_s.item[idx].rate.volume.amount.cost = entry->rate.volume.amount;
3524  aoc_s.item[idx].rate.volume.amount.multiplier =
3526 
3527  if (!ast_strlen_zero(entry->rate.volume.currency_name)) {
3528  ast_copy_string(aoc_s.item[idx].rate.volume.currency,
3529  entry->rate.volume.currency_name,
3530  sizeof(aoc_s.item[idx].rate.volume.currency));
3531  }
3532  break;
3534  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
3535  aoc_s.item[idx].rate.special = entry->rate.special_code;
3536  break;
3538  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
3539  break;
3541  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
3542  break;
3543  default:
3544  case AST_AOC_RATE_TYPE_NA:
3545  aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
3546  break;
3547  }
3548  }
3549  aoc_s.num_items = idx;
3550 
3551  /* if this rate should be sent as a response to an AOC-S request we will
3552  * have an aoc_s_request_invoke_id associated with this pvt */
3553  if (pvt->aoc_s_request_invoke_id_valid) {
3554  pri_aoc_s_request_response_send(pvt->pri->pri, pvt->call, pvt->aoc_s_request_invoke_id, &aoc_s);
3556  } else {
3557  pri_aoc_s_send(pvt->pri->pri, pvt->call, &aoc_s);
3558  }
3559 }
int aoc_s_request_invoke_id
Definition: sig_pri.h:260
struct ast_aoc_s_entry * ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific AOC-S rate entry.
Definition: aoc.c:630
uint16_t volume_unit
Definition: aoc.h:134
struct ast_aoc_duration_rate duration
Definition: aoc.h:171
q931_call * call
Definition: sig_pri.h:297
Definition: aoc.h:165
uint32_t amount
Definition: aoc.h:132
unsigned int aoc_s_request_invoke_id_valid
Definition: sig_pri.h:261
uint16_t charged_item
Definition: aoc.h:166
uint8_t charging_type
Charging interval type.
Definition: aoc.h:122
uint32_t amount
Definition: aoc.h:104
uint16_t multiplier
Definition: aoc.h:109
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
Definition: aoc.c:625
static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri(enum ast_aoc_time_scale value)
Definition: sig_pri.c:3012
uint16_t special_code
Definition: aoc.h:174
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_aoc_flat_rate flat
Definition: aoc.h:172
char currency_name[AOC_CURRENCY_NAME_SIZE]
Definition: aoc.h:142
uint16_t multiplier
Definition: aoc.h:140
uint16_t multiplier
Definition: aoc.h:133
uint16_t time_scale
Definition: aoc.h:110
struct ast_aoc_volume_rate volume
Definition: aoc.h:173
uint32_t granularity_time
Definition: aoc.h:107
char currency_name[AOC_CURRENCY_NAME_SIZE]
Definition: aoc.h:114
uint32_t time
Definition: aoc.h:105
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int sig_pri_aoc_multiplier_from_ast(enum ast_aoc_currency_multiplier mult)
Definition: sig_pri.c:2948
union ast_aoc_s_entry::@141 rate
Charge rate being applied.
struct sig_pri_span * pri
Definition: sig_pri.h:296
uint32_t amount
Definition: aoc.h:139
uint16_t rate_type
Definition: aoc.h:167
struct pri * pri
Definition: sig_pri.h:481
uint16_t granularity_time_scale
Definition: aoc.h:111
static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(enum PRI_AOC_CHARGED_ITEM value)
Definition: sig_pri.c:2886
char currency_name[AOC_CURRENCY_NAME_SIZE]
Definition: aoc.h:135
static void sig_pri_aoc_s_from_pri ( const struct pri_subcmd_aoc_s *  aoc_s,
struct ast_channel owner,
int  passthrough 
)
static

Definition at line 3083 of file sig_pri.c.

References AST_AOC_CHARGED_ITEM_NA, ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), ast_aoc_manager_event(), AST_AOC_S, ast_aoc_s_add_rate_duration(), ast_aoc_s_add_rate_flat(), ast_aoc_s_add_rate_free(), ast_aoc_s_add_rate_na(), ast_aoc_s_add_rate_special_charge_code(), ast_aoc_s_add_rate_volume(), AST_CONTROL_AOC, ast_queue_control_data(), sig_pri_aoc_charged_item_to_ast(), sig_pri_aoc_multiplier_from_pri(), and sig_pri_aoc_scale_to_ast().

Referenced by sig_pri_handle_subcmds().

3084 {
3085  struct ast_aoc_decoded *decoded = NULL;
3086  struct ast_aoc_encoded *encoded = NULL;
3087  size_t encoded_size = 0;
3088  int idx;
3089 
3090  if (!owner || !aoc_s) {
3091  return;
3092  }
3093 
3094  if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
3095  return;
3096  }
3097 
3098  for (idx = 0; idx < aoc_s->num_items; ++idx) {
3099  enum ast_aoc_s_charged_item charged_item;
3100 
3101  charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
3102  if (charged_item == AST_AOC_CHARGED_ITEM_NA) {
3103  /* Delete the unknown charged item from the list. */
3104  continue;
3105  }
3106  switch (aoc_s->item[idx].rate_type) {
3107  case PRI_AOC_RATE_TYPE_DURATION:
3109  charged_item,
3110  aoc_s->item[idx].rate.duration.amount.cost,
3111  sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
3112  aoc_s->item[idx].rate.duration.currency,
3113  aoc_s->item[idx].rate.duration.time.length,
3114  sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
3115  aoc_s->item[idx].rate.duration.granularity.length,
3116  sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
3117  aoc_s->item[idx].rate.duration.charging_type);
3118  break;
3119  case PRI_AOC_RATE_TYPE_FLAT:
3120  ast_aoc_s_add_rate_flat(decoded,
3121  charged_item,
3122  aoc_s->item[idx].rate.flat.amount.cost,
3123  sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
3124  aoc_s->item[idx].rate.flat.currency);
3125  break;
3126  case PRI_AOC_RATE_TYPE_VOLUME:
3127  ast_aoc_s_add_rate_volume(decoded,
3128  charged_item,
3129  aoc_s->item[idx].rate.volume.unit,
3130  aoc_s->item[idx].rate.volume.amount.cost,
3131  sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
3132  aoc_s->item[idx].rate.volume.currency);
3133  break;
3134  case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
3136  charged_item,
3137  aoc_s->item[idx].rate.special);
3138  break;
3139  case PRI_AOC_RATE_TYPE_FREE:
3140  ast_aoc_s_add_rate_free(decoded, charged_item, 0);
3141  break;
3142  case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3143  ast_aoc_s_add_rate_free(decoded, charged_item, 1);
3144  break;
3145  default:
3146  ast_aoc_s_add_rate_na(decoded, charged_item);
3147  break;
3148  }
3149  }
3150 
3151  if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
3152  ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
3153  }
3154 
3155  ast_aoc_manager_event(decoded, owner);
3156 
3157  ast_aoc_destroy_decoded(decoded);
3158  ast_aoc_destroy_encoded(encoded);
3159 }
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Definition: aoc.c:639
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
Definition: aoc.c:670
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
Definition: aoc.c:713
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
Definition: aoc.c:691
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
Definition: aoc.c:1512
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
Definition: aoc.c:726
static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast(enum PRI_AOC_CHARGED_ITEM value)
Definition: sig_pri.c:2918
static int sig_pri_aoc_multiplier_from_pri(const int mult)
Definition: sig_pri.c:2979
ast_aoc_s_charged_item
Definition: aoc.h:145
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
Definition: aoc.c:738
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:519
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:145
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1608
Definition: aoc.h:64
static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast(enum PRI_AOC_TIME_SCALE value)
Definition: sig_pri.c:3044
static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast ( enum PRI_AOC_TIME_SCALE  value)
static

Definition at line 3044 of file sig_pri.c.

References AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, and AST_AOC_TIME_SCALE_TENTH_SECOND.

Referenced by sig_pri_aoc_s_from_pri().

3045 {
3046  switch (value) {
3047  default:
3048  case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3050  case PRI_AOC_TIME_SCALE_TENTH_SECOND:
3052  case PRI_AOC_TIME_SCALE_SECOND:
3054  case PRI_AOC_TIME_SCALE_TEN_SECOND:
3056  case PRI_AOC_TIME_SCALE_MINUTE:
3058  case PRI_AOC_TIME_SCALE_HOUR:
3059  return AST_AOC_TIME_SCALE_HOUR;
3060  case PRI_AOC_TIME_SCALE_DAY:
3061  return AST_AOC_TIME_SCALE_DAY;
3062  }
3064 }
int value
Definition: syslog.c:39
static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri ( enum ast_aoc_time_scale  value)
static

Definition at line 3012 of file sig_pri.c.

References AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, and AST_AOC_TIME_SCALE_TENTH_SECOND.

Referenced by sig_pri_aoc_s_from_ast().

3013 {
3014  switch (value) {
3015  default:
3017  return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3019  return PRI_AOC_TIME_SCALE_TENTH_SECOND;
3021  return PRI_AOC_TIME_SCALE_SECOND;
3023  return PRI_AOC_TIME_SCALE_TEN_SECOND;
3025  return PRI_AOC_TIME_SCALE_MINUTE;
3027  return PRI_AOC_TIME_SCALE_HOUR;
3029  return PRI_AOC_TIME_SCALE_DAY;
3030  }
3031 }
int value
Definition: syslog.c:39
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 2347 of file sig_pri.c.

References ast_bridged_channel(), ast_channel_transfer_masquerade(), ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_verb, sig_pri_span::lock, sig_pri_chan::owner, pri_find_principle_by_call(), sig_pri_span::pvts, sig_pri_lock_owner(), sig_pri_lock_private(), and sig_pri_unlock_private().

Referenced by pri_dchannel(), and sig_pri_handle_subcmds().

2348 {
2349  struct attempt_xfer_call {
2350  q931_call *pri;
2351  struct ast_channel *ast;
2352  int held;
2353  int chanpos;
2354  };
2355  int retval;
2356  struct ast_channel *transferee;
2357  struct attempt_xfer_call *call_1;
2358  struct attempt_xfer_call *call_2;
2359  struct attempt_xfer_call *swap_call;
2360  struct attempt_xfer_call c1;
2361  struct attempt_xfer_call c2;
2362 
2363  c1.pri = call_1_pri;
2364  c1.held = call_1_held;
2365  call_1 = &c1;
2366 
2367  c2.pri = call_2_pri;
2368  c2.held = call_2_held;
2369  call_2 = &c2;
2370 
2371  call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
2372  call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
2373  if (call_1->chanpos < 0 || call_2->chanpos < 0) {
2374  /* Calls not found in span control. */
2375  if (rsp_callback) {
2376  /* Transfer failed. */
2377  rsp_callback(data, 0);
2378  }
2379  return -1;
2380  }
2381 
2382  /* Attempt to make transferee and target consistent. */
2383  if (!call_1->held && call_2->held) {
2384  /*
2385  * Swap call_1 and call_2 to make call_1 the transferee(held call)
2386  * and call_2 the target(active call).
2387  */
2388  swap_call = call_1;
2389  call_1 = call_2;
2390  call_2 = swap_call;
2391  }
2392 
2393  /* Deadlock avoidance is attempted. */
2394  sig_pri_lock_private(pri->pvts[call_1->chanpos]);
2395  sig_pri_lock_owner(pri, call_1->chanpos);
2396  sig_pri_lock_private(pri->pvts[call_2->chanpos]);
2397  sig_pri_lock_owner(pri, call_2->chanpos);
2398 
2399  call_1->ast = pri->pvts[call_1->chanpos]->owner;
2400  call_2->ast = pri->pvts[call_2->chanpos]->owner;
2401  if (!call_1->ast || !call_2->ast) {
2402  /* At least one owner is not present. */
2403  if (call_1->ast) {
2404  ast_channel_unlock(call_1->ast);
2405  }
2406  if (call_2->ast) {
2407  ast_channel_unlock(call_2->ast);
2408  }
2409  sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
2410  sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
2411  if (rsp_callback) {
2412  /* Transfer failed. */
2413  rsp_callback(data, 0);
2414  }
2415  return -1;
2416  }
2417 
2418  for (;;) {
2419  transferee = ast_bridged_channel(call_1->ast);
2420  if (transferee) {
2421  break;
2422  }
2423 
2424  /* Try masquerading the other way. */
2425  swap_call = call_1;
2426  call_1 = call_2;
2427  call_2 = swap_call;
2428 
2429  transferee = ast_bridged_channel(call_1->ast);
2430  if (transferee) {
2431  break;
2432  }
2433 
2434  /* Could not transfer. Neither call is bridged. */
2435  ast_channel_unlock(call_1->ast);
2436  ast_channel_unlock(call_2->ast);
2437  sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
2438  sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
2439 
2440  if (rsp_callback) {
2441  /* Transfer failed. */
2442  rsp_callback(data, 0);
2443  }
2444  return -1;
2445  }
2446 
2447  ast_verb(3, "TRANSFERRING %s to %s\n", call_1->ast->name, call_2->ast->name);
2448 
2449  /*
2450  * Setup transfer masquerade.
2451  *
2452  * Note: There is an extremely nasty deadlock avoidance issue
2453  * with ast_channel_transfer_masquerade(). Deadlock may be possible if
2454  * the channels involved are proxies (chan_agent channels) and
2455  * it is called with locks. Unfortunately, there is no simple
2456  * or even merely difficult way to guarantee deadlock avoidance
2457  * and still be able to send an ECT success response without the
2458  * possibility of the bridged channel hanging up on us.
2459  */
2460  ast_mutex_unlock(&pri->lock);
2462  call_2->ast,
2463  &call_2->ast->connected,
2464  call_2->held,
2465  transferee,
2466  &call_1->ast->connected,
2467  call_1->held);
2468 
2469  /* Reacquire the pri->lock to hold off completion of the transfer masquerade. */
2470  ast_mutex_lock(&pri->lock);
2471 
2472  ast_channel_unlock(call_1->ast);
2473  ast_channel_unlock(call_2->ast);
2474  sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
2475  sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
2476 
2477  if (rsp_callback) {
2478  /*
2479  * Report transfer status.
2480  *
2481  * Must do the callback before the masquerade completes to ensure
2482  * that the protocol message goes out before the call leg is
2483  * disconnected.
2484  */
2485  rsp_callback(data, retval ? 0 : 1);
2486  }
2487  return retval;
2488 }
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * owner
Definition: sig_pri.h:294
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
ast_mutex_t lock
Definition: sig_pri.h:495
static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
Definition: sig_pri.c:1265
int ast_channel_transfer_masquerade(struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held)
Setup a masquerade to transfer a call.
Definition: channel.c:6184
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_available ( struct sig_pri_chan **  pvt,
int  is_specific_channel 
)

Definition at line 7412 of file sig_pri.c.

References sig_pri_chan::allocated, ast_mutex_lock, ast_mutex_unlock, HAVE_PRI_CALL_WAITING, sig_pri_span::lock, sig_pri_span::num_call_waiting_calls, sig_pri_chan::pri, sig_pri_span::pri, sig_pri_available_check(), and sig_pri_cw_available().

Referenced by available().

7413 {
7414  struct sig_pri_chan *p = *pvt;
7415  struct sig_pri_span *pri;
7416 
7417  if (!p->pri) {
7418  /* Something is wrong here. A PRI channel without the pri pointer? */
7419  return 0;
7420  }
7421  pri = p->pri;
7422 
7423  ast_mutex_lock(&pri->lock);
7424  if (
7425 #if defined(HAVE_PRI_CALL_WAITING)
7426  /*
7427  * Only do call waiting calls if we have any
7428  * call waiting call outstanding. We do not
7429  * want new calls to steal a B channel
7430  * freed for an earlier call waiting call.
7431  */
7432  !pri->num_call_waiting_calls &&
7433 #endif /* defined(HAVE_PRI_CALL_WAITING) */
7435  p->allocated = 1;
7436  ast_mutex_unlock(&pri->lock);
7437  return 1;
7438  }
7439 
7440 #if defined(HAVE_PRI_CALL_WAITING)
7441  if (!is_specific_channel) {
7442  struct sig_pri_chan *cw;
7443 
7444  cw = sig_pri_cw_available(pri);
7445  if (cw) {
7446  /* We have a call waiting interface to use instead. */
7447  cw->allocated = 1;
7448  *pvt = cw;
7449  ast_mutex_unlock(&pri->lock);
7450  return 1;
7451  }
7452  }
7453 #endif /* defined(HAVE_PRI_CALL_WAITING) */
7454  ast_mutex_unlock(&pri->lock);
7455  return 0;
7456 }
#define HAVE_PRI_CALL_WAITING
Definition: autoconfig.h:580
static struct sig_pri_chan * sig_pri_cw_available(struct sig_pri_span *pri)
Definition: sig_pri.c:7379
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
int num_call_waiting_calls
Number of outstanding call waiting calls.
Definition: sig_pri.h:467
struct sig_pri_span * pri
Definition: sig_pri.h:296
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:280
static int sig_pri_available_check(struct sig_pri_chan *pvt)
Definition: sig_pri.c:7354
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sig_pri_available_check ( struct sig_pri_chan pvt)
static

Definition at line 7354 of file sig_pri.c.

References sig_pri_chan::no_b_channel, and sig_pri_is_chan_available().

Referenced by sig_pri_available(), and sig_pri_cw_available().

7355 {
7356  /*
7357  * If interface has a B channel and is available for use
7358  * then the channel is available.
7359  */
7360  if (!pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
7361  return 1;
7362  }
7363  return 0;
7364 }
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
int sig_pri_call ( struct sig_pri_chan p,
struct ast_channel ast,
char *  rdest,
int  timeout,
int  layer1 
)
Note
Parsing must remain in sync with sig_pri_extract_called_num_subaddr().

Definition at line 6641 of file sig_pri.c.

References ast_channel::_state, ao2_ref, sig_pri_span::append_msn_to_user_tag, args, AST_APP_ARG, ast_app_parse_options(), ast_assert, ast_cc_get_monitor_by_recall_core_id(), ast_cc_is_recall(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_party_subaddress_init(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strlen_zero(), ast_test_flag, ast_transfercapability2str(), ast_verb, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::caller, sig_pri_cc_monitor_instance::cc_id, sig_pri_chan::channel, ast_channel::connected, sig_pri_chan::deferred_digits, sig_pri_chan::dialdest, sig_pri_span::dialplan, dialplan2str(), sig_pri_chan::digital, ext, sig_pri_span::facilityenable, sig_pri_chan::hidecallerid, sig_pri_chan::hidecalleridname, ast_party_caller::id, ast_party_connected_line::id, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, sig_pri_chan::is_call_waiting, IS_DIGITAL, sig_pri_span::localdialplan, LOG_DEBUG, LOG_ERROR, LOG_WARNING, monitor, ast_party_id::name, ast_channel::name, sig_pri_span::nationalprefix, sig_pri_chan::no_dialed_digits, sig_pri_span::nodetype, ast_party_id::number, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_pri_cc_monitor_instance::pri, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), PRI_TRANS_CAP_DIGITAL, sig_pri_chan::priexclusive, ast_cc_monitor::private_data, PVT_TO_CHANNEL(), S_COR, SIG_PRI_CALL_LEVEL_SETUP, sig_pri_call_opts, sig_pri_cc_type_name, sig_pri_party_subaddress_from_ast(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_set_outgoing(), ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, sig_pri_chan::stripmsd, ast_party_id::subaddress, ast_party_id::tag, ast_channel::transfercapability, ast_party_subaddress::type, sig_pri_chan::use_callingpres, sig_pri_chan::user_tag, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

Referenced by dahdi_call().

6642 {
6643  char dest[256]; /* must be same length as p->dialdest */
6644  struct ast_party_subaddress dialed_subaddress; /* Called subaddress */
6645  struct pri_sr *sr;
6646  char *c, *l, *n, *s;
6647 #ifdef SUPPORT_USERUSER
6648  const char *useruser;
6649 #endif
6650  int core_id;
6651  int pridialplan;
6652  int dp_strip;
6653  int prilocaldialplan;
6654  int ldp_strip;
6655  int exclusive;
6656 #if defined(HAVE_PRI_SETUP_KEYPAD)
6657  const char *keypad;
6658 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
6660  AST_APP_ARG(group); /* channel/group token */
6661  AST_APP_ARG(ext); /* extension token */
6662  AST_APP_ARG(opts); /* options token */
6663  AST_APP_ARG(other); /* Any remining unused arguments */
6664  );
6665  struct ast_flags opts;
6666  char *opt_args[OPT_ARG_ARRAY_SIZE];
6667 
6668  ast_log(LOG_DEBUG, "CALLER NAME: %s NUM: %s\n",
6669  S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
6670  S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""));
6671 
6672  if (!p->pri) {
6673  ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
6674  return -1;
6675  }
6676 
6677  if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
6678  ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast->name);
6679  return -1;
6680  }
6681 
6682  p->dialdest[0] = '\0';
6683  sig_pri_set_outgoing(p, 1);
6684 
6685  ast_copy_string(dest, rdest, sizeof(dest));
6686  AST_NONSTANDARD_APP_ARGS(args, dest, '/');
6687  if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
6688  /* General invalid option syntax. */
6689  return -1;
6690  }
6691 
6692  c = args.ext;
6693  if (!c) {
6694  c = "";
6695  }
6696 
6697  /* setup dialed_subaddress if found */
6698  ast_party_subaddress_init(&dialed_subaddress);
6699  s = strchr(c, ':');
6700  if (s) {
6701  *s = '\0';
6702  s++;
6703  /* prefix */
6704  /* 'n' = NSAP */
6705  /* 'u' = User Specified */
6706  /* Default = NSAP */
6707  switch (*s) {
6708  case 'U':
6709  case 'u':
6710  s++;
6711  dialed_subaddress.type = 2;
6712  break;
6713  case 'N':
6714  case 'n':
6715  s++;
6716  /* default already covered with ast_party_subaddress_init */
6717  break;
6718  }
6719  dialed_subaddress.str = s;
6720  dialed_subaddress.valid = 1;
6721  }
6722 
6723  l = NULL;
6724  n = NULL;
6725  if (!p->hidecallerid) {
6726  if (ast->connected.id.number.valid) {
6727  /* If we get to the end of this loop without breaking, there's no
6728  * calleridnum. This is done instead of testing for "unknown" or
6729  * the thousands of other ways that the calleridnum could be
6730  * invalid. */
6731  for (l = ast->connected.id.number.str; l && *l; l++) {
6732  if (strchr("0123456789", *l)) {
6733  l = ast->connected.id.number.str;
6734  break;
6735  }
6736  }
6737  } else {
6738  l = NULL;
6739  }
6740  if (!p->hidecalleridname) {
6741  n = ast->connected.id.name.valid ? ast->connected.id.name.str : NULL;
6742  }
6743  }
6744 
6745  if (strlen(c) < p->stripmsd) {
6746  ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
6747  return -1;
6748  }
6749 
6750  /* Extract any 'w' deferred digits. */
6751  s = strchr(c + p->stripmsd, 'w');
6752  if (s) {
6753  *s++ = '\0';
6754  ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits));
6755  /*
6756  * Since we have a 'w', this means that there will not be any
6757  * more normal dialed digits. Therefore, the sending complete
6758  * ie needs to be sent with any normal digits.
6759  */
6760  } else {
6761  p->deferred_digits[0] = '\0';
6762  }
6763 
6764  pri_grab(p, p->pri);
6765  if (!(p->call = pri_new_call(p->pri->pri))) {
6766  ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
6767  pri_rel(p->pri);
6768  return -1;
6769  }
6770  if (!(sr = pri_sr_new())) {
6771  ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n",
6772  p->channel);
6773  pri_destroycall(p->pri->pri, p->call);
6774  p->call = NULL;
6775  pri_rel(p->pri);
6776  return -1;
6777  }
6778 
6779  sig_pri_set_digital(p, IS_DIGITAL(ast->transfercapability)); /* push up to parent for EC */
6780 
6781 #if defined(HAVE_PRI_CALL_WAITING)
6782  if (p->is_call_waiting) {
6783  /*
6784  * Indicate that this is a call waiting call.
6785  * i.e., Normal call but with no B channel.
6786  */
6787  pri_sr_set_channel(sr, 0, 0, 1);
6788  } else
6789 #endif /* defined(HAVE_PRI_CALL_WAITING) */
6790  {
6791  /* Should the picked channel be used exclusively? */
6792  if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
6793  exclusive = 1;
6794  } else {
6795  exclusive = 0;
6796  }
6797  pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
6798  }
6799 
6800  pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
6801  (p->digital ? -1 : layer1));
6802 
6803  if (p->pri->facilityenable)
6804  pri_facility_enable(p->pri->pri);
6805 
6806  ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", (unsigned)ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
6807  dp_strip = 0;
6808  pridialplan = p->pri->dialplan - 1;
6809  if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
6810  if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
6811  if (pridialplan == -2) {
6812  dp_strip = strlen(p->pri->internationalprefix);
6813  }
6814  pridialplan = PRI_INTERNATIONAL_ISDN;
6815  } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
6816  if (pridialplan == -2) {
6817  dp_strip = strlen(p->pri->nationalprefix);
6818  }
6819  pridialplan = PRI_NATIONAL_ISDN;
6820  } else {
6821  pridialplan = PRI_LOCAL_ISDN;
6822  }
6823  }
6824  while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
6825  switch (c[p->stripmsd]) {
6826  case 'U':
6827  pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
6828  break;
6829  case 'I':
6830  pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
6831  break;
6832  case 'N':
6833  pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
6834  break;
6835  case 'L':
6836  pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
6837  break;
6838  case 'S':
6839  pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
6840  break;
6841  case 'V':
6842  pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
6843  break;
6844  case 'R':
6845  pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
6846  break;
6847  case 'u':
6848  pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
6849  break;
6850  case 'e':
6851  pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
6852  break;
6853  case 'x':
6854  pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
6855  break;
6856  case 'f':
6857  pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
6858  break;
6859  case 'n':
6860  pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
6861  break;
6862  case 'p':
6863  pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
6864  break;
6865  case 'r':
6866  pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
6867  break;
6868  default:
6869  if (isalpha(c[p->stripmsd])) {
6870  ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
6871  c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
6872  }
6873  break;
6874  }
6875  c++;
6876  }
6877 #if defined(HAVE_PRI_SETUP_KEYPAD)
6878  if (ast_test_flag(&opts, OPT_KEYPAD)
6879  && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
6880  /* We have a keypad facility digits option with digits. */
6881  keypad = opt_args[OPT_ARG_KEYPAD];
6882  pri_sr_set_keypad_digits(sr, keypad);
6883  } else {
6884  keypad = NULL;
6885  }
6886  if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
6887 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
6888  {
6889  char *called = c + p->stripmsd + dp_strip;
6890 
6891  pri_sr_set_called(sr, called, pridialplan, s ? 1 : 0);
6892 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
6893  p->no_dialed_digits = !called[0];
6894 #endif /* defined(HAVE_PRI_SETUP_ACK_INBAND) */
6895  }
6896 
6897 #if defined(HAVE_PRI_SUBADDR)
6898  if (dialed_subaddress.valid) {
6899  struct pri_party_subaddress subaddress;
6900 
6901  memset(&subaddress, 0, sizeof(subaddress));
6902  sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
6903  pri_sr_set_called_subaddress(sr, &subaddress);
6904  }
6905 #endif /* defined(HAVE_PRI_SUBADDR) */
6906 #if defined(HAVE_PRI_REVERSE_CHARGE)
6907  if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
6908  pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
6909  }
6910 #endif /* defined(HAVE_PRI_REVERSE_CHARGE) */
6911 #if defined(HAVE_PRI_AOC_EVENTS)
6912  if (ast_test_flag(&opts, OPT_AOC_REQUEST)
6913  && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
6914  if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
6915  pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
6916  }
6917  if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
6918  pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
6919  }
6920  if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
6921  pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
6922  }
6923  }
6924 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
6925 
6926  /* Setup the user tag for party id's from this device for this call. */
6927  if (p->pri->append_msn_to_user_tag) {
6928  snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
6929  p->pri->nodetype == PRI_NETWORK
6930  ? c + p->stripmsd + dp_strip
6931  : S_COR(ast->connected.id.number.valid,
6932  ast->connected.id.number.str, ""));
6933  } else {
6934  ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
6935  }
6936 
6937  /*
6938  * Replace the caller id tag from the channel creation
6939  * with the actual tag value.
6940  */
6941  ast_free(ast->caller.id.tag);
6942  ast->caller.id.tag = ast_strdup(p->user_tag);
6943 
6944  ldp_strip = 0;
6945  prilocaldialplan = p->pri->localdialplan - 1;
6946  if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
6947  if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
6948  if (prilocaldialplan == -2) {
6949  ldp_strip = strlen(p->pri->internationalprefix);
6950  }
6951  prilocaldialplan = PRI_INTERNATIONAL_ISDN;
6952  } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
6953  if (prilocaldialplan == -2) {
6954  ldp_strip = strlen(p->pri->nationalprefix);
6955  }
6956  prilocaldialplan = PRI_NATIONAL_ISDN;
6957  } else {
6958  prilocaldialplan = PRI_LOCAL_ISDN;
6959  }
6960  }
6961  if (l != NULL) {
6962  while (*l > '9' && *l != '*' && *l != '#') {
6963  switch (*l) {
6964  case 'U':
6965  prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
6966  break;
6967  case 'I':
6968  prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
6969  break;
6970  case 'N':
6971  prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
6972  break;
6973  case 'L':
6974  prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
6975  break;
6976  case 'S':
6977  prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
6978  break;
6979  case 'V':
6980  prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
6981  break;
6982  case 'R':
6983  prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
6984  break;
6985  case 'u':
6986  prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
6987  break;
6988  case 'e':
6989  prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
6990  break;
6991  case 'x':
6992  prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
6993  break;
6994  case 'f':
6995  prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
6996  break;
6997  case 'n':
6998  prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
6999  break;
7000  case 'p':
7001  prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
7002  break;
7003  case 'r':
7004  prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
7005  break;
7006  default:
7007  if (isalpha(*l)) {
7009  "Unrecognized prilocaldialplan %s modifier: %c\n",
7010  *l > 'Z' ? "NPI" : "TON", *l);
7011  }
7012  break;
7013  }
7014  l++;
7015  }
7016  }
7017  pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
7018  p->use_callingpres ? ast->connected.id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
7019 
7020 #if defined(HAVE_PRI_SUBADDR)
7021  if (ast->connected.id.subaddress.valid) {
7022  struct pri_party_subaddress subaddress;
7023 
7024  memset(&subaddress, 0, sizeof(subaddress));
7026  pri_sr_set_caller_subaddress(sr, &subaddress);
7027  }
7028 #endif /* defined(HAVE_PRI_SUBADDR) */
7029 
7031 
7032 #ifdef SUPPORT_USERUSER
7033  /* User-user info */
7034  useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
7035  if (useruser)
7036  pri_sr_set_useruser(sr, useruser);
7037 #endif
7038 
7039 #if defined(HAVE_PRI_CCSS)
7040  if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
7041  struct ast_cc_monitor *monitor;
7042  char device_name[AST_CHANNEL_NAME];
7043 
7044  /* This is a CC recall call. */
7045  ast_channel_get_device_name(ast, device_name, sizeof(device_name));
7046  monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
7047  if (monitor) {
7048  struct sig_pri_cc_monitor_instance *instance;
7049 
7050  instance = monitor->private_data;
7051 
7052  /* If this fails then we have monitor instance ambiguity. */
7053  ast_assert(p->pri == instance->pri);
7054 
7055  if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
7056  /* The CC recall call failed for some reason. */
7057  ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
7058  device_name);
7059  ao2_ref(monitor, -1);
7060  pri_destroycall(p->pri->pri, p->call);
7061  p->call = NULL;
7062  pri_rel(p->pri);
7063  pri_sr_free(sr);
7064  return -1;
7065  }
7066  ao2_ref(monitor, -1);
7067  } else {
7068  core_id = -1;
7069  }
7070  } else
7071 #endif /* defined(HAVE_PRI_CCSS) */
7072  {
7073  core_id = -1;
7074  }
7075  if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
7076  ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
7077  c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
7078  pri_destroycall(p->pri->pri, p->call);
7079  p->call = NULL;
7080  pri_rel(p->pri);
7081  pri_sr_free(sr);
7082  return -1;
7083  }
7085  pri_sr_free(sr);
7087  sig_pri_set_dialing(p, 1);
7088  pri_rel(p->pri);
7089  return 0;
7090 }
int nodetype
Definition: sig_pri.h:434
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
unsigned int priexclusive
Definition: sig_pri.h:227
#define IS_DIGITAL(cap)
Definition: transcap.h:43
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
unsigned int use_callingpres
Definition: sig_pri.h:230
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
static void sig_pri_party_subaddress_from_ast(struct pri_party_subaddress *pri_subaddress, const struct ast_party_subaddress *ast_subaddress)
Definition: sig_pri.c:773
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int facilityenable
Definition: sig_pri.h:361
#define LOG_WARNING
Definition: logger.h:144
char nationalprefix[10]
Definition: sig_pri.h:407
q931_call * call
Definition: sig_pri.h:297
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
Definition: sig_pri.c:179
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ast_channel * owner
Definition: sig_pri.h:294
char * str
Subscriber name (Malloced)
Definition: channel.h:214
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
#define ast_assert(a)
Definition: utils.h:738
int dialplan
Definition: sig_pri.h:404
int localdialplan
Definition: sig_pri.h:405
unsigned short transfercapability
Definition: channel.h:863
#define LOG_DEBUG
Definition: logger.h:122
const char * ext
Definition: http.c:112
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
#define ast_verb(level,...)
Definition: logger.h:243
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
Definition: ccss.c:3172
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
Definition: sig_pri.c:171
char dialdest[256]
Definition: sig_pri.h:250
int stripmsd
Definition: sig_pri.h:233
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
char internationalprefix[10]
Definition: sig_pri.h:406
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
static unsigned int monitor
Definition: chan_phone.c:108
#define PRI_TRANS_CAP_DIGITAL
Definition: isdn_lib.h:818
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
unsigned int hidecalleridname
Definition: sig_pri.h:225
unsigned int append_msn_to_user_tag
Definition: sig_pri.h:399
#define AST_CHANNEL_NAME
Definition: channel.h:137
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:427
static char * dialplan2str(int dialplan)
Definition: sig_pri.c:1614
static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_channel *ast)
Definition: sig_pri.c:890
char deferred_digits[AST_MAX_EXTENSION]
Definition: sig_pri.h:256
Structure used to handle boolean flags.
Definition: utils.h:200
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
Definition: sig_pri.c:164
unsigned int hidecallerid
Definition: sig_pri.h:224
unsigned int is_call_waiting
TRUE if this is a call waiting call.
Definition: sig_pri.h:287
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
Definition: channel.c:2034
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
unsigned int digital
Definition: sig_pri.h:282
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:1041
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:9776
struct sig_pri_span * pri
Definition: sig_pri.h:296
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
Information needed to specify a subaddress in a call.
Definition: channel.h:257
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
Definition: ccss.c:3253
unsigned int no_dialed_digits
Definition: sig_pri.h:291
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct pri * pri
Definition: sig_pri.h:481
int channel
Definition: sig_pri.h:234
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static struct ast_app_option sig_pri_call_opts[128]
Definition: sig_pri.c:6638
static const char* sig_pri_call_level2str ( enum sig_pri_call_level  level)
static

Definition at line 123 of file sig_pri.c.

References SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, SIG_PRI_CALL_LEVEL_IDLE, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and SIG_PRI_CALL_LEVEL_SETUP.

Referenced by sig_pri_cli_show_channels(), and sig_pri_digit_begin().

124 {
125  switch (level) {
127  return "Idle";
129  return "Setup";
131  return "Overlap";
133  return "Proceeding";
135  return "Alerting";
137  return "DeferDial";
139  return "Connect";
140  }
141  return "Unknown";
142 }
int sig_pri_cc_agent_callee_available ( struct ast_cc_agent agent)

Alert the caller that it is time to try recalling.

Since
1.8
Parameters
agentCC core agent control.

The core will call this function when it receives notice that a monitored party has become available.

The agent's job is to send a message to the caller to notify it of such a change. If the agent is able to discern that the caller is currently unavailable, then the agent should react by calling the ast_cc_caller_unavailable function.

Return values
0on success.
-1on error.

Definition at line 8430 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

8431 {
8432  struct sig_pri_cc_agent_prv *cc_pvt;
8433 
8434  cc_pvt = agent->private_data;
8435  ast_mutex_lock(&cc_pvt->pri->lock);
8436  pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
8437  ast_mutex_unlock(&cc_pvt->pri->lock);
8438  return 0;
8439 }
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sig_pri_cc_agent_cmp_cc_id ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 2503 of file sig_pri.c.

References sig_pri_cc_agent_prv::cc_id, CMP_MATCH, CMP_STOP, sig_pri_cc_agent_prv::pri, and ast_cc_agent::private_data.

Referenced by sig_pri_find_cc_agent_by_cc_id().

2504 {
2505  struct ast_cc_agent *agent_1 = obj;
2506  struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->private_data;
2507  struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
2508 
2509  return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
2510  && agent_prv_1->cc_id == agent_prv_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
2511 }
void * private_data
Definition: ccss.h:854
struct sig_pri_span * pri
Definition: sig_pri.c:80
void sig_pri_cc_agent_destructor ( struct ast_cc_agent agent)

Destroy private data on the agent.

Since
1.8
Parameters
agentCC core agent control.

The core will call this function upon completion or failure of CC.

Note
The agent private_data pointer may be NULL if the agent constructor failed.
Returns
Nothing

Definition at line 8459 of file sig_pri.c.

References ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

Referenced by dahdi_pri_cc_agent_destructor().

8460 {
8461  struct sig_pri_cc_agent_prv *cc_pvt;
8462  int res;
8463 
8464  cc_pvt = agent->private_data;
8465  if (!cc_pvt) {
8466  /* The agent constructor probably failed. */
8467  return;
8468  }
8469  ast_mutex_lock(&cc_pvt->pri->lock);
8470  res = -1;
8471  if (cc_pvt->cc_request_response_pending) {
8472  res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */);
8473  }
8474  if (res) {
8475  pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
8476  }
8477  ast_mutex_unlock(&cc_pvt->pri->lock);
8478  ast_free(cc_pvt);
8479 }
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
#define ast_free(a)
Definition: astmm.h:97
unsigned char cc_request_response_pending
Definition: sig_pri.c:84
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_agent_init ( struct ast_cc_agent agent,
struct sig_pri_chan pvt_chan 
)

PRI CC agent initialization.

Since
1.8
Parameters
agentCC core agent control.
pvt_chanOriginal channel the agent will attempt to recall.

This callback is called when the CC core is initialized. Agents should allocate any private data necessary for the call and assign it to the private_data on the agent. Additionally, if any ast_cc_agent_flags are pertinent to the specific agent type, they should be set in this function as well.

Return values
0on success.
-1on error.

Definition at line 8142 of file sig_pri.c.

References ast_calloc, ast_free, ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_chan::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

Referenced by dahdi_pri_cc_agent_init().

8143 {
8144  struct sig_pri_cc_agent_prv *cc_pvt;
8145 
8146  cc_pvt = ast_calloc(1, sizeof(*cc_pvt));
8147  if (!cc_pvt) {
8148  return -1;
8149  }
8150 
8151  ast_mutex_lock(&pvt_chan->pri->lock);
8152  cc_pvt->pri = pvt_chan->pri;
8153  cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call);
8154  ast_mutex_unlock(&pvt_chan->pri->lock);
8155  if (cc_pvt->cc_id == -1) {
8156  ast_free(cc_pvt);
8157  return -1;
8158  }
8159  agent->private_data = cc_pvt;
8160  return 0;
8161 }
void * private_data
Definition: ccss.h:854
q931_call * call
Definition: sig_pri.h:297
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_agent_party_b_free ( struct ast_cc_agent agent)

Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line.

Since
1.8
Parameters
agentCC core agent control.

This is something that really only affects a scenario where a phone places a call over ISDN PTMP to Asterisk, who then connects over PTMP again to the ISDN network. For most agent types, there is no need to implement this callback at all because they don't really need to actually do anything in this situation. If you're having trouble understanding what the purpose of this callback is, then you can be safe simply not implementing it.

Return values
0on success.
-1on error.

Definition at line 8374 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

8375 {
8376  struct sig_pri_cc_agent_prv *cc_pvt;
8377 
8378  cc_pvt = agent->private_data;
8379  ast_mutex_lock(&cc_pvt->pri->lock);
8380  pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
8381  ast_mutex_unlock(&cc_pvt->pri->lock);
8382  return 0;
8383 }
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
void sig_pri_cc_agent_req_rsp ( struct ast_cc_agent agent,
enum ast_cc_agent_response_reason  reason 
)

Response to a CC request.

Since
1.8
Parameters
agentCC core agent control.
reasonCC request response status.

When the core receives knowledge that a called party has accepted a CC request, it will call this callback. The core may also call this if there is some error when attempting to process the incoming CC request.

The duty of this is to issue a propper response to a CC request from the caller by acknowledging receipt of that request or rejecting it.

Returns
Nothing

Definition at line 8235 of file sig_pri.c.

References AST_CC_AGENT_RESPONSE_FAILURE_INVALID, AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY, AST_CC_AGENT_RESPONSE_SUCCESS, ast_cc_failed(), ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::cc_request_response_pending, ast_cc_agent::core_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, ast_cc_agent::private_data, sig_pri_cc_type_name, and status.

8236 {
8237  struct sig_pri_cc_agent_prv *cc_pvt;
8238  int res;
8239  int status;
8240  const char *failed_msg;
8241  static const char *failed_to_send = "Failed to send the CC request response.";
8242  static const char *not_accepted = "The core declined the CC request.";
8243 
8244  cc_pvt = agent->private_data;
8245  ast_mutex_lock(&cc_pvt->pri->lock);
8246  if (cc_pvt->cc_request_response_pending) {
8247  cc_pvt->cc_request_response_pending = 0;
8248 
8249  /* Convert core response reason to ISDN response status. */
8250  status = 2;/* short_term_denial */
8251  switch (reason) {
8253  status = 0;/* success */
8254  break;
8256  status = 2;/* short_term_denial */
8257  break;
8259  status = 5;/* queue_full */
8260  break;
8261  }
8262 
8263  res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
8264  if (!status) {
8265  /* CC core request was accepted. */
8266  if (res) {
8267  failed_msg = failed_to_send;
8268  } else {
8269  failed_msg = NULL;
8270  }
8271  } else {
8272  /* CC core request was declined. */
8273  if (res) {
8274  failed_msg = failed_to_send;
8275  } else {
8276  failed_msg = not_accepted;
8277  }
8278  }
8279  } else {
8280  failed_msg = NULL;
8281  }
8282  ast_mutex_unlock(&cc_pvt->pri->lock);
8283  if (failed_msg) {
8284  ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg);
8285  }
8286 }
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3613
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
unsigned int core_id
Definition: ccss.h:832
unsigned char cc_request_response_pending
Definition: sig_pri.c:84
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
struct pri * pri
Definition: sig_pri.h:481
jack_status_t status
Definition: app_jack.c:143
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_agent_start_monitoring ( struct ast_cc_agent agent)

Begin monitoring a busy device.

Since
1.8
Parameters
agentCC core agent control.

The core will call this callback if the callee becomes available but the caller has reported that he is busy. The agent should begin monitoring the caller's device. When the caller becomes available again, the agent should call ast_cc_agent_caller_available.

Return values
0on success.
-1on error.

Definition at line 8403 of file sig_pri.c.

8404 {
8405  /* libpri already knows when and how it needs to monitor Party A. */
8406  return 0;
8407 }
int sig_pri_cc_agent_start_offer_timer ( struct ast_cc_agent agent)

Start the offer timer.

Since
1.8
Parameters
agentCC core agent control.

This is called by the core when the caller hangs up after a call for which CC may be requested. The agent should begin the timer as configured.

The primary reason why this functionality is left to the specific agent implementations is due to the differing use of schedulers throughout the code. Some channel drivers may already have a scheduler context they wish to use, and amongst those, some may use the ast_sched API while others may use the ast_sched_thread API, which are incompatible.

Return values
0on success.
-1on error.

Definition at line 8186 of file sig_pri.c.

8187 {
8188  /* libpri maintains it's own offer timer in the form of T_RETENTION. */
8189  return 0;
8190 }
int sig_pri_cc_agent_status_req ( struct ast_cc_agent agent)

Request the status of the agent's device.

Since
1.8
Parameters
agentCC core agent control.

Asynchronous request for the status of any caller which may be a valid caller for the CC transaction. Status responses should be made using the ast_cc_status_response function.

Return values
0on success.
-1on error.

Definition at line 8305 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

8306 {
8307  struct sig_pri_cc_agent_prv *cc_pvt;
8308 
8309  cc_pvt = agent->private_data;
8310  ast_mutex_lock(&cc_pvt->pri->lock);
8311  pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
8312  ast_mutex_unlock(&cc_pvt->pri->lock);
8313  return 0;
8314 }
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_agent_stop_offer_timer ( struct ast_cc_agent agent)

Stop the offer timer.

Since
1.8
Parameters
agentCC core agent control.

This callback is called by the CC core when the caller has requested CC.

Return values
0on success.
-1on error.

Definition at line 8207 of file sig_pri.c.

8208 {
8209  /* libpri maintains it's own offer timer in the form of T_RETENTION. */
8210  return 0;
8211 }
int sig_pri_cc_agent_stop_ringing ( struct ast_cc_agent agent)

Request for an agent's phone to stop ringing.

Since
1.8
Parameters
agentCC core agent control.

The usefulness of this is quite limited. The only specific known case for this is if Asterisk requests CC over an ISDN PTMP link as the TE side. If other phones are in the same recall group as the Asterisk server, and one of those phones picks up the recall notice, then Asterisk will receive a "stop ringing" notification from the NT side of the PTMP link. This indication needs to be passed to the phone on the other side of the Asterisk server which originally placed the call so that it will stop ringing. Since the phone may be of any type, it is necessary to have a callback that the core can know about.

Return values
0on success.
-1on error.

Definition at line 8340 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_agent_prv::cc_id, sig_pri_span::lock, sig_pri_cc_agent_prv::pri, sig_pri_span::pri, and ast_cc_agent::private_data.

8341 {
8342  struct sig_pri_cc_agent_prv *cc_pvt;
8343 
8344  cc_pvt = agent->private_data;
8345  ast_mutex_lock(&cc_pvt->pri->lock);
8346  pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
8347  ast_mutex_unlock(&cc_pvt->pri->lock);
8348  return 0;
8349 }
void * private_data
Definition: ccss.h:854
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_span * pri
Definition: sig_pri.c:80
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sig_pri_cc_available ( struct sig_pri_span pri,
int  chanpos,
long  cc_id,
enum ast_cc_service_type  service 
)
static

Definition at line 2679 of file sig_pri.c.

References ao2_ref, ao2_unlink, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_get_cc_monitor_policy(), ast_queue_cc_frame(), sig_pri_cc_monitor_instance::cc_id, sig_pri_cc_monitor_instance::core_id, monitor, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_cc_monitor_instance_init(), sig_pri_cc_type_name, sig_pri_get_orig_dialstring(), and sig_pri_make_cc_dialstring().

Referenced by sig_pri_handle_subcmds().

2680 {
2681  struct sig_pri_chan *pvt;
2682  struct ast_cc_config_params *cc_params;
2684  enum ast_cc_monitor_policies monitor_policy;
2685  int core_id;
2686  int res;
2687  char device_name[AST_CHANNEL_NAME];
2688  char dialstring[AST_CHANNEL_NAME];
2689 
2690  pvt = pri->pvts[chanpos];
2691 
2692  core_id = ast_cc_get_current_core_id(pvt->owner);
2693  if (core_id == -1) {
2694  return -1;
2695  }
2696 
2697  cc_params = ast_channel_get_cc_config_params(pvt->owner);
2698  if (!cc_params) {
2699  return -1;
2700  }
2701 
2702  res = -1;
2703  monitor_policy = ast_get_cc_monitor_policy(cc_params);
2704  switch (monitor_policy) {
2705  case AST_CC_MONITOR_NEVER:
2706  /* CCSS is not enabled. */
2707  break;
2708  case AST_CC_MONITOR_NATIVE:
2709  case AST_CC_MONITOR_ALWAYS:
2710  /*
2711  * If it is AST_CC_MONITOR_ALWAYS and native fails we will attempt the fallback
2712  * later in the call to sig_pri_cc_generic_check().
2713  */
2714  ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
2715  sig_pri_make_cc_dialstring(pvt, dialstring, sizeof(dialstring));
2716  monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
2717  if (!monitor) {
2718  break;
2719  }
2720  res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service,
2721  monitor);
2722  if (res) {
2723  monitor->cc_id = -1;
2724  ao2_unlink(sig_pri_cc_monitors, monitor);
2725  ao2_ref(monitor, -1);
2726  }
2727  break;
2730  sig_pri_get_orig_dialstring(pvt), service, NULL);
2731  /* Say it failed to force caller to cancel native CC. */
2732  break;
2733  }
2734  return res;
2735 }
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
Definition: ccss.c:2224
struct ast_channel * owner
Definition: sig_pri.h:294
enum ast_cc_service_type service
Definition: chan_sip.c:821
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
Definition: ccss.c:3886
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
Definition: ccss.h:74
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:9754
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:763
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static const char * sig_pri_get_orig_dialstring(struct sig_pri_chan *p)
Definition: sig_pri.c:207
static struct sig_pri_cc_monitor_instance * sig_pri_cc_monitor_instance_init(int core_id, struct sig_pri_span *pri, long cc_id, const char *device_name)
Definition: sig_pri.c:2635
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:472
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101
static unsigned int monitor
Definition: chan_phone.c:108
static void sig_pri_make_cc_dialstring(struct sig_pri_chan *p, char *buf, size_t buf_size)
Definition: sig_pri.c:217
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define AST_CHANNEL_NAME
Definition: channel.h:137
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:9776
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static void sig_pri_cc_generic_check ( struct sig_pri_span pri,
int  chanpos,
enum ast_cc_service_type  service 
)
static

Definition at line 2752 of file sig_pri.c.

References ao2_ref, AST_CC_GENERIC_MONITOR_TYPE, ast_cc_get_current_core_id(), ast_cc_get_monitor_by_recall_core_id(), AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, ast_channel_get_cc_config_params(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_unlock, ast_get_cc_monitor_policy(), ast_queue_cc_frame(), ast_cc_monitor::core_id, monitor, sig_pri_span::nodetype, sig_pri_chan::outgoing, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_span::sig, SIG_BRI_PTMP, sig_pri_get_orig_dialstring(), and sig_pri_lock_owner().

Referenced by pri_dchannel().

2753 {
2754  struct ast_channel *owner;
2755  struct ast_cc_config_params *cc_params;
2756 #if defined(HAVE_PRI_CCSS)
2757  struct ast_cc_monitor *monitor;
2758  char device_name[AST_CHANNEL_NAME];
2759 #endif /* defined(HAVE_PRI_CCSS) */
2760  enum ast_cc_monitor_policies monitor_policy;
2761  int core_id;
2762 
2763  if (!pri->pvts[chanpos]->outgoing) {
2764  /* This is not an outgoing call so it cannot be CC monitor. */
2765  return;
2766  }
2767 
2768  sig_pri_lock_owner(pri, chanpos);
2769  owner = pri->pvts[chanpos]->owner;
2770  if (!owner) {
2771  return;
2772  }
2773  core_id = ast_cc_get_current_core_id(owner);
2774  if (core_id == -1) {
2775  /* No CC core setup */
2776  goto done;
2777  }
2778 
2779  cc_params = ast_channel_get_cc_config_params(owner);
2780  if (!cc_params) {
2781  /* Could not get CC config parameters. */
2782  goto done;
2783  }
2784 
2785 #if defined(HAVE_PRI_CCSS)
2786  ast_channel_get_device_name(owner, device_name, sizeof(device_name));
2787  monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
2788  if (monitor) {
2789  /* CC monitor is already present so no need for generic CC. */
2790  ao2_ref(monitor, -1);
2791  goto done;
2792  }
2793 #endif /* defined(HAVE_PRI_CCSS) */
2794 
2795  monitor_policy = ast_get_cc_monitor_policy(cc_params);
2796  switch (monitor_policy) {
2797  case AST_CC_MONITOR_NEVER:
2798  /* CCSS is not enabled. */
2799  break;
2800  case AST_CC_MONITOR_NATIVE:
2801  if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
2802  /* Request generic CC monitor. */
2804  sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
2805  }
2806  break;
2807  case AST_CC_MONITOR_ALWAYS:
2808  if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) {
2809  /*
2810  * Cannot monitor PTMP TE side since this is not defined.
2811  * We are playing the roll of a phone in this case and
2812  * a phone cannot monitor a party over the network without
2813  * protocol help.
2814  */
2815  break;
2816  }
2817  /*
2818  * We are either falling back or this is a PTMP NT span.
2819  * Request generic CC monitor.
2820  */
2822  sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
2823  break;
2825  if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
2826  /* Request generic CC monitor. */
2828  sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
2829  }
2830  break;
2831  }
2832 
2833 done:
2834  ast_channel_unlock(owner);
2835 }
int nodetype
Definition: sig_pri.h:434
Main Channel structure associated with a channel.
Definition: channel.h:742
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
Definition: ccss.c:2224
#define SIG_BRI_PTMP
Definition: chan_dahdi.c:366
struct ast_channel * owner
Definition: sig_pri.h:294
enum ast_cc_service_type service
Definition: chan_sip.c:821
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
Definition: ccss.c:3886
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
Definition: ccss.h:74
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:9754
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:763
int core_id
Definition: ccss.h:511
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static const char * sig_pri_get_orig_dialstring(struct sig_pri_chan *p)
Definition: sig_pri.c:207
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:472
static unsigned int monitor
Definition: chan_phone.c:108
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define AST_CHANNEL_NAME
Definition: channel.h:137
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Definition: channel.c:9776
unsigned int outgoing
Definition: sig_pri.h:281
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
Definition: ccss.c:3253
static void sig_pri_cc_link_canceled ( struct sig_pri_span pri,
long  cc_id,
int  is_agent 
)
static

Definition at line 2849 of file sig_pri.c.

References ao2_ref, ast_cc_failed(), ast_cc_monitor_failed(), sig_pri_cc_monitor_instance::cc_id, sig_pri_cc_monitor_instance::core_id, ast_cc_agent::core_id, monitor, sig_pri_cc_monitor_instance::name, sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), and sig_pri_find_cc_monitor_by_cc_id().

Referenced by sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().

2850 {
2851  if (is_agent) {
2852  struct ast_cc_agent *agent;
2853 
2854  agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
2855  if (!agent) {
2856  return;
2857  }
2858  ast_cc_failed(agent->core_id, "%s agent got canceled by link",
2860  ao2_ref(agent, -1);
2861  } else {
2863 
2864  monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
2865  if (!monitor) {
2866  return;
2867  }
2868  monitor->cc_id = -1;
2869  ast_cc_monitor_failed(monitor->core_id, monitor->name,
2870  "%s monitor got canceled by link", sig_pri_cc_type_name);
2871  ao2_ref(monitor, -1);
2872  }
2873 }
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
Definition: ccss.c:3678
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3613
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static unsigned int monitor
Definition: chan_phone.c:108
static struct sig_pri_cc_monitor_instance * sig_pri_find_cc_monitor_by_cc_id(struct sig_pri_span *pri, long cc_id)
Definition: sig_pri.c:2582
unsigned int core_id
Definition: ccss.h:832
static struct ast_cc_agent * sig_pri_find_cc_agent_by_cc_id(struct sig_pri_span *pri, long cc_id)
Definition: sig_pri.c:2531
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
int sig_pri_cc_monitor_cancel_available_timer ( struct ast_cc_monitor monitor,
int *  sched_id 
)

Cancel the running available timer.

Since
1.8
Parameters
monitorCC core monitor control.
sched_idAvailable timer scheduler id to cancel. Will never be NULL for a device monitor.

In most cases, this function will likely consist of just a call to AST_SCHED_DEL. It might have been possible to do this within the core, but unfortunately the mixture of sched_thread and sched usage in Asterisk prevents such usage.

Return values
0on success
-1on failure.

Definition at line 8685 of file sig_pri.c.

8686 {
8687  /*
8688  * libpri maintains it's own available timer as one of:
8689  * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2
8690  * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2
8691  */
8692  return 0;
8693 }
static int sig_pri_cc_monitor_cmp_cc_id ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 2555 of file sig_pri.c.

References sig_pri_cc_monitor_instance::cc_id, CMP_MATCH, CMP_STOP, and sig_pri_cc_monitor_instance::pri.

Referenced by sig_pri_find_cc_monitor_by_cc_id().

2556 {
2557  struct sig_pri_cc_monitor_instance *monitor_1 = obj;
2558  struct sig_pri_cc_monitor_instance *monitor_2 = arg;
2559 
2560  return (monitor_1->pri == monitor_2->pri
2561  && monitor_1->cc_id == monitor_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
2562 }
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
void sig_pri_cc_monitor_destructor ( void *  monitor_pvt)

Destroy PRI private data on the monitor.

Since
1.8
Parameters
monitor_pvtCC device monitor private data pointer.

Implementers of this callback are responsible for destroying all heap-allocated data in the monitor's private_data pointer, including the private_data itself.

Definition at line 8708 of file sig_pri.c.

References ao2_ref, and ao2_unlink.

8709 {
8710  struct sig_pri_cc_monitor_instance *instance;
8711 
8712  instance = monitor_pvt;
8713  if (!instance) {
8714  return;
8715  }
8716  ao2_unlink(sig_pri_cc_monitors, instance);
8717  ao2_ref(instance, -1);
8718 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static int sig_pri_cc_monitor_instance_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 8513 of file sig_pri.c.

References CMP_MATCH, CMP_STOP, and sig_pri_cc_monitor_instance::core_id.

Referenced by sig_pri_load().

8514 {
8515  struct sig_pri_cc_monitor_instance *monitor_1 = obj;
8516  struct sig_pri_cc_monitor_instance *monitor_2 = arg;
8517 
8518  return monitor_1->core_id == monitor_2->core_id ? CMP_MATCH | CMP_STOP : 0;
8519 }
static void sig_pri_cc_monitor_instance_destroy ( void *  data)
static

Definition at line 2603 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_span::calls, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_callback::module_unref, sig_pri_cc_monitor_instance::pri, and sig_pri_span::pri.

Referenced by sig_pri_cc_monitor_instance_init().

2604 {
2605  struct sig_pri_cc_monitor_instance *monitor_instance = data;
2606 
2607  if (monitor_instance->cc_id != -1) {
2608  ast_mutex_lock(&monitor_instance->pri->lock);
2609  pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
2610  ast_mutex_unlock(&monitor_instance->pri->lock);
2611  }
2612  monitor_instance->pri->calls->module_unref();
2613 }
void(* module_unref)(void)
Definition: sig_pri.h:180
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_callback * calls
Definition: sig_pri.h:497
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sig_pri_cc_monitor_instance_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 8493 of file sig_pri.c.

References sig_pri_cc_monitor_instance::core_id.

Referenced by sig_pri_load().

8494 {
8495  const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
8496 
8497  return monitor_instance->core_id;
8498 }
static struct sig_pri_cc_monitor_instance* sig_pri_cc_monitor_instance_init ( int  core_id,
struct sig_pri_span pri,
long  cc_id,
const char *  device_name 
)
static

Definition at line 2635 of file sig_pri.c.

References ao2_alloc, ao2_link, sig_pri_span::calls, sig_pri_cc_monitor_instance::cc_id, sig_pri_cc_monitor_instance::core_id, sig_pri_callback::module_ref, sig_pri_callback::module_unref, sig_pri_cc_monitor_instance::name, sig_pri_cc_monitor_instance::pri, and sig_pri_cc_monitor_instance_destroy().

Referenced by sig_pri_cc_available().

2636 {
2637  struct sig_pri_cc_monitor_instance *monitor_instance;
2638 
2639  if (!pri->calls->module_ref || !pri->calls->module_unref) {
2640  return NULL;
2641  }
2642 
2643  monitor_instance = ao2_alloc(sizeof(*monitor_instance) + strlen(device_name),
2645  if (!monitor_instance) {
2646  return NULL;
2647  }
2648 
2649  monitor_instance->cc_id = cc_id;
2650  monitor_instance->pri = pri;
2651  monitor_instance->core_id = core_id;
2652  strcpy(monitor_instance->name, device_name);
2653 
2654  pri->calls->module_ref();
2655 
2656  ao2_link(sig_pri_cc_monitors, monitor_instance);
2657  return monitor_instance;
2658 }
void(* module_ref)(void)
Definition: sig_pri.h:178
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
void(* module_unref)(void)
Definition: sig_pri.h:180
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
static void sig_pri_cc_monitor_instance_destroy(void *data)
Definition: sig_pri.c:2603
struct sig_pri_callback * calls
Definition: sig_pri.h:497
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
int sig_pri_cc_monitor_req_cc ( struct ast_cc_monitor monitor,
int *  available_timer_id 
)

Request CCSS.

Since
1.8
Parameters
monitorCC core monitor control.
available_timer_idWhere to put the available timer scheduler id. Will never be NULL for a device monitor.

Perform whatever steps are necessary in order to request CC. In addition, the monitor implementation is responsible for starting the available timer in this callback. The scheduler ID for the callback must be stored in the parent_link's child_avail_id field.

Return values
0on success
-1on failure.

Definition at line 8541 of file sig_pri.c.

References AST_CC_CCBS, AST_CC_CCNR, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_cc_monitor_instance::pri, sig_pri_span::pri, ast_cc_monitor::private_data, and ast_cc_monitor::service_offered.

8542 {
8543  struct sig_pri_cc_monitor_instance *instance;
8544  int cc_mode;
8545  int res;
8546 
8547  switch (monitor->service_offered) {
8548  case AST_CC_CCBS:
8549  cc_mode = 0;/* CCBS */
8550  break;
8551  case AST_CC_CCNR:
8552  cc_mode = 1;/* CCNR */
8553  break;
8554  default:
8555  /* CC service not supported by ISDN. */
8556  return -1;
8557  }
8558 
8559  instance = monitor->private_data;
8560 
8561  /* libpri handles it's own available timer. */
8562  ast_mutex_lock(&instance->pri->lock);
8563  res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
8564  ast_mutex_unlock(&instance->pri->lock);
8565 
8566  return res;
8567 }
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
ast_mutex_t lock
Definition: sig_pri.h:495
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
enum ast_cc_service_type service_offered
Definition: ccss.h:515
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_monitor_status_rsp ( struct ast_cc_monitor monitor,
enum ast_device_state  devstate 
)

Status response to an ast_cc_monitor_status_request().

Since
1.8
Parameters
monitorCC core monitor control.
devstateCurrent status of a Party A device.

Alert a monitor as to the status of the agent for which the monitor had previously requested a status request.

Note
Zero or more responses may come as a result.
Return values
0on success
-1on failure.

Definition at line 8640 of file sig_pri.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_cc_monitor_instance::pri, sig_pri_span::pri, and ast_cc_monitor::private_data.

8641 {
8642  struct sig_pri_cc_monitor_instance *instance;
8643  int cc_status;
8644 
8645  switch (devstate) {
8646  case AST_DEVICE_UNKNOWN:
8647  case AST_DEVICE_NOT_INUSE:
8648  cc_status = 0;/* free */
8649  break;
8650  case AST_DEVICE_BUSY:
8651  case AST_DEVICE_INUSE:
8652  cc_status = 1;/* busy */
8653  break;
8654  default:
8655  /* Don't know how to interpret this device state into free/busy status. */
8656  return 0;
8657  }
8658  instance = monitor->private_data;
8659  ast_mutex_lock(&instance->pri->lock);
8660  pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
8661  ast_mutex_unlock(&instance->pri->lock);
8662 
8663  return 0;
8664 }
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
ast_mutex_t lock
Definition: sig_pri.h:495
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_monitor_suspend ( struct ast_cc_monitor monitor)

Suspend monitoring.

Since
1.8
Parameters
monitorCC core monitor control.

Implementers must perform the necessary steps to suspend monitoring.

Return values
0on success
-1on failure.

Definition at line 8584 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_cc_monitor_instance::pri, sig_pri_span::pri, and ast_cc_monitor::private_data.

8585 {
8586  struct sig_pri_cc_monitor_instance *instance;
8587 
8588  instance = monitor->private_data;
8589  ast_mutex_lock(&instance->pri->lock);
8590  pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */);
8591  ast_mutex_unlock(&instance->pri->lock);
8592 
8593  return 0;
8594 }
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
ast_mutex_t lock
Definition: sig_pri.h:495
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
int sig_pri_cc_monitor_unsuspend ( struct ast_cc_monitor monitor)

Unsuspend monitoring.

Since
1.8
Parameters
monitorCC core monitor control.

Perform the necessary steps to unsuspend monitoring.

Return values
0on success
-1on failure.

Definition at line 8610 of file sig_pri.c.

References ast_mutex_lock, ast_mutex_unlock, sig_pri_cc_monitor_instance::cc_id, sig_pri_span::lock, sig_pri_cc_monitor_instance::pri, sig_pri_span::pri, and ast_cc_monitor::private_data.

8611 {
8612  struct sig_pri_cc_monitor_instance *instance;
8613 
8614  instance = monitor->private_data;
8615  ast_mutex_lock(&instance->pri->lock);
8616  pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */);
8617  ast_mutex_unlock(&instance->pri->lock);
8618 
8619  return 0;
8620 }
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
ast_mutex_t lock
Definition: sig_pri.h:495
void * private_data
Data that is private to a monitor technology.
Definition: ccss.h:544
struct pri * pri
Definition: sig_pri.h:481
#define ast_mutex_unlock(a)
Definition: lock.h:156
void sig_pri_chan_alarm_notify ( struct sig_pri_chan p,
int  noalarm 
)

Notify new alarm status.

Parameters
pChannel private pointer.
noalarmNon-zero if not in alarm mode.
Note
Assumes the sig_pri_lock_private(p) is already obtained.
Returns
Nothing

Definition at line 7894 of file sig_pri.c.

References ast_channel::_softhangup, AST_SOFTHANGUP_DEV, sig_pri_chan::call, sig_pri_chan::owner, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_set_alarm(), and sig_pri_span_devstate_changed().

Referenced by dahdi_handle_event(), and handle_init_event().

7895 {
7896  pri_grab(p, p->pri);
7897  sig_pri_set_alarm(p, !noalarm);
7898  if (!noalarm) {
7899  if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
7900  /* T309 is not enabled : destroy calls when alarm occurs */
7901  if (p->call) {
7902  pri_destroycall(p->pri->pri, p->call);
7903  p->call = NULL;
7904  }
7905  if (p->owner)
7907  }
7908  }
7910  pri_rel(p->pri);
7911 }
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
q931_call * call
Definition: sig_pri.h:297
struct ast_channel * owner
Definition: sig_pri.h:294
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
Definition: sig_pri.c:187
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
int _softhangup
Definition: channel.h:832
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
void sig_pri_chan_delete ( struct sig_pri_chan doomed)

Delete the sig_pri private channel structure.

Since
1.8
Parameters
doomedsig_pri private channel structure to delete.
Returns
Nothing

Definition at line 7953 of file sig_pri.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

7954 {
7955  ast_free(doomed);
7956 }
#define ast_free(a)
Definition: astmm.h:97
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 7925 of file sig_pri.c.

References ast_calloc, sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::logicalspan, sig_pri_chan::mastertrunkgroup, sig_pri_chan::pri, and sig_pri_chan::prioffset.

Referenced by dahdi_new_pri_nobch_channel(), and mkintf().

7926 {
7927  struct sig_pri_chan *p;
7928 
7929  p = ast_calloc(1, sizeof(*p));
7930  if (!p)
7931  return p;
7932 
7933  p->logicalspan = logicalspan;
7934  p->prioffset = channo;
7935  p->mastertrunkgroup = trunkgroup;
7936 
7937  p->calls = callback;
7938  p->chan_pvt = pvt_data;
7939 
7940  p->pri = pri;
7941 
7942  return p;
7943 }
int logicalspan
Definition: sig_pri.h:304
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
int mastertrunkgroup
Definition: sig_pri.h:305
#define ast_calloc(a, b)
Definition: astmm.h:82
struct sig_pri_span * pri
Definition: sig_pri.h:296
int prioffset
Definition: sig_pri.h:303
void sig_pri_cli_show_channels ( int  fd,
struct sig_pri_span pri 
)

Definition at line 7966 of file sig_pri.c.

References ast_channel_unlock, ast_cli(), ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::channel, sig_pri_span::lock, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_call_level2str(), sig_pri_is_chan_available(), sig_pri_lock_owner(), sig_pri_lock_private(), SIG_PRI_SC_LINE, sig_pri_unlock_private(), and sig_pri_span::span.

Referenced by handle_pri_show_channels().

7967 {
7968  char line[256];
7969  int idx;
7970  struct sig_pri_chan *pvt;
7971 
7972  ast_mutex_lock(&pri->lock);
7973  for (idx = 0; idx < pri->numchans; ++idx) {
7974  if (!pri->pvts[idx]) {
7975  continue;
7976  }
7977  pvt = pri->pvts[idx];
7978  sig_pri_lock_private(pvt);
7979  sig_pri_lock_owner(pri, idx);
7980  if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
7981  /* Don't show held/call-waiting channels if they are not in use. */
7983  continue;
7984  }
7985 
7986  snprintf(line, sizeof(line), SIG_PRI_SC_LINE,
7987  pri->span,
7988  pvt->channel,
7989  pvt->no_b_channel ? "No" : "Yes",/* Has media */
7990  sig_pri_is_chan_available(pvt) ? "Yes" : "No",
7992  pvt->call ? "Yes" : "No",
7993  pvt->owner ? pvt->owner->name : "");
7994 
7995  if (pvt->owner) {
7996  ast_channel_unlock(pvt->owner);
7997  }
7999 
8000  ast_mutex_unlock(&pri->lock);
8001  ast_cli(fd, "%s\n", line);
8002  ast_mutex_lock(&pri->lock);
8003  }
8004  ast_mutex_unlock(&pri->lock);
8005 }
#define SIG_PRI_SC_LINE
Definition: sig_pri.c:7959
q931_call * call
Definition: sig_pri.h:297
struct ast_channel * owner
Definition: sig_pri.h:294
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
ast_mutex_t lock
Definition: sig_pri.h:495
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
static const char * sig_pri_call_level2str(enum sig_pri_call_level level)
Definition: sig_pri.c:123
const ast_string_field name
Definition: channel.h:787
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
int numchans
Definition: sig_pri.h:492
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
int channel
Definition: sig_pri.h:234
#define ast_mutex_unlock(a)
Definition: lock.h:156
void sig_pri_cli_show_channels_header ( int  fd)

Definition at line 7960 of file sig_pri.c.

References ast_cli(), and SIG_PRI_SC_HEADER.

Referenced by handle_pri_show_channels().

7961 {
7962  ast_cli(fd, SIG_PRI_SC_HEADER, "PRI", "", "B", "Chan", "Call", "PRI", "Channel");
7963  ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name");
7964 }
#define SIG_PRI_SC_HEADER
Definition: sig_pri.c:7958
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
void sig_pri_cli_show_span ( int  fd,
int *  dchannels,
struct sig_pri_span pri 
)

Definition at line 8038 of file sig_pri.c.

References ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_std_free(), build_status(), DAHDI_OVERLAPDIAL_INCOMING, sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::lock, sig_pri_span::overlapdial, sig_pri_span::pri, pri_order(), SIG_PRI_NUM_DCHANS, and status.

Referenced by handle_pri_show_span().

8039 {
8040  int x;
8041  char status[256];
8042 
8043  for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
8044  if (pri->dchans[x]) {
8045 #ifdef PRI_DUMP_INFO_STR
8046  char *info_str = NULL;
8047 #endif
8048  ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
8049  build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
8050  ast_cli(fd, "Status: %s\n", status);
8051  ast_mutex_lock(&pri->lock);
8052 #ifdef PRI_DUMP_INFO_STR
8053  info_str = pri_dump_info_str(pri->pri);
8054  if (info_str) {
8055  ast_cli(fd, "%s", info_str);
8056  ast_std_free(info_str);
8057  }
8058 #else
8059  pri_dump_info(pri->pri);
8060 #endif
8061  ast_mutex_unlock(&pri->lock);
8062  ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
8063  ast_cli(fd, "\n");
8064  }
8065  }
8066 }
void ast_std_free(void *ptr)
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:197
static const char * pri_order(int level)
Definition: sig_pri.c:1037
#define ast_mutex_lock(a)
Definition: lock.h:155
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
ast_mutex_t lock
Definition: sig_pri.h:495
int overlapdial
Definition: sig_pri.h:358
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
static void build_status(char *s, size_t len, int status, int active)
Definition: sig_pri.c:8007
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
struct pri * pri
Definition: sig_pri.h:481
jack_status_t status
Definition: app_jack.c:143
#define ast_mutex_unlock(a)
Definition: lock.h:156
void sig_pri_cli_show_spans ( int  fd,
int  span,
struct sig_pri_span pri 
)

Definition at line 8026 of file sig_pri.c.

References ast_cli(), build_status(), sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::pri, SIG_PRI_NUM_DCHANS, and status.

Referenced by handle_pri_show_spans().

8027 {
8028  char status[256];
8029  int x;
8030  for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
8031  if (pri->dchans[x]) {
8032  build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
8033  ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
8034  }
8035  }
8036 }
int dchanavail[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:469
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
static void build_status(char *s, size_t len, int status, int active)
Definition: sig_pri.c:8007
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
struct pri * pri
Definition: sig_pri.h:481
jack_status_t status
Definition: app_jack.c:143
static int sig_pri_cmp_pri_chans ( const void *  left,
const void *  right 
)
static

Definition at line 7665 of file sig_pri.c.

References sig_pri_chan::channel.

Referenced by sig_pri_sort_pri_chans().

7666 {
7667  const struct sig_pri_chan *pvt_left;
7668  const struct sig_pri_chan *pvt_right;
7669 
7670  pvt_left = *(struct sig_pri_chan **) left;
7671  pvt_right = *(struct sig_pri_chan **) right;
7672  if (!pvt_left) {
7673  if (!pvt_right) {
7674  return 0;
7675  }
7676  return 1;
7677  }
7678  if (!pvt_right) {
7679  return -1;
7680  }
7681 
7682  return pvt_left->channel - pvt_right->channel;
7683 }
int channel
Definition: sig_pri.h:234
static struct sig_pri_chan* sig_pri_cw_available ( struct sig_pri_span pri)
static

Definition at line 7379 of file sig_pri.c.

References ast_atomic_fetchadd_int(), sig_pri_chan::is_call_waiting, sig_pri_span::max_call_waiting_calls, sig_pri_span::num_call_waiting_calls, sig_pri_span::numchans, pri_find_empty_nobch(), sig_pri_span::pvts, sig_pri_available_check(), and sig_pri_init_config().

Referenced by sig_pri_available().

7380 {
7381  struct sig_pri_chan *cw;
7382  int idx;
7383 
7384  cw = NULL;
7386  if (!pri->num_call_waiting_calls) {
7387  /*
7388  * There are no outstanding call waiting calls. Check to see
7389  * if the span is in a congested state for the first call
7390  * waiting call.
7391  */
7392  for (idx = 0; idx < pri->numchans; ++idx) {
7393  if (pri->pvts[idx] && sig_pri_available_check(pri->pvts[idx])) {
7394  /* There is another channel that is available on this span. */
7395  return cw;
7396  }
7397  }
7398  }
7399  idx = pri_find_empty_nobch(pri);
7400  if (0 <= idx) {
7401  /* Setup the call waiting interface to use. */
7402  cw = pri->pvts[idx];
7403  cw->is_call_waiting = 1;
7404  sig_pri_init_config(cw, pri);
7406  }
7407  }
7408  return cw;
7409 }
int max_call_waiting_calls
Number of extra outgoing calls to allow on a span before considering that span congested.
Definition: sig_pri.h:448
static void sig_pri_init_config(struct sig_pri_chan *pvt, struct sig_pri_span *pri)
Definition: sig_pri.c:1740
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
static int pri_find_empty_nobch(struct sig_pri_span *pri)
Definition: sig_pri.c:1811
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
int numchans
Definition: sig_pri.h:492
unsigned int is_call_waiting
TRUE if this is a call waiting call.
Definition: sig_pri.h:287
int num_call_waiting_calls
Number of outstanding call waiting calls.
Definition: sig_pri.h:467
static int sig_pri_available_check(struct sig_pri_chan *pvt)
Definition: sig_pri.c:7354
void sig_pri_dial_complete ( struct sig_pri_chan pvt,
struct ast_channel ast 
)

DTMF dial string complete.

Since
1.8.11
Parameters
pvtsig_pri private channel structure.
astAsterisk channel
Note
Channel and private lock are already held.
Returns
Nothing

Definition at line 7506 of file sig_pri.c.

References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), sig_pri_chan::call_level, sig_pri_chan::calls, sig_pri_chan::chan_pvt, ast_frame_subclass::integer, sig_pri_callback::queue_control, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_DEFER_DIAL, sig_pri_open_media(), sig_pri_set_dialing(), sig_pri_set_echocanceller(), and ast_frame::subclass.

Referenced by dahdi_handle_event().

7507 {
7508  /* If we just completed 'w' deferred dialing digits, we need to answer now. */
7511 
7512  sig_pri_open_media(pvt);
7513  {
7514  struct ast_frame f = {AST_FRAME_CONTROL, };
7515 
7516  if (pvt->calls->queue_control) {
7518  }
7519 
7521  ast_queue_frame(ast, &f);
7522  }
7523  sig_pri_set_dialing(pvt, 0);
7524  /* Enable echo cancellation if it's not on already */
7525  sig_pri_set_echocanceller(pvt, 1);
7526  }
7527 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
static void sig_pri_open_media(struct sig_pri_chan *p)
Definition: sig_pri.c:984
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
void(*const queue_control)(void *pvt, int subclass)
Definition: sig_pri.h:157
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
static struct ast_format f[]
Definition: format_g726.c:181
static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
Definition: sig_pri.c:164
Data structure associated with a single frame of data.
Definition: frame.h:142
static int sig_pri_set_echocanceller(struct sig_pri_chan *p, int enable)
Definition: sig_pri.c:921
static void sig_pri_dial_digits ( struct sig_pri_chan p,
const char *  dial_string 
)
static

Definition at line 228 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::dial_digits.

Referenced by pri_dchannel().

229 {
230  if (p->calls->dial_digits) {
231  p->calls->dial_digits(p->chan_pvt, dial_string);
232  }
233 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const dial_digits)(void *pvt, const char *dial_string)
Definition: sig_pri.h:163
int sig_pri_digit_begin ( struct sig_pri_chan pvt,
struct ast_channel ast,
char  digit 
)

Definition at line 7460 of file sig_pri.c.

References ast_channel::_state, ast_debug, ast_log(), AST_STATE_DIALING, sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::dialdest, len(), LOG_WARNING, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_call_level2str(), SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING, and sig_pri_span::span.

Referenced by dahdi_digit_begin().

7461 {
7462  if (ast->_state == AST_STATE_DIALING) {
7464  unsigned int len;
7465 
7466  len = strlen(pvt->dialdest);
7467  if (len < sizeof(pvt->dialdest) - 1) {
7468  ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
7469  digit);
7470  pvt->dialdest[len++] = digit;
7471  pvt->dialdest[len] = '\0';
7472  } else {
7474  "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
7475  pvt->pri->span, digit);
7476  }
7477  return 0;
7478  }
7480  pri_grab(pvt, pvt->pri);
7481  pri_information(pvt->pri->pri, pvt->call, digit);
7482  pri_rel(pvt->pri);
7483  return 0;
7484  }
7487  "Span %d: Digit '%c' may be ignored by peer. (Call level:%u(%s))\n",
7488  pvt->pri->span, digit, pvt->call_level,
7490  }
7491  }
7492  return 1;
7493 }
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
#define LOG_WARNING
Definition: logger.h:144
q931_call * call
Definition: sig_pri.h:297
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char dialdest[256]
Definition: sig_pri.h:250
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
static const char * sig_pri_call_level2str(enum sig_pri_call_level level)
Definition: sig_pri.c:123
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct sig_pri_span * pri
Definition: sig_pri.h:296
struct pri * pri
Definition: sig_pri.h:481
static void sig_pri_dsp_reset_and_flush_digits ( struct sig_pri_chan p)
static

Definition at line 914 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().

915 {
918  }
919 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
int(*const dsp_reset_and_flush_digits)(void *pvt)
Definition: sig_pri.h:142
static void sig_pri_event_party_id ( struct ast_str **  msg,
const char *  prefix,
struct ast_party_id party 
)
static

Definition at line 2178 of file sig_pri.c.

References ast_describe_caller_presentation(), ast_party_id_presentation(), ast_party_name_charset_describe(), ast_str_append(), ast_party_name::char_set, ast_party_id::name, ast_party_id::number, ast_party_subaddress::odd_even_indicator, ast_party_number::plan, ast_party_name::presentation, ast_party_number::presentation, S_COR, S_OR, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_subaddress::type, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

Referenced by sig_pri_mcid_event().

2179 {
2180  int pres;
2181 
2182  /* Combined party presentation */
2183  pres = ast_party_id_presentation(party);
2184  ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix, pres,
2186 
2187  /* Party number */
2188  ast_str_append(msg, 0, "%sNumValid: %d\r\n", prefix,
2189  party->number.valid);
2190  ast_str_append(msg, 0, "%sNum: %s\r\n", prefix,
2191  S_COR(party->number.valid, party->number.str, ""));
2192  ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number.plan);
2193  if (party->number.valid) {
2194  ast_str_append(msg, 0, "%sNumPlan: %d\r\n", prefix, party->number.plan);
2195  ast_str_append(msg, 0, "%sNumPres: %d (%s)\r\n", prefix,
2196  party->number.presentation,
2198  }
2199 
2200  /* Party name */
2201  ast_str_append(msg, 0, "%sNameValid: %d\r\n", prefix,
2202  party->name.valid);
2203  ast_str_append(msg, 0, "%sName: %s\r\n", prefix,
2204  S_COR(party->name.valid, party->name.str, ""));
2205  if (party->name.valid) {
2206  ast_str_append(msg, 0, "%sNameCharSet: %s\r\n", prefix,
2208  ast_str_append(msg, 0, "%sNamePres: %d (%s)\r\n", prefix,
2209  party->name.presentation,
2211  }
2212 
2213 #if defined(HAVE_PRI_SUBADDR)
2214  /* Party subaddress */
2215  if (party->subaddress.valid) {
2216  static const char subaddress[] = "Subaddr";
2217 
2218  ast_str_append(msg, 0, "%s%s: %s\r\n", prefix, subaddress,
2219  S_OR(party->subaddress.str, ""));
2220  ast_str_append(msg, 0, "%s%sType: %d\r\n", prefix, subaddress,
2221  party->subaddress.type);
2222  ast_str_append(msg, 0, "%s%sOdd: %d\r\n", prefix, subaddress,
2224  }
2225 #endif /* defined(HAVE_PRI_SUBADDR) */
2226 }
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:227
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1165
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:2151
int char_set
Character set the name is using.
Definition: channel.h:222
char * str
Subscriber name (Malloced)
Definition: channel.h:214
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
char * str
Malloced subaddress string.
Definition: channel.h:263
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:276
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
int type
Q.931 subaddress type.
Definition: channel.h:270
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const char * ast_party_name_charset_describe(int data)
Convert ast_party_name.char_set value to explanatory string.
Definition: callerid.c:1333
static char prefix[MAX_PREFIX]
Definition: http.c:107
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
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.

Since
1.8
Parameters
psig_pri channel structure.
rdestDial string buffer to extract called number and subaddress.
calledBuffer to fill with extracted <number>[:<subaddress>]
called_buff_sizeSize of buffer to fill.
Note
Parsing must remain in sync with sig_pri_call().
Returns
Nothing

Definition at line 6555 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().

6556 {
6557  char *dial;
6558  char *number;
6559  char *subaddr;
6561  AST_APP_ARG(group); /* channel/group token */
6562  AST_APP_ARG(ext); /* extension token */
6563  //AST_APP_ARG(opts); /* options token */
6564  AST_APP_ARG(other); /* Any remining unused arguments */
6565  );
6566 
6567  /* Get private copy of dial string and break it up. */
6568  dial = ast_strdupa(rdest);
6569  AST_NONSTANDARD_APP_ARGS(args, dial, '/');
6570 
6571  number = args.ext;
6572  if (!number) {
6573  number = "";
6574  }
6575 
6576  /* Find and extract dialed_subaddress */
6577  subaddr = strchr(number, ':');
6578  if (subaddr) {
6579  *subaddr++ = '\0';
6580 
6581  /* Skip subaddress type prefix. */
6582  switch (*subaddr) {
6583  case 'U':
6584  case 'u':
6585  case 'N':
6586  case 'n':
6587  ++subaddr;
6588  break;
6589  default:
6590  break;
6591  }
6592  }
6593 
6594  /* Skip type-of-number/dial-plan prefix characters. */
6595  if (strlen(number) < p->stripmsd) {
6596  number = "";
6597  } else {
6598  char *deferred;
6599 
6600  number += p->stripmsd;
6601  deferred = strchr(number, 'w');
6602  if (deferred) {
6603  /* Remove any 'w' deferred digits. */
6604  *deferred = '\0';
6605  }
6606  while (isalpha(*number)) {
6607  ++number;
6608  }
6609  }
6610 
6611  /* Fill buffer with extracted number and subaddress. */
6612  if (ast_strlen_zero(subaddr)) {
6613  /* Put in called number only since there is no subaddress. */
6614  snprintf(called, called_buff_size, "%s", number);
6615  } else {
6616  /* Put in called number and subaddress. */
6617  snprintf(called, called_buff_size, "%s:%s", number, subaddr);
6618  }
6619 }
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
const char * ext
Definition: http.c:112
Number structure.
Definition: app_followme.c:109
int stripmsd
Definition: sig_pri.h:233
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
static struct ast_cc_agent* sig_pri_find_cc_agent_by_cc_id ( struct sig_pri_span pri,
long  cc_id 
)
static

Definition at line 2531 of file sig_pri.c.

References ast_cc_agent_callback(), sig_pri_cc_agent_prv::cc_id, sig_pri_cc_agent_prv::pri, sig_pri_cc_agent_cmp_cc_id(), and sig_pri_cc_type_name.

Referenced by sig_pri_cc_link_canceled(), sig_pri_handle_cis_subcmds(), and sig_pri_handle_subcmds().

2532 {
2533  struct sig_pri_cc_agent_prv finder = {
2534  .pri = pri,
2535  .cc_id = cc_id,
2536  };
2537 
2540 }
struct sig_pri_span * pri
Definition: sig_pri.c:80
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
Definition: ccss.c:446
static int sig_pri_cc_agent_cmp_cc_id(void *obj, void *arg, int flags)
Definition: sig_pri.c:2503
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
static struct sig_pri_cc_monitor_instance* sig_pri_find_cc_monitor_by_cc_id ( struct sig_pri_span pri,
long  cc_id 
)
static

Definition at line 2582 of file sig_pri.c.

References ao2_callback, sig_pri_cc_monitor_instance::cc_id, sig_pri_cc_monitor_instance::pri, and sig_pri_cc_monitor_cmp_cc_id().

Referenced by sig_pri_cc_link_canceled(), and sig_pri_handle_cis_subcmds().

2583 {
2584  struct sig_pri_cc_monitor_instance finder = {
2585  .pri = pri,
2586  .cc_id = cc_id,
2587  };
2588 
2590 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
struct sig_pri_span * pri
Asterisk span D channel control structure.
Definition: sig_pri.c:89
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101
static int sig_pri_cc_monitor_cmp_cc_id(void *obj, void *arg, int flags)
Definition: sig_pri.c:2555
void sig_pri_fixup ( struct ast_channel oldchan,
struct ast_channel newchan,
struct sig_pri_chan pchan 
)

Definition at line 8118 of file sig_pri.c.

References sig_pri_chan::owner.

Referenced by dahdi_fixup().

8119 {
8120  if (pchan->owner == oldchan) {
8121  pchan->owner = newchan;
8122  }
8123 }
struct ast_channel * owner
Definition: sig_pri.h:294
static void sig_pri_fixup_chans ( struct sig_pri_chan old_chan,
struct sig_pri_chan new_chan 
)
static

Definition at line 929 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().

930 {
931  if (old_chan->calls->fixup_chans)
932  old_chan->calls->fixup_chans(old_chan->chan_pvt, new_chan->chan_pvt);
933 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void(*const fixup_chans)(void *old_chan, void *new_chan)
Definition: sig_pri.h:146
void * chan_pvt
Definition: sig_pri.h:312
static const char* sig_pri_get_orig_dialstring ( struct sig_pri_chan p)
static

Definition at line 207 of file sig_pri.c.

References ast_log(), sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_callback::get_orig_dialstring, and LOG_ERROR.

Referenced by sig_pri_cc_available(), and sig_pri_cc_generic_check().

208 {
209  if (p->calls->get_orig_dialstring) {
210  return p->calls->get_orig_dialstring(p->chan_pvt);
211  }
212  ast_log(LOG_ERROR, "get_orig_dialstring callback not defined\n");
213  return "";
214 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char *(*const get_orig_dialstring)(void *pvt)
Definition: sig_pri.h:160
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 3851 of file sig_pri.c.

References ao2_ref, ast_cc_agent_accept_request(), ast_cc_agent_caller_available(), ast_cc_agent_caller_busy(), ast_cc_agent_status_response(), ast_cc_failed(), ast_cc_monitor_callee_available(), ast_cc_monitor_failed(), ast_cc_monitor_party_b_free(), ast_cc_monitor_request_acked(), ast_cc_monitor_status_request(), ast_cc_monitor_stop_ringing(), ast_cc_request_is_within_limits(), ast_debug, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_verb, sig_pri_cc_agent_prv::cc_request_response_pending, sig_pri_cc_monitor_instance::core_id, ast_cc_agent::core_id, monitor, sig_pri_cc_monitor_instance::name, sig_pri_span::pri, ast_cc_agent::private_data, sig_pri_aoc_e_from_pri(), sig_pri_cc_link_canceled(), sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), sig_pri_find_cc_monitor_by_cc_id(), and sig_pri_span::span.

Referenced by pri_dchannel().

3853 {
3854  int index;
3855 #if defined(HAVE_PRI_CCSS)
3856  struct ast_cc_agent *agent;
3857  struct sig_pri_cc_agent_prv *agent_prv;
3859 #endif /* defined(HAVE_PRI_CCSS) */
3860 
3861  if (!subcmds) {
3862  return;
3863  }
3864  for (index = 0; index < subcmds->counter_subcmd; ++index) {
3865  const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
3866 
3867  switch (subcmd->cmd) {
3868 #if defined(STATUS_REQUEST_PLACE_HOLDER)
3869  case PRI_SUBCMD_STATUS_REQ:
3870  case PRI_SUBCMD_STATUS_REQ_RSP:
3871  /* Ignore for now. */
3872  break;
3873 #endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
3874 #if defined(HAVE_PRI_CCSS)
3875  case PRI_SUBCMD_CC_REQ:
3876  agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
3877  if (!agent) {
3878  pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
3879  break;
3880  }
3882  if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
3883  5/* queue_full */)) {
3884  pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
3885  }
3886  ast_cc_failed(agent->core_id, "%s agent system CC queue full",
3888  ao2_ref(agent, -1);
3889  break;
3890  }
3891  agent_prv = agent->private_data;
3892  agent_prv->cc_request_response_pending = 1;
3894  "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
3895  agent_prv->cc_request_response_pending = 0;
3896  if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
3897  2/* short_term_denial */)) {
3898  pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
3899  }
3900  ast_cc_failed(agent->core_id, "%s agent CC core request accept failed",
3902  }
3903  ao2_ref(agent, -1);
3904  break;
3905 #endif /* defined(HAVE_PRI_CCSS) */
3906 #if defined(HAVE_PRI_CCSS)
3907  case PRI_SUBCMD_CC_REQ_RSP:
3908  monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
3909  subcmd->u.cc_request_rsp.cc_id);
3910  if (!monitor) {
3911  pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id);
3912  break;
3913  }
3914  switch (subcmd->u.cc_request_rsp.status) {
3915  case 0:/* success */
3917  "%s far end accepted CC request", sig_pri_cc_type_name);
3918  break;
3919  case 1:/* timeout */
3920  ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id,
3922  ast_cc_monitor_failed(monitor->core_id, monitor->name,
3923  "%s CC request timeout", sig_pri_cc_type_name);
3924  break;
3925  case 2:/* error */
3926  ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id,
3928  pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
3929  ast_cc_monitor_failed(monitor->core_id, monitor->name,
3930  "%s CC request error", sig_pri_cc_type_name);
3931  break;
3932  case 3:/* reject */
3933  ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id,
3935  pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
3936  ast_cc_monitor_failed(monitor->core_id, monitor->name,
3937  "%s CC request reject", sig_pri_cc_type_name);
3938  break;
3939  default:
3940  ast_verb(2, "core_id:%d %s CC request unknown status %d\n",
3941  monitor->core_id, sig_pri_cc_type_name,
3942  subcmd->u.cc_request_rsp.status);
3943  ast_cc_monitor_failed(monitor->core_id, monitor->name,
3944  "%s CC request unknown status", sig_pri_cc_type_name);
3945  break;
3946  }
3947  ao2_ref(monitor, -1);
3948  break;
3949 #endif /* defined(HAVE_PRI_CCSS) */
3950 #if defined(HAVE_PRI_CCSS)
3951  case PRI_SUBCMD_CC_REMOTE_USER_FREE:
3952  monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
3953  subcmd->u.cc_remote_user_free.cc_id);
3954  if (!monitor) {
3955  pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id);
3956  break;
3957  }
3959  "%s callee has become available", sig_pri_cc_type_name);
3960  ao2_ref(monitor, -1);
3961  break;
3962 #endif /* defined(HAVE_PRI_CCSS) */
3963 #if defined(HAVE_PRI_CCSS)
3964  case PRI_SUBCMD_CC_B_FREE:
3965  monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
3966  subcmd->u.cc_b_free.cc_id);
3967  if (!monitor) {
3968  pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id);
3969  break;
3970  }
3972  ao2_ref(monitor, -1);
3973  break;
3974 #endif /* defined(HAVE_PRI_CCSS) */
3975 #if defined(HAVE_PRI_CCSS)
3976  case PRI_SUBCMD_CC_STATUS_REQ:
3977  monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
3978  subcmd->u.cc_status_req.cc_id);
3979  if (!monitor) {
3980  pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id);
3981  break;
3982  }
3984  ao2_ref(monitor, -1);
3985  break;
3986 #endif /* defined(HAVE_PRI_CCSS) */
3987 #if defined(HAVE_PRI_CCSS)
3988  case PRI_SUBCMD_CC_STATUS_REQ_RSP:
3989  agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
3990  if (!agent) {
3991  pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id);
3992  break;
3993  }
3995  subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE
3997  ao2_ref(agent, -1);
3998  break;
3999 #endif /* defined(HAVE_PRI_CCSS) */
4000 #if defined(HAVE_PRI_CCSS)
4001  case PRI_SUBCMD_CC_STATUS:
4002  agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
4003  if (!agent) {
4004  pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id);
4005  break;
4006  }
4007  if (subcmd->u.cc_status.status) {
4008  ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy",
4010  } else {
4012  "%s agent caller is available", sig_pri_cc_type_name);
4013  }
4014  ao2_ref(agent, -1);
4015  break;
4016 #endif /* defined(HAVE_PRI_CCSS) */
4017 #if defined(HAVE_PRI_CCSS)
4018  case PRI_SUBCMD_CC_CANCEL:
4019  sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4020  subcmd->u.cc_cancel.is_agent);
4021  break;
4022 #endif /* defined(HAVE_PRI_CCSS) */
4023 #if defined(HAVE_PRI_CCSS)
4024  case PRI_SUBCMD_CC_STOP_ALERTING:
4025  monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4026  subcmd->u.cc_stop_alerting.cc_id);
4027  if (!monitor) {
4028  pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id);
4029  break;
4030  }
4032  ao2_ref(monitor, -1);
4033  break;
4034 #endif /* defined(HAVE_PRI_CCSS) */
4035 #if defined(HAVE_PRI_AOC_EVENTS)
4036  case PRI_SUBCMD_AOC_E:
4037  /* Queue AST_CONTROL_AOC frame */
4038  sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0);
4039  break;
4040 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4041  default:
4042  ast_debug(2,
4043  "Unknown CIS subcommand(%d) in %s event on span %d.\n",
4044  subcmd->cmd, pri_event2str(event_id), pri->span);
4045  break;
4046  }
4047  }
4048 }
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
Definition: ccss.c:3678
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
Definition: ccss.c:3613
void * private_data
Definition: ccss.h:854
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
Definition: ccss.c:3543
static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
Definition: sig_pri.c:3356
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller&#39;s current status.
Definition: ccss.c:3830
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
Definition: ccss.c:3521
int ast_cc_monitor_party_b_free(int core_id)
Alert a caller that though the callee has become free, the caller himself is not and may not call bac...
Definition: ccss.c:3788
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
Definition: ccss.c:3510
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
Definition: ccss.c:3554
static void sig_pri_cc_link_canceled(struct sig_pri_span *pri, long cc_id, int is_agent)
Definition: sig_pri.c:2849
static unsigned int monitor
Definition: chan_phone.c:108
static struct sig_pri_cc_monitor_instance * sig_pri_find_cc_monitor_by_cc_id(struct sig_pri_span *pri, long cc_id)
Definition: sig_pri.c:2582
unsigned int core_id
Definition: ccss.h:832
int ast_cc_monitor_status_request(int core_id)
Request the status of a caller or callers.
Definition: ccss.c:3723
int ast_cc_request_is_within_limits(void)
Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option...
Definition: ccss.c:2219
unsigned char cc_request_response_pending
Definition: sig_pri.c:84
static struct ast_cc_agent * sig_pri_find_cc_agent_by_cc_id(struct sig_pri_span *pri, long cc_id)
Definition: sig_pri.c:2531
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
int ast_cc_monitor_stop_ringing(int core_id)
Alert a caller to stop ringing.
Definition: ccss.c:3760
struct pri * pri
Definition: sig_pri.h:481
int ast_cc_monitor_callee_available(const int core_id, const char *const debug,...)
Alert the core that a device being monitored has become available.
Definition: ccss.c:3532
static void sig_pri_handle_dchan_exception ( struct sig_pri_span pri,
int  index 
)
static

Definition at line 158 of file sig_pri.c.

References sig_pri_span::calls, and sig_pri_callback::handle_dchan_exception.

Referenced by pri_dchannel().

159 {
160  if (pri->calls->handle_dchan_exception)
161  pri->calls->handle_dchan_exception(pri, index);
162 }
struct sig_pri_callback * calls
Definition: sig_pri.h:497
void(*const handle_dchan_exception)(struct sig_pri_span *pri, int index)
Definition: sig_pri.h:149
static int sig_pri_handle_hold ( struct sig_pri_span pri,
pri_event *  ev 
)
static

Definition at line 4460 of file sig_pri.c.

References ast_channel_unlock, AST_CONTROL_HOLD, AST_FRAME_CONTROL, ast_log(), ast_queue_frame(), sig_pri_chan::call_level, ast_frame_subclass::integer, LOG_WARNING, sig_pri_chan::no_b_channel, sig_pri_chan::owner, pri_find_empty_nobch(), pri_find_principle_by_call(), pri_fixup_principle(), sig_pri_span::pvts, SIG_PRI_CALL_LEVEL_CONNECT, sig_pri_handle_subcmds(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_span_devstate_changed(), sig_pri_unlock_private(), sig_pri_span::span, and ast_frame::subclass.

Referenced by pri_dchannel().

4461 {
4462  int retval;
4463  int chanpos_old;
4464  int chanpos_new;
4465  struct ast_channel *owner;
4466 
4467  chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
4468  if (chanpos_old < 0) {
4469  ast_log(LOG_WARNING, "Span %d: Received HOLD for unknown call.\n", pri->span);
4470  return -1;
4471  }
4472  if (pri->pvts[chanpos_old]->no_b_channel) {
4473  /* Call is already on hold or is call waiting call. */
4474  return -1;
4475  }
4476 
4477  chanpos_new = -1;
4478 
4479  sig_pri_lock_private(pri->pvts[chanpos_old]);
4480  sig_pri_lock_owner(pri, chanpos_old);
4481  owner = pri->pvts[chanpos_old]->owner;
4482  if (!owner) {
4483  goto done_with_private;
4484  }
4485  if (pri->pvts[chanpos_old]->call_level != SIG_PRI_CALL_LEVEL_CONNECT) {
4486  /*
4487  * Make things simple. Don't allow placing a call on hold that
4488  * is not connected.
4489  */
4490  goto done_with_owner;
4491  }
4492  chanpos_new = pri_find_empty_nobch(pri);
4493  if (chanpos_new < 0) {
4494  /* No hold channel available. */
4495  goto done_with_owner;
4496  }
4497  sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.channel, ev->hold.subcmds,
4498  ev->hold.call);
4499  chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
4500  if (chanpos_new < 0) {
4501  /* Should never happen. */
4502  } else {
4503  struct ast_frame f = { AST_FRAME_CONTROL, };
4504 
4505  /*
4506  * Things are in an odd state here so we cannot use pri_queue_control().
4507  * However, we already have the owner lock so we can simply queue the frame.
4508  */
4510  ast_queue_frame(owner, &f);
4511  }
4512 
4513 done_with_owner:;
4514  ast_channel_unlock(owner);
4515 done_with_private:;
4516  sig_pri_unlock_private(pri->pvts[chanpos_old]);
4517 
4518  if (chanpos_new < 0) {
4519  retval = -1;
4520  } else {
4522  retval = 0;
4523  }
4524 
4525  return retval;
4526 }
union ast_frame_subclass subclass
Definition: frame.h:146
Main Channel structure associated with a channel.
Definition: channel.h:742
#define LOG_WARNING
Definition: logger.h:144
struct ast_channel * owner
Definition: sig_pri.h:294
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
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)
Definition: sig_pri.c:4107
static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
Definition: sig_pri.c:1397
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
Definition: sig_pri.c:1265
static int pri_find_empty_nobch(struct sig_pri_span *pri)
Definition: sig_pri.c:1811
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
Data structure associated with a single frame of data.
Definition: frame.h:142
static void sig_pri_handle_retrieve ( struct sig_pri_span pri,
pri_event *  ev 
)
static

Definition at line 4542 of file sig_pri.c.

References AST_CONTROL_UNHOLD, ast_log(), LOG_WARNING, sig_pri_span::pri, PRI_CHANNEL, pri_find_empty_chan(), pri_find_principle(), pri_find_principle_by_call(), pri_fixup_principle(), PRI_HELD_CALL, pri_queue_control(), PVT_TO_CHANNEL(), sig_pri_span::pvts, sig_pri_handle_subcmds(), sig_pri_is_chan_available(), sig_pri_lock_private(), sig_pri_span_devstate_changed(), sig_pri_unlock_private(), and sig_pri_span::span.

Referenced by pri_dchannel().

4543 {
4544  int chanpos;
4545 
4546  if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
4547  /* The call is not currently held. */
4548  pri_retrieve_rej(pri->pri, ev->retrieve.call,
4549  PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
4550  return;
4551  }
4552  if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
4553  ast_log(LOG_WARNING, "Span %d: Received RETRIEVE for unknown call.\n", pri->span);
4554  pri_retrieve_rej(pri->pri, ev->retrieve.call,
4555  PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
4556  return;
4557  }
4558  if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
4559  chanpos = pri_find_empty_chan(pri, 1);
4560  } else {
4561  chanpos = pri_find_principle(pri,
4562  ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
4563  if (ev->retrieve.flexible
4564  && (chanpos < 0 || !sig_pri_is_chan_available(pri->pvts[chanpos]))) {
4565  /*
4566  * Channel selection is flexible and the requested channel
4567  * is bad or not available. Pick another channel.
4568  */
4569  chanpos = pri_find_empty_chan(pri, 1);
4570  }
4571  }
4572  if (chanpos < 0) {
4573  pri_retrieve_rej(pri->pri, ev->retrieve.call,
4574  ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
4575  : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
4576  return;
4577  }
4578  chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
4579  if (chanpos < 0) {
4580  /* Channel is already in use. */
4581  pri_retrieve_rej(pri->pri, ev->retrieve.call,
4582  PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
4583  return;
4584  }
4585  sig_pri_lock_private(pri->pvts[chanpos]);
4586  sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.channel,
4587  ev->retrieve.subcmds, ev->retrieve.call);
4588  pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
4589  sig_pri_unlock_private(pri->pvts[chanpos]);
4590  pri_retrieve_ack(pri->pri, ev->retrieve.call,
4591  PVT_TO_CHANNEL(pri->pvts[chanpos]));
4593 }
#define LOG_WARNING
Definition: logger.h:144
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
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)
Definition: sig_pri.c:4107
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
Definition: sig_pri.c:1239
static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
Definition: sig_pri.c:1397
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
Definition: sig_pri.c:1160
static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
Definition: sig_pri.c:1265
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define PRI_HELD_CALL
Definition: sig_pri.c:116
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static int pri_find_empty_chan(struct sig_pri_span *pri, int backwards)
Definition: sig_pri.c:1771
static int pri_find_principle(struct sig_pri_span *pri, int channel, q931_call *call)
Definition: sig_pri.c:1330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
#define PRI_CHANNEL(p)
Definition: sig_pri.c:112
struct pri * pri
Definition: sig_pri.h:481
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
Todo:
XXX Original called data can be put in a channel data store that is inherited.

Definition at line 4107 of file sig_pri.c.

References ast_party_caller::ani, ao2_ref, sig_pri_span::aoc_passthrough_flag, ast_cc_agent_recalling(), ast_cc_agent_set_interfaces_chanvar(), AST_CC_CCBS, AST_CC_CCNR, AST_CC_NONE, ast_channel_queue_connected_line_update(), ast_channel_queue_redirecting_update(), ast_channel_set_caller_event(), ast_channel_set_redirecting(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_copy_string(), ast_debug, ast_log(), ast_null_frame, ast_party_caller_set_init(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_party_redirecting_free(), ast_queue_frame(), ast_setup_cc_recall_datastore(), ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_verb, xfer_rsp_data::call, ast_channel::caller, sig_pri_chan::callingpres, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::cid_ton, ast_cc_agent::core_id, ast_party_redirecting::from, ast_party_caller::id, ast_party_connected_line::id, xfer_rsp_data::invoke_id, LOG_ERROR, LOG_WARNING, ast_party_id::name, ast_channel::name, ast_party_id::number, sig_pri_chan::owner, ast_party_number::plan, sig_pri_span::pri, xfer_rsp_data::pri, PRI_CHANNEL, PRI_SPAN, sig_pri_span::pvts, ast_channel::redirecting, service, sig_pri_aoc_d_from_pri(), sig_pri_aoc_e_from_pri(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_aoc_request_from_pri(), sig_pri_aoc_s_from_pri(), sig_pri_attempt_transfer(), sig_pri_cc_available(), sig_pri_cc_link_canceled(), sig_pri_cc_type_name, sig_pri_find_cc_agent_by_cc_id(), sig_pri_lock_owner(), sig_pri_lock_private(), sig_pri_mcid_event(), sig_pri_party_id_convert(), sig_pri_redirecting_convert(), sig_pri_set_caller_id(), sig_pri_transfer_rsp(), sig_pri_unlock_private(), ast_party_connected_line::source, sig_pri_span::span, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_redirecting::to, sig_pri_span::transfer, and sig_pri_chan::user_tag.

Referenced by pri_dchannel(), sig_pri_handle_hold(), and sig_pri_handle_retrieve().

4109 {
4110  int index;
4111  struct ast_channel *owner;
4112  struct ast_party_redirecting ast_redirecting;
4113 #if defined(HAVE_PRI_TRANSFER)
4114  struct xfer_rsp_data xfer_rsp;
4115 #endif /* defined(HAVE_PRI_TRANSFER) */
4116 
4117  if (!subcmds) {
4118  return;
4119  }
4120  for (index = 0; index < subcmds->counter_subcmd; ++index) {
4121  const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4122 
4123  switch (subcmd->cmd) {
4124  case PRI_SUBCMD_CONNECTED_LINE:
4125  sig_pri_lock_owner(pri, chanpos);
4126  owner = pri->pvts[chanpos]->owner;
4127  if (owner) {
4128  struct ast_party_connected_line ast_connected;
4129  int caller_id_update;
4130 
4131  /* Extract the connected line information */
4132  ast_party_connected_line_init(&ast_connected);
4133  sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
4134  pri);
4135  ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
4136 
4137  caller_id_update = 0;
4138  if (ast_connected.id.name.str) {
4139  /* Save name for Caller-ID update */
4140  ast_copy_string(pri->pvts[chanpos]->cid_name,
4141  ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name));
4142  caller_id_update = 1;
4143  }
4144  if (ast_connected.id.number.str) {
4145  /* Save number for Caller-ID update */
4146  ast_copy_string(pri->pvts[chanpos]->cid_num,
4147  ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num));
4148  pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan;
4149  caller_id_update = 1;
4150  }
4151  ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
4152 
4153  pri->pvts[chanpos]->cid_subaddr[0] = '\0';
4154 #if defined(HAVE_PRI_SUBADDR)
4155  if (ast_connected.id.subaddress.str) {
4156  ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
4157  ast_connected.id.subaddress.str,
4158  sizeof(pri->pvts[chanpos]->cid_subaddr));
4159  caller_id_update = 1;
4160  }
4161 #endif /* defined(HAVE_PRI_SUBADDR) */
4162  if (caller_id_update) {
4163  struct ast_party_caller ast_caller;
4164 
4165  pri->pvts[chanpos]->callingpres =
4166  ast_party_id_presentation(&ast_connected.id);
4167  sig_pri_set_caller_id(pri->pvts[chanpos]);
4168 
4169  ast_party_caller_set_init(&ast_caller, &owner->caller);
4170  ast_caller.id = ast_connected.id;
4171  ast_caller.ani = ast_connected.id;
4172  ast_channel_set_caller_event(owner, &ast_caller, NULL);
4173 
4174  /* Update the connected line information on the other channel */
4175  if (event_id != PRI_EVENT_RING) {
4176  /* This connected_line update was not from a SETUP message. */
4177  ast_channel_queue_connected_line_update(owner, &ast_connected,
4178  NULL);
4179  }
4180  }
4181 
4182  ast_party_connected_line_free(&ast_connected);
4183  ast_channel_unlock(owner);
4184  }
4185  break;
4186  case PRI_SUBCMD_REDIRECTING:
4187  sig_pri_lock_owner(pri, chanpos);
4188  owner = pri->pvts[chanpos]->owner;
4189  if (owner) {
4190  sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
4191  &owner->redirecting, pri);
4192  ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
4193  ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
4194 
4195 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */
4196 
4197  ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
4198  if (event_id != PRI_EVENT_RING) {
4199  /* This redirection was not from a SETUP message. */
4200  ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
4201  }
4202  ast_party_redirecting_free(&ast_redirecting);
4203 
4204  ast_channel_unlock(owner);
4205  }
4206  break;
4207 #if defined(HAVE_PRI_CALL_REROUTING)
4208  case PRI_SUBCMD_REROUTING:
4209  sig_pri_lock_owner(pri, chanpos);
4210  owner = pri->pvts[chanpos]->owner;
4211  if (owner) {
4212  struct pri_party_redirecting pri_deflection;
4213 
4214  if (!call_rsp) {
4216  "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
4217  pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
4218  ast_channel_unlock(owner);
4219  break;
4220  }
4221  if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) {
4223  "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
4224  pri->span, owner->name);
4225  pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
4226  PRI_REROUTING_RSP_INVALID_NUMBER);
4227  ast_channel_unlock(owner);
4228  break;
4229  }
4230 
4231  ast_verb(3, "Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
4232  pri->span, owner->name, subcmd->u.rerouting.deflection.to.number.str);
4233 
4234  /*
4235  * Send back positive ACK to CallRerouting/CallDeflection.
4236  *
4237  * Note: This call will be hungup by the core when it processes
4238  * the call_forward string.
4239  */
4240  pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
4241  PRI_REROUTING_RSP_OK_CLEAR);
4242 
4243  pri_deflection = subcmd->u.rerouting.deflection;
4244 
4245  /* Adjust the deflecting to number based upon the subscription option. */
4246  switch (subcmd->u.rerouting.subscription_option) {
4247  case 0: /* noNotification */
4248  case 1: /* notificationWithoutDivertedToNr */
4249  /* Delete the number because the far end is not supposed to see it. */
4250  pri_deflection.to.number.presentation =
4251  PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
4252  pri_deflection.to.number.plan =
4253  (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
4254  pri_deflection.to.number.str[0] = '\0';
4255  break;
4256  case 2: /* notificationWithDivertedToNr */
4257  break;
4258  case 3: /* notApplicable */
4259  default:
4260  break;
4261  }
4262  sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
4263  &owner->redirecting, pri);
4264  ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
4265  ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
4266  ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
4267  ast_party_redirecting_free(&ast_redirecting);
4268 
4269  /* Request the core to forward to the new number. */
4270  ast_string_field_set(owner, call_forward,
4271  subcmd->u.rerouting.deflection.to.number.str);
4272 
4273  /* Wake up the channel. */
4275 
4276  ast_channel_unlock(owner);
4277  }
4278  break;
4279 #endif /* defined(HAVE_PRI_CALL_REROUTING) */
4280 #if defined(HAVE_PRI_CCSS)
4281  case PRI_SUBCMD_CC_AVAILABLE:
4282  sig_pri_lock_owner(pri, chanpos);
4283  owner = pri->pvts[chanpos]->owner;
4284  if (owner) {
4286 
4287  switch (event_id) {
4288  case PRI_EVENT_RINGING:
4289  service = AST_CC_CCNR;
4290  break;
4291  case PRI_EVENT_HANGUP_REQ:
4292  /* We will assume that the cause was busy/congestion. */
4293  service = AST_CC_CCBS;
4294  break;
4295  default:
4296  service = AST_CC_NONE;
4297  break;
4298  }
4299  if (service == AST_CC_NONE
4300  || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
4301  service)) {
4302  pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
4303  }
4304  ast_channel_unlock(owner);
4305  } else {
4306  /* No asterisk channel. */
4307  pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
4308  }
4309  break;
4310 #endif /* defined(HAVE_PRI_CCSS) */
4311 #if defined(HAVE_PRI_CCSS)
4312  case PRI_SUBCMD_CC_CALL:
4313  sig_pri_lock_owner(pri, chanpos);
4314  owner = pri->pvts[chanpos]->owner;
4315  if (owner) {
4316  struct ast_cc_agent *agent;
4317 
4318  agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
4319  if (agent) {
4320  ast_setup_cc_recall_datastore(owner, agent->core_id);
4323  "%s caller is attempting recall", sig_pri_cc_type_name);
4324  ao2_ref(agent, -1);
4325  }
4326 
4327  ast_channel_unlock(owner);
4328  }
4329  break;
4330 #endif /* defined(HAVE_PRI_CCSS) */
4331 #if defined(HAVE_PRI_CCSS)
4332  case PRI_SUBCMD_CC_CANCEL:
4333  sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4334  subcmd->u.cc_cancel.is_agent);
4335  break;
4336 #endif /* defined(HAVE_PRI_CCSS) */
4337 #if defined(HAVE_PRI_TRANSFER)
4338  case PRI_SUBCMD_TRANSFER_CALL:
4339  if (!call_rsp) {
4340  /* Should never happen. */
4342  "Call transfer subcommand without call to send response!\n");
4343  break;
4344  }
4345 
4346  sig_pri_unlock_private(pri->pvts[chanpos]);
4347  xfer_rsp.pri = pri;
4348  xfer_rsp.call = call_rsp;
4349  xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id;
4351  subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held,
4352  subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
4353  sig_pri_transfer_rsp, &xfer_rsp);
4354  sig_pri_lock_private(pri->pvts[chanpos]);
4355  break;
4356 #endif /* defined(HAVE_PRI_TRANSFER) */
4357 #if defined(HAVE_PRI_AOC_EVENTS)
4358  case PRI_SUBCMD_AOC_S:
4359  sig_pri_lock_owner(pri, chanpos);
4360  owner = pri->pvts[chanpos]->owner;
4361  if (owner) {
4362  sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
4364  ast_channel_unlock(owner);
4365  }
4366  break;
4367 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4368 #if defined(HAVE_PRI_AOC_EVENTS)
4369  case PRI_SUBCMD_AOC_D:
4370  sig_pri_lock_owner(pri, chanpos);
4371  owner = pri->pvts[chanpos]->owner;
4372  if (owner) {
4373  /* Queue AST_CONTROL_AOC frame on channel */
4374  sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
4376  ast_channel_unlock(owner);
4377  }
4378  break;
4379 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4380 #if defined(HAVE_PRI_AOC_EVENTS)
4381  case PRI_SUBCMD_AOC_E:
4382  sig_pri_lock_owner(pri, chanpos);
4383  owner = pri->pvts[chanpos]->owner;
4384  /* Queue AST_CONTROL_AOC frame */
4385  sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
4387  if (owner) {
4388  ast_channel_unlock(owner);
4389  }
4390  break;
4391 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4392 #if defined(HAVE_PRI_AOC_EVENTS)
4393  case PRI_SUBCMD_AOC_CHARGING_REQ:
4394  sig_pri_lock_owner(pri, chanpos);
4395  owner = pri->pvts[chanpos]->owner;
4396  if (owner) {
4397  sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos],
4398  call_rsp);
4399  ast_channel_unlock(owner);
4400  }
4401  break;
4402 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4403 #if defined(HAVE_PRI_AOC_EVENTS)
4404  case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
4405  /*
4406  * An AOC request response may contain an AOC-S rate list.
4407  * If this is the case handle this just like we
4408  * would an incoming AOC-S msg.
4409  */
4410  if (subcmd->u.aoc_request_response.valid_aoc_s) {
4411  sig_pri_lock_owner(pri, chanpos);
4412  owner = pri->pvts[chanpos]->owner;
4413  if (owner) {
4414  sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
4416  ast_channel_unlock(owner);
4417  }
4418  }
4419  break;
4420 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
4421 #if defined(HAVE_PRI_MCID)
4422  case PRI_SUBCMD_MCID_REQ:
4423  sig_pri_lock_owner(pri, chanpos);
4424  owner = pri->pvts[chanpos]->owner;
4425  sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
4426  if (owner) {
4427  ast_channel_unlock(owner);
4428  }
4429  break;
4430 #endif /* defined(HAVE_PRI_MCID) */
4431 #if defined(HAVE_PRI_MCID)
4432  case PRI_SUBCMD_MCID_RSP:
4433  /* Ignore for now. */
4434  break;
4435 #endif /* defined(HAVE_PRI_MCID) */
4436  default:
4437  ast_debug(2,
4438  "Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n",
4439  subcmd->cmd, pri_event2str(event_id), PRI_SPAN(channel),
4440  PRI_CHANNEL(channel), pri->span);
4441  break;
4442  }
4443  }
4444 }
int cid_ton
Definition: sig_pri.h:238
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)
Definition: sig_pri.c:2090
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2308
Main Channel structure associated with a channel.
Definition: channel.h:742
static void sig_pri_mcid_event(struct sig_pri_span *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner)
Definition: sig_pri.c:2245
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7091
struct ast_frame ast_null_frame
Definition: frame.c:131
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int callingpres
Definition: sig_pri.h:239
#define ast_strdup(a)
Definition: astmm.h:109
#define PRI_SPAN(p)
Definition: sig_pri.c:113
unsigned int transfer
TRUE if call transfer is enabled for the span.
Definition: sig_pri.h:388
#define LOG_WARNING
Definition: logger.h:144
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:2151
struct ast_channel * owner
Definition: sig_pri.h:294
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)
Definition: sig_pri.c:2347
static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
Definition: sig_pri.c:3356
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
enum ast_cc_service_type service
Definition: chan_sip.c:821
static int sig_pri_cc_available(struct sig_pri_span *pri, int chanpos, long cc_id, enum ast_cc_service_type service)
Definition: sig_pri.c:2679
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2353
#define SIG_PRI_AOC_GRANT_S
Definition: sig_pri.h:66
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
Definition: ccss.c:3565
ast_cc_service_type
Definition: ccss.h:32
#define ast_verb(level,...)
Definition: logger.h:243
static void sig_pri_transfer_rsp(void *data, int is_successful)
Definition: sig_pri.c:2307
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9098
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
Definition: ccss.c:3365
static void sig_pri_aoc_s_from_pri(const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough)
Definition: sig_pri.c:3083
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
Definition: ccss.c:3139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Caller Party information.
Definition: channel.h:368
#define ao2_ref(o, delta)
Definition: astobj2.h:472
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9111
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
static void sig_pri_cc_link_canceled(struct sig_pri_span *pri, long cc_id, int is_agent)
Definition: sig_pri.c:2849
#define LOG_ERROR
Definition: logger.h:155
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:2288
Connected Line/Party information.
Definition: channel.h:401
const ast_string_field name
Definition: channel.h:787
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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)
Definition: sig_pri.c:2120
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:447
unsigned int core_id
Definition: ccss.h:832
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static void sig_pri_aoc_request_from_pri(const struct pri_subcmd_aoc_request *aoc_request, struct sig_pri_chan *pvt, q931_call *call)
Definition: sig_pri.c:3176
char cid_subaddr[AST_MAX_EXTENSION]
Definition: sig_pri.h:241
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
char cid_num[AST_MAX_EXTENSION]
Definition: sig_pri.h:240
static void sig_pri_set_caller_id(struct sig_pri_chan *p)
Definition: sig_pri.c:262
static struct ast_cc_agent * sig_pri_find_cc_agent_by_cc_id(struct sig_pri_span *pri, long cc_id)
Definition: sig_pri.c:2531
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2396
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:9605
#define SIG_PRI_AOC_GRANT_E
Definition: sig_pri.h:68
static void sig_pri_aoc_d_from_pri(const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough)
Definition: sig_pri.c:3247
#define PRI_CHANNEL(p)
Definition: sig_pri.c:112
char cid_name[AST_MAX_EXTENSION]
Definition: sig_pri.h:242
int aoc_passthrough_flag
Definition: sig_pri.h:370
#define SIG_PRI_AOC_GRANT_D
Definition: sig_pri.h:67
struct pri * pri
Definition: sig_pri.h:481
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
int sig_pri_hangup ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 6464 of file sig_pri.c.

References sig_pri_chan::allocated, sig_pri_chan::alreadyhungup, sig_pri_chan::aoc_e, sig_pri_chan::aoc_s_request_invoke_id_valid, ast_atomic_fetchadd_int(), ast_debug, ast_log(), ast_strlen_zero(), sig_pri_chan::call, sig_pri_chan::call_level, sig_pri_chan::channel, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::exten, ast_channel::hangupcause, sig_pri_chan::holding_aoce, sig_pri_chan::is_call_waiting, LOG_WARNING, sig_pri_span::num_call_waiting_calls, sig_pri_chan::owner, pbx_builtin_getvar_helper(), sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::progress, SIG_PRI_CALL_LEVEL_IDLE, sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_set_outgoing(), sig_pri_span_devstate_changed(), ast_channel::tech_pvt, sig_pri_chan::user_tag, and sig_pri_chan::waiting_for_aoce.

Referenced by dahdi_hangup().

6465 {
6466  ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
6467  if (!ast->tech_pvt) {
6468  ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
6469  return 0;
6470  }
6471 
6472  sig_pri_set_outgoing(p, 0);
6473  sig_pri_set_digital(p, 0); /* push up to parent for EC*/
6474 #if defined(HAVE_PRI_CALL_WAITING)
6475  if (p->is_call_waiting) {
6476  p->is_call_waiting = 0;
6478  }
6479 #endif /* defined(HAVE_PRI_CALL_WAITING) */
6481  p->progress = 0;
6482  p->cid_num[0] = '\0';
6483  p->cid_subaddr[0] = '\0';
6484  p->cid_name[0] = '\0';
6485  p->user_tag[0] = '\0';
6486  p->exten[0] = '\0';
6487  sig_pri_set_dialing(p, 0);
6488 
6489  /* Make sure we really have a call */
6490  pri_grab(p, p->pri);
6491  if (p->call) {
6492 #if defined(SUPPORT_USERUSER)
6493  const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
6494 
6495  if (!ast_strlen_zero(useruser)) {
6496  pri_call_set_useruser(p->call, useruser);
6497  }
6498 #endif /* defined(SUPPORT_USERUSER) */
6499 
6500 #if defined(HAVE_PRI_AOC_EVENTS)
6501  if (p->holding_aoce) {
6502  pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
6503  }
6504 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
6505 
6506  if (p->alreadyhungup) {
6507  ast_debug(1, "Already hungup... Calling hangup once, and clearing call\n");
6508 
6509  pri_hangup(p->pri->pri, p->call, -1);
6510  p->call = NULL;
6511  } else {
6512  const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
6513  int icause = ast->hangupcause ? ast->hangupcause : -1;
6514 
6515  p->alreadyhungup = 1;
6516  if (!ast_strlen_zero(cause)) {
6517  if (atoi(cause)) {
6518  icause = atoi(cause);
6519  }
6520  }
6521  ast_debug(1,
6522  "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
6523  icause);
6524 
6525  pri_hangup(p->pri->pri, p->call, icause);
6526  }
6527  }
6528 #if defined(HAVE_PRI_AOC_EVENTS)
6530  p->holding_aoce = 0;
6531  p->waiting_for_aoce = 0;
6532 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
6533 
6534  p->allocated = 0;
6535  p->owner = NULL;
6536 
6538  pri_rel(p->pri);
6539  return 0;
6540 }
unsigned int alreadyhungup
Definition: sig_pri.h:266
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
q931_call * call
Definition: sig_pri.h:297
static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
Definition: sig_pri.c:179
unsigned int progress
Definition: sig_pri.h:268
struct ast_channel * owner
Definition: sig_pri.h:294
unsigned int aoc_s_request_invoke_id_valid
Definition: sig_pri.h:261
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
Definition: sig_pri.c:171
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
struct pri_subcmd_aoc_e aoc_e
Definition: sig_pri.h:259
unsigned int holding_aoce
Definition: sig_pri.h:263
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char exten[AST_MAX_EXTENSION]
Definition: sig_pri.h:246
char cid_subaddr[AST_MAX_EXTENSION]
Definition: sig_pri.h:241
char cid_num[AST_MAX_EXTENSION]
Definition: sig_pri.h:240
static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
Definition: sig_pri.c:164
unsigned int is_call_waiting
TRUE if this is a call waiting call.
Definition: sig_pri.h:287
int num_call_waiting_calls
Number of outstanding call waiting calls.
Definition: sig_pri.h:467
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
int hangupcause
Definition: channel.h:849
struct sig_pri_span * pri
Definition: sig_pri.h:296
char cid_name[AST_MAX_EXTENSION]
Definition: sig_pri.h:242
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:280
unsigned int waiting_for_aoce
Definition: sig_pri.h:262
struct pri * pri
Definition: sig_pri.h:481
int channel
Definition: sig_pri.h:234
int sig_pri_indicate ( struct sig_pri_chan p,
struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)

Definition at line 7092 of file sig_pri.c.

References ast_channel::_softhangup, ast_channel::_state, sig_pri_span::aoc_passthrough_flag, AST_AOC_D, ast_aoc_decode(), ast_aoc_destroy_decoded(), AST_AOC_E, ast_aoc_get_msg_type(), ast_aoc_get_termination_request(), AST_AOC_REQUEST, AST_AOC_S, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, sig_pri_chan::call, sig_pri_chan::call_level, ast_channel::connected, DAHDI_OVERLAPDIAL_INCOMING, sig_pri_chan::digital, ast_channel::hangupcause, ast_party_connected_line::id, LOG_DEBUG, sig_pri_chan::mohinterpret, ast_channel::name, sig_pri_chan::no_b_channel, sig_pri_chan::outgoing, sig_pri_span::overlapdial, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), pri_rel(), sig_pri_chan::priindication_oob, sig_pri_chan::prioffset, sig_pri_chan::progress, PVT_TO_CHANNEL(), sig_pri_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, sig_pri_aoc_s_from_ast(), SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_CONNECT, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_chan::waiting_for_aoce.

Referenced by dahdi_indicate().

7093 {
7094  int res = -1;
7095 
7096  switch (condition) {
7097  case AST_CONTROL_BUSY:
7098  if (p->priindication_oob || p->no_b_channel) {
7101  res = 0;
7102  break;
7103  }
7107  p->progress = 1;/* No need to send plain PROGRESS after this. */
7108  if (p->pri && p->pri->pri) {
7109  pri_grab(p, p->pri);
7110 #ifdef HAVE_PRI_PROG_W_CAUSE
7111  pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
7112 #else
7113  pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7114 #endif
7115  pri_rel(p->pri);
7116  }
7117  }
7118  break;
7119  case AST_CONTROL_RINGING:
7122  if (p->pri && p->pri->pri) {
7123  pri_grab(p, p->pri);
7124  pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
7125  p->no_b_channel || p->digital ? 0 : 1);
7126  pri_rel(p->pri);
7127  }
7128  }
7130  if (chan->_state != AST_STATE_UP) {
7131  if (chan->_state != AST_STATE_RING)
7133  }
7134  break;
7136  ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
7139  if (p->pri && p->pri->pri) {
7140  pri_grab(p, p->pri);
7141  pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 0);
7142  pri_rel(p->pri);
7143  }
7144  }
7145  /* don't continue in ast_indicate */
7146  res = 0;
7147  break;
7148  case AST_CONTROL_PROGRESS:
7149  ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
7150  sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
7152  && !p->no_b_channel) {
7153  p->progress = 1;/* No need to send plain PROGRESS again. */
7154  if (p->pri && p->pri->pri) {
7155  pri_grab(p, p->pri);
7156 #ifdef HAVE_PRI_PROG_W_CAUSE
7157  pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */
7158 #else
7159  pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7160 #endif
7161  pri_rel(p->pri);
7162  }
7163  }
7164  /* don't continue in ast_indicate */
7165  res = 0;
7166  break;
7168  /* If we are connected or if we support overlap dialing, wait for additional digits */
7170  res = 0;
7171  break;
7172  }
7173  /* Otherwise, treat as congestion */
7175  /* Falls through */
7177  if (p->priindication_oob || p->no_b_channel) {
7178  /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
7179  switch (chan->hangupcause) {
7180  case AST_CAUSE_USER_BUSY:
7182  case 0:/* Cause has not been set. */
7183  /* Supply a more appropriate cause. */
7185  break;
7186  default:
7187  break;
7188  }
7190  res = 0;
7191  break;
7192  }
7195  /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
7196  switch (chan->hangupcause) {
7197  case AST_CAUSE_USER_BUSY:
7199  case 0:/* Cause has not been set. */
7200  /* Supply a more appropriate cause. */
7202  break;
7203  default:
7204  break;
7205  }
7206  p->progress = 1;/* No need to send plain PROGRESS after this. */
7207  if (p->pri && p->pri->pri) {
7208  pri_grab(p, p->pri);
7209 #ifdef HAVE_PRI_PROG_W_CAUSE
7210  pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, chan->hangupcause);
7211 #else
7212  pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7213 #endif
7214  pri_rel(p->pri);
7215  }
7216  }
7217  break;
7218  case AST_CONTROL_HOLD:
7219  if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
7220  pri_grab(p, p->pri);
7221  res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
7222  pri_rel(p->pri);
7223  } else
7224  ast_moh_start(chan, data, p->mohinterpret);
7225  break;
7226  case AST_CONTROL_UNHOLD:
7227  if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
7228  pri_grab(p, p->pri);
7229  res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
7230  pri_rel(p->pri);
7231  } else
7232  ast_moh_stop(chan);
7233  break;
7234  case AST_CONTROL_SRCUPDATE:
7235  res = 0;
7236  break;
7237  case -1:
7238  res = sig_pri_play_tone(p, -1);
7239  break;
7241  ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name);
7242  if (p->pri) {
7243  struct pri_party_connected_line connected;
7244 
7245  pri_grab(p, p->pri);
7246  memset(&connected, 0, sizeof(connected));
7248 
7249  pri_connected_line_update(p->pri->pri, p->call, &connected);
7250  pri_rel(p->pri);
7251  }
7252  break;
7254  ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name);
7255  if (p->pri) {
7256  pri_grab(p, p->pri);
7257  sig_pri_redirecting_update(p, chan);
7258  pri_rel(p->pri);
7259  }
7260  break;
7261  case AST_CONTROL_AOC:
7262 #if defined(HAVE_PRI_AOC_EVENTS)
7263  {
7264  struct ast_aoc_decoded *decoded
7265  = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
7266  ast_debug(1, "Received AST_CONTROL_AOC on %s\n", chan->name);
7267  if (decoded && p->pri) {
7268  pri_grab(p, p->pri);
7269  switch (ast_aoc_get_msg_type(decoded)) {
7270  case AST_AOC_S:
7272  sig_pri_aoc_s_from_ast(p, decoded);
7273  }
7274  break;
7275  case AST_AOC_D:
7277  sig_pri_aoc_d_from_ast(p, decoded);
7278  }
7279  break;
7280  case AST_AOC_E:
7282  sig_pri_aoc_e_from_ast(p, decoded);
7283  }
7284  /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
7285  * will be set. A hangup is already occuring via a timeout during
7286  * this delay. Instead of waiting for that timeout to occur, go ahead
7287  * and initiate the softhangup since the delay is no longer necessary */
7288  if (p->waiting_for_aoce) {
7289  p->waiting_for_aoce = 0;
7291  "Received final AOC-E msg, continue with hangup on %s\n",
7292  chan->name);
7294  }
7295  break;
7296  case AST_AOC_REQUEST:
7297  /* We do not pass through AOC requests, So unless this
7298  * is an AOC termination request it will be ignored */
7299  if (ast_aoc_get_termination_request(decoded)) {
7300  pri_hangup(p->pri->pri, p->call, -1);
7301  }
7302  break;
7303  default:
7304  break;
7305  }
7306  pri_rel(p->pri);
7307  }
7308  ast_aoc_destroy_decoded(decoded);
7309  }
7310 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
7311  break;
7312  }
7313 
7314  return res;
7315 }
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:197
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
static int pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
Definition: sig_pri.c:342
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
unsigned int priindication_oob
Definition: sig_pri.h:228
static void sig_pri_aoc_s_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
Definition: sig_pri.c:3475
static int sig_pri_play_tone(struct sig_pri_chan *p, enum sig_pri_tone tone)
Definition: sig_pri.c:935
q931_call * call
Definition: sig_pri.h:297
unsigned int progress
Definition: sig_pri.h:268
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
#define SIG_PRI_AOC_GRANT_S
Definition: sig_pri.h:66
#define LOG_DEBUG
Definition: logger.h:122
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
Definition: sig_pri.c:3657
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
static void pri_rel(struct sig_pri_span *pri)
Definition: sig_pri.c:144
static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
Definition: sig_pri.c:149
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
Definition: aoc.c:318
static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
Definition: sig_pri.c:171
enum sig_pri_call_level call_level
Definition: sig_pri.h:300
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int overlapdial
Definition: sig_pri.h:358
static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct ast_party_id *ast_id)
Definition: sig_pri.c:869
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded)
get whether or not the AST_AOC_REQUEST message as a termination request.
Definition: aoc.c:948
int _softhangup
Definition: channel.h:832
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_channel *ast)
Definition: sig_pri.c:890
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
unsigned int digital
Definition: sig_pri.h:282
int hangupcause
Definition: channel.h:849
struct sig_pri_span * pri
Definition: sig_pri.h:296
Definition: aoc.h:64
Definition: aoc.h:66
static int connected
Definition: cdr_pgsql.c:57
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
Definition: aoc.c:761
int prioffset
Definition: sig_pri.h:303
#define SIG_PRI_AOC_GRANT_E
Definition: sig_pri.h:68
unsigned int outgoing
Definition: sig_pri.h:281
int aoc_passthrough_flag
Definition: sig_pri.h:370
static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
Definition: sig_pri.c:3574
#define SIG_PRI_AOC_GRANT_D
Definition: sig_pri.h:67
unsigned int waiting_for_aoce
Definition: sig_pri.h:262
struct pri * pri
Definition: sig_pri.h:481
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:232
Definition: aoc.h:65
static void sig_pri_init_config ( struct sig_pri_chan pvt,
struct sig_pri_span pri 
)
static

Definition at line 1740 of file sig_pri.c.

References ast_copy_string(), sig_pri_span::calls, sig_pri_span::ch_cfg, sig_pri_chan::chan_pvt, sig_pri_chan::context, sig_pri_span::context, sig_pri_chan::hidecallerid, sig_pri_span::hidecallerid, sig_pri_chan::hidecalleridname, sig_pri_span::hidecalleridname, sig_pri_chan::immediate, sig_pri_span::immediate, sig_pri_callback::init_config, sig_pri_chan::mohinterpret, sig_pri_span::mohinterpret, sig_pri_chan::priexclusive, sig_pri_span::priexclusive, sig_pri_chan::priindication_oob, sig_pri_span::priindication_oob, sig_pri_chan::stripmsd, sig_pri_span::stripmsd, sig_pri_chan::use_callerid, sig_pri_span::use_callerid, sig_pri_chan::use_callingpres, and sig_pri_span::use_callingpres.

Referenced by pri_dchannel(), and sig_pri_cw_available().

1741 {
1742  pvt->stripmsd = pri->ch_cfg.stripmsd;
1743  pvt->hidecallerid = pri->ch_cfg.hidecallerid;
1745  pvt->immediate = pri->ch_cfg.immediate;
1746  pvt->priexclusive = pri->ch_cfg.priexclusive;
1748  pvt->use_callerid = pri->ch_cfg.use_callerid;
1750  ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
1751  ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
1752 
1753  if (pri->calls->init_config) {
1754  pri->calls->init_config(pvt->chan_pvt, pri);
1755  }
1756 }
unsigned int priexclusive
Definition: sig_pri.h:227
unsigned int use_callingpres
Definition: sig_pri.h:230
unsigned int priindication_oob
Definition: sig_pri.h:228
unsigned int use_callerid
Definition: sig_pri.h:229
struct sig_pri_span::@120 ch_cfg
unsigned int hidecalleridname
Definition: sig_pri.h:452
void(*const init_config)(void *pvt, struct sig_pri_span *pri)
Definition: sig_pri.h:159
void * chan_pvt
Definition: sig_pri.h:312
int stripmsd
Definition: sig_pri.h:233
int stripmsd
Definition: sig_pri.h:450
struct sig_pri_callback * calls
Definition: sig_pri.h:497
unsigned int use_callingpres
Definition: sig_pri.h:457
unsigned int hidecallerid
Definition: sig_pri.h:451
unsigned int immediate
Definition: sig_pri.h:226
unsigned int hidecalleridname
Definition: sig_pri.h:225
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:459
unsigned int priindication_oob
Definition: sig_pri.h:455
unsigned int hidecallerid
Definition: sig_pri.h:224
unsigned int priexclusive
Definition: sig_pri.h:454
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
unsigned int use_callerid
Definition: sig_pri.h:456
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:458
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:231
unsigned int immediate
Definition: sig_pri.h:453
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:232
void sig_pri_init_pri ( struct sig_pri_span pri)

Definition at line 6451 of file sig_pri.c.

References ast_mutex_init, AST_PTHREADT_NULL, sig_pri_span::fds, sig_pri_span::lock, sig_pri_span::master, and SIG_PRI_NUM_DCHANS.

Referenced by dahdi_restart(), and load_module().

6452 {
6453  int i;
6454 
6455  memset(pri, 0, sizeof(*pri));
6456 
6457  ast_mutex_init(&pri->lock);
6458 
6459  pri->master = AST_PTHREADT_NULL;
6460  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
6461  pri->fds[i] = -1;
6462 }
ast_mutex_t lock
Definition: sig_pri.h:495
#define AST_PTHREADT_NULL
Definition: lock.h:65
pthread_t master
Definition: sig_pri.h:494
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
#define ast_mutex_init(pmutex)
Definition: lock.h:152
int fds[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:367
int sig_pri_is_alarm_ignored ( struct sig_pri_span pri)

Determine if layer 1 alarms are ignored.

Parameters
pChannel private pointer.
Returns
TRUE if the alarm is ignored.

Definition at line 7920 of file sig_pri.c.

References sig_pri_span::layer1_ignored.

Referenced by handle_alarms(), handle_clear_alarms(), my_handle_dchan_exception(), and sig_pri_set_alarm().

7921 {
7922  return pri->layer1_ignored;
7923 }
unsigned int layer1_ignored
Definition: sig_pri.h:394
int sig_pri_is_chan_available ( struct sig_pri_chan pvt)

Determine if a private channel structure is available.

Since
1.8
Parameters
pvtChannel to determine if available.
Returns
TRUE if the channel is available.

Definition at line 1160 of file sig_pri.c.

References sig_pri_chan::service_status, and sig_pri_is_chan_in_use().

Referenced by dahdi_pri_update_span_devstate(), pri_dchannel(), pri_find_empty_chan(), pri_find_empty_nobch(), pri_fixup_principle(), sig_pri_available_check(), sig_pri_cli_show_channels(), and sig_pri_handle_retrieve().

1161 {
1162  return !sig_pri_is_chan_in_use(pvt)
1163 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1164  /* And not out-of-service */
1165  && !pvt->service_status
1166 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
1167  ;
1168 }
unsigned service_status
Active SRVST_DBKEY out-of-service status value.
Definition: sig_pri.h:308
static int sig_pri_is_chan_in_use(struct sig_pri_chan *pvt)
Definition: sig_pri.c:1146
static int sig_pri_is_chan_in_use ( struct sig_pri_chan pvt)
static

Definition at line 1146 of file sig_pri.c.

References sig_pri_chan::allocated, sig_pri_chan::call, sig_pri_chan::inalarm, sig_pri_chan::owner, sig_pri_chan::resetting, and SIG_PRI_RESET_IDLE.

Referenced by pri_check_restart(), and sig_pri_is_chan_available().

1147 {
1148  return pvt->owner || pvt->call || pvt->allocated || pvt->inalarm
1149  || pvt->resetting != SIG_PRI_RESET_IDLE;
1150 }
q931_call * call
Definition: sig_pri.h:297
struct ast_channel * owner
Definition: sig_pri.h:294
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:302
The channel is not being RESTARTed.
Definition: sig_pri.h:106
unsigned int inalarm
Definition: sig_pri.h:265
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:280
static int sig_pri_is_cis_call ( int  channel)
static

Definition at line 3829 of file sig_pri.c.

References PRI_CIS_CALL.

Referenced by pri_dchannel().

3830 {
3831  return channel != -1 && (channel & PRI_CIS_CALL);
3832 }
#define PRI_CIS_CALL
Definition: sig_pri.c:115
static void sig_pri_kill_call ( struct sig_pri_span pri,
q931_call *  call,
int  cause 
)
static

Definition at line 1295 of file sig_pri.c.

References AST_CONTROL_HANGUP, sig_pri_chan::call, ast_channel::hangupcause, sig_pri_chan::owner, sig_pri_span::pri, pri_find_principle_by_call(), pri_queue_control(), sig_pri_span::pvts, sig_pri_lock_private(), sig_pri_span_devstate_changed(), and sig_pri_unlock_private().

Referenced by pri_find_fixup_principle().

1296 {
1297  int chanpos;
1298 
1299  chanpos = pri_find_principle_by_call(pri, call);
1300  if (chanpos < 0) {
1301  pri_hangup(pri->pri, call, cause);
1302  return;
1303  }
1304  sig_pri_lock_private(pri->pvts[chanpos]);
1305  if (!pri->pvts[chanpos]->owner) {
1306  pri_hangup(pri->pri, call, cause);
1307  pri->pvts[chanpos]->call = NULL;
1308  sig_pri_unlock_private(pri->pvts[chanpos]);
1310  return;
1311  }
1312  pri->pvts[chanpos]->owner->hangupcause = cause;
1313  pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
1314  sig_pri_unlock_private(pri->pvts[chanpos]);
1315 }
q931_call * call
Definition: sig_pri.h:297
struct ast_channel * owner
Definition: sig_pri.h:294
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
Definition: sig_pri.c:1239
static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
Definition: sig_pri.c:1265
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
int hangupcause
Definition: channel.h:849
struct pri * pri
Definition: sig_pri.h:481
int sig_pri_load ( const char *  cc_type_name)

Load the sig_pri submodule.

Since
1.8
Parameters
cc_type_nameCC type name to use when looking up agent/monitor.
Return values
0on success.
-1on error.

Definition at line 8730 of file sig_pri.c.

References ao2_container_alloc, sig_pri_cc_monitor_instance_cmp_fn(), sig_pri_cc_monitor_instance_hash_fn(), and sig_pri_cc_type_name.

Referenced by load_module().

8731 {
8732 #if defined(HAVE_PRI_CCSS)
8733  sig_pri_cc_type_name = cc_type_name;
8736  if (!sig_pri_cc_monitors) {
8737  return -1;
8738  }
8739 #endif /* defined(HAVE_PRI_CCSS) */
8740  return 0;
8741 }
static int sig_pri_cc_monitor_instance_hash_fn(const void *obj, const int flags)
Definition: sig_pri.c:8493
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
static int sig_pri_cc_monitor_instance_cmp_fn(void *obj, void *arg, int flags)
Definition: sig_pri.c:8513
static void sig_pri_lock_owner ( struct sig_pri_span pri,
int  chanpos 
)
static

Definition at line 1183 of file sig_pri.c.

References ast_channel_trylock, DEADLOCK_AVOIDANCE, sig_pri_span::lock, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_lock_private(), and sig_pri_unlock_private().

Referenced by pri_dchannel(), pri_fixup_principle(), pri_queue_frame(), sig_pri_attempt_transfer(), sig_pri_cc_generic_check(), sig_pri_cli_show_channels(), sig_pri_handle_hold(), sig_pri_handle_subcmds(), and sig_pri_send_aoce_termination_request().

1184 {
1185  for (;;) {
1186  if (!pri->pvts[chanpos]->owner) {
1187  /* There is no owner lock to get. */
1188  break;
1189  }
1190  if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) {
1191  /* We got the lock */
1192  break;
1193  }
1194 
1195  /* Avoid deadlock */
1196  sig_pri_unlock_private(pri->pvts[chanpos]);
1197  DEADLOCK_AVOIDANCE(&pri->lock);
1198  sig_pri_lock_private(pri->pvts[chanpos]);
1199  }
1200 }
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
struct ast_channel * owner
Definition: sig_pri.h:294
ast_mutex_t lock
Definition: sig_pri.h:495
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
static void sig_pri_unlock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:330
static void sig_pri_lock_private(struct sig_pri_chan *p)
Definition: sig_pri.c:336
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static void sig_pri_make_cc_dialstring ( struct sig_pri_chan p,
char *  buf,
size_t  buf_size 
)
static

Definition at line 217 of file sig_pri.c.

References ast_log(), sig_pri_chan::calls, sig_pri_chan::chan_pvt, LOG_ERROR, and sig_pri_callback::make_cc_dialstring.

Referenced by sig_pri_cc_available().

218 {
219  if (p->calls->make_cc_dialstring) {
220  p->calls->make_cc_dialstring(p->chan_pvt, buf, buf_size);
221  } else {
222  ast_log(LOG_ERROR, "make_cc_dialstring callback not defined\n");
223  buf[0] = '\0';
224  }
225 }
void(*const make_cc_dialstring)(void *pvt, char *buf, size_t buf_size)
Definition: sig_pri.h:161
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void sig_pri_mcid_event ( struct sig_pri_span pri,
const struct pri_subcmd_mcid_req *  mcid,
struct ast_channel owner 
)
static

Definition at line 2245 of file sig_pri.c.

References ast_free, ast_manager_event_multichan, ast_party_id_free(), ast_party_id_init(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_channel::connected, EVENT_FLAG_CALL, ast_party_connected_line::id, ast_channel::name, sig_pri_event_party_id(), sig_pri_party_id_convert(), and ast_channel::uniqueid.

Referenced by sig_pri_handle_subcmds().

2246 {
2247  struct ast_channel *chans[1];
2248  struct ast_str *msg;
2249  struct ast_party_id party;
2250 
2251  msg = ast_str_create(4096);
2252  if (!msg) {
2253  return;
2254  }
2255 
2256  if (owner) {
2257  /* The owner channel is present. */
2258  ast_str_append(&msg, 0, "Channel: %s\r\n", owner->name);
2259  ast_str_append(&msg, 0, "UniqueID: %s\r\n", owner->uniqueid);
2260 
2261  sig_pri_event_party_id(&msg, "CallerID", &owner->connected.id);
2262  } else {
2263  /*
2264  * Since we no longer have an owner channel,
2265  * we have to use the caller information supplied by libpri.
2266  */
2267  ast_party_id_init(&party);
2268  sig_pri_party_id_convert(&party, &mcid->originator, pri);
2269  sig_pri_event_party_id(&msg, "CallerID", &party);
2270  ast_party_id_free(&party);
2271  }
2272 
2273  /* Always use libpri's called party information. */
2274  ast_party_id_init(&party);
2275  sig_pri_party_id_convert(&party, &mcid->answerer, pri);
2276  sig_pri_event_party_id(&msg, "ConnectedID", &party);
2277  ast_party_id_free(&party);
2278 
2279  chans[0] = owner;
2280  ast_manager_event_multichan(EVENT_FLAG_CALL, "MCID", owner ? 1 : 0, chans, "%s",
2281  ast_str_buffer(msg));
2282  ast_free(msg);
2283 }
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)
Definition: sig_pri.c:2090
Information needed to identify an endpoint in a call.
Definition: channel.h:288
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
const ast_string_field uniqueid
Definition: channel.h:787
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define EVENT_FLAG_CALL
Definition: manager.h:72
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
Definition: channel.c:2141
static void sig_pri_event_party_id(struct ast_str **msg, const char *prefix, struct ast_party_id *party)
Definition: sig_pri.c:2178
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
const ast_string_field name
Definition: channel.h:787
#define ast_free(a)
Definition: astmm.h:97
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:2087
#define ast_manager_event_multichan(category, event, nchans, chans, contents,...)
Definition: manager.h:226
static int sig_pri_msn_match ( const char *  msn_patterns,
const char *  exten 
)
static

Definition at line 2144 of file sig_pri.c.

References ast_extension_match(), ast_strdupa, ast_strip(), and ast_strlen_zero().

Referenced by pri_dchannel().

2145 {
2146  char *pattern;
2147  char *msn_list;
2148  char *list_tail;
2149 
2150  msn_list = ast_strdupa(msn_patterns);
2151 
2152  list_tail = NULL;
2153  pattern = strtok_r(msn_list, ",", &list_tail);
2154  while (pattern) {
2155  pattern = ast_strip(pattern);
2156  if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) {
2157  /* Extension matched the pattern. */
2158  return 1;
2159  }
2160  pattern = strtok_r(NULL, ",", &list_tail);
2161  }
2162  /* Did not match any pattern in the list. */
2163  return 0;
2164 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
static void sig_pri_mwi_cache_update ( struct sig_pri_span pri)
static

Definition at line 7602 of file sig_pri.c.

References ARRAY_LEN, ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, sig_pri_mbox::context, sig_pri_span::mbox, sig_pri_mbox::number, sig_pri_send_mwi_indication(), and sig_pri_mbox::sub.

Referenced by sig_pri_start_pri().

7603 {
7604  int idx;
7605  int num_messages;
7606  struct ast_event *event;
7607 
7608  for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
7609  if (!pri->mbox[idx].sub) {
7610  /* There are no more mailboxes on this span. */
7611  break;
7612  }
7613 
7618  if (!event) {
7619  /* No cached event for this mailbox. */
7620  continue;
7621  }
7622  num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
7623  sig_pri_send_mwi_indication(pri, pri->mbox[idx].number, pri->mbox[idx].context,
7624  num_messages);
7625  ast_event_destroy(event);
7626  }
7627 }
const char * context
Mailbox context.
Definition: sig_pri.h:350
An event.
Definition: event.c:85
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void sig_pri_send_mwi_indication(struct sig_pri_span *pri, const char *mbox_number, const char *mbox_context, int num_messages)
Definition: sig_pri.c:7542
struct ast_event * ast_event_get_cached(enum ast_event_type,...)
Retrieve an event from the cache.
Definition: event.c:1342
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
const char * number
Mailbox number.
Definition: sig_pri.h:348
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
struct sig_pri_mbox mbox[SIG_PRI_MAX_MWI_MAILBOXES]
Active MWI mailboxes.
Definition: sig_pri.h:414
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
void ast_event_destroy(struct ast_event *event)
Destroy an event.
Definition: event.c:1314
struct ast_event_sub * sub
MWI mailbox event subscription.
Definition: sig_pri.h:346
Mailbox name.
Definition: event_defs.h:83
static void sig_pri_mwi_event_cb ( const struct ast_event event,
void *  userdata 
)
static

Definition at line 7572 of file sig_pri.c.

References ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, ast_strlen_zero(), sig_pri_span::pri, and sig_pri_send_mwi_indication().

Referenced by sig_pri_start_pri().

7573 {
7574  struct sig_pri_span *pri = userdata;
7575  const char *mbox_context;
7576  const char *mbox_number;
7577  int num_messages;
7578 
7579  mbox_number = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
7580  if (ast_strlen_zero(mbox_number)) {
7581  return;
7582  }
7583  mbox_context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
7584  if (ast_strlen_zero(mbox_context)) {
7585  return;
7586  }
7587  num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
7588  sig_pri_send_mwi_indication(pri, mbox_number, mbox_context, num_messages);
7589 }
static void sig_pri_send_mwi_indication(struct sig_pri_span *pri, const char *mbox_number, const char *mbox_context, int num_messages)
Definition: sig_pri.c:7542
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
struct pri * pri
Definition: sig_pri.h:481
Mailbox name.
Definition: event_defs.h:83
static struct ast_channel* sig_pri_new_ast_channel ( struct sig_pri_chan p,
int  state,
enum sig_pri_law  law,
int  transfercapability,
char *  exten,
const struct ast_channel requestor 
)
static

Definition at line 943 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 pri_dchannel(), and sig_pri_request().

944 {
945  struct ast_channel *c;
946 
947  if (p->calls->new_ast_channel) {
948  c = p->calls->new_ast_channel(p->chan_pvt, state, law, exten, requestor);
949  } else {
950  return NULL;
951  }
952  if (!c) {
953  return NULL;
954  }
955 
956  if (!p->owner)
957  p->owner = c;
958  p->isidlecall = 0;
959  p->alreadyhungup = 0;
961  pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY",
964  sig_pri_set_digital(p, 1);
965  }
966  if (p->pri) {
967  ast_mutex_lock(&p->pri->lock);
969  ast_mutex_unlock(&p->pri->lock);
970  }
971 
972  return c;
973 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
unsigned int alreadyhungup
Definition: sig_pri.h:266
struct ast_channel * owner
Definition: sig_pri.h:294
struct sig_pri_callback * calls
Definition: sig_pri.h:311
unsigned int isidlecall
Definition: sig_pri.h:267
#define ast_mutex_lock(a)
Definition: lock.h:155
unsigned short transfercapability
Definition: channel.h:863
void * chan_pvt
Definition: sig_pri.h:312
static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
Definition: sig_pri.c:246
ast_mutex_t lock
Definition: sig_pri.h:495
static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
Definition: sig_pri.c:171
struct ast_channel *(*const new_ast_channel)(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *chan)
Definition: sig_pri.h:144
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:1041
struct sig_pri_span * pri
Definition: sig_pri.h:296
#define AST_TRANS_CAP_DIGITAL
Definition: transcap.h:35
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void sig_pri_open_media ( struct sig_pri_chan p)
static

Definition at line 984 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_dchannel(), pri_fixup_principle(), sig_pri_answer(), and sig_pri_dial_complete().

985 {
986  if (p->no_b_channel) {
987  return;
988  }
989 
990  if (p->calls->open_media) {
991  p->calls->open_media(p->chan_pvt);
992  }
993 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
Definition: sig_pri.h:284
void * chan_pvt
Definition: sig_pri.h:312
void(*const open_media)(void *pvt)
Definition: sig_pri.h:165
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 2090 of file sig_pri.c.

References ast_party_id::name, ast_party_id::number, sig_pri_party_name_convert(), sig_pri_party_number_convert(), sig_pri_set_subaddress(), and ast_party_id::subaddress.

Referenced by sig_pri_handle_subcmds(), sig_pri_mcid_event(), and sig_pri_redirecting_convert().

2091 {
2092  if (pri_id->name.valid) {
2093  sig_pri_party_name_convert(&ast_id->name, &pri_id->name);
2094  }
2095  if (pri_id->number.valid) {
2096  sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri);
2097  }
2098 #if defined(HAVE_PRI_SUBADDR)
2099  if (pri_id->subaddress.valid) {
2100  sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress);
2101  }
2102 #endif /* defined(HAVE_PRI_SUBADDR) */
2103 }
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
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)
Definition: sig_pri.c:2064
static void sig_pri_set_subaddress(struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress)
Definition: sig_pri.c:650
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
static void sig_pri_party_name_convert(struct ast_party_name *ast_name, const struct pri_party_name *pri_name)
Definition: sig_pri.c:2042
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
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 869 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().

870 {
871  sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name);
872  sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number);
873 #if defined(HAVE_PRI_SUBADDR)
874  sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress);
875 #endif /* defined(HAVE_PRI_SUBADDR) */
876 }
static void sig_pri_party_name_from_ast(struct pri_party_name *pri_name, const struct ast_party_name *ast_name)
Definition: sig_pri.c:819
static void sig_pri_party_subaddress_from_ast(struct pri_party_subaddress *pri_subaddress, const struct ast_party_subaddress *ast_subaddress)
Definition: sig_pri.c:773
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
static void sig_pri_party_number_from_ast(struct pri_party_number *pri_number, const struct ast_party_number *ast_number)
Definition: sig_pri.c:844
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void sig_pri_party_name_convert ( struct ast_party_name ast_name,
const struct pri_party_name *  pri_name 
)
static

Definition at line 2042 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().

2043 {
2044  ast_name->str = ast_strdup(pri_name->str);
2045  ast_name->char_set = pri_to_ast_char_set(pri_name->char_set);
2046  ast_name->presentation = pri_to_ast_presentation(pri_name->presentation);
2047  ast_name->valid = 1;
2048 }
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:227
#define ast_strdup(a)
Definition: astmm.h:109
int char_set
Character set the name is using.
Definition: channel.h:222
char * str
Subscriber name (Malloced)
Definition: channel.h:214
static enum AST_PARTY_CHAR_SET pri_to_ast_char_set(int pri_char_set)
Definition: sig_pri.c:547
static int pri_to_ast_presentation(int pri_presentation)
Definition: sig_pri.c:437
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
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 819 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().

820 {
821  if (!ast_name->valid) {
822  return;
823  }
824  pri_name->valid = 1;
825  pri_name->presentation = ast_to_pri_presentation(ast_name->presentation);
826  pri_name->char_set = ast_to_pri_char_set(ast_name->char_set);
827  if (!ast_strlen_zero(ast_name->str)) {
828  ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str));
829  }
830 }
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:227
static int ast_to_pri_presentation(int ast_presentation)
Definition: sig_pri.c:492
static int ast_to_pri_char_set(enum AST_PARTY_CHAR_SET ast_char_set)
Definition: sig_pri.c:597
int char_set
Character set the name is using.
Definition: channel.h:222
char * str
Subscriber name (Malloced)
Definition: channel.h:214
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
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 2064 of file sig_pri.c.

References apply_plan_to_existing_number(), AST_MAX_EXTENSION, ast_strdup, ast_party_number::plan, ast_party_number::presentation, pri_to_ast_presentation(), ast_party_number::str, and ast_party_number::valid.

Referenced by sig_pri_party_id_convert().

2065 {
2066  char number[AST_MAX_EXTENSION];
2067 
2068  apply_plan_to_existing_number(number, sizeof(number), pri, pri_number->str,
2069  pri_number->plan);
2070  ast_number->str = ast_strdup(number);
2071  ast_number->plan = pri_number->plan;
2072  ast_number->presentation = pri_to_ast_presentation(pri_number->presentation);
2073  ast_number->valid = 1;
2074 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
#define ast_strdup(a)
Definition: astmm.h:109
Number structure.
Definition: app_followme.c:109
#define AST_MAX_EXTENSION
Definition: channel.h:135
static void apply_plan_to_existing_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
Definition: sig_pri.c:1670
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static int pri_to_ast_presentation(int pri_presentation)
Definition: sig_pri.c:437
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
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 844 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().

845 {
846  if (!ast_number->valid) {
847  return;
848  }
849  pri_number->valid = 1;
850  pri_number->presentation = ast_to_pri_presentation(ast_number->presentation);
851  pri_number->plan = ast_number->plan;
852  if (!ast_strlen_zero(ast_number->str)) {
853  ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str));
854  }
855 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
static int ast_to_pri_presentation(int ast_presentation)
Definition: sig_pri.c:492
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
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 773 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().

774 {
775  if (ast_subaddress->valid && !ast_strlen_zero(ast_subaddress->str)) {
776  pri_subaddress->type = ast_subaddress->type;
777  if (!ast_subaddress->type) {
778  /* 0 = NSAP */
779  ast_copy_string((char *) pri_subaddress->data, ast_subaddress->str,
780  sizeof(pri_subaddress->data));
781  pri_subaddress->length = strlen((char *) pri_subaddress->data);
782  pri_subaddress->odd_even_indicator = 0;
783  pri_subaddress->valid = 1;
784  } else {
785  /* 2 = User Specified */
786  /*
787  * Copy HexString to packed HexData,
788  * if odd length then right pad trailing byte with 0
789  */
790  int length = ast_pri_pack_hex_string(pri_subaddress->data,
791  ast_subaddress->str, sizeof(pri_subaddress->data));
792 
793  pri_subaddress->length = length; /* packed data length */
794 
795  length = strlen(ast_subaddress->str);
796  if (length > 2 * sizeof(pri_subaddress->data)) {
797  pri_subaddress->odd_even_indicator = 0;
798  } else {
799  pri_subaddress->odd_even_indicator = (length & 1);
800  }
801  pri_subaddress->valid = 1;
802  }
803  }
804 }
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
char * str
Malloced subaddress string.
Definition: channel.h:263
static int ast_pri_pack_hex_string(unsigned char *dst, char *src, int maxlen)
Definition: sig_pri.c:735
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int type
Q.931 subaddress type.
Definition: channel.h:270
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int sig_pri_play_tone ( struct sig_pri_chan p,
enum sig_pri_tone  tone 
)
static

Definition at line 935 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().

936 {
937  if (p->calls->play_tone)
938  return p->calls->play_tone(p->chan_pvt, tone);
939  else
940  return -1;
941 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
int(*const play_tone)(void *pvt, enum sig_pri_tone tone)
Definition: sig_pri.h:138
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 2120 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().

2124 {
2125  ast_party_redirecting_set_init(ast_redirecting, ast_guide);
2126 
2127  sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri);
2128  sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri);
2129  ast_redirecting->count = pri_redirecting->count;
2130  ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason);
2131 }
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)
Definition: sig_pri.c:2090
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
int count
Number of times the call was redirected.
Definition: channel.h:455
static enum AST_REDIRECTING_REASON pri_to_ast_reason(int pri_reason)
Definition: sig_pri.c:367
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
Definition: channel.c:2380
int reason
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:458
static void sig_pri_redirecting_update ( struct sig_pri_chan pvt,
struct ast_channel ast 
)
static
Todo:
XXX Original called data can be put in a channel data store that is inherited.

Definition at line 890 of file sig_pri.c.

References ast_to_pri_reason(), sig_pri_chan::call, ast_party_redirecting::count, ast_party_redirecting::from, sig_pri_chan::pri, sig_pri_span::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().

891 {
892  struct pri_party_redirecting pri_redirecting;
893 
894 /*! \todo XXX Original called data can be put in a channel data store that is inherited. */
895 
896  memset(&pri_redirecting, 0, sizeof(pri_redirecting));
897  sig_pri_party_id_from_ast(&pri_redirecting.from, &ast->redirecting.from);
898  sig_pri_party_id_from_ast(&pri_redirecting.to, &ast->redirecting.to);
899  pri_redirecting.count = ast->redirecting.count;
900  pri_redirecting.reason = ast_to_pri_reason(ast->redirecting.reason);
901 
902  pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting);
903 }
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
static int ast_to_pri_reason(enum AST_REDIRECTING_REASON ast_reason)
Definition: sig_pri.c:402
q931_call * call
Definition: sig_pri.h:297
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct ast_party_id *ast_id)
Definition: sig_pri.c:869
int count
Number of times the call was redirected.
Definition: channel.h:455
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
struct sig_pri_span * pri
Definition: sig_pri.h:296
int reason
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:458
struct pri * pri
Definition: sig_pri.h:481
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 1013 of file sig_pri.c.

References ast_log(), AST_STATE_RESERVED, sig_pri_chan::channel, sig_pri_chan::exten, LOG_DEBUG, sig_pri_new_ast_channel(), and sig_pri_set_outgoing().

Referenced by dahdi_request(), and pri_dchannel().

1014 {
1015  struct ast_channel *ast;
1016 
1017  ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
1018 
1019  sig_pri_set_outgoing(p, 1);
1020  ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
1021  if (!ast) {
1022  sig_pri_set_outgoing(p, 0);
1023  }
1024  return ast;
1025 }
Main Channel structure associated with a channel.
Definition: channel.h:742
static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
Definition: sig_pri.c:179
unsigned short transfercapability
Definition: channel.h:863
#define LOG_DEBUG
Definition: logger.h:122
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char exten[AST_MAX_EXTENSION]
Definition: sig_pri.h:246
static struct ast_channel * sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, enum sig_pri_law law, int transfercapability, char *exten, const struct ast_channel *requestor)
Definition: sig_pri.c:943
int channel
Definition: sig_pri.h:234
static void sig_pri_send_aoce_termination_request ( struct sig_pri_span pri,
int  chanpos,
unsigned int  ms 
)
static

Definition at line 3774 of file sig_pri.c.

References ast_aoc_create(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), AST_AOC_REQUEST, AST_AOC_REQUEST_E, ast_aoc_set_termination_request(), ast_channel_setwhentohangup_tv(), ast_channel_unlock, AST_CONTROL_AOC, ast_log(), ast_queue_control_data(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), LOG_DEBUG, ast_channel::name, sig_pri_chan::owner, sig_pri_span::pvts, sig_pri_lock_owner(), and sig_pri_chan::waiting_for_aoce.

Referenced by pri_dchannel().

3775 {
3776  struct sig_pri_chan *pvt;
3777  struct ast_aoc_decoded *decoded = NULL;
3778  struct ast_aoc_encoded *encoded = NULL;
3779  size_t encoded_size;
3780  struct timeval whentohangup = { 0, };
3781 
3782  sig_pri_lock_owner(pri, chanpos);
3783  pvt = pri->pvts[chanpos];
3784  if (!pvt->owner) {
3785  return;
3786  }
3787 
3788  if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
3790  goto cleanup_termination_request;
3791  }
3792 
3794 
3795  if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
3797  goto cleanup_termination_request;
3798  }
3799 
3800  /* convert ms to timeval */
3801  whentohangup.tv_usec = (ms % 1000) * 1000;
3802  whentohangup.tv_sec = ms / 1000;
3803 
3804  if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) {
3806  goto cleanup_termination_request;
3807  }
3808 
3809  pvt->waiting_for_aoce = 1;
3810  ast_channel_setwhentohangup_tv(pvt->owner, whentohangup);
3811  ast_log(LOG_DEBUG, "Delaying hangup on %s for aoc-e msg\n", pvt->owner->name);
3812 
3813 cleanup_termination_request:
3814  ast_channel_unlock(pvt->owner);
3815  ast_aoc_destroy_decoded(decoded);
3816  ast_aoc_destroy_encoded(encoded);
3817 }
int ast_aoc_set_termination_request(struct ast_aoc_decoded *decoded)
Mark the AST_AOC_REQUEST message as a termination request.
Definition: aoc.c:938
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:871
struct ast_channel * owner
Definition: sig_pri.h:294
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
#define LOG_DEBUG
Definition: logger.h:122
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:519
const ast_string_field name
Definition: channel.h:787
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:145
static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
Definition: sig_pri.c:1183
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1608
unsigned int waiting_for_aoce
Definition: sig_pri.h:262
static void sig_pri_send_mwi_indication ( struct sig_pri_span pri,
const char *  mbox_number,
const char *  mbox_context,
int  num_messages 
)
static

Definition at line 7542 of file sig_pri.c.

References ast_copy_string(), ast_debug, ast_mutex_lock, ast_mutex_unlock, sig_pri_span::lock, and sig_pri_span::pri.

Referenced by sig_pri_mwi_cache_update(), and sig_pri_mwi_event_cb().

7543 {
7544  struct pri_party_id mailbox;
7545 
7546  ast_debug(1, "Send MWI indication for %s@%s num_messages:%d\n", mbox_number,
7547  mbox_context, num_messages);
7548 
7549  memset(&mailbox, 0, sizeof(mailbox));
7550  mailbox.number.valid = 1;
7551  mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
7552  mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
7553  ast_copy_string(mailbox.number.str, mbox_number, sizeof(mailbox.number.str));
7554 
7555  ast_mutex_lock(&pri->lock);
7556  pri_mwi_indicate(pri->pri, &mailbox, 1 /* speech */, num_messages, NULL, NULL, -1, 0);
7557  ast_mutex_unlock(&pri->lock);
7558 }
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: sig_pri.h:495
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct pri * pri
Definition: sig_pri.h:481
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define ast_mutex_unlock(a)
Definition: lock.h:156
void sig_pri_set_alarm ( struct sig_pri_chan p,
int  in_alarm 
)

Definition at line 187 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::inalarm, sig_pri_chan::pri, sig_pri_chan::resetting, sig_pri_callback::set_alarm, sig_pri_is_alarm_ignored(), and SIG_PRI_RESET_IDLE.

Referenced by mkintf(), pri_dchannel(), and sig_pri_chan_alarm_notify().

188 {
189  if (sig_pri_is_alarm_ignored(p->pri)) {
190  /* Always set not in alarm */
191  in_alarm = 0;
192  }
193 
194  /*
195  * Clear the channel restart state when the channel alarm
196  * changes to prevent the state from getting stuck when the link
197  * goes down.
198  */
200 
201  p->inalarm = in_alarm;
202  if (p->calls->set_alarm) {
203  p->calls->set_alarm(p->chan_pvt, in_alarm);
204  }
205 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:302
The channel is not being RESTARTed.
Definition: sig_pri.h:106
unsigned int inalarm
Definition: sig_pri.h:265
void * chan_pvt
Definition: sig_pri.h:312
void(*const set_alarm)(void *pvt, int in_alarm)
Definition: sig_pri.h:150
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
Determine if layer 1 alarms are ignored.
Definition: sig_pri.c:7920
struct sig_pri_span * pri
Definition: sig_pri.h:296
static void sig_pri_set_caller_id ( struct sig_pri_chan p)
static

Definition at line 262 of file sig_pri.c.

References ast_party_caller::ani, ast_party_caller::ani2, ast_party_caller_init(), ast_strlen_zero(), sig_pri_chan::callingpres, sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::cid_ani, sig_pri_chan::cid_ani2, sig_pri_chan::cid_name, sig_pri_chan::cid_num, sig_pri_chan::cid_subaddr, sig_pri_chan::cid_ton, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_number::plan, ast_party_name::presentation, ast_party_number::presentation, sig_pri_callback::set_callerid, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_id::tag, sig_pri_chan::user_tag, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

Referenced by pri_dchannel(), and sig_pri_handle_subcmds().

263 {
264  struct ast_party_caller caller;
265 
266  if (p->calls->set_callerid) {
267  ast_party_caller_init(&caller);
268 
269  caller.id.name.str = p->cid_name;
270  caller.id.name.presentation = p->callingpres;
271  caller.id.name.valid = 1;
272 
273  caller.id.number.str = p->cid_num;
274  caller.id.number.plan = p->cid_ton;
275  caller.id.number.presentation = p->callingpres;
276  caller.id.number.valid = 1;
277 
278  if (!ast_strlen_zero(p->cid_subaddr)) {
279  caller.id.subaddress.valid = 1;
280  //caller.id.subaddress.type = 0;/* nsap */
281  //caller.id.subaddress.odd_even_indicator = 0;
282  caller.id.subaddress.str = p->cid_subaddr;
283  }
284  caller.id.tag = p->user_tag;
285 
286  caller.ani.number.str = p->cid_ani;
287  //caller.ani.number.plan = p->xxx;
288  //caller.ani.number.presentation = p->xxx;
289  caller.ani.number.valid = 1;
290 
291  caller.ani2 = p->cid_ani2;
292  p->calls->set_callerid(p->chan_pvt, &caller);
293  }
294 }
int cid_ton
Definition: sig_pri.h:238
int callingpres
Definition: sig_pri.h:239
struct sig_pri_callback * calls
Definition: sig_pri.h:311
char cid_ani[AST_MAX_EXTENSION]
Definition: sig_pri.h:243
void * chan_pvt
Definition: sig_pri.h:312
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Caller Party information.
Definition: channel.h:368
char cid_subaddr[AST_MAX_EXTENSION]
Definition: sig_pri.h:241
char cid_num[AST_MAX_EXTENSION]
Definition: sig_pri.h:240
int cid_ani2
Definition: sig_pri.h:237
char user_tag[AST_MAX_EXTENSION]
User tag for party id&#39;s sent from this device driver.
Definition: sig_pri.h:245
void(*const set_callerid)(void *pvt, const struct ast_party_caller *caller)
Definition: sig_pri.h:154
char cid_name[AST_MAX_EXTENSION]
Definition: sig_pri.h:242
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:2269
static void sig_pri_set_dialing ( struct sig_pri_chan p,
int  is_dialing 
)
static

Definition at line 164 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_dialing.

Referenced by pri_dchannel(), sig_pri_answer(), sig_pri_call(), sig_pri_dial_complete(), and sig_pri_hangup().

165 {
166  if (p->calls->set_dialing) {
167  p->calls->set_dialing(p->chan_pvt, is_dialing);
168  }
169 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const set_dialing)(void *pvt, int is_dialing)
Definition: sig_pri.h:151
static void sig_pri_set_digital ( struct sig_pri_chan p,
int  is_digital 
)
static

Definition at line 171 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::digital, and sig_pri_callback::set_digital.

Referenced by sig_pri_call(), sig_pri_hangup(), sig_pri_indicate(), and sig_pri_new_ast_channel().

172 {
173  p->digital = is_digital;
174  if (p->calls->set_digital) {
175  p->calls->set_digital(p->chan_pvt, is_digital);
176  }
177 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const set_digital)(void *pvt, int is_digital)
Definition: sig_pri.h:152
unsigned int digital
Definition: sig_pri.h:282
static void sig_pri_set_dnid ( struct sig_pri_chan p,
const char *  dnid 
)
static

Definition at line 306 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_dnid.

Referenced by pri_dchannel().

307 {
308  if (p->calls->set_dnid) {
309  p->calls->set_dnid(p->chan_pvt, dnid);
310  }
311 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
void(*const set_dnid)(void *pvt, const char *dnid)
Definition: sig_pri.h:155
static int sig_pri_set_echocanceller ( struct sig_pri_chan p,
int  enable 
)
static

Definition at line 921 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_echocanceller.

Referenced by pri_dchannel(), pri_ss_thread(), and sig_pri_dial_complete().

922 {
923  if (p->calls->set_echocanceller)
924  return p->calls->set_echocanceller(p->chan_pvt, enable);
925  else
926  return -1;
927 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
int(*const set_echocanceller)(void *pvt, int enable)
Definition: sig_pri.h:140
static void sig_pri_set_outgoing ( struct sig_pri_chan p,
int  is_outgoing 
)
static

Definition at line 179 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, sig_pri_chan::outgoing, and sig_pri_callback::set_outgoing.

Referenced by sig_pri_call(), sig_pri_hangup(), and sig_pri_request().

180 {
181  p->outgoing = is_outgoing;
182  if (p->calls->set_outgoing) {
183  p->calls->set_outgoing(p->chan_pvt, is_outgoing);
184  }
185 }
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
unsigned int outgoing
Definition: sig_pri.h:281
void(*const set_outgoing)(void *pvt, int is_outgoing)
Definition: sig_pri.h:153
static void sig_pri_set_rdnis ( struct sig_pri_chan p,
const char *  rdnis 
)
static

Definition at line 323 of file sig_pri.c.

References sig_pri_chan::calls, sig_pri_chan::chan_pvt, and sig_pri_callback::set_rdnis.

Referenced by pri_dchannel().

324 {
325  if (p->calls->set_rdnis) {
326  p->calls->set_rdnis(p->chan_pvt, rdnis);
327  }
328 }
void(*const set_rdnis)(void *pvt, const char *rdnis)
Definition: sig_pri.h:156
struct sig_pri_callback * calls
Definition: sig_pri.h:311
void * chan_pvt
Definition: sig_pri.h:312
static void sig_pri_set_subaddress ( struct ast_party_subaddress ast_subaddress,
const struct pri_party_subaddress *  pri_subaddress 
)
static

Definition at line 650 of file sig_pri.c.

References ast_free, ast_malloc, ast_party_subaddress_init(), ast_strdup, len(), ast_party_subaddress::odd_even_indicator, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by pri_dchannel(), and sig_pri_party_id_convert().

651 {
652  ast_free(ast_subaddress->str);
653  if (pri_subaddress->length <= 0) {
654  ast_party_subaddress_init(ast_subaddress);
655  return;
656  }
657 
658  if (!pri_subaddress->type) {
659  /* NSAP */
660  ast_subaddress->str = ast_strdup((char *) pri_subaddress->data);
661  } else {
662  char *cnum;
663  char *ptr;
664  int x;
665  int len;
666 
667  /* User Specified */
668  cnum = ast_malloc(2 * pri_subaddress->length + 1);
669  if (!cnum) {
670  ast_party_subaddress_init(ast_subaddress);
671  return;
672  }
673 
674  ptr = cnum;
675  len = pri_subaddress->length - 1; /* -1 account for zero based indexing */
676  for (x = 0; x < len; ++x) {
677  ptr += sprintf(ptr, "%02x", (unsigned)pri_subaddress->data[x]);
678  }
679 
680  if (pri_subaddress->odd_even_indicator) {
681  /* ODD */
682  sprintf(ptr, "%01x", (unsigned)((pri_subaddress->data[len]) >> 4));
683  } else {
684  /* EVEN */
685  sprintf(ptr, "%02x", (unsigned)pri_subaddress->data[len]);
686  }
687  ast_subaddress->str = cnum;
688  }
689  ast_subaddress->type = pri_subaddress->type;
690  ast_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator;
691  ast_subaddress->valid = 1;
692 }
#define ast_strdup(a)
Definition: astmm.h:109
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
char * str
Malloced subaddress string.
Definition: channel.h:263
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:276
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:97
int type
Q.931 subaddress type.
Definition: channel.h:270
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
Definition: channel.c:2034
#define ast_malloc(a)
Definition: astmm.h:91
static void sig_pri_sort_pri_chans ( struct sig_pri_span pri)
static

Definition at line 7698 of file sig_pri.c.

References sig_pri_span::numchans, sig_pri_span::pvts, and sig_pri_cmp_pri_chans().

Referenced by sig_pri_start_pri().

7699 {
7700  qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans);
7701 }
static int sig_pri_cmp_pri_chans(const void *left, const void *right)
Definition: sig_pri.c:7665
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
Definition: sig_pri.h:493
int numchans
Definition: sig_pri.h:492
static void sig_pri_span_devstate_changed ( struct sig_pri_span pri)
static

Definition at line 246 of file sig_pri.c.

References sig_pri_span::calls, and sig_pri_callback::update_span_devstate.

Referenced by pri_check_restart(), pri_dchannel(), pri_ss_thread(), sig_pri_chan_alarm_notify(), sig_pri_handle_hold(), sig_pri_handle_retrieve(), sig_pri_hangup(), sig_pri_kill_call(), and sig_pri_new_ast_channel().

247 {
248  if (pri->calls->update_span_devstate) {
249  pri->calls->update_span_devstate(pri);
250  }
251 }
struct sig_pri_callback * calls
Definition: sig_pri.h:497
void(*const update_span_devstate)(struct sig_pri_span *pri)
Definition: sig_pri.h:162
int sig_pri_start_pri ( struct sig_pri_span pri)

Definition at line 7703 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_pthread_create_background, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strip(), ast_strlen_zero(), sig_pri_span::cc_ptmp_recall_mode, sig_pri_span::cc_qsig_signaling_link_req, sig_pri_span::cc_qsig_signaling_link_rsp, sig_pri_mbox::context, DAHDI_CHAN_MAPPING_LOGICAL, DAHDI_OVERLAPDIAL_OUTGOING, sig_pri_span::dchans, sig_pri_span::enable_service_message_support, errno, sig_pri_span::fds, sig_pri_span::inbanddisconnect, sig_pri_span::l2_persistence, sig_pri_span::lock, LOG_ERROR, sig_pri_span::master, sig_pri_span::mbox, sig_pri_span::mwi_mailboxes, sig_pri_span::nodetype, sig_pri_span::nsf, sig_pri_mbox::number, sig_pri_span::overlapdial, sig_pri_span::pri, pri_dchannel(), sig_pri_span::pritimers, sig_pri_span::qsigchannelmapping, sig_pri_span::resetpos, sig_pri_span::sig, SIG_BRI, SIG_BRI_PTMP, sig_pri_cc_type_name, SIG_PRI_DEBUG_DEFAULT, sig_pri_mwi_cache_update(), sig_pri_mwi_event_cb(), SIG_PRI_NUM_DCHANS, sig_pri_sort_pri_chans(), sig_pri_span::span, strsep(), sig_pri_mbox::sub, and sig_pri_span::switchtype.

Referenced by setup_dahdi_int().

7704 {
7705  int x;
7706  int i;
7707 #if defined(HAVE_PRI_MWI)
7708  char *saveptr;
7709  char *mbox_number;
7710  char *mbox_context;
7711  struct ast_str *mwi_description = ast_str_alloca(64);
7712 #endif /* defined(HAVE_PRI_MWI) */
7713 
7714 #if defined(HAVE_PRI_MWI)
7715  /* Prepare the mbox[] for use. */
7716  for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
7717  if (pri->mbox[i].sub) {
7718  pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
7719  }
7720  }
7721 #endif /* defined(HAVE_PRI_MWI) */
7722 
7723  ast_mutex_init(&pri->lock);
7725 
7726 #if defined(HAVE_PRI_MWI)
7727  /*
7728  * Split the mwi_mailboxes configuration string into the mbox[]:
7729  * mailbox_number[@context]{,mailbox_number[@context]}
7730  */
7731  i = 0;
7732  saveptr = pri->mwi_mailboxes;
7733  while (i < ARRAY_LEN(pri->mbox)) {
7734  mbox_number = strsep(&saveptr, ",");
7735  if (!mbox_number) {
7736  break;
7737  }
7738  /* Split the mailbox_number and context */
7739  mbox_context = strchr(mbox_number, '@');
7740  if (mbox_context) {
7741  *mbox_context++ = '\0';
7742  mbox_context = ast_strip(mbox_context);
7743  }
7744  mbox_number = ast_strip(mbox_number);
7745  if (ast_strlen_zero(mbox_number)) {
7746  /* There is no mailbox number. Skip it. */
7747  continue;
7748  }
7749  if (ast_strlen_zero(mbox_context)) {
7750  /* There was no context so use the default. */
7751  mbox_context = "default";
7752  }
7753 
7754  /* Fill the mbox[] element. */
7755  ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
7756  sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
7758  ast_str_buffer(mwi_description), pri,
7762  if (!pri->mbox[i].sub) {
7763  ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
7764  sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
7765  continue;
7766  }
7767  pri->mbox[i].number = mbox_number;
7768  pri->mbox[i].context = mbox_context;
7769  ++i;
7770  }
7771 #endif /* defined(HAVE_PRI_MWI) */
7772 
7773  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
7774  if (pri->fds[i] == -1) {
7775  break;
7776  }
7777 
7778  switch (pri->sig) {
7779  case SIG_BRI:
7780  pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
7781  break;
7782  case SIG_BRI_PTMP:
7783  pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
7784  break;
7785  default:
7786  pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
7787 #if defined(HAVE_PRI_SERVICE_MESSAGES)
7788  if (pri->enable_service_message_support) {
7789  pri_set_service_message_support(pri->dchans[i], 1);
7790  }
7791 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
7792  break;
7793  }
7794 
7795  pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
7796 #ifdef HAVE_PRI_PROG_W_CAUSE
7797  pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
7798 #endif
7799 #ifdef HAVE_PRI_INBANDDISCONNECT
7800  pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
7801 #endif
7802  /* Enslave to master if appropriate */
7803  if (i)
7804  pri_enslave(pri->dchans[0], pri->dchans[i]);
7805  if (!pri->dchans[i]) {
7806  if (pri->fds[i] > 0)
7807  close(pri->fds[i]);
7808  pri->fds[i] = -1;
7809  ast_log(LOG_ERROR, "Unable to create PRI structure\n");
7810  return -1;
7811  }
7812  pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
7813  pri_set_nsf(pri->dchans[i], pri->nsf);
7814 #ifdef PRI_GETSET_TIMERS
7815  for (x = 0; x < PRI_MAX_TIMERS; x++) {
7816  if (pri->pritimers[x] != 0)
7817  pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
7818  }
7819 #endif
7820  }
7821 
7822  /* Assume primary is the one we use */
7823  pri->pri = pri->dchans[0];
7824 
7825 #if defined(HAVE_PRI_CALL_HOLD)
7826  pri_hold_enable(pri->pri, 1);
7827 #endif /* defined(HAVE_PRI_CALL_HOLD) */
7828 #if defined(HAVE_PRI_CALL_REROUTING)
7829  pri_reroute_enable(pri->pri, 1);
7830 #endif /* defined(HAVE_PRI_CALL_REROUTING) */
7831 #if defined(HAVE_PRI_HANGUP_FIX)
7832  pri_hangup_fix_enable(pri->pri, 1);
7833 #endif /* defined(HAVE_PRI_HANGUP_FIX) */
7834 #if defined(HAVE_PRI_CCSS)
7835  pri_cc_enable(pri->pri, 1);
7836  pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
7837  pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
7838  pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
7839 #endif /* defined(HAVE_PRI_CCSS) */
7840 #if defined(HAVE_PRI_TRANSFER)
7841  pri_transfer_enable(pri->pri, 1);
7842 #endif /* defined(HAVE_PRI_TRANSFER) */
7843 #if defined(HAVE_PRI_AOC_EVENTS)
7844  pri_aoc_events_enable(pri->pri, 1);
7845 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
7846 #if defined(HAVE_PRI_CALL_WAITING)
7847  pri_connect_ack_enable(pri->pri, 1);
7848 #endif /* defined(HAVE_PRI_CALL_WAITING) */
7849 #if defined(HAVE_PRI_MCID)
7850  pri_mcid_enable(pri->pri, 1);
7851 #endif /* defined(HAVE_PRI_MCID) */
7852 #if defined(HAVE_PRI_L2_PERSISTENCE)
7853  pri_persistent_layer2_option(pri->pri, pri->l2_persistence);
7854 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
7855 
7856  pri->resetpos = -1;
7857  if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
7858  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
7859  if (!pri->dchans[i])
7860  break;
7861  if (pri->fds[i] > 0)
7862  close(pri->fds[i]);
7863  pri->fds[i] = -1;
7864  }
7865  ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
7866  return -1;
7867  }
7868 
7869 #if defined(HAVE_PRI_MWI)
7870  /*
7871  * Send the initial MWI indications from the event cache for this span.
7872  *
7873  * If we were loaded after app_voicemail the event would already be in
7874  * the cache. If we were loaded before app_voicemail the event would not
7875  * be in the cache yet and app_voicemail will send the event when it
7876  * gets loaded.
7877  */
7879 #endif /* defined(HAVE_PRI_MWI) */
7880 
7881  return 0;
7882 }
static void sig_pri_mwi_cache_update(struct sig_pri_span *pri)
Definition: sig_pri.c:7602
const char * context
Mailbox context.
Definition: sig_pri.h:350
int nodetype
Definition: sig_pri.h:434
int cc_qsig_signaling_link_req
Definition: sig_pri.h:440
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * strsep(char **str, const char *delims)
#define SIG_BRI_PTMP
Definition: chan_dahdi.c:366
static void sig_pri_sort_pri_chans(struct sig_pri_span *pri)
Definition: sig_pri.c:7698
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
unsigned int enable_service_message_support
Definition: sig_pri.h:375
#define DAHDI_OVERLAPDIAL_OUTGOING
Definition: sig_pri.h:196
const char * number
Mailbox number.
Definition: sig_pri.h:348
#define ast_str_alloca(init_len)
Definition: strings.h:608
int switchtype
Definition: sig_pri.h:435
int qsigchannelmapping
Definition: sig_pri.h:359
static void sig_pri_mwi_event_cb(const struct ast_event *event, void *userdata)
Definition: sig_pri.c:7572
ast_mutex_t lock
Definition: sig_pri.h:495
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
int cc_qsig_signaling_link_rsp
Definition: sig_pri.h:441
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
struct sig_pri_mbox mbox[SIG_PRI_MAX_MWI_MAILBOXES]
Active MWI mailboxes.
Definition: sig_pri.h:414
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int cc_ptmp_recall_mode
Definition: sig_pri.h:439
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
int overlapdial
Definition: sig_pri.h:358
#define LOG_ERROR
Definition: logger.h:155
pthread_t master
Definition: sig_pri.h:494
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
unsigned int inbanddisconnect
Definition: sig_pri.h:378
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:183
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
int resetpos
Definition: sig_pri.h:473
static void * pri_dchannel(void *vpri)
Definition: sig_pri.c:4596
char mwi_mailboxes[SIG_PRI_MAX_MWI_MAILBOX_STR]
Comma separated list of mailboxes to indicate MWI.
Definition: sig_pri.h:421
int l2_persistence
Definition: sig_pri.h:364
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
#define SIG_BRI
Definition: chan_dahdi.c:365
int pritimers[PRI_MAX_TIMERS]
Definition: sig_pri.h:357
static const char * sig_pri_cc_type_name
Definition: sig_pri.c:99
#define DAHDI_CHAN_MAPPING_LOGICAL
Definition: sig_pri.h:192
#define ast_mutex_init(pmutex)
Definition: lock.h:152
struct pri * dchans[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:480
#define SIG_PRI_DEBUG_DEFAULT
Definition: sig_pri.h:63
struct ast_event_sub * sub
MWI mailbox event subscription.
Definition: sig_pri.h:346
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
struct pri * pri
Definition: sig_pri.h:481
int fds[SIG_PRI_NUM_DCHANS]
Definition: sig_pri.h:367
Mailbox name.
Definition: event_defs.h:83
void sig_pri_stop_pri ( struct sig_pri_span pri)

Stop PRI span.

Since
1.8
Parameters
priPRI span control structure.
Returns
Nothing

Definition at line 7638 of file sig_pri.c.

References ARRAY_LEN, ast_event_unsubscribe(), sig_pri_span::mbox, and sig_pri_mbox::sub.

Referenced by __unload_module().

7639 {
7640 #if defined(HAVE_PRI_MWI)
7641  int idx;
7642 #endif /* defined(HAVE_PRI_MWI) */
7643 
7644 #if defined(HAVE_PRI_MWI)
7645  for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
7646  if (pri->mbox[idx].sub) {
7647  pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
7648  }
7649  }
7650 #endif /* defined(HAVE_PRI_MWI) */
7651 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct sig_pri_mbox mbox[SIG_PRI_MAX_MWI_MAILBOXES]
Active MWI mailboxes.
Definition: sig_pri.h:414
struct ast_event_sub * sub
MWI mailbox event subscription.
Definition: sig_pri.h:346
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
static void sig_pri_transfer_rsp ( void *  data,
int  is_successful 
)
static

Definition at line 2307 of file sig_pri.c.

References xfer_rsp_data::call, xfer_rsp_data::invoke_id, sig_pri_span::pri, and xfer_rsp_data::pri.

Referenced by sig_pri_handle_subcmds().

2308 {
2309  struct xfer_rsp_data *rsp = data;
2310 
2311  pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
2312 }
struct sig_pri_span * pri
Definition: sig_pri.c:2288
q931_call * call
Definition: sig_pri.c:2290
struct pri * pri
Definition: sig_pri.h:481
void sig_pri_unload ( void  )

Unload the sig_pri submodule.

Since
1.8
Returns
Nothing

Definition at line 8749 of file sig_pri.c.

References ao2_ref.

Referenced by __unload_module().

8750 {
8751 #if defined(HAVE_PRI_CCSS)
8752  if (sig_pri_cc_monitors) {
8754  sig_pri_cc_monitors = NULL;
8755  }
8756 #endif /* defined(HAVE_PRI_CCSS) */
8757 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * sig_pri_cc_monitors
Definition: sig_pri.c:101

Variable Documentation

int pri_gendigittimeout = 8000
static

Definition at line 106 of file sig_pri.c.

Referenced by pri_ss_thread().

int pri_matchdigittimeout = 3000
static

Definition at line 104 of file sig_pri.c.

Referenced by pri_ss_thread().

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

Definition at line 6638 of file sig_pri.c.

Referenced by sig_pri_call().

struct ao2_container* sig_pri_cc_monitors
static

Container of sig_pri monitor instances.

Definition at line 101 of file sig_pri.c.

const char* sig_pri_cc_type_name
static