Sat Apr 26 2014 22:03:17

Asterisk developer's documentation


sig_pri.h File Reference

Interface header for PRI signaling module. More...

#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/event.h"
#include "asterisk/ccss.h"
#include <libpri.h>
#include <dahdi/user.h>
Include dependency graph for sig_pri.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  sig_pri_callback
struct  sig_pri_chan
struct  sig_pri_mbox
struct  sig_pri_span

Defines

#define DAHDI_CHAN_MAPPING_LOGICAL   1
#define DAHDI_CHAN_MAPPING_PHYSICAL   0
#define DAHDI_OVERLAPDIAL_BOTH   (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
#define DAHDI_OVERLAPDIAL_INCOMING   2
#define DAHDI_OVERLAPDIAL_NONE   0
#define DAHDI_OVERLAPDIAL_OUTGOING   1
#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)
#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)
#define SIG_PRI   DAHDI_SIG_CLEAR
#define SIG_PRI_AOC_GRANT_D   (1 << 1)
#define SIG_PRI_AOC_GRANT_E   (1 << 2)
#define SIG_PRI_AOC_GRANT_S   (1 << 0)
#define SIG_PRI_DEBUG_DEFAULT   0
#define SIG_PRI_DEBUG_NORMAL   (PRI_DEBUG_APDU | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE | PRI_DEBUG_CC)
#define SIG_PRI_MAX_CHANNELS   672
#define SIG_PRI_MAX_MWI_CONTEXT_LEN   10
#define SIG_PRI_MAX_MWI_MAILBOX_STR
 Maximum mwi_mailboxs string length.
#define SIG_PRI_MAX_MWI_MAILBOXES   8
#define SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN   10 /* digits in number */
#define SIG_PRI_MAX_MWI_VM_NUMBER_LEN   10 /* digits in number */
#define SIG_PRI_MAX_MWI_VM_NUMBER_STR
 Maximum mwi_vm_numbers string length.
#define SIG_PRI_NUM_DCHANS   4
#define SRVST_BOTH   (SRVST_NEAREND | SRVST_FAREND)
 SRVST_BOTH is used to indicate that both sides of the channel are out-of-service.
#define SRVST_DBKEY   "service-state"
 Persistent Service State.
#define SRVST_FAREND   (1 << 1)
 SRVST_FAREND is used to indicate that the far end was taken out-of-service.
#define SRVST_INITIALIZED   0
 SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service.
#define SRVST_NEAREND   (1 << 0)
 SRVST_NEAREND is used to indicate that the near end was put out-of-service.
#define SRVST_TYPE_OOS   "O"
 The out-of-service SERVICE state.

Enumerations

enum  sig_pri_call_level {
  SIG_PRI_CALL_LEVEL_IDLE, SIG_PRI_CALL_LEVEL_SETUP, SIG_PRI_CALL_LEVEL_OVERLAP, SIG_PRI_CALL_LEVEL_PROCEEDING,
  SIG_PRI_CALL_LEVEL_ALERTING, SIG_PRI_CALL_LEVEL_DEFER_DIAL, SIG_PRI_CALL_LEVEL_CONNECT
}
enum  sig_pri_colp_signaling { SIG_PRI_COLP_BLOCK, SIG_PRI_COLP_CONNECT, SIG_PRI_COLP_UPDATE }
enum  sig_pri_law { SIG_PRI_DEFLAW = 0, SIG_PRI_ULAW, SIG_PRI_ALAW }
enum  sig_pri_moh_event {
  SIG_PRI_MOH_EVENT_RESET, SIG_PRI_MOH_EVENT_HOLD, SIG_PRI_MOH_EVENT_UNHOLD, SIG_PRI_MOH_EVENT_HOLD_ACK,
  SIG_PRI_MOH_EVENT_HOLD_REJ, SIG_PRI_MOH_EVENT_RETRIEVE_ACK, SIG_PRI_MOH_EVENT_RETRIEVE_REJ, SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK,
  SIG_PRI_MOH_EVENT_NUM
}
enum  sig_pri_moh_signaling { SIG_PRI_MOH_SIGNALING_MOH, SIG_PRI_MOH_SIGNALING_NOTIFY, SIG_PRI_MOH_SIGNALING_HOLD }
enum  sig_pri_moh_state {
  SIG_PRI_MOH_STATE_IDLE, SIG_PRI_MOH_STATE_NOTIFY, SIG_PRI_MOH_STATE_MOH, SIG_PRI_MOH_STATE_HOLD_REQ,
  SIG_PRI_MOH_STATE_PEND_UNHOLD, SIG_PRI_MOH_STATE_HOLD, SIG_PRI_MOH_STATE_RETRIEVE_REQ, SIG_PRI_MOH_STATE_PEND_HOLD,
  SIG_PRI_MOH_STATE_RETRIEVE_FAIL, SIG_PRI_MOH_STATE_NUM
}
enum  sig_pri_reset_state { SIG_PRI_RESET_IDLE, SIG_PRI_RESET_ACTIVE, SIG_PRI_RESET_NO_ACK }
enum  sig_pri_tone {
  SIG_PRI_TONE_RINGTONE = 0, SIG_PRI_TONE_STUTTER, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_DIALTONE,
  SIG_PRI_TONE_DIALRECALL, SIG_PRI_TONE_INFO, SIG_PRI_TONE_BUSY
}

Functions

void pri_event_alarm (struct sig_pri_span *pri, int index, int before_start_pri)
void pri_event_noalarm (struct sig_pri_span *pri, int index, int before_start_pri)
int pri_is_up (struct sig_pri_span *pri)
int pri_maintenance_bservice (struct pri *pri, struct sig_pri_chan *p, int changestatus)
int pri_send_callrerouting_facility_exec (struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
int pri_send_keypad_facility_exec (struct sig_pri_chan *p, const char *digits)
int sig_pri_ami_show_spans (struct mansession *s, const char *show_cmd, struct sig_pri_span *pri, const int *dchannels, const char *action_id)
 Output AMI show spans response events for the given PRI span.
int sig_pri_answer (struct sig_pri_chan *p, struct ast_channel *ast)
int sig_pri_available (struct sig_pri_chan **pvt, int is_specific_channel)
int sig_pri_call (struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
int sig_pri_cc_agent_callee_available (struct ast_cc_agent *agent)
 Alert the caller that it is time to try recalling.
void sig_pri_cc_agent_destructor (struct ast_cc_agent *agent)
 Destroy private data on the agent.
int sig_pri_cc_agent_init (struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
 PRI CC agent initialization.
int sig_pri_cc_agent_party_b_free (struct ast_cc_agent *agent)
 Let the caller know that the callee has become free but that the caller cannot attempt to call back because he is either busy or there is congestion on his line.
void sig_pri_cc_agent_req_rsp (struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
 Response to a CC request.
int sig_pri_cc_agent_start_monitoring (struct ast_cc_agent *agent)
 Begin monitoring a busy device.
int sig_pri_cc_agent_start_offer_timer (struct ast_cc_agent *agent)
 Start the offer timer.
int sig_pri_cc_agent_status_req (struct ast_cc_agent *agent)
 Request the status of the agent's device.
int sig_pri_cc_agent_stop_offer_timer (struct ast_cc_agent *agent)
 Stop the offer timer.
int sig_pri_cc_agent_stop_ringing (struct ast_cc_agent *agent)
 Request for an agent's phone to stop ringing.
int sig_pri_cc_monitor_cancel_available_timer (struct ast_cc_monitor *monitor, int *sched_id)
 Cancel the running available timer.
void sig_pri_cc_monitor_destructor (void *monitor_pvt)
 Destroy PRI private data on the monitor.
int sig_pri_cc_monitor_req_cc (struct ast_cc_monitor *monitor, int *available_timer_id)
 Request CCSS.
int sig_pri_cc_monitor_status_rsp (struct ast_cc_monitor *monitor, enum ast_device_state devstate)
 Status response to an ast_cc_monitor_status_request().
int sig_pri_cc_monitor_suspend (struct ast_cc_monitor *monitor)
 Suspend monitoring.
int sig_pri_cc_monitor_unsuspend (struct ast_cc_monitor *monitor)
 Unsuspend monitoring.
void sig_pri_chan_alarm_notify (struct sig_pri_chan *p, int noalarm)
 Notify new alarm status.
void sig_pri_chan_delete (struct sig_pri_chan *doomed)
 Delete the sig_pri private channel structure.
struct sig_pri_chansig_pri_chan_new (void *pvt_data, 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)
void sig_pri_dial_complete (struct sig_pri_chan *pvt, struct ast_channel *ast)
 DTMF dial string complete.
int sig_pri_digit_begin (struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
void sig_pri_extract_called_num_subaddr (struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
 Extract the called number and subaddress from the dial string.
void sig_pri_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
int sig_pri_hangup (struct sig_pri_chan *p, struct ast_channel *ast)
int sig_pri_indicate (struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
void sig_pri_init_pri (struct sig_pri_span *pri)
int sig_pri_is_alarm_ignored (struct sig_pri_span *pri)
 Determine if layer 1 alarms are ignored.
int sig_pri_is_chan_available (struct sig_pri_chan *pvt)
 Determine if a private channel structure is available.
int sig_pri_load (const char *cc_type_name)
 Load the sig_pri submodule.
struct ast_channelsig_pri_request (struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
void sig_pri_sendtext (struct sig_pri_chan *pchan, const char *text)
 Send display text.
void sig_pri_set_alarm (struct sig_pri_chan *p, int in_alarm)
int sig_pri_start_pri (struct sig_pri_span *pri)
void sig_pri_stop_pri (struct sig_pri_span *pri)
 Stop PRI span.
void sig_pri_unload (void)
 Unload the sig_pri submodule.

Variables

static const char dahdi_db [] = "dahdi/registry"
 The AstDB family.
struct sig_pri_callback sig_pri_callbacks

Detailed Description

Interface header for PRI signaling module.

Author:
Matthew Fredrickson <creslin@digium.com>

Definition in file sig_pri.h.


Define Documentation

Definition at line 246 of file sig_pri.h.

Referenced by process_dahdi(), and sig_pri_start_pri().

Definition at line 245 of file sig_pri.h.

Referenced by dahdi_chan_conf_default(), and process_dahdi().

#define DAHDI_OVERLAPDIAL_NONE   0

Definition at line 249 of file sig_pri.h.

Referenced by process_dahdi().

Definition at line 250 of file sig_pri.h.

Referenced by dahdi_read(), pri_dchannel(), process_dahdi(), and sig_pri_start_pri().

#define SIG_BRI   (0x2000000 | DAHDI_SIG_CLEAR)

Definition at line 241 of file sig_pri.h.

#define SIG_BRI_PTMP   (0X4000000 | DAHDI_SIG_CLEAR)

Definition at line 242 of file sig_pri.h.

#define SIG_PRI   DAHDI_SIG_CLEAR

Definition at line 240 of file sig_pri.h.

#define SIG_PRI_AOC_GRANT_D   (1 << 1)
#define SIG_PRI_AOC_GRANT_E   (1 << 2)
#define SIG_PRI_AOC_GRANT_S   (1 << 0)
#define SIG_PRI_DEBUG_DEFAULT   0

PRI debug message flags set on initial startup.

Definition at line 51 of file sig_pri.h.

Referenced by sig_pri_start_pri().

#define SIG_PRI_DEBUG_NORMAL   (PRI_DEBUG_APDU | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q921_STATE | PRI_DEBUG_CC)

PRI debug message flags when normal PRI debugging is turned on at the command line.

Definition at line 37 of file sig_pri.h.

Referenced by handle_pri_debug().

#define SIG_PRI_MAX_CHANNELS   672

No more than a DS3 per trunk group

Definition at line 238 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_CONTEXT_LEN   10

Typical maximum length of mwi mailbox context

Definition at line 385 of file sig_pri.h.

Value:

Maximum mwi_mailboxs string length.

max_length = #mailboxes * (mbox_number + '@' + context + ',') The last ',' is a null terminator instead.

Definition at line 400 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_MAILBOXES   8

Maximum number of mailboxes per span.

Definition at line 379 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_MBOX_NUMBER_LEN   10 /* digits in number */

Typical maximum length of mwi mailbox number

Definition at line 383 of file sig_pri.h.

#define SIG_PRI_MAX_MWI_VM_NUMBER_LEN   10 /* digits in number */

Typical maximum length of mwi voicemail controlling number

Definition at line 381 of file sig_pri.h.

Value:

Maximum mwi_vm_numbers string length.

max_length = #mailboxes * (vm_number + ',') The last ',' is a null terminator instead.

Definition at line 392 of file sig_pri.h.

SRVST_BOTH is used to indicate that both sides of the channel are out-of-service.

Definition at line 270 of file sig_pri.h.

#define SRVST_DBKEY   "service-state"

Persistent Service State.

Definition at line 256 of file sig_pri.h.

Referenced by destroy_all_channels(), handle_pri_service_generic(), mkintf(), and pri_dchannel().

#define SRVST_FAREND   (1 << 1)

SRVST_FAREND is used to indicate that the far end was taken out-of-service.

Definition at line 268 of file sig_pri.h.

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

#define SRVST_INITIALIZED   0

SRVST_INITIALIZED is used to indicate a channel being out-of-service The SRVST_INITIALIZED is mostly used maintain backwards compatibility but also may mean that the channel has not yet received a RESTART message. If a channel is out-of-service with this reason a RESTART message will result in the channel being put into service.

Definition at line 264 of file sig_pri.h.

#define SRVST_NEAREND   (1 << 0)

SRVST_NEAREND is used to indicate that the near end was put out-of-service.

Definition at line 266 of file sig_pri.h.

Referenced by handle_pri_service_generic(), mkintf(), pri_check_restart(), and pri_dchannel().

#define SRVST_TYPE_OOS   "O"

The out-of-service SERVICE state.

Definition at line 258 of file sig_pri.h.

Referenced by handle_pri_service_generic(), and pri_dchannel().


Enumeration Type Documentation

Call establishment life cycle level for simple comparisons.

Enumerator:
SIG_PRI_CALL_LEVEL_IDLE 

Call does not exist.

SIG_PRI_CALL_LEVEL_SETUP 

Call is present but has no response yet. (SETUP)

SIG_PRI_CALL_LEVEL_OVERLAP 

Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE)

SIG_PRI_CALL_LEVEL_PROCEEDING 

Call routing is happening. (PROCEEDING)

SIG_PRI_CALL_LEVEL_ALERTING 

Called party is being alerted of the call. (ALERTING)

SIG_PRI_CALL_LEVEL_DEFER_DIAL 

Call is dialing 'w' deferred digits. (CONNECT)

SIG_PRI_CALL_LEVEL_CONNECT 

Call is connected/answered. (CONNECT)

Definition at line 136 of file sig_pri.h.

                        {
   /*! Call does not exist. */
   SIG_PRI_CALL_LEVEL_IDLE,
   /*! Call is present but has no response yet. (SETUP) */
   SIG_PRI_CALL_LEVEL_SETUP,
   /*! Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE) */
   SIG_PRI_CALL_LEVEL_OVERLAP,
   /*! Call routing is happening. (PROCEEDING) */
   SIG_PRI_CALL_LEVEL_PROCEEDING,
   /*! Called party is being alerted of the call. (ALERTING) */
   SIG_PRI_CALL_LEVEL_ALERTING,
   /*! Call is dialing 'w' deferred digits. (CONNECT) */
   SIG_PRI_CALL_LEVEL_DEFER_DIAL,
   /*! Call is connected/answered. (CONNECT) */
   SIG_PRI_CALL_LEVEL_CONNECT,
};
Enumerator:
SIG_PRI_COLP_BLOCK 

Block all connected line updates.

SIG_PRI_COLP_CONNECT 

Only send connected line information with the CONNECT message.

SIG_PRI_COLP_UPDATE 

Allow all connected line updates.

Definition at line 418 of file sig_pri.h.

                            {
   /*! Block all connected line updates. */
   SIG_PRI_COLP_BLOCK,
   /*! Only send connected line information with the CONNECT message. */
   SIG_PRI_COLP_CONNECT,
   /*! Allow all connected line updates. */
   SIG_PRI_COLP_UPDATE,
};
Enumerator:
SIG_PRI_DEFLAW 
SIG_PRI_ULAW 
SIG_PRI_ALAW 

Definition at line 68 of file sig_pri.h.

Enumerator:
SIG_PRI_MOH_EVENT_RESET 

Reset the MOH state machine. (Because of hangup.)

SIG_PRI_MOH_EVENT_HOLD 

Bridged peer placed this channel on hold.

SIG_PRI_MOH_EVENT_UNHOLD 

Bridged peer took this channel off hold.

SIG_PRI_MOH_EVENT_HOLD_ACK 

The hold request was successfully acknowledged.

SIG_PRI_MOH_EVENT_HOLD_REJ 

The hold request was rejected.

SIG_PRI_MOH_EVENT_RETRIEVE_ACK 

The unhold request was successfully acknowledged.

SIG_PRI_MOH_EVENT_RETRIEVE_REJ 

The unhold request was rejected.

SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK 

The remote party took this channel off hold.

SIG_PRI_MOH_EVENT_NUM 

Number of MOH events. Must be last in enum.

Definition at line 111 of file sig_pri.h.

                       {
   /*! Reset the MOH state machine. (Because of hangup.) */
   SIG_PRI_MOH_EVENT_RESET,
   /*! Bridged peer placed this channel on hold. */
   SIG_PRI_MOH_EVENT_HOLD,
   /*! Bridged peer took this channel off hold. */
   SIG_PRI_MOH_EVENT_UNHOLD,
#if defined(HAVE_PRI_CALL_HOLD)
   /*! The hold request was successfully acknowledged. */
   SIG_PRI_MOH_EVENT_HOLD_ACK,
   /*! The hold request was rejected. */
   SIG_PRI_MOH_EVENT_HOLD_REJ,
   /*! The unhold request was successfully acknowledged. */
   SIG_PRI_MOH_EVENT_RETRIEVE_ACK,
   /*! The unhold request was rejected. */
   SIG_PRI_MOH_EVENT_RETRIEVE_REJ,
   /*! The remote party took this channel off hold. */
   SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK,
#endif   /* defined(HAVE_PRI_CALL_HOLD) */

   /*! Number of MOH events.  Must be last in enum. */
   SIG_PRI_MOH_EVENT_NUM
};
Enumerator:
SIG_PRI_MOH_SIGNALING_MOH 

Generate MOH to the remote party.

SIG_PRI_MOH_SIGNALING_NOTIFY 

Send hold notification signaling to the remote party.

SIG_PRI_MOH_SIGNALING_HOLD 

Use HOLD/RETRIEVE signaling to release the B channel while on hold.

Definition at line 74 of file sig_pri.h.

                           {
   /*! Generate MOH to the remote party. */
   SIG_PRI_MOH_SIGNALING_MOH,
   /*! Send hold notification signaling to the remote party. */
   SIG_PRI_MOH_SIGNALING_NOTIFY,
#if defined(HAVE_PRI_CALL_HOLD)
   /*! Use HOLD/RETRIEVE signaling to release the B channel while on hold. */
   SIG_PRI_MOH_SIGNALING_HOLD,
#endif   /* defined(HAVE_PRI_CALL_HOLD) */
};
Enumerator:
SIG_PRI_MOH_STATE_IDLE 

Bridged peer has not put us on hold.

SIG_PRI_MOH_STATE_NOTIFY 

Bridged peer has put us on hold and we were to notify the remote party.

SIG_PRI_MOH_STATE_MOH 

Bridged peer has put us on hold and we were to play MOH or HOLD/RETRIEVE fallback.

SIG_PRI_MOH_STATE_HOLD_REQ 

Requesting to put channel on hold.

SIG_PRI_MOH_STATE_PEND_UNHOLD 

Trying to go on hold when bridged peer requested to unhold.

SIG_PRI_MOH_STATE_HOLD 

Channel is held.

SIG_PRI_MOH_STATE_RETRIEVE_REQ 

Requesting to take channel out of hold.

SIG_PRI_MOH_STATE_PEND_HOLD 

Trying to take channel out of hold when bridged peer requested to hold.

SIG_PRI_MOH_STATE_RETRIEVE_FAIL 

Failed to take the channel out of hold. No B channels were available?

SIG_PRI_MOH_STATE_NUM 

Number of MOH states. Must be last in enum.

Definition at line 85 of file sig_pri.h.

                       {
   /*! Bridged peer has not put us on hold. */
   SIG_PRI_MOH_STATE_IDLE,
   /*! Bridged peer has put us on hold and we were to notify the remote party. */
   SIG_PRI_MOH_STATE_NOTIFY,
   /*! Bridged peer has put us on hold and we were to play MOH or HOLD/RETRIEVE fallback. */
   SIG_PRI_MOH_STATE_MOH,
#if defined(HAVE_PRI_CALL_HOLD)
   /*! Requesting to put channel on hold. */
   SIG_PRI_MOH_STATE_HOLD_REQ,
   /*! Trying to go on hold when bridged peer requested to unhold. */
   SIG_PRI_MOH_STATE_PEND_UNHOLD,
   /*! Channel is held. */
   SIG_PRI_MOH_STATE_HOLD,
   /*! Requesting to take channel out of hold. */
   SIG_PRI_MOH_STATE_RETRIEVE_REQ,
   /*! Trying to take channel out of hold when bridged peer requested to hold. */
   SIG_PRI_MOH_STATE_PEND_HOLD,
   /*! Failed to take the channel out of hold. No B channels were available? */
   SIG_PRI_MOH_STATE_RETRIEVE_FAIL,
#endif   /* defined(HAVE_PRI_CALL_HOLD) */

   /*! Number of MOH states.  Must be last in enum. */
   SIG_PRI_MOH_STATE_NUM
};
Enumerator:
SIG_PRI_RESET_IDLE 

The channel is not being RESTARTed.

SIG_PRI_RESET_ACTIVE 

The channel is being RESTARTed.

Note:
Waiting for a RESTART ACKNOWLEDGE from the peer.
SIG_PRI_RESET_NO_ACK 

Peer may not be sending the expected RESTART ACKNOWLEDGE.

We have already received a SETUP on this channel. If another SETUP comes in on this channel then the peer considers this channel useable. Assume that the peer is never going to give us a RESTART ACKNOWLEDGE and assume that we have received one. This is not according to Q.931, but some peers occasionally fail to send a RESTART ACKNOWLEDGE.

Definition at line 153 of file sig_pri.h.

                         {
   /*! \brief The channel is not being RESTARTed. */
   SIG_PRI_RESET_IDLE,
   /*!
    * \brief The channel is being RESTARTed.
    * \note Waiting for a RESTART ACKNOWLEDGE from the peer.
    */
   SIG_PRI_RESET_ACTIVE,
   /*!
    * \brief Peer may not be sending the expected RESTART ACKNOWLEDGE.
    *
    * \details We have already received a SETUP on this channel.
    * If another SETUP comes in on this channel then the peer
    * considers this channel useable.  Assume that the peer is
    * never going to give us a RESTART ACKNOWLEDGE and assume that
    * we have received one.  This is not according to Q.931, but
    * some peers occasionally fail to send a RESTART ACKNOWLEDGE.
    */
   SIG_PRI_RESET_NO_ACK,
};
Enumerator:
SIG_PRI_TONE_RINGTONE 
SIG_PRI_TONE_STUTTER 
SIG_PRI_TONE_CONGESTION 
SIG_PRI_TONE_DIALTONE 
SIG_PRI_TONE_DIALRECALL 
SIG_PRI_TONE_INFO 
SIG_PRI_TONE_BUSY 

Definition at line 58 of file sig_pri.h.


Function Documentation

void pri_event_alarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

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

{
   pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
   if (!before_start_pri) {
      pri_find_dchan(pri);
   }
}
void pri_event_noalarm ( struct sig_pri_span pri,
int  index,
int  before_start_pri 
)

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

{
   pri->dchanavail[index] |= DCHAN_NOTINALARM;
   if (!before_start_pri)
      pri_restart(pri->dchans[index]);
}
int pri_is_up ( struct sig_pri_span pri)

Definition at line 1051 of file sig_pri.c.

References DCHAN_AVAILABLE, sig_pri_span::dchanavail, and SIG_PRI_NUM_DCHANS.

Referenced by pri_dchannel().

{
   int x;
   for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
      if (pri->dchanavail[x] == DCHAN_AVAILABLE)
         return 1;
   }
   return 0;
}
int pri_maintenance_bservice ( struct pri *  pri,
struct sig_pri_chan p,
int  changestatus 
)

Definition at line 9342 of file sig_pri.c.

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

Referenced by handle_pri_service_generic().

{
   int channel = PVT_TO_CHANNEL(p);
   int span = PRI_SPAN(channel);

   return pri_maintenance_service(pri, span, channel, changestatus);
}
int pri_send_callrerouting_facility_exec ( struct sig_pri_chan p,
enum ast_channel_state  chanstate,
const char *  destination,
const char *  original,
const char *  reason 
)

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

{
   int res;

   sig_pri_lock_private(p);

   if (!p->pri || !p->call) {
      ast_debug(1, "Unable to find pri or call on channel!\n");
      sig_pri_unlock_private(p);
      return -1;
   }

   pri_grab(p, p->pri);
   res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
   pri_rel(p->pri);

   sig_pri_unlock_private(p);

   return res;
}
int pri_send_keypad_facility_exec ( struct sig_pri_chan p,
const char *  digits 
)

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

{
   sig_pri_lock_private(p);

   if (!p->pri || !p->call) {
      ast_debug(1, "Unable to find pri or call on channel!\n");
      sig_pri_unlock_private(p);
      return -1;
   }

   pri_grab(p, p->pri);
   pri_keypad_facility(p->pri->pri, p->call, digits);
   pri_rel(p->pri);

   sig_pri_unlock_private(p);

   return 0;
}
int sig_pri_ami_show_spans ( struct mansession s,
const char *  show_cmd,
struct sig_pri_span pri,
const int *  dchannels,
const char *  action_id 
)

Output AMI show spans response events for the given PRI span.

Since:
10.0
Parameters:
show_cmdAMI command name
sAMI session to output span information.
priPRI span control structure.
dchannelsArray of D channel channel numbers.
action_idAction ID line to use.
Returns:
Number of D channels on this span.

Definition at line 7513 of file sig_pri.c.

References ARRAY_LEN, astman_append(), DCHAN_NOTINALARM, DCHAN_UP, sig_pri_span::dchanavail, sig_pri_span::dchans, sig_pri_span::pri, pri_order(), and sig_pri_span::span.

Referenced by action_prishowspans().

{
   int count;
   int x;

   count = 0;
   for (x = 0; x < ARRAY_LEN(pri->dchans); ++x) {
      if (pri->dchans[x]) {
         ++count;

         astman_append(s,
            "Event: %s\r\n"
            "Span: %d\r\n"
            "DChannel: %d\r\n"
            "Order: %s\r\n"
            "Active: %s\r\n"
            "Alarm: %s\r\n"
            "Up: %s\r\n"
            "%s"
            "\r\n",
            show_cmd,
            pri->span,
            dchannels[x],
            pri_order(x),
            (pri->dchans[x] == pri->pri) ? "Yes" : "No",
            (pri->dchanavail[x] & DCHAN_NOTINALARM) ? "No" : "Yes",
            (pri->dchanavail[x] & DCHAN_UP) ? "Yes" : "No",
            action_id
            );
      }
   }
   return count;
}
int sig_pri_answer ( struct sig_pri_chan p,
struct ast_channel ast 
)

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

{
   int res;

   /* Send a pri acknowledge */
   pri_grab(p, p->pri);
#if defined(HAVE_PRI_AOC_EVENTS)
   if (p->aoc_s_request_invoke_id_valid) {
      /* if AOC-S was requested and the invoke id is still present on answer.  That means
       * no AOC-S rate list was provided, so send a NULL response which will indicate that
       * AOC-S is not available */
      pri_aoc_s_request_response_send(p->pri->pri, p->call,
         p->aoc_s_request_invoke_id, NULL);
      p->aoc_s_request_invoke_id_valid = 0;
   }
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */
   if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
      p->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
   }
   sig_pri_set_dialing(p, 0);
   sig_pri_open_media(p);
   res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
   pri_rel(p->pri);
   ast_setstate(ast, AST_STATE_UP);
   return res;
}
int sig_pri_available ( struct sig_pri_chan **  pvt,
int  is_specific_channel 
)

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

{
   struct sig_pri_chan *p = *pvt;
   struct sig_pri_span *pri;

   if (!p->pri) {
      /* Something is wrong here.  A PRI channel without the pri pointer? */
      return 0;
   }
   pri = p->pri;

   ast_mutex_lock(&pri->lock);
   if (
#if defined(HAVE_PRI_CALL_WAITING)
      /*
       * Only do call waiting calls if we have any
       * call waiting call outstanding.  We do not
       * want new calls to steal a B channel
       * freed for an earlier call waiting call.
       */
      !pri->num_call_waiting_calls &&
#endif   /* defined(HAVE_PRI_CALL_WAITING) */
      sig_pri_available_check(p)) {
      p->allocated = 1;
      ast_mutex_unlock(&pri->lock);
      return 1;
   }

#if defined(HAVE_PRI_CALL_WAITING)
   if (!is_specific_channel) {
      struct sig_pri_chan *cw;

      cw = sig_pri_cw_available(pri);
      if (cw) {
         /* We have a call waiting interface to use instead. */
         cw->allocated = 1;
         *pvt = cw;
         ast_mutex_unlock(&pri->lock);
         return 1;
      }
   }
#endif   /* defined(HAVE_PRI_CALL_WAITING) */
   ast_mutex_unlock(&pri->lock);
   return 0;
}
int sig_pri_call ( struct sig_pri_chan p,
struct ast_channel ast,
const char *  rdest,
int  timeout,
int  layer1 
)
Note:
Parsing must remain in sync with sig_pri_extract_called_num_subaddr().

Definition at line 7738 of file sig_pri.c.

References 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_caller(), ast_channel_connected(), ast_channel_connected_effective_id(), ast_channel_get_device_name(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_transfercapability(), ast_copy_string(), ast_debug, 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, sig_pri_cc_monitor_instance::cc_id, sig_pri_chan::channel, 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, sig_pri_span::initial_user_tag, sig_pri_span::internationalprefix, sig_pri_chan::is_call_waiting, IS_DIGITAL, sig_pri_span::localdialplan, LOG_ERROR, LOG_WARNING, monitor, ast_party_id::name, sig_pri_span::nationalprefix, sig_pri_span::nodetype, ast_party_id::number, OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST, OPT_ARG_ARRAY_SIZE, OPT_ARG_KEYPAD, OPT_KEYPAD, OPT_REVERSE_CHARGE, sig_pri_chan::owner, pbx_builtin_getvar_helper(), ast_party_number::plan, 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_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().

{
   char dest[256]; /* must be same length as p->dialdest */
   struct ast_party_subaddress dialed_subaddress; /* Called subaddress */
   struct pri_sr *sr;
   char *c, *l, *n, *s;
#ifdef SUPPORT_USERUSER
   const char *useruser;
#endif
   int core_id;
   int pridialplan;
   int dp_strip;
   int prilocaldialplan;
   int ldp_strip;
   int exclusive;
#if defined(HAVE_PRI_SETUP_KEYPAD)
   const char *keypad;
#endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(group);  /* channel/group token */
      AST_APP_ARG(ext); /* extension token */
      AST_APP_ARG(opts);   /* options token */
      AST_APP_ARG(other);  /* Any remining unused arguments */
   );
   struct ast_flags opts;
   char *opt_args[OPT_ARG_ARRAY_SIZE];
   struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);

   ast_debug(1, "CALLER NAME: %s NUM: %s\n",
      S_COR(connected_id.name.valid, connected_id.name.str, ""),
      S_COR(connected_id.number.valid, connected_id.number.str, ""));

   if (!p->pri) {
      ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
      return -1;
   }

   if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
      ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
      return -1;
   }

   p->dialdest[0] = '\0';
   sig_pri_set_outgoing(p, 1);

   ast_copy_string(dest, rdest, sizeof(dest));
   AST_NONSTANDARD_APP_ARGS(args, dest, '/');
   if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
      /* General invalid option syntax. */
      return -1;
   }

   c = args.ext;
   if (!c) {
      c = "";
   }

   /* setup dialed_subaddress if found */
   ast_party_subaddress_init(&dialed_subaddress);
   s = strchr(c, ':');
   if (s) {
      *s = '\0';
      s++;
      /* prefix */
      /* 'n' = NSAP */
      /* 'u' = User Specified */
      /* Default = NSAP */
      switch (*s) {
      case 'U':
      case 'u':
         s++;
         dialed_subaddress.type = 2;
         break;
      case 'N':
      case 'n':
         s++;
         /* default already covered with ast_party_subaddress_init */
         break;
      }
      dialed_subaddress.str = s;
      dialed_subaddress.valid = 1;
   }

   l = NULL;
   n = NULL;
   if (!p->hidecallerid) {
      if (connected_id.number.valid) {
         /* If we get to the end of this loop without breaking, there's no
          * calleridnum.  This is done instead of testing for "unknown" or
          * the thousands of other ways that the calleridnum could be
          * invalid. */
         for (l = connected_id.number.str; l && *l; l++) {
            if (strchr("0123456789", *l)) {
               l = connected_id.number.str;
               break;
            }
         }
      } else {
         l = NULL;
      }
      if (!p->hidecalleridname) {
         n = connected_id.name.valid ? connected_id.name.str : NULL;
      }
   }

   if (strlen(c) < p->stripmsd) {
      ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
      return -1;
   }

   /* Extract any 'w' deferred digits. */
   s = strchr(c + p->stripmsd, 'w');
   if (s) {
      *s++ = '\0';
      ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits));
      /*
       * Since we have a 'w', this means that there will not be any
       * more normal dialed digits.  Therefore, the sending complete
       * ie needs to be sent with any normal digits.
       */
   } else {
      p->deferred_digits[0] = '\0';
   }

   pri_grab(p, p->pri);
   if (!(p->call = pri_new_call(p->pri->pri))) {
      ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
      pri_rel(p->pri);
      return -1;
   }
   if (!(sr = pri_sr_new())) {
      ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n",
         p->channel);
      pri_destroycall(p->pri->pri, p->call);
      p->call = NULL;
      pri_rel(p->pri);
      return -1;
   }

   sig_pri_set_digital(p, IS_DIGITAL(ast_channel_transfercapability(ast)));   /* push up to parent for EC */

#if defined(HAVE_PRI_CALL_WAITING)
   if (p->is_call_waiting) {
      /*
       * Indicate that this is a call waiting call.
       * i.e., Normal call but with no B channel.
       */
      pri_sr_set_channel(sr, 0, 0, 1);
   } else
#endif   /* defined(HAVE_PRI_CALL_WAITING) */
   {
      /* Should the picked channel be used exclusively? */
      if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
         exclusive = 1;
      } else {
         exclusive = 0;
      }
      pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
   }

   pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast_channel_transfercapability(ast),
      (p->digital ? -1 : layer1));

   if (p->pri->facilityenable)
      pri_facility_enable(p->pri->pri);

   ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast_channel_transfercapability(ast), ast_transfercapability2str(ast_channel_transfercapability(ast)));
   dp_strip = 0;
   pridialplan = p->pri->dialplan - 1;
   if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
      if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
         if (pridialplan == -2) {
            dp_strip = strlen(p->pri->internationalprefix);
         }
         pridialplan = PRI_INTERNATIONAL_ISDN;
      } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
         if (pridialplan == -2) {
            dp_strip = strlen(p->pri->nationalprefix);
         }
         pridialplan = PRI_NATIONAL_ISDN;
      } else {
         pridialplan = PRI_LOCAL_ISDN;
      }
   }
   while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
      switch (c[p->stripmsd]) {
      case 'U':
         pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
         break;
      case 'I':
         pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
         break;
      case 'N':
         pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
         break;
      case 'L':
         pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
         break;
      case 'S':
         pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
         break;
      case 'V':
         pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
         break;
      case 'R':
         pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
         break;
      case 'u':
         pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
         break;
      case 'e':
         pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
         break;
      case 'x':
         pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
         break;
      case 'f':
         pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
         break;
      case 'n':
         pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
         break;
      case 'p':
         pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
         break;
      case 'r':
         pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
         break;
      default:
         if (isalpha(c[p->stripmsd])) {
            ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
               c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
         }
         break;
      }
      c++;
   }
#if defined(HAVE_PRI_SETUP_KEYPAD)
   if (ast_test_flag(&opts, OPT_KEYPAD)
      && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
      /* We have a keypad facility digits option with digits. */
      keypad = opt_args[OPT_ARG_KEYPAD];
      pri_sr_set_keypad_digits(sr, keypad);
   } else {
      keypad = NULL;
   }
   if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
#endif   /* defined(HAVE_PRI_SETUP_KEYPAD) */
   {
      pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
   }

#if defined(HAVE_PRI_SUBADDR)
   if (dialed_subaddress.valid) {
      struct pri_party_subaddress subaddress;

      memset(&subaddress, 0, sizeof(subaddress));
      sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
      pri_sr_set_called_subaddress(sr, &subaddress);
   }
#endif   /* defined(HAVE_PRI_SUBADDR) */
#if defined(HAVE_PRI_REVERSE_CHARGE)
   if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
      pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
   }
#endif   /* defined(HAVE_PRI_REVERSE_CHARGE) */
#if defined(HAVE_PRI_AOC_EVENTS)
   if (ast_test_flag(&opts, OPT_AOC_REQUEST)
      && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
      if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
         pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
      }
      if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
         pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
      }
      if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
         pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
      }
   }
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */

   /* Setup the user tag for party id's from this device for this call. */
   if (p->pri->append_msn_to_user_tag) {
      snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
         p->pri->nodetype == PRI_NETWORK
            ? c + p->stripmsd + dp_strip
            : S_COR(ast_channel_connected(ast)->id.number.valid,
               ast_channel_connected(ast)->id.number.str, ""));
   } else {
      ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
   }

   /*
    * Replace the caller id tag from the channel creation
    * with the actual tag value.
    */
   ast_free(ast_channel_caller(ast)->id.tag);
   ast_channel_caller(ast)->id.tag = ast_strdup(p->user_tag);

   ldp_strip = 0;
   prilocaldialplan = p->pri->localdialplan - 1;
   if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
      if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
         if (prilocaldialplan == -2) {
            ldp_strip = strlen(p->pri->internationalprefix);
         }
         prilocaldialplan = PRI_INTERNATIONAL_ISDN;
      } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
         if (prilocaldialplan == -2) {
            ldp_strip = strlen(p->pri->nationalprefix);
         }
         prilocaldialplan = PRI_NATIONAL_ISDN;
      } else {
         prilocaldialplan = PRI_LOCAL_ISDN;
      }
   } else if (prilocaldialplan == -1) {
      /* Use the numbering plan passed in. */
      prilocaldialplan = connected_id.number.plan;
   }
   if (l != NULL) {
      while (*l > '9' && *l != '*' && *l != '#') {
         switch (*l) {
         case 'U':
            prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
            break;
         case 'I':
            prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
            break;
         case 'N':
            prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
            break;
         case 'L':
            prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
            break;
         case 'S':
            prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
            break;
         case 'V':
            prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
            break;
         case 'R':
            prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
            break;
         case 'u':
            prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
            break;
         case 'e':
            prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
            break;
         case 'x':
            prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
            break;
         case 'f':
            prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
            break;
         case 'n':
            prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
            break;
         case 'p':
            prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
            break;
         case 'r':
            prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
            break;
         default:
            if (isalpha(*l)) {
               ast_log(LOG_WARNING,
                  "Unrecognized prilocaldialplan %s modifier: %c\n",
                  *l > 'Z' ? "NPI" : "TON", *l);
            }
            break;
         }
         l++;
      }
   }
   pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
      p->use_callingpres ? connected_id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));

#if defined(HAVE_PRI_SUBADDR)
   if (connected_id.subaddress.valid) {
      struct pri_party_subaddress subaddress;

      memset(&subaddress, 0, sizeof(subaddress));
      sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.subaddress);
      pri_sr_set_caller_subaddress(sr, &subaddress);
   }
#endif   /* defined(HAVE_PRI_SUBADDR) */

   sig_pri_redirecting_update(p, ast);

#ifdef SUPPORT_USERUSER
   /* User-user info */
   useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
   if (useruser)
      pri_sr_set_useruser(sr, useruser);
#endif

#if defined(HAVE_PRI_CCSS)
   if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
      struct ast_cc_monitor *monitor;
      char device_name[AST_CHANNEL_NAME];

      /* This is a CC recall call. */
      ast_channel_get_device_name(ast, device_name, sizeof(device_name));
      monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
      if (monitor) {
         struct sig_pri_cc_monitor_instance *instance;

         instance = monitor->private_data;

         /* If this fails then we have monitor instance ambiguity. */
         ast_assert(p->pri == instance->pri);

         if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
            /* The CC recall call failed for some reason. */
            ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
               device_name);
            ao2_ref(monitor, -1);
            pri_destroycall(p->pri->pri, p->call);
            p->call = NULL;
            pri_rel(p->pri);
            pri_sr_free(sr);
            return -1;
         }
         ao2_ref(monitor, -1);
      } else {
         core_id = -1;
      }
   } else
#endif   /* defined(HAVE_PRI_CCSS) */
   {
      core_id = -1;
   }
   if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
      ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
         c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
      pri_destroycall(p->pri->pri, p->call);
      p->call = NULL;
      pri_rel(p->pri);
      pri_sr_free(sr);
      return -1;
   }
   p->call_level = SIG_PRI_CALL_LEVEL_SETUP;
   pri_sr_free(sr);
   ast_setstate(ast, AST_STATE_DIALING);
   sig_pri_set_dialing(p, 1);
   pri_rel(p->pri);
   return 0;
}

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 9688 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.

{
   struct sig_pri_cc_agent_prv *cc_pvt;

   cc_pvt = agent->private_data;
   ast_mutex_lock(&cc_pvt->pri->lock);
   pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
   ast_mutex_unlock(&cc_pvt->pri->lock);
   return 0;
}
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 9717 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().

{
   struct sig_pri_cc_agent_prv *cc_pvt;
   int res;

   cc_pvt = agent->private_data;
   if (!cc_pvt) {
      /* The agent constructor probably failed. */
      return;
   }
   ast_mutex_lock(&cc_pvt->pri->lock);
   res = -1;
   if (cc_pvt->cc_request_response_pending) {
      res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2/* short_term_denial */);
   }
   if (res) {
      pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
   }
   ast_mutex_unlock(&cc_pvt->pri->lock);
   ast_free(cc_pvt);
}
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 9400 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().

{
   struct sig_pri_cc_agent_prv *cc_pvt;

   cc_pvt = ast_calloc(1, sizeof(*cc_pvt));
   if (!cc_pvt) {
      return -1;
   }

   ast_mutex_lock(&pvt_chan->pri->lock);
   cc_pvt->pri = pvt_chan->pri;
   cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call);
   ast_mutex_unlock(&pvt_chan->pri->lock);
   if (cc_pvt->cc_id == -1) {
      ast_free(cc_pvt);
      return -1;
   }
   agent->private_data = cc_pvt;
   return 0;
}

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 9632 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.

{
   struct sig_pri_cc_agent_prv *cc_pvt;

   cc_pvt = agent->private_data;
   ast_mutex_lock(&cc_pvt->pri->lock);
   pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
   ast_mutex_unlock(&cc_pvt->pri->lock);
   return 0;
}
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 9493 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.

{
   struct sig_pri_cc_agent_prv *cc_pvt;
   int res;
   int status;
   const char *failed_msg;
   static const char *failed_to_send = "Failed to send the CC request response.";
   static const char *not_accepted = "The core declined the CC request.";

   cc_pvt = agent->private_data;
   ast_mutex_lock(&cc_pvt->pri->lock);
   if (cc_pvt->cc_request_response_pending) {
      cc_pvt->cc_request_response_pending = 0;

      /* Convert core response reason to ISDN response status. */
      status = 2;/* short_term_denial */
      switch (reason) {
      case AST_CC_AGENT_RESPONSE_SUCCESS:
         status = 0;/* success */
         break;
      case AST_CC_AGENT_RESPONSE_FAILURE_INVALID:
         status = 2;/* short_term_denial */
         break;
      case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY:
         status = 5;/* queue_full */
         break;
      }

      res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
      if (!status) {
         /* CC core request was accepted. */
         if (res) {
            failed_msg = failed_to_send;
         } else {
            failed_msg = NULL;
         }
      } else {
         /* CC core request was declined. */
         if (res) {
            failed_msg = failed_to_send;
         } else {
            failed_msg = not_accepted;
         }
      }
   } else {
      failed_msg = NULL;
   }
   ast_mutex_unlock(&cc_pvt->pri->lock);
   if (failed_msg) {
      ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg);
   }
}

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 9661 of file sig_pri.c.

{
   /* libpri already knows when and how it needs to monitor Party A. */
   return 0;
}

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 9444 of file sig_pri.c.

{
   /* libpri maintains it's own offer timer in the form of T_RETENTION. */
   return 0;
}
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 9563 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.

{
   struct sig_pri_cc_agent_prv *cc_pvt;

   cc_pvt = agent->private_data;
   ast_mutex_lock(&cc_pvt->pri->lock);
   pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
   ast_mutex_unlock(&cc_pvt->pri->lock);
   return 0;
}

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 9465 of file sig_pri.c.

{
   /* libpri maintains it's own offer timer in the form of T_RETENTION. */
   return 0;
}

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 9598 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.

{
   struct sig_pri_cc_agent_prv *cc_pvt;

   cc_pvt = agent->private_data;
   ast_mutex_lock(&cc_pvt->pri->lock);
   pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
   ast_mutex_unlock(&cc_pvt->pri->lock);
   return 0;
}
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 9943 of file sig_pri.c.

{
   /*
    * libpri maintains it's own available timer as one of:
    * T_CCBS2/T_CCBS5/T_CCBS6/QSIG_CCBS_T2
    * T_CCNR2/T_CCNR5/T_CCNR6/QSIG_CCNR_T2
    */
   return 0;
}
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 9966 of file sig_pri.c.

References ao2_ref, and ao2_unlink.

{
   struct sig_pri_cc_monitor_instance *instance;

   instance = monitor_pvt;
   if (!instance) {
      return;
   }
   ao2_unlink(sig_pri_cc_monitors, instance);
   ao2_ref(instance, -1);
}
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 9799 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.

{
   struct sig_pri_cc_monitor_instance *instance;
   int cc_mode;
   int res;

   switch (monitor->service_offered) {
   case AST_CC_CCBS:
      cc_mode = 0;/* CCBS */
      break;
   case AST_CC_CCNR:
      cc_mode = 1;/* CCNR */
      break;
   default:
      /* CC service not supported by ISDN. */
      return -1;
   }

   instance = monitor->private_data;

   /* libpri handles it's own available timer. */
   ast_mutex_lock(&instance->pri->lock);
   res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
   ast_mutex_unlock(&instance->pri->lock);

   return res;
}
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 9898 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.

{
   struct sig_pri_cc_monitor_instance *instance;
   int cc_status;

   switch (devstate) {
   case AST_DEVICE_UNKNOWN:
   case AST_DEVICE_NOT_INUSE:
      cc_status = 0;/* free */
      break;
   case AST_DEVICE_BUSY:
   case AST_DEVICE_INUSE:
      cc_status = 1;/* busy */
      break;
   default:
      /* Don't know how to interpret this device state into free/busy status. */
      return 0;
   }
   instance = monitor->private_data;
   ast_mutex_lock(&instance->pri->lock);
   pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
   ast_mutex_unlock(&instance->pri->lock);

   return 0;
}
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 9842 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.

{
   struct sig_pri_cc_monitor_instance *instance;

   instance = monitor->private_data;
   ast_mutex_lock(&instance->pri->lock);
   pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */);
   ast_mutex_unlock(&instance->pri->lock);

   return 0;
}
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 9868 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.

{
   struct sig_pri_cc_monitor_instance *instance;

   instance = monitor->private_data;
   ast_mutex_lock(&instance->pri->lock);
   pri_cc_status(instance->pri->pri, instance->cc_id, 0/* free */);
   ast_mutex_unlock(&instance->pri->lock);

   return 0;
}
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 9136 of file sig_pri.c.

References ast_channel_softhangup_internal_flag_add(), 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().

{
   pri_grab(p, p->pri);
   sig_pri_set_alarm(p, !noalarm);
   if (!noalarm) {
      if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
         /* T309 is not enabled : destroy calls when alarm occurs */
         if (p->call) {
            pri_destroycall(p->pri->pri, p->call);
            p->call = NULL;
         }
         if (p->owner)
            ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
      }
   }
   sig_pri_span_devstate_changed(p->pri);
   pri_rel(p->pri);
}
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 9194 of file sig_pri.c.

References ast_free.

Referenced by destroy_dahdi_pvt().

{
   ast_free(doomed);
}
struct sig_pri_chan* sig_pri_chan_new ( void *  pvt_data,
struct sig_pri_span pri,
int  logicalspan,
int  channo,
int  trunkgroup 
) [read]

Definition at line 9167 of file sig_pri.c.

References ast_calloc, 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().

{
   struct sig_pri_chan *p;

   p = ast_calloc(1, sizeof(*p));
   if (!p)
      return p;

   p->logicalspan = logicalspan;
   p->prioffset = channo;
   p->mastertrunkgroup = trunkgroup;

   p->chan_pvt = pvt_data;

   p->pri = pri;

   return p;
}
void sig_pri_cli_show_channels ( int  fd,
struct sig_pri_span pri 
)

Definition at line 9207 of file sig_pri.c.

References ast_channel_name(), 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, 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().

{
   char line[256];
   int idx;
   struct sig_pri_chan *pvt;

   ast_mutex_lock(&pri->lock);
   for (idx = 0; idx < pri->numchans; ++idx) {
      if (!pri->pvts[idx]) {
         continue;
      }
      pvt = pri->pvts[idx];
      sig_pri_lock_private(pvt);
      sig_pri_lock_owner(pri, idx);
      if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
         /* Don't show held/call-waiting channels if they are not in use. */
         sig_pri_unlock_private(pvt);
         continue;
      }

      snprintf(line, sizeof(line), SIG_PRI_SC_LINE,
         pri->span,
         pvt->channel,
         pvt->no_b_channel ? "No" : "Yes",/* Has media */
         sig_pri_is_chan_available(pvt) ? "Yes" : "No",
         sig_pri_call_level2str(pvt->call_level),
         pvt->call ? "Yes" : "No",
         pvt->owner ? ast_channel_name(pvt->owner) : "");

      if (pvt->owner) {
         ast_channel_unlock(pvt->owner);
      }
      sig_pri_unlock_private(pvt);

      ast_mutex_unlock(&pri->lock);
      ast_cli(fd, "%s\n", line);
      ast_mutex_lock(&pri->lock);
   }
   ast_mutex_unlock(&pri->lock);
}

Definition at line 9201 of file sig_pri.c.

References ast_cli(), and SIG_PRI_SC_HEADER.

Referenced by handle_pri_show_channels().

{
   ast_cli(fd, SIG_PRI_SC_HEADER, "PRI",  "",     "B",    "Chan", "Call",  "PRI",  "Channel");
   ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name");
}
void sig_pri_cli_show_span ( int  fd,
int *  dchannels,
struct sig_pri_span pri 
)

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

{
   int x;
   char status[256];

   for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
      if (pri->dchans[x]) {
#ifdef PRI_DUMP_INFO_STR
         char *info_str = NULL;
#endif
         ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
         build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
         ast_cli(fd, "Status: %s\n", status);
         ast_mutex_lock(&pri->lock);
#ifdef PRI_DUMP_INFO_STR
         info_str = pri_dump_info_str(pri->pri);
         if (info_str) {
            ast_cli(fd, "%s", info_str);
            ast_std_free(info_str);
         }
#else
         pri_dump_info(pri->pri);
#endif
         ast_mutex_unlock(&pri->lock);
         ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
         ast_cli(fd, "\n");
      }
   }
}
void sig_pri_cli_show_spans ( int  fd,
int  span,
struct sig_pri_span pri 
)

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

{
   char status[256];
   int x;
   for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
      if (pri->dchans[x]) {
         build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
         ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
      }
   }
}
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 8683 of file sig_pri.c.

References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), sig_pri_chan::call_level, 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_callbacks, sig_pri_open_media(), sig_pri_set_dialing(), sig_pri_set_echocanceller(), and ast_frame::subclass.

Referenced by dahdi_handle_event().

{
   /* If we just completed 'w' deferred dialing digits, we need to answer now. */
   if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
      pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT;

      sig_pri_open_media(pvt);
      {
         struct ast_frame f = {AST_FRAME_CONTROL, };

         if (sig_pri_callbacks.queue_control) {
            sig_pri_callbacks.queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER);
         }

         f.subclass.integer = AST_CONTROL_ANSWER;
         ast_queue_frame(ast, &f);
      }
      sig_pri_set_dialing(pvt, 0);
      /* Enable echo cancellation if it's not on already */
      sig_pri_set_echocanceller(pvt, 1);
   }
}
int sig_pri_digit_begin ( struct sig_pri_chan pvt,
struct ast_channel ast,
char  digit 
)

Definition at line 8637 of file sig_pri.c.

References 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().

{
   if (ast_channel_state(ast) == AST_STATE_DIALING) {
      if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
         unsigned int len;

         len = strlen(pvt->dialdest);
         if (len < sizeof(pvt->dialdest) - 1) {
            ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
               digit);
            pvt->dialdest[len++] = digit;
            pvt->dialdest[len] = '\0';
         } else {
            ast_log(LOG_WARNING,
               "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
               pvt->pri->span, digit);
         }
         return 0;
      }
      if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
         pri_grab(pvt, pvt->pri);
         pri_information(pvt->pri->pri, pvt->call, digit);
         pri_rel(pvt->pri);
         return 0;
      }
      if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
         ast_log(LOG_WARNING,
            "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n",
            pvt->pri->span, digit, pvt->call_level,
            sig_pri_call_level2str(pvt->call_level));
      }
   }
   return 1;
}
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 7652 of file sig_pri.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), ext, and sig_pri_chan::stripmsd.

Referenced by dahdi_call(), and dahdi_request().

{
   char *dial;
   char *number;
   char *subaddr;
   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(group);  /* channel/group token */
      AST_APP_ARG(ext); /* extension token */
      //AST_APP_ARG(opts); /* options token */
      AST_APP_ARG(other);  /* Any remining unused arguments */
   );

   /* Get private copy of dial string and break it up. */
   dial = ast_strdupa(rdest);
   AST_NONSTANDARD_APP_ARGS(args, dial, '/');

   number = args.ext;
   if (!number) {
      number = "";
   }

   /* Find and extract dialed_subaddress */
   subaddr = strchr(number, ':');
   if (subaddr) {
      *subaddr++ = '\0';

      /* Skip subaddress type prefix. */
      switch (*subaddr) {
      case 'U':
      case 'u':
      case 'N':
      case 'n':
         ++subaddr;
         break;
      default:
         break;
      }
   }

   /* Skip type-of-number/dial-plan prefix characters. */
   if (strlen(number) < p->stripmsd) {
      number = "";
   } else {
      char *deferred;

      number += p->stripmsd;
      deferred = strchr(number, 'w');
      if (deferred) {
         /* Remove any 'w' deferred digits. */
         *deferred = '\0';
      }
      while (isalpha(*number)) {
         ++number;
      }
   }

   /* Fill buffer with extracted number and subaddress. */
   if (ast_strlen_zero(subaddr)) {
      /* Put in called number only since there is no subaddress. */
      snprintf(called, called_buff_size, "%s", number);
   } else {
      /* Put in called number and subaddress. */
      snprintf(called, called_buff_size, "%s:%s", number, subaddr);
   }
}
void sig_pri_fixup ( struct ast_channel oldchan,
struct ast_channel newchan,
struct sig_pri_chan pchan 
)

Definition at line 9351 of file sig_pri.c.

References sig_pri_chan::owner.

Referenced by dahdi_fixup().

{
   if (pchan->owner == oldchan) {
      pchan->owner = newchan;
   }
}
int sig_pri_hangup ( struct sig_pri_chan p,
struct ast_channel ast 
)

Definition at line 7560 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_channel_hangupcause(), ast_channel_tech_pvt(), 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, 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_MOH_EVENT_RESET, sig_pri_moh_fsm_event(), sig_pri_set_dialing(), sig_pri_set_digital(), sig_pri_set_outgoing(), sig_pri_span_devstate_changed(), sig_pri_chan::user_tag, and sig_pri_chan::waiting_for_aoce.

Referenced by dahdi_hangup().

{
   ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
   if (!ast_channel_tech_pvt(ast)) {
      ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
      return 0;
   }

   sig_pri_set_outgoing(p, 0);
   sig_pri_set_digital(p, 0); /* push up to parent for EC*/
#if defined(HAVE_PRI_CALL_WAITING)
   if (p->is_call_waiting) {
      p->is_call_waiting = 0;
      ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
   }
#endif   /* defined(HAVE_PRI_CALL_WAITING) */
   p->call_level = SIG_PRI_CALL_LEVEL_IDLE;
   p->progress = 0;
   p->cid_num[0] = '\0';
   p->cid_subaddr[0] = '\0';
   p->cid_name[0] = '\0';
   p->user_tag[0] = '\0';
   p->exten[0] = '\0';
   sig_pri_set_dialing(p, 0);

   /* Make sure we really have a call */
   pri_grab(p, p->pri);
   sig_pri_moh_fsm_event(ast, p, SIG_PRI_MOH_EVENT_RESET);
   if (p->call) {
#if defined(SUPPORT_USERUSER)
      const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");

      if (!ast_strlen_zero(useruser)) {
         pri_call_set_useruser(p->call, useruser);
      }
#endif   /* defined(SUPPORT_USERUSER) */

#if defined(HAVE_PRI_AOC_EVENTS)
      if (p->holding_aoce) {
         pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
      }
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */

      if (p->alreadyhungup) {
         ast_debug(1, "Already hungup...  Calling hangup once, and clearing call\n");

         pri_hangup(p->pri->pri, p->call, -1);
         p->call = NULL;
      } else {
         const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
         int icause = ast_channel_hangupcause(ast) ? ast_channel_hangupcause(ast) : -1;

         p->alreadyhungup = 1;
         if (!ast_strlen_zero(cause)) {
            if (atoi(cause)) {
               icause = atoi(cause);
            }
         }
         ast_debug(1,
            "Not yet hungup...  Calling hangup with cause %d, and clearing call\n",
            icause);

         pri_hangup(p->pri->pri, p->call, icause);
      }
   }
#if defined(HAVE_PRI_AOC_EVENTS)
   p->aoc_s_request_invoke_id_valid = 0;
   p->holding_aoce = 0;
   p->waiting_for_aoce = 0;
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */

   p->allocated = 0;
   p->owner = NULL;

   sig_pri_span_devstate_changed(p->pri);
   pri_rel(p->pri);
   return 0;
}
int sig_pri_indicate ( struct sig_pri_chan p,
struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)

Definition at line 8188 of file sig_pri.c.

References 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_channel_connected_effective_id(), ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_name(), ast_channel_softhangup_internal_flag_add(), AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MCID, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, 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, sig_pri_span::colp_send, sig_pri_span::cpndialplan, DAHDI_OVERLAPDIAL_INCOMING, sig_pri_chan::digital, sig_pri_span::internationalprefix, sig_pri_span::mcid_send, sig_pri_chan::moh_suggested, sig_pri_chan::mohinterpret, sig_pri_span::nationalprefix, 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::progress, PVT_TO_CHANNEL(), S_OR, 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_COLP_BLOCK, SIG_PRI_COLP_CONNECT, SIG_PRI_COLP_UPDATE, SIG_PRI_MOH_EVENT_HOLD, SIG_PRI_MOH_EVENT_UNHOLD, sig_pri_moh_fsm_event(), sig_pri_party_id_from_ast(), sig_pri_play_tone(), sig_pri_redirecting_update(), sig_pri_set_dialing(), sig_pri_set_digital(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_RINGTONE, and sig_pri_chan::waiting_for_aoce.

Referenced by dahdi_indicate().

{
   int res = -1;

   switch (condition) {
   case AST_CONTROL_BUSY:
      if (p->priindication_oob || p->no_b_channel) {
         ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
         ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
         res = 0;
         break;
      }
      res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
      if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
         ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
         p->progress = 1;/* No need to send plain PROGRESS after this. */
         if (p->pri && p->pri->pri) {
            pri_grab(p, p->pri);
#ifdef HAVE_PRI_PROG_W_CAUSE
            pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
#else
            pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
#endif
            pri_rel(p->pri);
         }
      }
      break;
   case AST_CONTROL_RINGING:
      if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
         p->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
         if (p->pri && p->pri->pri) {
            pri_grab(p, p->pri);
            pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
               p->no_b_channel || p->digital ? 0 : 1);
            pri_rel(p->pri);
         }
      }
      res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
      if (ast_channel_state(chan) != AST_STATE_UP) {
         if (ast_channel_state(chan) != AST_STATE_RING)
            ast_setstate(chan, AST_STATE_RINGING);
      }
      break;
   case AST_CONTROL_PROCEEDING:
      ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n",ast_channel_name(chan));
      if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
         p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
         if (p->pri && p->pri->pri) {
            pri_grab(p, p->pri);
            pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
               p->no_b_channel || p->digital ? 0 : 1);
            if (!p->no_b_channel && !p->digital) {
               sig_pri_set_dialing(p, 0);
            }
            pri_rel(p->pri);
         }
      }
      /* don't continue in ast_indicate */
      res = 0;
      break;
   case AST_CONTROL_PROGRESS:
      ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n",ast_channel_name(chan));
      sig_pri_set_digital(p, 0); /* Digital-only calls isn't allowing any inband progress messages */
      if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing
         && !p->no_b_channel) {
         p->progress = 1;/* No need to send plain PROGRESS again. */
         if (p->pri && p->pri->pri) {
            pri_grab(p, p->pri);
#ifdef HAVE_PRI_PROG_W_CAUSE
            pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);  /* no cause at all */
#else
            pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
#endif
            pri_rel(p->pri);
         }
      }
      /* don't continue in ast_indicate */
      res = 0;
      break;
   case AST_CONTROL_INCOMPLETE:
      /* If we are connected or if we support overlap dialing, wait for additional digits */
      if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
         res = 0;
         break;
      }
      /* Otherwise, treat as congestion */
      ast_channel_hangupcause_set(chan, AST_CAUSE_INVALID_NUMBER_FORMAT);
      /* Falls through */
   case AST_CONTROL_CONGESTION:
      if (p->priindication_oob || p->no_b_channel) {
         /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
         switch (ast_channel_hangupcause(chan)) {
         case AST_CAUSE_USER_BUSY:
         case AST_CAUSE_NORMAL_CLEARING:
         case 0:/* Cause has not been set. */
            /* Supply a more appropriate cause. */
            ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
            break;
         default:
            break;
         }
         ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
         res = 0;
         break;
      }
      res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
      if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
         /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
         switch (ast_channel_hangupcause(chan)) {
         case AST_CAUSE_USER_BUSY:
         case AST_CAUSE_NORMAL_CLEARING:
         case 0:/* Cause has not been set. */
            /* Supply a more appropriate cause. */
            ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
            break;
         default:
            break;
         }
         p->progress = 1;/* No need to send plain PROGRESS after this. */
         if (p->pri && p->pri->pri) {
            pri_grab(p, p->pri);
#ifdef HAVE_PRI_PROG_W_CAUSE
            pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
#else
            pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
#endif
            pri_rel(p->pri);
         }
      }
      break;
   case AST_CONTROL_HOLD:
      ast_copy_string(p->moh_suggested, S_OR(data, ""), sizeof(p->moh_suggested));
      if (p->pri) {
         pri_grab(p, p->pri);
         sig_pri_moh_fsm_event(chan, p, SIG_PRI_MOH_EVENT_HOLD);
         pri_rel(p->pri);
      } else {
         /* Something is wrong here.  A PRI channel without the pri pointer? */
         ast_moh_start(chan, data, p->mohinterpret);
      }
      break;
   case AST_CONTROL_UNHOLD:
      if (p->pri) {
         pri_grab(p, p->pri);
         sig_pri_moh_fsm_event(chan, p, SIG_PRI_MOH_EVENT_UNHOLD);
         pri_rel(p->pri);
      } else {
         /* Something is wrong here.  A PRI channel without the pri pointer? */
         ast_moh_stop(chan);
      }
      break;
   case AST_CONTROL_SRCUPDATE:
      res = 0;
      break;
   case -1:
      res = sig_pri_play_tone(p, -1);
      break;
   case AST_CONTROL_CONNECTED_LINE:
      ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", ast_channel_name(chan));
      if (p->pri) {
         struct pri_party_connected_line connected;
         int dialplan;
         int prefix_strip;
         int colp_allowed = 0;
         struct ast_party_id connected_id = ast_channel_connected_effective_id(chan);

         pri_grab(p, p->pri);

         /* Check if a connected line update is allowed at this time. */
         switch (p->pri->colp_send) {
         case SIG_PRI_COLP_BLOCK:
            break;
         case SIG_PRI_COLP_CONNECT:
            /*
             * Outgoing calls receive CONNECT and act like an update before
             * the call is connected.
             */
            if (p->call_level <= SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
               colp_allowed = 1;
            }
            break;
         case SIG_PRI_COLP_UPDATE:
            colp_allowed = 1;
            break;
         }
         if (!colp_allowed) {
            pri_rel(p->pri);
            ast_debug(1, "Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
               ast_channel_name(chan));
            break;
         }

         memset(&connected, 0, sizeof(connected));
         sig_pri_party_id_from_ast(&connected.id, &connected_id);

         /* Determine the connected line numbering plan to actually use. */
         switch (p->pri->cpndialplan) {
         case -2:/* redundant */
         case -1:/* dynamic */
            /* compute dynamically */
            prefix_strip = 0;
            if (!strncmp(connected.id.number.str, p->pri->internationalprefix,
               strlen(p->pri->internationalprefix))) {
               prefix_strip = strlen(p->pri->internationalprefix);
               dialplan = PRI_INTERNATIONAL_ISDN;
            } else if (!strncmp(connected.id.number.str, p->pri->nationalprefix,
               strlen(p->pri->nationalprefix))) {
               prefix_strip = strlen(p->pri->nationalprefix);
               dialplan = PRI_NATIONAL_ISDN;
            } else {
               dialplan = PRI_LOCAL_ISDN;
            }
            connected.id.number.plan = dialplan;

            if (prefix_strip && p->pri->cpndialplan != -2) {
               /* Strip the prefix from the connected line number. */
               memmove(connected.id.number.str,
                  connected.id.number.str + prefix_strip,
                  strlen(connected.id.number.str + prefix_strip) + 1);
            }
            break;
         case 0:/* from_channel */
            /* Use the numbering plan passed in. */
            break;
         default:
            connected.id.number.plan = p->pri->cpndialplan - 1;
            break;
         }

         pri_connected_line_update(p->pri->pri, p->call, &connected);
         pri_rel(p->pri);
      }
      break;
   case AST_CONTROL_REDIRECTING:
      ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", ast_channel_name(chan));
      if (p->pri) {
         pri_grab(p, p->pri);
         sig_pri_redirecting_update(p, chan);
         pri_rel(p->pri);
      }
      break;
   case AST_CONTROL_AOC:
#if defined(HAVE_PRI_AOC_EVENTS)
      {
         struct ast_aoc_decoded *decoded
            = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
         ast_debug(1, "Received AST_CONTROL_AOC on %s\n", ast_channel_name(chan));
         if (decoded && p->pri) {
            pri_grab(p, p->pri);
            switch (ast_aoc_get_msg_type(decoded)) {
            case AST_AOC_S:
               if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
                  sig_pri_aoc_s_from_ast(p, decoded);
               }
               break;
            case AST_AOC_D:
               if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
                  sig_pri_aoc_d_from_ast(p, decoded);
               }
               break;
            case AST_AOC_E:
               if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
                  sig_pri_aoc_e_from_ast(p, decoded);
               }
               /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
                * will be set.  A hangup is already occuring via a timeout during
                * this delay.  Instead of waiting for that timeout to occur, go ahead
                * and initiate the softhangup since the delay is no longer necessary */
               if (p->waiting_for_aoce) {
                  p->waiting_for_aoce = 0;
                  ast_debug(1,
                     "Received final AOC-E msg, continue with hangup on %s\n",
                     ast_channel_name(chan));
                  ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
               }
               break;
            case AST_AOC_REQUEST:
               /* We do not pass through AOC requests, So unless this
                * is an AOC termination request it will be ignored */
               if (ast_aoc_get_termination_request(decoded)) {
                  pri_hangup(p->pri->pri, p->call, -1);
               }
               break;
            default:
               break;
            }
            pri_rel(p->pri);
         }
         ast_aoc_destroy_decoded(decoded);
      }
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */
      break;
#if defined(HAVE_PRI_MCID)
   case AST_CONTROL_MCID:
      if (p->pri && p->pri->pri && p->pri->mcid_send) {
         pri_grab(p, p->pri);
         pri_mcid_req_send(p->pri->pri, p->call);
         pri_rel(p->pri);
      }
      break;
#endif   /* defined(HAVE_PRI_MCID) */
   }

   return res;
}
void sig_pri_init_pri ( struct sig_pri_span pri)

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

{
   int i;

   memset(pri, 0, sizeof(*pri));

   ast_mutex_init(&pri->lock);

   pri->master = AST_PTHREADT_NULL;
   for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
      pri->fds[i] = -1;
}
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 9162 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().

{
   return pri->layer1_ignored;
}
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 1184 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().

{
   return !sig_pri_is_chan_in_use(pvt)
#if defined(HAVE_PRI_SERVICE_MESSAGES)
      /* And not out-of-service */
      && !pvt->service_status
#endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
      ;
}
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 9988 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().

{
#if defined(HAVE_PRI_CCSS)
   sig_pri_cc_type_name = cc_type_name;
   sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
      sig_pri_cc_monitor_instance_cmp_fn);
   if (!sig_pri_cc_monitors) {
      return -1;
   }
#endif   /* defined(HAVE_PRI_CCSS) */
   return 0;
}
struct ast_channel* sig_pri_request ( struct sig_pri_chan p,
enum sig_pri_law  law,
const struct ast_channel requestor,
int  transfercapability 
) [read]

Definition at line 1037 of file sig_pri.c.

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

Referenced by dahdi_request(), and pri_dchannel().

{
   struct ast_channel *ast;

   ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);

   sig_pri_set_outgoing(p, 1);
   ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
   if (!ast) {
      sig_pri_set_outgoing(p, 0);
   }
   return ast;
}
void sig_pri_sendtext ( struct sig_pri_chan p,
const char *  text 
)

Send display text.

Since:
10.0
Parameters:
pChannel to send text over
textText to send.
Returns:
Nothing

Definition at line 9368 of file sig_pri.c.

References ast_copy_string(), sig_pri_chan::call, sig_pri_chan::pri, sig_pri_span::pri, pri_grab(), and pri_rel().

Referenced by dahdi_sendtext().

{
   struct pri_subcmd_display_txt display;

   if (p->pri && p->pri->pri) {
      ast_copy_string(display.text, text, sizeof(display.text));
      display.length = strlen(display.text);
      display.char_set = 0;/* unknown(0) */
      pri_grab(p, p->pri);
      pri_display_text(p->pri->pri, p->call, &display);
      pri_rel(p->pri);
   }
}
void sig_pri_set_alarm ( struct sig_pri_chan p,
int  in_alarm 
)

Definition at line 192 of file sig_pri.c.

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

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

{
   if (sig_pri_is_alarm_ignored(p->pri)) {
      /* Always set not in alarm */
      in_alarm = 0;
   }

   /*
    * Clear the channel restart state when the channel alarm
    * changes to prevent the state from getting stuck when the link
    * goes down.
    */
   p->resetting = SIG_PRI_RESET_IDLE;

   p->inalarm = in_alarm;
   if (sig_pri_callbacks.set_alarm) {
      sig_pri_callbacks.set_alarm(p->chan_pvt, in_alarm);
   }
}
int sig_pri_start_pri ( struct sig_pri_span pri)

Definition at line 8909 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::datetime_send, sig_pri_span::dchans, sig_pri_span::display_flags_receive, sig_pri_span::display_flags_send, 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, LOG_WARNING, sig_pri_span::master, sig_pri_span::mbox, sig_pri_span::mwi_mailboxes, sig_pri_span::mwi_vm_numbers, 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, sig_pri_mbox::sub, sig_pri_span::switchtype, and sig_pri_mbox::vm_number.

Referenced by setup_dahdi_int().

{
   int x;
   int i;
#if defined(HAVE_PRI_MWI)
   char *saveptr;
   char *prev_vm_number;
   struct ast_str *mwi_description = ast_str_alloca(64);
#endif   /* defined(HAVE_PRI_MWI) */

#if defined(HAVE_PRI_MWI)
   /* Prepare the mbox[] for use. */
   for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
      if (pri->mbox[i].sub) {
         pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
      }
   }
#endif   /* defined(HAVE_PRI_MWI) */

   ast_mutex_init(&pri->lock);
   sig_pri_sort_pri_chans(pri);

#if defined(HAVE_PRI_MWI)
   /*
    * Split the mwi_vm_numbers configuration string into the mbox[].vm_number:
    * vm_number{,vm_number}
    */
   prev_vm_number = NULL;
   saveptr = pri->mwi_vm_numbers;
   for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
      char *vm_number;

      vm_number = strsep(&saveptr, ",");
      if (vm_number) {
         vm_number = ast_strip(vm_number);
      }
      if (ast_strlen_zero(vm_number)) {
         /* There was no number so reuse the previous number. */
         vm_number = prev_vm_number;
      } else {
         /* We have a new number. */
         prev_vm_number = vm_number;
      }
      pri->mbox[i].vm_number = vm_number;
   }

   /*
    * Split the mwi_mailboxes configuration string into the mbox[]:
    * mailbox_number[@context]{,mailbox_number[@context]}
    */
   saveptr = pri->mwi_mailboxes;
   for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
      char *mbox_number;
      char *mbox_context;

      mbox_number = strsep(&saveptr, ",");
      if (!mbox_number) {
         /* No more defined mailboxes. */
         break;
      }
      /* Split the mailbox_number and context */
      mbox_context = strchr(mbox_number, '@');
      if (mbox_context) {
         *mbox_context++ = '\0';
         mbox_context = ast_strip(mbox_context);
      }
      mbox_number = ast_strip(mbox_number);
      if (ast_strlen_zero(mbox_number)) {
         /* There is no mailbox number.  Skip it. */
         continue;
      }
      if (ast_strlen_zero(mbox_context)) {
         /* There was no context so use the default. */
         mbox_context = "default";
      }

      /* Fill the mbox[] element. */
      pri->mbox[i].number = mbox_number;
      pri->mbox[i].context = mbox_context;
      ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
         sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
      pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
         ast_str_buffer(mwi_description), pri,
         AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
         AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
         AST_EVENT_IE_END);
      if (!pri->mbox[i].sub) {
         ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
            sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
      }
#if defined(HAVE_PRI_MWI_V2)
      if (ast_strlen_zero(pri->mbox[i].vm_number)) {
         ast_log(LOG_WARNING, "%s span %d MWI voicemail number for %s@%s is empty.\n",
            sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
      }
#endif   /* defined(HAVE_PRI_MWI_V2) */
   }
#endif   /* defined(HAVE_PRI_MWI) */

   for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
      if (pri->fds[i] == -1) {
         break;
      }

      switch (pri->sig) {
      case SIG_BRI:
         pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
         break;
      case SIG_BRI_PTMP:
         pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
         break;
      default:
         pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
#if defined(HAVE_PRI_SERVICE_MESSAGES)
         if (pri->enable_service_message_support) {
            pri_set_service_message_support(pri->dchans[i], 1);
         }
#endif   /* defined(HAVE_PRI_SERVICE_MESSAGES) */
         break;
      }

      pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
#ifdef HAVE_PRI_PROG_W_CAUSE
      pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
#endif
#ifdef HAVE_PRI_INBANDDISCONNECT
      pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
#endif
      /* Enslave to master if appropriate */
      if (i)
         pri_enslave(pri->dchans[0], pri->dchans[i]);
      if (!pri->dchans[i]) {
         if (pri->fds[i] > 0)
            close(pri->fds[i]);
         pri->fds[i] = -1;
         ast_log(LOG_ERROR, "Unable to create PRI structure\n");
         return -1;
      }
      pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
      pri_set_nsf(pri->dchans[i], pri->nsf);
#ifdef PRI_GETSET_TIMERS
      for (x = 0; x < PRI_MAX_TIMERS; x++) {
         if (pri->pritimers[x] != 0)
            pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
      }
#endif
   }

   /* Assume primary is the one we use */
   pri->pri = pri->dchans[0];

#if defined(HAVE_PRI_CALL_HOLD)
   pri_hold_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_CALL_HOLD) */
#if defined(HAVE_PRI_CALL_REROUTING)
   pri_reroute_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_CALL_REROUTING) */
#if defined(HAVE_PRI_HANGUP_FIX)
   pri_hangup_fix_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_HANGUP_FIX) */
#if defined(HAVE_PRI_CCSS)
   pri_cc_enable(pri->pri, 1);
   pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
   pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
   pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
#endif   /* defined(HAVE_PRI_CCSS) */
#if defined(HAVE_PRI_TRANSFER)
   pri_transfer_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_TRANSFER) */
#if defined(HAVE_PRI_AOC_EVENTS)
   pri_aoc_events_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_AOC_EVENTS) */
#if defined(HAVE_PRI_CALL_WAITING)
   pri_connect_ack_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_CALL_WAITING) */
#if defined(HAVE_PRI_MCID)
   pri_mcid_enable(pri->pri, 1);
#endif   /* defined(HAVE_PRI_MCID) */
#if defined(HAVE_PRI_DISPLAY_TEXT)
   pri_display_options_send(pri->pri, pri->display_flags_send);
   pri_display_options_receive(pri->pri, pri->display_flags_receive);
#endif   /* defined(HAVE_PRI_DISPLAY_TEXT) */
#if defined(HAVE_PRI_DATETIME_SEND)
   pri_date_time_send_option(pri->pri, pri->datetime_send);
#endif   /* defined(HAVE_PRI_DATETIME_SEND) */
#if defined(HAVE_PRI_L2_PERSISTENCE)
   pri_persistent_layer2_option(pri->pri, pri->l2_persistence);
#endif   /* defined(HAVE_PRI_L2_PERSISTENCE) */

   pri->resetpos = -1;
   if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
      for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
         if (!pri->dchans[i])
            break;
         if (pri->fds[i] > 0)
            close(pri->fds[i]);
         pri->fds[i] = -1;
      }
      ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
      return -1;
   }

#if defined(HAVE_PRI_MWI)
   /*
    * Send the initial MWI indications from the event cache for this span.
    *
    * If we were loaded after app_voicemail the event would already be in
    * the cache.  If we were loaded before app_voicemail the event would not
    * be in the cache yet and app_voicemail will send the event when it
    * gets loaded.
    */
   sig_pri_mwi_cache_update(pri);
#endif   /* defined(HAVE_PRI_MWI) */

   return 0;
}
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 8844 of file sig_pri.c.

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

Referenced by __unload_module().

{
#if defined(HAVE_PRI_MWI)
   int idx;
#endif   /* defined(HAVE_PRI_MWI) */

#if defined(HAVE_PRI_MWI)
   for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
      if (pri->mbox[idx].sub) {
         pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
      }
   }
#endif   /* defined(HAVE_PRI_MWI) */
}
void sig_pri_unload ( void  )

Unload the sig_pri submodule.

Since:
1.8
Returns:
Nothing

Definition at line 10007 of file sig_pri.c.

References ao2_ref.

Referenced by __unload_module().

{
#if defined(HAVE_PRI_CCSS)
   if (sig_pri_cc_monitors) {
      ao2_ref(sig_pri_cc_monitors, -1);
      sig_pri_cc_monitors = NULL;
   }
#endif   /* defined(HAVE_PRI_CCSS) */
}

Variable Documentation

const char dahdi_db[] = "dahdi/registry" [static]

The AstDB family.

Definition at line 273 of file sig_pri.h.

Referenced by destroy_all_channels(), handle_pri_service_generic(), mkintf(), and pri_dchannel().