mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Since Doxygen 1.8.16, a special comment block is required. Otherwise (pure C comment), the group command is ignored. Additionally, several unbalanced group commands were fixed. ASTERISK-29732 Change-Id: I4687857b9d56e6f44fd440b73af156691660202e
		
			
				
	
	
		
			1897 lines
		
	
	
		
			92 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1897 lines
		
	
	
		
			92 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Asterisk -- An open source telephony toolkit.
 | |
|  *
 | |
|  * Copyright (C) 2010, Digium, Inc.
 | |
|  *
 | |
|  * See http://www.asterisk.org for more information about
 | |
|  * the Asterisk project. Please do not directly contact
 | |
|  * any of the maintainers of this project for assistance;
 | |
|  * the project provides a web site, mailing lists and IRC
 | |
|  * channels for your use.
 | |
|  *
 | |
|  * This program is free software, distributed under the terms of
 | |
|  * the GNU General Public License Version 2. See the LICENSE file
 | |
|  * at the top of the source tree.
 | |
|  */
 | |
| 
 | |
| /*!
 | |
|  * \file
 | |
|  * \brief chan_sip header file
 | |
|  */
 | |
| 
 | |
| #ifndef _SIP_H
 | |
| #define _SIP_H
 | |
| 
 | |
| #include "asterisk.h"
 | |
| 
 | |
| #include "asterisk/stringfields.h"
 | |
| #include "asterisk/linkedlists.h"
 | |
| #include "asterisk/strings.h"
 | |
| #include "asterisk/tcptls.h"
 | |
| #include "asterisk/test.h"
 | |
| #include "asterisk/channel.h"
 | |
| #include "asterisk/app.h"
 | |
| #include "asterisk/indications.h"
 | |
| #include "asterisk/security_events.h"
 | |
| #include "asterisk/features.h"
 | |
| #include "asterisk/rtp_engine.h"
 | |
| #include "asterisk/netsock2.h"
 | |
| #include "asterisk/features_config.h"
 | |
| 
 | |
| #include "route.h"
 | |
| 
 | |
| #ifndef FALSE
 | |
| #define FALSE    0
 | |
| #endif
 | |
| 
 | |
| #ifndef TRUE
 | |
| #define TRUE     1
 | |
| #endif
 | |
| 
 | |
| /* Arguments for sip_find_peer */
 | |
| #define FINDUSERS (1 << 0)
 | |
| #define FINDPEERS (1 << 1)
 | |
| #define FINDALLDEVICES (FINDUSERS | FINDPEERS)
 | |
| 
 | |
| #define	SIPBUFSIZE      512             /*!< Buffer size for many operations */
 | |
| 
 | |
| #define XMIT_ERROR      -2
 | |
| 
 | |
| #define SIP_RESERVED    ";/?:@&=+$,# "  /*!< Reserved characters in the username part of the URI */
 | |
| 
 | |
| #define DEFAULT_DEFAULT_EXPIRY       120
 | |
| #define DEFAULT_MIN_EXPIRY           60
 | |
| #define DEFAULT_MAX_EXPIRY           3600
 | |
| #define DEFAULT_MWI_EXPIRY           3600
 | |
| #define DEFAULT_REGISTRATION_TIMEOUT 20
 | |
| #define DEFAULT_MAX_FORWARDS         70
 | |
| 
 | |
| #define DEFAULT_AUTHLIMIT            100
 | |
| #define DEFAULT_AUTHTIMEOUT          30
 | |
| 
 | |
| /* guard limit must be larger than guard secs */
 | |
| /* guard min must be < 1000, and should be >= 250 */
 | |
| #define EXPIRY_GUARD_SECS    15   /*!< How long before expiry do we reregister */
 | |
| #define EXPIRY_GUARD_LIMIT   30   /*!< Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS */
 | |
| #define EXPIRY_GUARD_MIN     500  /*!< This is the minimum guard time applied. If
 | |
|                                    *   GUARD_PCT turns out to be lower than this, it
 | |
|                                    *   will use this time instead.
 | |
|                                    *   This is in milliseconds.
 | |
| 								   */
 | |
| #define EXPIRY_GUARD_PCT     0.20 /*!< Percentage of expires timeout to use when
 | |
|                                    *   below EXPIRY_GUARD_LIMIT */
 | |
| #define DEFAULT_EXPIRY       900  /*!< Expire slowly */
 | |
| 
 | |
| #define DEFAULT_QUALIFY_GAP   100
 | |
| #define DEFAULT_QUALIFY_PEERS 1
 | |
| 
 | |
| #define CALLERID_UNKNOWN          "Anonymous"
 | |
| #define FROMDOMAIN_INVALID        "anonymous.invalid"
 | |
| 
 | |
| #define DEFAULT_MAXMS             2000        /*!< Qualification: Must be faster than 2 seconds by default */
 | |
| #define DEFAULT_QUALIFYFREQ       60 * 1000   /*!< Qualification: How often to check for the host to be up */
 | |
| #define DEFAULT_FREQ_NOTOK        10 * 1000   /*!< Qualification: How often to check, if the host is down... */
 | |
| 
 | |
| #define DEFAULT_RETRANS           1000        /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */
 | |
| #define DEFAULT_TIMER_T1          500         /*!< SIP timer T1 (according to RFC 3261) */
 | |
| #define SIP_TRANS_TIMEOUT         64 * DEFAULT_TIMER_T1 /*!< SIP request timeout (rfc 3261) 64*T1
 | |
|                                                          *  \todo Use known T1 for timeout (peerpoke)
 | |
|                                                          */
 | |
| #define DEFAULT_TRANS_TIMEOUT     -1     /*!< Use default SIP transaction timeout */
 | |
| #define PROVIS_KEEPALIVE_TIMEOUT  60000  /*!< How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1) */
 | |
| #define MAX_AUTHTRIES             3      /*!< Try authentication three times, then fail */
 | |
| 
 | |
| #define SIP_MAX_HEADERS           64     /*!< Max amount of SIP headers to read */
 | |
| #define SIP_MAX_LINES             256    /*!< Max amount of lines in SIP attachment (like SDP) */
 | |
| #define SIP_MAX_PACKET_SIZE       20480  /*!< Max SIP packet size */
 | |
| #define SIP_MIN_PACKET            4096   /*!< Initialize size of memory to allocate for packets */
 | |
| #define MAX_HISTORY_ENTRIES		  50	 /*!< Max entires in the history list for a sip_pvt */
 | |
| 
 | |
| #define INITIAL_CSEQ              101    /*!< Our initial sip sequence number */
 | |
| 
 | |
| #define DEFAULT_MAX_SE            1800   /*!< Session-Timer Default Session-Expires period (RFC 4028) */
 | |
| #define DEFAULT_MIN_SE            90     /*!< Session-Timer Default Min-SE period (RFC 4028) */
 | |
| 
 | |
| #define SDP_MAX_RTPMAP_CODECS     32     /*!< Maximum number of codecs allowed in received SDP */
 | |
| 
 | |
| #define RTP     1
 | |
| #define NO_RTP  0
 | |
| 
 | |
| #define DEC_CALL_LIMIT   0
 | |
| #define INC_CALL_LIMIT   1
 | |
| #define DEC_CALL_RINGING 2
 | |
| #define INC_CALL_RINGING 3
 | |
| 
 | |
| /*! Define SIP option tags, used in Require: and Supported: headers
 | |
|  *  We need to be aware of these properties in the phones to use
 | |
|  *  the replace: header. We should not do that without knowing
 | |
|  *  that the other end supports it...
 | |
|  *  This is nothing we can configure, we learn by the dialog
 | |
|  *  Supported: header on the REGISTER (peer) or the INVITE
 | |
|  *  (other devices)
 | |
|  *  We are not using many of these today, but will in the future.
 | |
|  *  This is documented in RFC 3261
 | |
|  */
 | |
| #define SUPPORTED       1
 | |
| #define NOT_SUPPORTED   0
 | |
| 
 | |
| /* SIP options */
 | |
| #define SIP_OPT_REPLACES      (1 << 0)
 | |
| #define SIP_OPT_100REL        (1 << 1)
 | |
| #define SIP_OPT_TIMER         (1 << 2)
 | |
| #define SIP_OPT_EARLY_SESSION (1 << 3)
 | |
| #define SIP_OPT_JOIN          (1 << 4)
 | |
| #define SIP_OPT_PATH          (1 << 5)
 | |
| #define SIP_OPT_PREF          (1 << 6)
 | |
| #define SIP_OPT_PRECONDITION  (1 << 7)
 | |
| #define SIP_OPT_PRIVACY       (1 << 8)
 | |
| #define SIP_OPT_SDP_ANAT      (1 << 9)
 | |
| #define SIP_OPT_SEC_AGREE     (1 << 10)
 | |
| #define SIP_OPT_EVENTLIST     (1 << 11)
 | |
| #define SIP_OPT_GRUU          (1 << 12)
 | |
| #define SIP_OPT_TARGET_DIALOG (1 << 13)
 | |
| #define SIP_OPT_NOREFERSUB    (1 << 14)
 | |
| #define SIP_OPT_HISTINFO      (1 << 15)
 | |
| #define SIP_OPT_RESPRIORITY   (1 << 16)
 | |
| #define SIP_OPT_FROMCHANGE    (1 << 17)
 | |
| #define SIP_OPT_RECLISTINV    (1 << 18)
 | |
| #define SIP_OPT_RECLISTSUB    (1 << 19)
 | |
| #define SIP_OPT_OUTBOUND      (1 << 20)
 | |
| #define SIP_OPT_UNKNOWN       (1 << 21)
 | |
| 
 | |
| /*! \brief SIP Methods we support
 | |
|  *  \todo This string should be set dynamically. We only support REFER and SUBSCRIBE if we have
 | |
|  *  allowsubscribe and allowrefer on in sip.conf.
 | |
|  */
 | |
| #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE"
 | |
| 
 | |
| /*! \brief Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS */
 | |
| #define STANDARD_SIP_PORT	5060
 | |
| /*! \brief Standard SIP TLS port from RFC 3261. DO NOT CHANGE THIS */
 | |
| #define STANDARD_TLS_PORT	5061
 | |
| 
 | |
| /*! \note in many SIP headers, absence of a port number implies port 5060,
 | |
|  * and this is why we cannot change the above constant.
 | |
|  * There is a limited number of places in asterisk where we could,
 | |
|  * in principle, use a different "default" port number, but
 | |
|  * we do not support this feature at the moment.
 | |
|  * You can run Asterisk with SIP on a different port with a configuration
 | |
|  * option. If you change this value in the source code, the signalling will be incorrect.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| /*! \name DefaultValues Default values, set and reset in reload_config before reading configuration
 | |
| 
 | |
|    These are default values in the source. There are other recommended values in the
 | |
|    sip.conf.sample for new installations. These may differ to keep backwards compatibility,
 | |
|    yet encouraging new behaviour on new installations
 | |
| 
 | |
|    @{
 | |
|  */
 | |
| #define DEFAULT_CONTEXT        "default"  /*!< The default context for [general] section as well as devices */
 | |
| #define DEFAULT_RECORD_FEATURE   "automon"  /*!< The default feature specified for use with INFO */
 | |
| #define DEFAULT_MOHINTERPRET   "default"  /*!< The default music class */
 | |
| #define DEFAULT_MOHSUGGEST     ""
 | |
| #define DEFAULT_VMEXTEN        "asterisk" /*!< Default voicemail extension */
 | |
| #define DEFAULT_CALLERID       "asterisk" /*!< Default caller ID */
 | |
| #define DEFAULT_MWI_FROM       ""
 | |
| #define DEFAULT_NOTIFYMIME     "application/simple-message-summary"
 | |
| #define DEFAULT_ALLOWGUEST     TRUE
 | |
| #define DEFAULT_RTPKEEPALIVE   0      /*!< Default RTPkeepalive setting */
 | |
| #define DEFAULT_CALLCOUNTER    FALSE   /*!< Do not enable call counters by default */
 | |
| #define DEFAULT_SRVLOOKUP      TRUE    /*!< Recommended setting is ON */
 | |
| #define DEFAULT_COMPACTHEADERS FALSE  /*!< Send compact (one-character) SIP headers. Default off */
 | |
| #define DEFAULT_TOS_SIP        0      /*!< Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions. */
 | |
| #define DEFAULT_TOS_AUDIO      0      /*!< Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions. */
 | |
| #define DEFAULT_TOS_VIDEO      0      /*!< Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions. */
 | |
| #define DEFAULT_TOS_TEXT       0      /*!< Text packets should be marked as XXXX XXXX, but the default is 0 to be compatible with previous versions. */
 | |
| #define DEFAULT_COS_SIP        4      /*!< Level 2 class of service for SIP signalling */
 | |
| #define DEFAULT_COS_AUDIO      5      /*!< Level 2 class of service for audio media  */
 | |
| #define DEFAULT_COS_VIDEO      6      /*!< Level 2 class of service for video media */
 | |
| #define DEFAULT_COS_TEXT       5      /*!< Level 2 class of service for text media (T.140) */
 | |
| #define DEFAULT_ALLOW_EXT_DOM  TRUE    /*!< Allow external domains */
 | |
| #define DEFAULT_REALM          "asterisk" /*!< Realm for HTTP digest authentication */
 | |
| #define DEFAULT_DOMAINSASREALM FALSE    /*!< Use the domain option to guess the realm for registration and invite requests */
 | |
| #define DEFAULT_NOTIFYRINGING  NOTIFYRINGING_ENABLED /*!< Notify devicestate system on ringing state */
 | |
| #define DEFAULT_NOTIFYCID      DISABLED	/*!< Include CID with ringing notifications */
 | |
| #define DEFAULT_PEDANTIC       TRUE     /*!< Follow SIP standards for dialog matching */
 | |
| #define DEFAULT_AUTOCREATEPEER AUTOPEERS_DISABLED    /*!< Don't create peers automagically */
 | |
| #define	DEFAULT_MATCHEXTERNADDRLOCALLY FALSE /*!< Match extern IP locally default setting */
 | |
| #define DEFAULT_QUALIFY        FALSE    /*!< Don't monitor devices */
 | |
| #define DEFAULT_KEEPALIVE      0        /*!< Don't send keep alive packets */
 | |
| #define DEFAULT_KEEPALIVE_INTERVAL 60   /*!< Send keep alive packets at 60 second intervals */
 | |
| #define DEFAULT_ALWAYSAUTHREJECT  TRUE  /*!< Don't reject authentication requests always */
 | |
| #define DEFAULT_AUTH_OPTIONS  FALSE
 | |
| #define DEFAULT_AUTH_MESSAGE  TRUE
 | |
| #define DEFAULT_ACCEPT_OUTOFCALL_MESSAGE TRUE
 | |
| #define DEFAULT_REGEXTENONQUALIFY FALSE
 | |
| #define DEFAULT_LEGACY_USEROPTION_PARSING FALSE
 | |
| #define DEFAULT_SEND_DIVERSION TRUE
 | |
| #define DEFAULT_T1MIN             100   /*!< 100 MS for minimal roundtrip time */
 | |
| #define DEFAULT_MAX_CALL_BITRATE (384)  /*!< Max bitrate for video */
 | |
| #ifndef DEFAULT_USERAGENT
 | |
| #define DEFAULT_USERAGENT  "Asterisk PBX"  /*!< Default Useragent: header unless re-defined in sip.conf */
 | |
| #define DEFAULT_SDPSESSION "Asterisk PBX"  /*!< Default SDP session name, (s=) header unless re-defined in sip.conf */
 | |
| #define DEFAULT_SDPOWNER   "root"          /*!< Default SDP username field in (o=) header unless re-defined in sip.conf */
 | |
| #define DEFAULT_ENGINE     "asterisk"      /*!< Default RTP engine to use for sessions */
 | |
| #define DEFAULT_STORE_SIP_CAUSE FALSE      /*!< Don't store HASH(SIP_CAUSE,<channel name>) for channels by default */
 | |
| #endif
 | |
| 
 | |
| /*! @} */
 | |
| 
 | |
| /*! \name SIPflags
 | |
| 	Various flags for the flags field in the pvt structure
 | |
| 	Trying to sort these up (one or more of the following):
 | |
| 	D: Dialog
 | |
| 	P: Peer/user
 | |
| 	G: Global flag
 | |
| 	When flags are used by multiple structures, it is important that
 | |
| 	they have a common layout so it is easy to copy them.
 | |
|    @{
 | |
|  */
 | |
| #define SIP_OUTGOING        (1 << 0) /*!< D: Direction of the last transaction in this dialog */
 | |
| #define SIP_OFFER_CC        (1 << 1) /*!< D: Offer CC on subsequent responses */
 | |
| #define SIP_RINGING         (1 << 2) /*!< D: Have sent 180 ringing */
 | |
| #define SIP_PROGRESS_SENT   (1 << 3) /*!< D: Have sent 183 message progress */
 | |
| #define SIP_NEEDREINVITE    (1 << 4) /*!< D: Do we need to send another reinvite? */
 | |
| #define SIP_PENDINGBYE      (1 << 5) /*!< D: Need to send bye after we ack? */
 | |
| #define SIP_GOTREFER        (1 << 6) /*!< D: Got a refer? */
 | |
| #define SIP_CALL_LIMIT      (1 << 7) /*!< D: Call limit enforced for this call */
 | |
| #define SIP_INC_COUNT       (1 << 8) /*!< D: Did this dialog increment the counter of in-use calls? */
 | |
| #define SIP_INC_RINGING     (1 << 9) /*!< D: Did this connection increment the counter of in-use calls? */
 | |
| #define SIP_DEFER_BYE_ON_TRANSFER	(1 << 10) /*!< D: Do not hangup at first ast_hangup */
 | |
| 
 | |
| #define SIP_PROMISCREDIR    (1 << 11) /*!< DP: Promiscuous redirection */
 | |
| #define SIP_TRUSTRPID       (1 << 12) /*!< DP: Trust RPID headers? */
 | |
| #define SIP_USEREQPHONE     (1 << 13) /*!< DP: Add user=phone to numeric URI. Default off */
 | |
| #define SIP_USECLIENTCODE   (1 << 14) /*!< DP: Trust X-ClientCode info message */
 | |
| 
 | |
| /* DTMF flags - see str2dtmfmode() and dtmfmode2str() */
 | |
| #define SIP_DTMF            (7 << 15) /*!< DP: DTMF Support: five settings, uses three bits */
 | |
| #define SIP_DTMF_RFC2833    (0 << 15) /*!< DP: DTMF Support: RTP DTMF - "rfc2833" */
 | |
| #define SIP_DTMF_INBAND     (1 << 15) /*!< DP: DTMF Support: Inband audio, only for ULAW/ALAW - "inband" */
 | |
| #define SIP_DTMF_INFO       (2 << 15) /*!< DP: DTMF Support: SIP Info messages - "info" */
 | |
| #define SIP_DTMF_AUTO       (3 << 15) /*!< DP: DTMF Support: AUTO switch between rfc2833 and in-band DTMF */
 | |
| #define SIP_DTMF_SHORTINFO  (4 << 15) /*!< DP: DTMF Support: SIP Info messages - "info" - short variant */
 | |
| 
 | |
| /* NAT settings */
 | |
| #define SIP_NAT_FORCE_RPORT     (1 << 18) /*!< DP: Force rport even if not present in the request */
 | |
| #define SIP_NAT_RPORT_PRESENT   (1 << 19) /*!< DP: rport was present in the request */
 | |
| 
 | |
| /* re-INVITE related settings */
 | |
| #define SIP_REINVITE         (7 << 20) /*!< DP: four settings, uses three bits */
 | |
| #define SIP_REINVITE_NONE    (0 << 20) /*!< DP: no reinvite allowed */
 | |
| #define SIP_DIRECT_MEDIA     (1 << 20) /*!< DP: allow peers to be reinvited to send media directly p2p */
 | |
| #define SIP_DIRECT_MEDIA_NAT (2 << 20) /*!< DP: allow media reinvite when new peer is behind NAT */
 | |
| #define SIP_REINVITE_UPDATE  (4 << 20) /*!< DP: use UPDATE (RFC3311) when reinviting this peer */
 | |
| 
 | |
| /* "insecure" settings - see insecure2str() */
 | |
| #define SIP_INSECURE         (3 << 23)    /*!< DP: three settings, uses two bits */
 | |
| #define SIP_INSECURE_NONE    (0 << 23)    /*!< DP: secure mode */
 | |
| #define SIP_INSECURE_PORT    (1 << 23)    /*!< DP: don't require matching port for incoming requests */
 | |
| #define SIP_INSECURE_INVITE  (1 << 24)    /*!< DP: don't require authentication for incoming INVITEs */
 | |
| 
 | |
| /* Sending PROGRESS in-band settings */
 | |
| #define SIP_PROG_INBAND        (3 << 25) /*!< DP: three settings, uses two bits */
 | |
| #define SIP_PROG_INBAND_NO     (0 << 25)
 | |
| #define SIP_PROG_INBAND_NEVER  (1 << 25)
 | |
| #define SIP_PROG_INBAND_YES    (2 << 25)
 | |
| 
 | |
| #define SIP_USEPATH          (1 << 27) /*!< GDP: Trust and use incoming Path headers? */
 | |
| #define SIP_SENDRPID         (3 << 29) /*!< DP: Remote Party-ID Support */
 | |
| #define SIP_SENDRPID_NO      (0 << 29)
 | |
| #define SIP_SENDRPID_PAI     (1 << 29) /*!< Use "P-Asserted-Identity" for rpid */
 | |
| #define SIP_SENDRPID_RPID    (2 << 29) /*!< Use "Remote-Party-ID" for rpid */
 | |
| #define SIP_G726_NONSTANDARD (1 << 31) /*!< DP: Use non-standard packing for G726-32 data */
 | |
| 
 | |
| /*! \brief Flags to copy from peer/user to dialog */
 | |
| #define SIP_FLAGS_TO_COPY \
 | |
| 	(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \
 | |
| 	 SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT_FORCE_RPORT | SIP_G726_NONSTANDARD | \
 | |
| 	 SIP_USEREQPHONE | SIP_INSECURE | SIP_USEPATH)
 | |
| 
 | |
| /*! @} */
 | |
| 
 | |
| /*! \name SIPflags2
 | |
| 	a second page of flags (for flags[1]
 | |
|    @{
 | |
|  */
 | |
| /* realtime flags */
 | |
| #define SIP_PAGE2_RTCACHEFRIENDS            (1 <<  0)   /*!< GP: Should we keep RT objects in memory for extended time? */
 | |
| #define SIP_PAGE2_RTAUTOCLEAR               (1 <<  1)   /*!< GP: Should we clean memory from peers after expiry? */
 | |
| #define SIP_PAGE2_RPID_UPDATE               (1 <<  2)
 | |
| #define SIP_PAGE2_Q850_REASON               (1 <<  3)   /*!< DP: Get/send cause code via Reason header */
 | |
| #define SIP_PAGE2_SYMMETRICRTP              (1 <<  4)   /*!< GDP: Whether symmetric RTP is enabled or not */
 | |
| #define SIP_PAGE2_STATECHANGEQUEUE          (1 <<  5)   /*!< D: Unsent state pending change exists */
 | |
| #define SIP_PAGE2_CONNECTLINEUPDATE_PEND    (1 <<  6)
 | |
| #define SIP_PAGE2_RPID_IMMEDIATE            (1 <<  7)
 | |
| #define SIP_PAGE2_RPORT_PRESENT             (1 <<  8)   /*!< Was rport received in the Via header? */
 | |
| #define SIP_PAGE2_PREFERRED_CODEC           (1 <<  9)   /*!< GDP: Only respond with single most preferred joint codec */
 | |
| #define SIP_PAGE2_VIDEOSUPPORT              (1 << 10)   /*!< DP: Video supported if offered? */
 | |
| #define SIP_PAGE2_TEXTSUPPORT               (1 << 11)   /*!< GDP: Global text enable */
 | |
| #define SIP_PAGE2_ALLOWSUBSCRIBE            (1 << 12)   /*!< GP: Allow subscriptions from this peer? */
 | |
| 
 | |
| #define SIP_PAGE2_ALLOWOVERLAP              (3 << 13)   /*!< DP: Allow overlap dialing ? */
 | |
| #define SIP_PAGE2_ALLOWOVERLAP_NO           (0 << 13)   /*!< No, terminate with 404 Not found */
 | |
| #define SIP_PAGE2_ALLOWOVERLAP_YES          (1 << 13)   /*!< Yes, using the 484 Address Incomplete response */
 | |
| #define SIP_PAGE2_ALLOWOVERLAP_DTMF         (2 << 13)   /*!< Yes, using the DTMF transmission through Early Media */
 | |
| #define SIP_PAGE2_ALLOWOVERLAP_SPARE        (3 << 13)   /*!< Spare (reserved for another dialling transmission mechanisms like KPML) */
 | |
| 
 | |
| #define SIP_PAGE2_SUBSCRIBEMWIONLY          (1 << 15)   /*!< GP: Only issue MWI notification if subscribed to */
 | |
| #define SIP_PAGE2_IGNORESDPVERSION          (1 << 16)   /*!< GDP: Ignore the SDP session version number we receive and treat all sessions as new */
 | |
| 
 | |
| #define SIP_PAGE2_T38SUPPORT                (3 << 17)   /*!< GDP: T.38 Fax Support */
 | |
| #define SIP_PAGE2_T38SUPPORT_UDPTL          (1 << 17)   /*!< GDP: T.38 Fax Support (no error correction) */
 | |
| #define SIP_PAGE2_T38SUPPORT_UDPTL_FEC      (2 << 17)   /*!< GDP: T.38 Fax Support (FEC error correction) */
 | |
| #define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY   (3 << 17)   /*!< GDP: T.38 Fax Support (redundancy error correction) */
 | |
| 
 | |
| #define SIP_PAGE2_CALL_ONHOLD               (3 << 19)   /*!< D: Call hold states: */
 | |
| #define SIP_PAGE2_CALL_ONHOLD_ACTIVE        (1 << 19)   /*!< D: Active hold */
 | |
| #define SIP_PAGE2_CALL_ONHOLD_ONEDIR        (2 << 19)   /*!< D: One directional hold */
 | |
| #define SIP_PAGE2_CALL_ONHOLD_INACTIVE      (3 << 19)   /*!< D: Inactive hold */
 | |
| 
 | |
| #define SIP_PAGE2_RFC2833_COMPENSATE        (1 << 21)   /*!< DP: Compensate for buggy RFC2833 implementations */
 | |
| #define SIP_PAGE2_BUGGY_MWI                 (1 << 22)   /*!< DP: Buggy CISCO MWI fix */
 | |
| #define SIP_PAGE2_DIALOG_ESTABLISHED        (1 << 23)   /*!< 29: Has a dialog been established? */
 | |
| 
 | |
| #define SIP_PAGE2_FAX_DETECT                (3 << 24)   /*!< DP: Fax Detection support */
 | |
| #define SIP_PAGE2_FAX_DETECT_CNG            (1 << 24)   /*!< DP: Fax Detection support - detect CNG in audio */
 | |
| #define SIP_PAGE2_FAX_DETECT_T38            (2 << 24)   /*!< DP: Fax Detection support - detect T.38 reinvite from peer */
 | |
| #define SIP_PAGE2_FAX_DETECT_BOTH           (3 << 24)   /*!< DP: Fax Detection support - detect both */
 | |
| 
 | |
| #define SIP_PAGE2_UDPTL_DESTINATION         (1 << 26)   /*!< DP: Use source IP of RTP as destination if NAT is enabled */
 | |
| #define SIP_PAGE2_VIDEOSUPPORT_ALWAYS       (1 << 27)   /*!< DP: Always set up video, even if endpoints don't support it */
 | |
| #define SIP_PAGE2_HAVEPEERCONTEXT           (1 << 28)   /*< Are we associated with a configured peer context? */
 | |
| #define SIP_PAGE2_USE_SRTP                  (1 << 29)   /*!< DP: Whether we should offer (only)  SRTP */
 | |
| 
 | |
| #define SIP_PAGE2_TRUST_ID_OUTBOUND         (3 << 30)   /*!< DP: Do we trust the peer with private presence information? */
 | |
| #define SIP_PAGE2_TRUST_ID_OUTBOUND_LEGACY  (0 << 30)   /*!< Legacy, Do not provide private presence information, but include PAI/RPID when private */
 | |
| #define SIP_PAGE2_TRUST_ID_OUTBOUND_NO      (1 << 30)   /*!< No, Do not provide private presence information, do not include PAI/RPID when private */
 | |
| #define SIP_PAGE2_TRUST_ID_OUTBOUND_YES     (2 << 30)   /*!< Yes, provide private presence information in PAI/RPID headers */
 | |
| 
 | |
| #define SIP_PAGE2_FLAGS_TO_COPY \
 | |
| 	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \
 | |
| 	SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \
 | |
| 	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
 | |
| 	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
 | |
| 	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP |\
 | |
| 	SIP_PAGE2_Q850_REASON | SIP_PAGE2_HAVEPEERCONTEXT | SIP_PAGE2_USE_SRTP | SIP_PAGE2_TRUST_ID_OUTBOUND)
 | |
| 
 | |
| 
 | |
| #define SIP_PAGE3_SNOM_AOC               (1 << 0)  /*!< DPG: Allow snom aoc messages */
 | |
| #define SIP_PAGE3_SRTP_TAG_32            (1 << 1)  /*!< DP: Use a 32bit auth tag in INVITE not 80bit */
 | |
| #define SIP_PAGE3_NAT_AUTO_RPORT         (1 << 2)  /*!< DGP: Set SIP_NAT_FORCE_RPORT when NAT is detected */
 | |
| #define SIP_PAGE3_NAT_AUTO_COMEDIA       (1 << 3)  /*!< DGP: Set SIP_PAGE2_SYMMETRICRTP when NAT is detected */
 | |
| #define SIP_PAGE3_DIRECT_MEDIA_OUTGOING  (1 << 4)  /*!< DP: Only send direct media reinvites on outgoing calls */
 | |
| #define SIP_PAGE3_USE_AVPF               (1 << 5)  /*!< DGP: Support a minimal AVPF-compatible profile */
 | |
| #define SIP_PAGE3_ICE_SUPPORT            (1 << 6)  /*!< DGP: Enable ICE support */
 | |
| #define SIP_PAGE3_IGNORE_PREFCAPS        (1 << 7)  /*!< DP: Ignore prefcaps when setting up an outgoing call leg */
 | |
| #define SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL  (1 << 8)  /*!< DGP: Stop telling the peer to start music on hold */
 | |
| #define SIP_PAGE3_FORCE_AVP              (1 << 9)  /*!< DGP: Force 'RTP/AVP' for all streams, even DTLS */
 | |
| #define SIP_PAGE3_RTCP_MUX               (1 << 10) /*!< DGP: Attempt to negotiate RFC 5761 RTCP multiplexing */
 | |
| 
 | |
| #define SIP_PAGE3_FLAGS_TO_COPY \
 | |
| 	(SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA | \
 | |
| 	 SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_USE_AVPF | SIP_PAGE3_ICE_SUPPORT | SIP_PAGE3_IGNORE_PREFCAPS | \
 | |
| 	 SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL | SIP_PAGE3_FORCE_AVP | SIP_PAGE3_RTCP_MUX)
 | |
| 
 | |
| #define CHECK_AUTH_BUF_INITLEN   256
 | |
| 
 | |
| /*! @} */
 | |
| 
 | |
| /*----------------------------------------------------------*/
 | |
| /*----                    ENUMS                         ----*/
 | |
| /*----------------------------------------------------------*/
 | |
| 
 | |
| /*! \brief Authorization scheme for call transfers
 | |
|  *
 | |
|  * \note Not a bitfield flag, since there are plans for other modes,
 | |
|  * like "only allow transfers for authenticated devices"
 | |
|  */
 | |
| enum transfermodes {
 | |
| 	TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
 | |
| 	TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
 | |
| };
 | |
| 
 | |
| /*! \brief The result of a lot of functions */
 | |
| enum sip_result {
 | |
| 	AST_SUCCESS = 0,		/*!< FALSE means success, funny enough */
 | |
| 	AST_FAILURE = -1,		/*!< Failure code */
 | |
| };
 | |
| 
 | |
| /*! \brief The results from handling an invite request
 | |
|  *
 | |
|  * \note Start at these values so we do not conflict with
 | |
|  * check_auth_results values when returning from
 | |
|  * handle_request_invite.  check_auth_results only returned during
 | |
|  * authentication routines
 | |
|  * */
 | |
| enum inv_req_result {
 | |
| 	INV_REQ_SUCCESS = 11,    /*!< Success code */
 | |
| 	INV_REQ_FAILED  = 10,    /*!< Failure code */
 | |
| 	INV_REQ_ERROR   = 9,     /*!< Error code */
 | |
| };
 | |
| 
 | |
| /*! \brief States for the INVITE transaction, not the dialog
 | |
|  *  \note this is for the INVITE that sets up the dialog
 | |
|  */
 | |
| enum invitestates {
 | |
| 	INV_NONE = 0,         /*!< No state at all, maybe not an INVITE dialog */
 | |
| 	INV_CALLING = 1,      /*!< Invite sent, no answer */
 | |
| 	INV_PROCEEDING = 2,   /*!< We got/sent 1xx message */
 | |
| 	INV_EARLY_MEDIA = 3,  /*!< We got 18x message with to-tag back */
 | |
| 	INV_COMPLETED = 4,    /*!< Got final response with error. Wait for ACK, then CONFIRMED */
 | |
| 	INV_CONFIRMED = 5,    /*!< Confirmed response - we've got an ack (Incoming calls only) */
 | |
| 	INV_TERMINATED = 6,   /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
 | |
| 				     The only way out of this is a BYE from one side */
 | |
| 	INV_CANCELLED = 7,    /*!< Transaction cancelled by client or server in non-terminated state */
 | |
| };
 | |
| 
 | |
| /*! \brief When sending a SIP message, we can send with a few options, depending on
 | |
|  * type of SIP request. UNRELIABLE is mostly used for responses to repeated requests,
 | |
|  * where the original response would be sent RELIABLE in an INVITE transaction
 | |
|  */
 | |
| enum xmittype {
 | |
| 	XMIT_CRITICAL = 2,    /*!< Transmit critical SIP message reliably, with re-transmits.
 | |
| 	                       *   If it fails, it's critical and will cause a teardown of the session */
 | |
| 	XMIT_RELIABLE = 1,    /*!< Transmit SIP message reliably, with re-transmits */
 | |
| 	XMIT_UNRELIABLE = 0,  /*!< Transmit SIP message without bothering with re-transmits */
 | |
| };
 | |
| 
 | |
| /*! \brief Results from the parse_register() function */
 | |
| enum parse_register_result {
 | |
| 	PARSE_REGISTER_DENIED,
 | |
| 	PARSE_REGISTER_FAILED,
 | |
| 	PARSE_REGISTER_UPDATE,
 | |
| 	PARSE_REGISTER_QUERY,
 | |
| };
 | |
| 
 | |
| /*! \brief Type of subscription, based on the packages we do support, see \ref subscription_types */
 | |
| enum subscriptiontype {
 | |
| 	NONE = 0,
 | |
| 	XPIDF_XML,
 | |
| 	DIALOG_INFO_XML,
 | |
| 	CPIM_PIDF_XML,
 | |
| 	PIDF_XML,
 | |
| 	MWI_NOTIFICATION,
 | |
| 	CALL_COMPLETION,
 | |
| };
 | |
| 
 | |
| /*! \brief The number of media types in enum \ref media_type below. */
 | |
| #define OFFERED_MEDIA_COUNT	4
 | |
| 
 | |
| /*! \brief Media types generate different "dummy answers" for not accepting the offer of
 | |
| 	a media stream. We need to add definitions for each RTP profile. Secure RTP is not
 | |
| 	the same as normal RTP and will require a new definition */
 | |
| enum media_type {
 | |
| 	SDP_AUDIO,   /*!< RTP/AVP Audio */
 | |
| 	SDP_VIDEO,   /*!< RTP/AVP Video */
 | |
| 	SDP_IMAGE,   /*!< Image udptl, not TCP or RTP */
 | |
| 	SDP_TEXT,    /*!< RTP/AVP Realtime Text */
 | |
| 	SDP_UNKNOWN, /*!< Unknown media type */
 | |
| };
 | |
| 
 | |
| /*! \brief Authentication types - proxy or www authentication
 | |
|  *  \note Endpoints, like Asterisk, should always use WWW authentication to
 | |
|  *  allow multiple authentications in the same call - to the proxy and
 | |
|  *  to the end point.
 | |
|  */
 | |
| enum sip_auth_type {
 | |
| 	PROXY_AUTH = 407,
 | |
| 	WWW_AUTH = 401,
 | |
| };
 | |
| 
 | |
| /*! \brief Result from get_destination function */
 | |
| enum sip_get_dest_result {
 | |
| 	SIP_GET_DEST_EXTEN_MATCHMORE = 1,
 | |
| 	SIP_GET_DEST_EXTEN_FOUND = 0,
 | |
| 	SIP_GET_DEST_EXTEN_NOT_FOUND = -1,
 | |
| 	SIP_GET_DEST_REFUSED = -2,
 | |
| 	SIP_GET_DEST_INVALID_URI = -3,
 | |
| };
 | |
| 
 | |
| /*! \brief Authentication result from check_auth* functions */
 | |
| enum check_auth_result {
 | |
| 	AUTH_DONT_KNOW = -100,	/*!< no result, need to check further */
 | |
| 		/* XXX maybe this is the same as AUTH_NOT_FOUND */
 | |
| 	AUTH_SUCCESSFUL = 0,
 | |
| 	AUTH_CHALLENGE_SENT = 1,
 | |
| 	AUTH_SECRET_FAILED = -1,
 | |
| 	AUTH_USERNAME_MISMATCH = -2,
 | |
| 	AUTH_NOT_FOUND = -3,	/*!< returned by register_verify */
 | |
| 	AUTH_UNKNOWN_DOMAIN = -5,
 | |
| 	AUTH_PEER_NOT_DYNAMIC = -6,
 | |
| 	AUTH_ACL_FAILED = -7,
 | |
| 	AUTH_BAD_TRANSPORT = -8,
 | |
| 	AUTH_RTP_FAILED = -9,
 | |
| 	AUTH_SESSION_LIMIT = -10,
 | |
| };
 | |
| 
 | |
| /*! \brief States for outbound registrations (with register= lines in sip.conf */
 | |
| enum sipregistrystate {
 | |
| 	REG_STATE_UNREGISTERED = 0,	/*!< We are not registered
 | |
| 		 *  \note Initial state. We should have a timeout scheduled for the initial
 | |
| 		 * (or next) registration transmission, calling sip_reregister
 | |
| 		 */
 | |
| 
 | |
| 	REG_STATE_REGSENT,	/*!< Registration request sent
 | |
| 		 * \note sent initial request, waiting for an ack or a timeout to
 | |
| 		 * retransmit the initial request.
 | |
| 		*/
 | |
| 
 | |
| 	REG_STATE_AUTHSENT,	/*!< We have tried to authenticate
 | |
| 		 * \note entered after transmit_register with auth info,
 | |
| 		 * waiting for an ack.
 | |
| 		 */
 | |
| 
 | |
| 	REG_STATE_REGISTERED,	/*!< Registered and done */
 | |
| 
 | |
| 	REG_STATE_REJECTED,	/*!< Registration rejected
 | |
| 		 * \note only used when the remote party has an expire larger than
 | |
| 		 * our max-expire. This is a final state from which we do not
 | |
| 		 * recover (not sure how correctly).
 | |
| 		 */
 | |
| 
 | |
| 	REG_STATE_TIMEOUT,	/*!< Registration about to expire, renewing registration */
 | |
| 
 | |
| 	REG_STATE_NOAUTH,	/*!< We have no accepted credentials
 | |
| 		 * \note fatal - no chance to proceed */
 | |
| 
 | |
| 	REG_STATE_FAILED,	/*!< Registration failed after several tries
 | |
| 		 * \note fatal - no chance to proceed */
 | |
| };
 | |
| 
 | |
| /*! \brief Modes in which Asterisk can be configured to run SIP Session-Timers */
 | |
| enum st_mode {
 | |
|         SESSION_TIMER_MODE_INVALID = 0, /*!< Invalid value */
 | |
|         SESSION_TIMER_MODE_ACCEPT,      /*!< Honor inbound Session-Timer requests */
 | |
|         SESSION_TIMER_MODE_ORIGINATE,   /*!< Originate outbound and honor inbound requests */
 | |
|         SESSION_TIMER_MODE_REFUSE       /*!< Ignore inbound Session-Timers requests */
 | |
| };
 | |
| 
 | |
| /*! \brief The entity playing the refresher role for Session-Timers */
 | |
| enum st_refresher {
 | |
|         SESSION_TIMER_REFRESHER_AUTO, /*!< Negotiated                      */
 | |
|         SESSION_TIMER_REFRESHER_US,   /*!< Initially prefer session refresh by Asterisk */
 | |
|         SESSION_TIMER_REFRESHER_THEM, /*!< Initially prefer session refresh by the other side */
 | |
| };
 | |
| 
 | |
| enum st_refresher_param {
 | |
| 	SESSION_TIMER_REFRESHER_PARAM_UNKNOWN,
 | |
| 	SESSION_TIMER_REFRESHER_PARAM_UAC,
 | |
| 	SESSION_TIMER_REFRESHER_PARAM_UAS,
 | |
| };
 | |
| 
 | |
| /*! \brief Automatic peer registration behavior
 | |
| */
 | |
| enum autocreatepeer_mode {
 | |
| 	AUTOPEERS_DISABLED = 0,		/*!< Automatic peer creation disabled */
 | |
| 	AUTOPEERS_VOLATILE,			/*!< Automatic peers dropped on sip reload (pre-1.8 behavior) */
 | |
| 	AUTOPEERS_PERSIST			/*!< Automatic peers survive sip configuration reload */
 | |
| };
 | |
| 
 | |
| /*! \brief States whether a SIP message can create a dialog in Asterisk. */
 | |
| enum can_create_dialog {
 | |
| 	CAN_NOT_CREATE_DIALOG,
 | |
| 	CAN_CREATE_DIALOG,
 | |
| 	CAN_CREATE_DIALOG_UNSUPPORTED_METHOD,
 | |
| };
 | |
| 
 | |
| /*! \brief SIP Request methods known by Asterisk
 | |
|  *
 | |
|  * \note Do _NOT_ make any changes to this enum, or the array following it;
 | |
|  * if you think you are doing the right thing, you are probably
 | |
|  * not doing the right thing. If you think there are changes
 | |
|  * needed, get someone else to review them first _before_
 | |
|  * submitting a patch. If these two lists do not match properly
 | |
|  * bad things will happen.
 | |
|  */
 | |
| enum sipmethod {
 | |
| 	SIP_UNKNOWN,    /*!< Unknown response */
 | |
| 	SIP_RESPONSE,   /*!< Not request, response to outbound request */
 | |
| 	SIP_REGISTER,   /*!< Registration to the mothership, tell us where you are located */
 | |
| 	SIP_OPTIONS,    /*!< Check capabilities of a device, used for "ping" too */
 | |
| 	SIP_NOTIFY,     /*!< Status update, Part of the event package standard, result of a SUBSCRIBE or a REFER */
 | |
| 	SIP_INVITE,     /*!< Set up a session */
 | |
| 	SIP_ACK,        /*!< End of a three-way handshake started with INVITE. */
 | |
| 	SIP_PRACK,      /*!< Reliable pre-call signalling. Not supported in Asterisk. */
 | |
| 	SIP_BYE,        /*!< End of a session */
 | |
| 	SIP_REFER,      /*!< Refer to another URI (transfer) */
 | |
| 	SIP_SUBSCRIBE,  /*!< Subscribe for updates (voicemail, session status, device status, presence) */
 | |
| 	SIP_MESSAGE,    /*!< Text messaging */
 | |
| 	SIP_UPDATE,     /*!< Update a dialog. We can send UPDATE; but not accept it */
 | |
| 	SIP_INFO,       /*!< Information updates during a session */
 | |
| 	SIP_CANCEL,     /*!< Cancel an INVITE */
 | |
| 	SIP_PUBLISH,    /*!< Not supported in Asterisk */
 | |
| 	SIP_PING,       /*!< Not supported at all, no standard but still implemented out there */
 | |
| };
 | |
| 
 | |
| /*! \brief Setting for the 'notifyringing' option, see sip.conf.sample for details. */
 | |
| enum notifyringing_setting {
 | |
| 	NOTIFYRINGING_DISABLED = 0,
 | |
| 	NOTIFYRINGING_ENABLED = 1,
 | |
| 	NOTIFYRINGING_NOTINUSE = 2,
 | |
| };
 | |
| 
 | |
| /*! \brief Settings for the 'notifycid' option, see sip.conf.sample for details. */
 | |
| enum notifycid_setting {
 | |
| 	DISABLED       = 0,
 | |
| 	ENABLED        = 1,
 | |
| 	IGNORE_CONTEXT = 2,
 | |
| };
 | |
| 
 | |
| /*! \brief Modes for SIP domain handling in the PBX */
 | |
| enum domain_mode {
 | |
| 	SIP_DOMAIN_AUTO,      /*!< This domain is auto-configured */
 | |
| 	SIP_DOMAIN_CONFIG,    /*!< This domain is from configuration */
 | |
| };
 | |
| 
 | |
| /*! \brief debugging state
 | |
|  * We store separately the debugging requests from the config file
 | |
|  * and requests from the CLI. Debugging is enabled if either is set
 | |
|  * (which means that if sipdebug is set in the config file, we can
 | |
|  * only turn it off by reloading the config).
 | |
|  */
 | |
| enum sip_debug_e {
 | |
| 	sip_debug_none = 0,
 | |
| 	sip_debug_config = 1,
 | |
| 	sip_debug_console = 2,
 | |
| };
 | |
| 
 | |
| /*! \brief T38 States for a call */
 | |
| enum t38state {
 | |
| 	T38_DISABLED = 0,     /*!< Not enabled */
 | |
| 	T38_LOCAL_REINVITE,   /*!< Offered from local - REINVITE */
 | |
| 	T38_PEER_REINVITE,    /*!< Offered from peer - REINVITE */
 | |
| 	T38_ENABLED,          /*!< Negotiated (enabled) */
 | |
| 	T38_REJECTED          /*!< Refused */
 | |
| };
 | |
| 
 | |
| /*! \brief Parameters to know status of transfer */
 | |
| enum referstatus {
 | |
| 	REFER_IDLE,           /*!< No REFER is in progress */
 | |
| 	REFER_SENT,           /*!< Sent REFER to transferee */
 | |
| 	REFER_RECEIVED,       /*!< Received REFER from transferrer */
 | |
| 	REFER_CONFIRMED,      /*!< Refer confirmed with a 100 TRYING (unused) */
 | |
| 	REFER_ACCEPTED,       /*!< Accepted by transferee */
 | |
| 	REFER_RINGING,        /*!< Target Ringing */
 | |
| 	REFER_200OK,          /*!< Answered by transfer target */
 | |
| 	REFER_FAILED,         /*!< REFER declined - go on */
 | |
| 	REFER_NOAUTH          /*!< We had no auth for REFER */
 | |
| };
 | |
| 
 | |
| enum sip_peer_type {
 | |
| 	SIP_TYPE_PEER = (1 << 0),
 | |
| 	SIP_TYPE_USER = (1 << 1),
 | |
| };
 | |
| 
 | |
| enum t38_action_flag {
 | |
| 	SDP_T38_NONE = 0, /*!< Do not modify T38 information at all */
 | |
| 	SDP_T38_INITIATE, /*!< Remote side has requested T38 with us */
 | |
| 	SDP_T38_ACCEPT,   /*!< Remote side accepted our T38 request */
 | |
| };
 | |
| 
 | |
| enum sip_tcptls_alert {
 | |
| 	TCPTLS_ALERT_DATA,  /*!< \brief There is new data to be sent out */
 | |
| 	TCPTLS_ALERT_STOP,  /*!< \brief A request to stop the tcp_handler thread */
 | |
| };
 | |
| 
 | |
| enum digest_keys {
 | |
|         K_RESP,
 | |
|         K_URI,
 | |
|         K_USER,
 | |
|         K_NONCE,
 | |
|         K_LAST
 | |
| };
 | |
| 
 | |
| /*----------------------------------------------------------*/
 | |
| /*----                    STRUCTS                       ----*/
 | |
| /*----------------------------------------------------------*/
 | |
| 
 | |
| /*! \brief definition of a sip proxy server
 | |
|  *
 | |
|  * For outbound proxies, a sip_peer will contain a reference to a
 | |
|  * dynamically allocated instance of a sip_proxy. A sip_pvt may also
 | |
|  * contain a reference to a peer's outboundproxy, or it may contain
 | |
|  * a reference to the sip_cfg.outboundproxy.
 | |
|  */
 | |
| struct sip_proxy {
 | |
| 	char name[MAXHOSTNAMELEN];      /*!< DNS name of domain/host or IP */
 | |
| 	struct ast_sockaddr ip;          /*!< Currently used IP address and port */
 | |
| 	int port;
 | |
| 	time_t last_dnsupdate;          /*!< When this was resolved */
 | |
| 	enum ast_transport transport;
 | |
| 	int force;                      /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
 | |
| 	/* Room for a SRV record chain based on the name */
 | |
| };
 | |
| 
 | |
| /*! \brief argument for the 'show channels|subscriptions' callback. */
 | |
| struct __show_chan_arg {
 | |
| 	int fd;
 | |
| 	int subscriptions;
 | |
| 	int numchans;   /* return value */
 | |
| };
 | |
| 
 | |
| /*! \name GlobalSettings
 | |
| 	Global settings apply to the channel (often settings you can change in the general section
 | |
| 	of sip.conf
 | |
|    @{
 | |
|  */
 | |
| /*! \brief a place to store all global settings for the sip channel driver
 | |
| 
 | |
| 	These are settings that will be possibly to apply on a group level later on.
 | |
| 	\note Do not add settings that only apply to the channel itself and can't
 | |
| 	      be applied to devices (trunks, services, phones)
 | |
| */
 | |
| struct sip_settings {
 | |
| 	int peer_rtupdate;          /*!< G: Update database with registration data for peer? */
 | |
| 	int rtsave_sysname;         /*!< G: Save system name at registration? */
 | |
| 	int rtsave_path;            /*!< G: Save path header on registration */
 | |
| 	int ignore_regexpire;       /*!< G: Ignore expiration of peer  */
 | |
| 	int rtautoclear;            /*!< Realtime ?? */
 | |
| 	int directrtpsetup;         /*!< Enable support for Direct RTP setup (no re-invites) */
 | |
| 	int pedanticsipchecking;    /*!< Extra checking ?  Default off */
 | |
| 	enum autocreatepeer_mode autocreatepeer;  /*!< Auto creation of peers at registration? Default off. */
 | |
| 	int srvlookup;              /*!< SRV Lookup on or off. Default is on */
 | |
| 	int allowguest;             /*!< allow unauthenticated peers to connect? */
 | |
| 	int alwaysauthreject;       /*!< Send 401 Unauthorized for all failing requests */
 | |
| 	int auth_options_requests;  /*!< Authenticate OPTIONS requests */
 | |
| 	int auth_message_requests;  /*!< Authenticate MESSAGE requests */
 | |
| 	int accept_outofcall_message; /*!< Accept MESSAGE outside of a call */
 | |
| 	int compactheaders;         /*!< send compact sip headers */
 | |
| 	int allow_external_domains; /*!< Accept calls to external SIP domains? */
 | |
| 	int regextenonqualify;      /*!< Whether to add/remove regexten when qualifying peers */
 | |
| 	int legacy_useroption_parsing; /*!< Whether to strip useroptions in URI via semicolons */
 | |
| 	int send_diversion;	        /*!< Whether to Send SIP Diversion headers */
 | |
| 	int matchexternaddrlocally;   /*!< Match externaddr/externhost setting against localnet setting */
 | |
| 	char regcontext[AST_MAX_CONTEXT];  /*!< Context for auto-extensions */
 | |
| 	char messagecontext[AST_MAX_CONTEXT];  /*!< Default context for out of dialog msgs. */
 | |
| 	unsigned int disallowed_methods;   /*!< methods that we should never try to use */
 | |
| 	int notifyringing;          /*!< Send notifications on ringing */
 | |
| 	int notifyhold;             /*!< Send notifications on hold */
 | |
| 	enum notifycid_setting notifycid;  /*!< Send CID with ringing notifications */
 | |
| 	enum transfermodes allowtransfer;  /*!< SIP Refer restriction scheme */
 | |
| 	int allowsubscribe;         /*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE
 | |
| 	                                 the global setting is in globals_flags[1] */
 | |
| 	char realm[MAXHOSTNAMELEN]; /*!< Default realm */
 | |
| 	int domainsasrealm;         /*!< Use domains lists as realms */
 | |
| 	struct sip_proxy outboundproxy; /*!< Outbound proxy */
 | |
| 	char default_context[AST_MAX_CONTEXT];
 | |
| 	char default_subscribecontext[AST_MAX_CONTEXT];
 | |
| 	char default_record_on_feature[AST_FEATURE_MAX_LEN];
 | |
| 	char default_record_off_feature[AST_FEATURE_MAX_LEN];
 | |
| 	struct ast_acl_list *contact_acl;  /*! \brief Global list of addresses dynamic peers are not allowed to use */
 | |
| 	struct ast_format_cap *caps; /*!< Supported codecs */
 | |
| 	int tcp_enabled;
 | |
| 	int default_max_forwards;    /*!< Default max forwards (SIP Anti-loop) */
 | |
| 	int websocket_write_timeout; /*!< Socket write timeout for websocket transports, in ms */
 | |
| 	int websocket_enabled;       /*!< Are websockets enabled? */
 | |
| };
 | |
| 
 | |
| /*! @} */
 | |
| 
 | |
| struct ast_websocket;
 | |
| 
 | |
| /*! \brief The SIP socket definition */
 | |
| struct sip_socket {
 | |
| 	enum ast_transport type;  /*!< UDP, TCP or TLS */
 | |
| 	int fd;                   /*!< Filed descriptor, the actual socket */
 | |
| 	uint16_t unused; /* since 1.6.2, retained not to change order/size of struct */
 | |
| 	struct ast_tcptls_session_instance *tcptls_session;  /* If tcp or tls, a socket manager */
 | |
| 	struct ast_websocket *ws_session; /*! If ws or wss, a WebSocket session */
 | |
| };
 | |
| 
 | |
| /*! \brief sip_request: The data grabbed from the UDP socket
 | |
|  *
 | |
|  * \verbatim
 | |
|  * Incoming messages: we first store the data from the socket in data[],
 | |
|  * adding a trailing \0 to make string parsing routines happy.
 | |
|  * Then call parse_request() and req.method = find_sip_method();
 | |
|  * to initialize the other fields. The \r\n at the end of each line is
 | |
|  * replaced by \0, so that data[] is not a conforming SIP message anymore.
 | |
|  * After this processing, rlpart1 is set to non-NULL to remember
 | |
|  * that we can run get_header() on this kind of packet.
 | |
|  *
 | |
|  * parse_request() splits the first line as follows:
 | |
|  * Requests have in the first line      method uri SIP/2.0
 | |
|  *      rlpart1 = method; rlpart2 = uri;
 | |
|  * Responses have in the first line     SIP/2.0 NNN description
 | |
|  *      rlpart1 = SIP/2.0; rlpart2 = NNN + description;
 | |
|  *
 | |
|  * For outgoing packets, we initialize the fields with init_req() or init_resp()
 | |
|  * (which fills the first line to "METHOD uri SIP/2.0" or "SIP/2.0 code text"),
 | |
|  * and then fill the rest with add_header() and add_line().
 | |
|  * The \r\n at the end of the line are still there, so the get_header()
 | |
|  * and similar functions don't work on these packets.
 | |
|  * \endverbatim
 | |
|  */
 | |
| struct sip_request {
 | |
| 	ptrdiff_t rlpart1;      /*!< Offset of the SIP Method Name or "SIP/2.0" protocol version */
 | |
| 	ptrdiff_t rlpart2;      /*!< Offset of the Request URI or Response Status */
 | |
| 	int headers;            /*!< # of SIP Headers */
 | |
| 	int method;             /*!< Method of this request */
 | |
| 	int lines;              /*!< Body Content */
 | |
| 	unsigned int sdp_start; /*!< the line number where the SDP begins */
 | |
| 	unsigned int sdp_count; /*!< the number of lines of SDP */
 | |
| 	char debug;             /*!< print extra debugging if non zero */
 | |
| 	char has_to_tag;        /*!< non-zero if packet has To: tag */
 | |
| 	char ignore;            /*!< if non-zero This is a re-transmit, ignore it */
 | |
| 	char authenticated;     /*!< non-zero if this request was authenticated */
 | |
| 	ptrdiff_t header[SIP_MAX_HEADERS]; /*!< Array of offsets into the request string of each SIP header*/
 | |
| 	ptrdiff_t line[SIP_MAX_LINES];     /*!< Array of offsets into the request string of each SDP line*/
 | |
| 	struct ast_str *data;
 | |
| 	struct ast_str *content;
 | |
| 	/* XXX Do we need to unref socket.ser when the request goes away? */
 | |
| 	struct sip_socket socket;          /*!< The socket used for this request */
 | |
| 	AST_LIST_ENTRY(sip_request) next;
 | |
| 	unsigned int reqsipoptions; /*!< Items needed for Required header in responses */
 | |
| };
 | |
| 
 | |
| /*! \brief given a sip_request and an offset, return the char * that resides there
 | |
|  *
 | |
|  * It used to be that rlpart1, rlpart2, and the header and line arrays were character
 | |
|  * pointers. They are now offsets into the ast_str portion of the sip_request structure.
 | |
|  * To avoid adding a bunch of redundant pointer arithmetic to the code, this macro is
 | |
|  * provided to retrieve the string at a particular offset within the request's buffer
 | |
|  */
 | |
| #define REQ_OFFSET_TO_STR(req,offset) (ast_str_buffer((req)->data) + ((req)->offset))
 | |
| 
 | |
| /*! \brief Parameters to the transmit_invite function */
 | |
| struct sip_invite_param {
 | |
| 	int addsipheaders;          /*!< Add extra SIP headers */
 | |
| 	const char *uri_options;    /*!< URI options to add to the URI */
 | |
| 	const char *vxml_url;       /*!< VXML url for Cisco phones */
 | |
| 	char *auth;                 /*!< Authentication */
 | |
| 	char *authheader;           /*!< Auth header */
 | |
| 	enum sip_auth_type auth_type;  /*!< Authentication type */
 | |
| 	const char *replaces;       /*!< Replaces header for call transfers */
 | |
| 	int transfer;               /*!< Flag - is this Invite part of a SIP transfer? (invite/replaces) */
 | |
| 	struct sip_proxy *outboundproxy; /*!< Outbound proxy URI */
 | |
| };
 | |
| 
 | |
| /*! \brief Structure to store Via information */
 | |
| struct sip_via {
 | |
| 	char *via;
 | |
| 	const char *protocol;
 | |
| 	const char *sent_by;
 | |
| 	const char *branch;
 | |
| 	const char *maddr;
 | |
| 	unsigned int port;
 | |
| 	unsigned char ttl;
 | |
| };
 | |
| 
 | |
| /*! \brief Domain data structure.
 | |
| 	\note In the future, we will connect this to a configuration tree specific
 | |
| 	for this domain
 | |
| */
 | |
| struct domain {
 | |
| 	char domain[MAXHOSTNAMELEN];       /*!< SIP domain we are responsible for */
 | |
| 	char context[AST_MAX_EXTENSION];   /*!< Incoming context for this domain */
 | |
| 	enum domain_mode mode;             /*!< How did we find this domain? */
 | |
| 	AST_LIST_ENTRY(domain) list;       /*!< List mechanics */
 | |
| };
 | |
| 
 | |
| /*! \brief sip_history: Structure for saving transactions within a SIP dialog */
 | |
| struct sip_history {
 | |
| 	AST_LIST_ENTRY(sip_history) list;
 | |
| 	char event[0];	/* actually more, depending on needs */
 | |
| };
 | |
| 
 | |
| /*! \brief sip_auth: Credentials for authentication to other SIP services */
 | |
| struct sip_auth {
 | |
| 	AST_LIST_ENTRY(sip_auth) node;
 | |
| 	char realm[AST_MAX_EXTENSION];  /*!< Realm in which these credentials are valid */
 | |
| 	char username[256];             /*!< Username */
 | |
| 	char secret[256];               /*!< Secret */
 | |
| 	char md5secret[256];            /*!< MD5Secret */
 | |
| };
 | |
| 
 | |
| /*! \brief Container of SIP authentication credentials. */
 | |
| struct sip_auth_container {
 | |
| 	AST_LIST_HEAD_NOLOCK(, sip_auth) list;
 | |
| };
 | |
| 
 | |
| /*! \brief T.38 channel settings (at some point we need to make this alloc'ed */
 | |
| struct t38properties {
 | |
| 	enum t38state state;            /*!< T.38 state */
 | |
| 	struct ast_control_t38_parameters our_parms;
 | |
| 	struct ast_control_t38_parameters their_parms;
 | |
| };
 | |
| 
 | |
| /*! \brief generic struct to map between strings and integers.
 | |
|  * Fill it with x-s pairs, terminate with an entry with s = NULL;
 | |
|  * Then you can call map_x_s(...) to map an integer to a string,
 | |
|  * and map_s_x() for the string -> integer mapping.
 | |
|  */
 | |
| struct _map_x_s {
 | |
| 	int x;
 | |
| 	const char *s;
 | |
| };
 | |
| 
 | |
| /*! \brief Structure to handle SIP transfers. Dynamically allocated when needed */
 | |
| struct sip_refer {
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(refer_to);             /*!< Place to store REFER-TO extension */
 | |
| 		AST_STRING_FIELD(refer_to_domain);      /*!< Place to store REFER-TO domain */
 | |
| 		AST_STRING_FIELD(refer_to_urioption);   /*!< Place to store REFER-TO uri options */
 | |
| 		AST_STRING_FIELD(refer_to_context);     /*!< Place to store REFER-TO context */
 | |
| 		AST_STRING_FIELD(referred_by);          /*!< Place to store REFERRED-BY extension */
 | |
| 		AST_STRING_FIELD(refer_contact);        /*!< Place to store Contact info from a REFER extension */
 | |
| 		AST_STRING_FIELD(replaces_callid);      /*!< Replace info: callid */
 | |
| 		AST_STRING_FIELD(replaces_callid_totag);   /*!< Replace info: to-tag */
 | |
| 		AST_STRING_FIELD(replaces_callid_fromtag); /*!< Replace info: from-tag */
 | |
| 	);
 | |
| 	int attendedtransfer;                           /*!< Attended or blind transfer? */
 | |
| 	int localtransfer;                              /*!< Transfer to local domain? */
 | |
| 	enum referstatus status;                        /*!< REFER status */
 | |
| };
 | |
| 
 | |
| /*! \brief Struct to handle custom SIP notify requests. Dynamically allocated when needed */
 | |
| struct sip_notify {
 | |
| 	struct ast_variable *headers;
 | |
| 	struct ast_str *content;
 | |
| };
 | |
| 
 | |
| /*! \brief Structure that encapsulates all attributes related to running
 | |
|  *   SIP Session-Timers feature on a per dialog basis.
 | |
|  */
 | |
| struct sip_st_dlg {
 | |
| 	int st_active;                     /*!< Session-Timers on/off */
 | |
| 	int st_interval;                   /*!< Session-Timers negotiated session refresh interval */
 | |
| 	enum st_refresher st_ref;          /*!< Session-Timers cached refresher */
 | |
| 	int st_schedid;                    /*!< Session-Timers ast_sched scheduler id */
 | |
| 	int st_active_peer_ua;             /*!< Session-Timers on/off in peer UA */
 | |
| 	int st_cached_min_se;              /*!< Session-Timers cached Min-SE */
 | |
| 	int st_cached_max_se;              /*!< Session-Timers cached Session-Expires */
 | |
| 	enum st_mode st_cached_mode;       /*!< Session-Timers cached M.O. */
 | |
| 	enum st_refresher st_cached_ref;   /*!< Session-Timers session refresher */
 | |
| };
 | |
| 
 | |
| 
 | |
| /*! \brief Structure that encapsulates all attributes related to configuration
 | |
|  *   of SIP Session-Timers feature on a per user/peer basis.
 | |
|  */
 | |
| struct sip_st_cfg {
 | |
| 	enum st_mode st_mode_oper;      /*!< Mode of operation for Session-Timers           */
 | |
| 	enum st_refresher_param st_ref; /*!< Session-Timer refresher                        */
 | |
| 	int st_min_se;                  /*!< Lowest threshold for session refresh interval  */
 | |
| 	int st_max_se;                  /*!< Highest threshold for session refresh interval */
 | |
| };
 | |
| 
 | |
| /*! \brief Structure for remembering offered media in an INVITE, to make sure we reply
 | |
| 	to all media streams. */
 | |
| struct offered_media {
 | |
| 	enum media_type type;		/*!< The type of media that was offered */
 | |
| 	char *decline_m_line;		/*!< Used if the media type is unknown/unused or a media stream is declined */
 | |
| 	AST_LIST_ENTRY(offered_media) next;
 | |
| };
 | |
| 
 | |
| /*! Additional headers to send with MESSAGE method packet. */
 | |
| struct sip_msg_hdr {
 | |
| 	AST_LIST_ENTRY(sip_msg_hdr) next;
 | |
| 	/*! Name of header to stick in MESSAGE */
 | |
| 	const char *name;
 | |
| 	/*! Value of header to stick in MESSAGE */
 | |
| 	const char *value;
 | |
| 	/*! The name and value strings are stuffed here in that order. */
 | |
| 	char stuff[0];
 | |
| };
 | |
| 
 | |
| /*! \brief Structure used for each SIP dialog, ie. a call, a registration, a subscribe.
 | |
|  * Created and initialized by sip_alloc(), the descriptor goes into the list of
 | |
|  * descriptors (dialoglist).
 | |
|  */
 | |
| struct sip_pvt {
 | |
| 	struct sip_pvt *next;                   /*!< Next dialog in chain */
 | |
| 	enum invitestates invitestate;          /*!< Track state of SIP_INVITEs */
 | |
| 	ast_callid logger_callid;               /*!< Identifier for call used in log messages */
 | |
| 	int method;                             /*!< SIP method that opened this dialog */
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(callid);       /*!< Global CallID */
 | |
| 		AST_STRING_FIELD(initviabranch); /*!< The branch ID from the topmost Via header in the initial request */
 | |
| 		AST_STRING_FIELD(initviasentby); /*!< The sent-by from the topmost Via header in the initial request */
 | |
| 		AST_STRING_FIELD(accountcode);  /*!< Account code */
 | |
| 		AST_STRING_FIELD(realm);        /*!< Authorization realm */
 | |
| 		AST_STRING_FIELD(nonce);        /*!< Authorization nonce */
 | |
| 		AST_STRING_FIELD(opaque);       /*!< Opaque nonsense */
 | |
| 		AST_STRING_FIELD(qop);          /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
 | |
| 		AST_STRING_FIELD(domain);       /*!< Authorization domain */
 | |
| 		AST_STRING_FIELD(from);         /*!< The From: header */
 | |
| 		AST_STRING_FIELD(useragent);    /*!< User agent in SIP request */
 | |
| 		AST_STRING_FIELD(exten);        /*!< Extension where to start */
 | |
| 		AST_STRING_FIELD(context);      /*!< Context for this call */
 | |
| 		AST_STRING_FIELD(messagecontext); /*!< Default context for outofcall messages. */
 | |
| 		AST_STRING_FIELD(subscribecontext); /*!< Subscribecontext */
 | |
| 		AST_STRING_FIELD(subscribeuri); /*!< Subscribecontext */
 | |
| 		AST_STRING_FIELD(fromdomain);   /*!< Domain to show in the from field */
 | |
| 		AST_STRING_FIELD(fromuser);     /*!< User to show in the user field */
 | |
| 		AST_STRING_FIELD(fromname);     /*!< Name to show in the user field */
 | |
| 		AST_STRING_FIELD(tohost);       /*!< Host we should put in the "to" field */
 | |
| 		AST_STRING_FIELD(todnid);       /*!< DNID of this call (overrides host) */
 | |
| 		AST_STRING_FIELD(language);     /*!< Default language for this call */
 | |
| 		AST_STRING_FIELD(mohinterpret); /*!< MOH class to use when put on hold */
 | |
| 		AST_STRING_FIELD(mohsuggest);   /*!< MOH class to suggest when putting a peer on hold */
 | |
| 		AST_STRING_FIELD(rdnis);        /*!< Referring DNIS */
 | |
| 		AST_STRING_FIELD(redircause);   /*!< Referring cause */
 | |
| 		AST_STRING_FIELD(theirtag);     /*!< Their tag */
 | |
| 		AST_STRING_FIELD(theirprovtag); /*!< Provisional their tag, used when evaluating responses to invites */
 | |
| 		AST_STRING_FIELD(tag);          /*!< Our tag for this session */
 | |
| 		AST_STRING_FIELD(username);     /*!< [user] name */
 | |
| 		AST_STRING_FIELD(peername);     /*!< [peer] name, not set if [user] */
 | |
| 		AST_STRING_FIELD(authname);     /*!< Who we use for authentication */
 | |
| 		AST_STRING_FIELD(uri);          /*!< Original requested URI */
 | |
| 		AST_STRING_FIELD(okcontacturi); /*!< URI from the 200 OK on INVITE */
 | |
| 		AST_STRING_FIELD(peersecret);   /*!< Password */
 | |
| 		AST_STRING_FIELD(peermd5secret);
 | |
| 		AST_STRING_FIELD(cid_num);      /*!< Caller*ID number */
 | |
| 		AST_STRING_FIELD(cid_name);     /*!< Caller*ID name */
 | |
| 		AST_STRING_FIELD(cid_tag);      /*!< Caller*ID tag */
 | |
| 		AST_STRING_FIELD(mwi_from);     /*!< Name to place in the From header in outgoing NOTIFY requests */
 | |
| 		AST_STRING_FIELD(fullcontact);  /*!< The Contact: that the UA registers with us */
 | |
| 		                                /* we only store the part in <brackets> in this field. */
 | |
| 		AST_STRING_FIELD(our_contact);  /*!< Our contact header */
 | |
| 		AST_STRING_FIELD(url);          /*!< URL to be sent with next message to peer */
 | |
| 		AST_STRING_FIELD(parkinglot);   /*!< Parkinglot */
 | |
| 		AST_STRING_FIELD(engine);       /*!< RTP engine to use */
 | |
| 		AST_STRING_FIELD(dialstring);   /*!< The dialstring used to call this SIP endpoint */
 | |
| 		AST_STRING_FIELD(last_presence_subtype);   /*!< The last presence subtype sent for a subscription. */
 | |
| 		AST_STRING_FIELD(last_presence_message);   /*!< The last presence message for a subscription */
 | |
| 		AST_STRING_FIELD(msg_body);     /*!< Text for a MESSAGE body */
 | |
| 		AST_STRING_FIELD(tel_phone_context);       /*!< The phone-context portion of a TEL URI */
 | |
| 		AST_STRING_FIELD(sessionunique_remote);    /*!< Remote UA's SDP Session unique parts */
 | |
| 	);
 | |
| 	char via[128];                          /*!< Via: header */
 | |
| 	int maxforwards;                        /*!< SIP Loop prevention */
 | |
| 	struct sip_socket socket;               /*!< The socket used for this dialog */
 | |
| 	uint32_t ocseq;                         /*!< Current outgoing seqno */
 | |
| 	uint32_t icseq;                         /*!< Current incoming seqno */
 | |
| 	uint32_t init_icseq;                    /*!< Initial incoming seqno from first request */
 | |
| 	ast_group_t callgroup;                  /*!< Call group */
 | |
| 	ast_group_t pickupgroup;                /*!< Pickup group */
 | |
| 	struct ast_namedgroups *named_callgroups;   /*!< Named call group */
 | |
| 	struct ast_namedgroups *named_pickupgroups; /*!< Named pickup group */
 | |
| 	uint32_t lastinvite;                    /*!< Last seqno of invite */
 | |
| 	struct ast_flags flags[3];              /*!< SIP_ flags */
 | |
| 
 | |
| 	/* boolean flags that don't belong in flags */
 | |
| 	unsigned short do_history:1;          /*!< Set if we want to record history */
 | |
| 	unsigned short alreadygone:1;         /*!< the peer has sent a message indicating termination of the dialog */
 | |
| 	unsigned short needdestroy:1;         /*!< this dialog needs to be destroyed by the monitor thread */
 | |
| 	unsigned short final_destruction_scheduled:1; /*!< final dialog destruction is scheduled. Keep dialog
 | |
| 	                                               *   around until then to handle retransmits. */
 | |
| 	unsigned short outgoing_call:1;       /*!< this is an outgoing call */
 | |
| 	unsigned short answered_elsewhere:1;  /*!< This call is cancelled due to answer on another channel */
 | |
| 	unsigned short novideo:1;             /*!< Didn't get video in invite, don't offer */
 | |
| 	unsigned short notext:1;              /*!< Text not supported  (?) */
 | |
| 	unsigned short session_modify:1;      /*!< Session modification request true/false  */
 | |
| 	unsigned short route_persistent:1;    /*!< Is this the "real" route? */
 | |
| 	unsigned short autoframing:1;         /*!< Whether to use our local configuration for frame sizes (off)
 | |
| 	                                       *   or respect the other endpoint's request for frame sizes (on)
 | |
| 	                                       *   for incoming calls
 | |
| 	                                       */
 | |
| 	unsigned short req_secure_signaling:1;/*!< Whether we are required to have secure signaling or not */
 | |
| 	unsigned short natdetected:1;         /*!< Whether we detected a NAT when processing the Via */
 | |
| 	int timer_t1;                     /*!< SIP timer T1, ms rtt */
 | |
| 	int timer_b;                      /*!< SIP timer B, ms */
 | |
| 	unsigned int sipoptions;          /*!< Supported SIP options on the other end */
 | |
| 	unsigned int reqsipoptions;       /*!< Required SIP options on the other end */
 | |
| 	struct ast_format_cap *caps;             /*!< Special capability (codec) */
 | |
| 	struct ast_format_cap *jointcaps;        /*!< Supported capability at both ends (codecs) */
 | |
| 	struct ast_format_cap *peercaps;         /*!< Supported peer capability */
 | |
| 	struct ast_format_cap *redircaps;        /*!< Redirect codecs */
 | |
| 	struct ast_format_cap *prefcaps;         /*!< Preferred codec (outbound only) */
 | |
| 	int noncodeccapability;	          /*!< DTMF RFC2833 telephony-event */
 | |
| 	int jointnoncodeccapability;      /*!< Joint Non codec capability */
 | |
| 	int maxcallbitrate;               /*!< Maximum Call Bitrate for Video Calls */
 | |
| 	int t38_maxdatagram;              /*!< T.38 FaxMaxDatagram override */
 | |
| 	int request_queue_sched_id;       /*!< Scheduler ID of any scheduled action to process queued requests */
 | |
| 	int provisional_keepalive_sched_id;   /*!< Scheduler ID for provisional responses that need to be sent out to avoid cancellation */
 | |
| 	const char *last_provisional;         /*!< The last successfully transmitted provisional response message */
 | |
| 	int authtries;                        /*!< Times we've tried to authenticate */
 | |
| 	struct sip_proxy *outboundproxy;      /*!< Outbound proxy for this dialog. Use ref_proxy to set this instead of setting it directly*/
 | |
| 	struct t38properties t38;             /*!< T38 settings */
 | |
| 	struct ast_sockaddr udptlredirip;     /*!< Where our T.38 UDPTL should be going if not to us */
 | |
| 	struct ast_udptl *udptl;              /*!< T.38 UDPTL session */
 | |
| 	char zone[MAX_TONEZONE_COUNTRY];      /*!< Default tone zone for channels created by this dialog */
 | |
| 	int callingpres;                      /*!< Calling presentation */
 | |
| 	int expiry;                         /*!< How long we take to expire */
 | |
| 	int sessionversion;                 /*!< SDP Session Version */
 | |
| 	int sessionid;                      /*!< SDP Session ID */
 | |
| 	long branch;                        /*!< The branch identifier of this session */
 | |
| 	long invite_branch;                 /*!< The branch used when we sent the initial INVITE */
 | |
| 	int64_t sessionversion_remote;      /*!< Remote UA's SDP Session Version */
 | |
| 	unsigned int portinuri:1;           /*!< Non zero if a port has been specified, will also disable srv lookups */
 | |
| 	struct ast_sockaddr sa;              /*!< Our peer */
 | |
| 	struct ast_sockaddr redirip;         /*!< Where our RTP should be going if not to us */
 | |
| 	struct ast_sockaddr vredirip;        /*!< Where our Video RTP should be going if not to us */
 | |
| 	struct ast_sockaddr tredirip;        /*!< Where our Text RTP should be going if not to us */
 | |
| 	time_t lastrtprx;                   /*!< Last RTP received */
 | |
| 	time_t lastrtptx;                   /*!< Last RTP sent */
 | |
| 	int rtptimeout;                     /*!< RTP timeout time */
 | |
| 	int rtpholdtimeout;                 /*!< RTP timeout time on hold*/
 | |
| 	int rtpkeepalive;                   /*!< RTP send packets for keepalive */
 | |
| 	struct ast_acl_list *directmediaacl; /*!< Which IPs are allowed to interchange direct media with this peer - copied from sip_peer */
 | |
| 	struct ast_sockaddr recv;            /*!< Received as */
 | |
| 	struct ast_sockaddr ourip;           /*!< Our IP (as seen from the outside) */
 | |
| 	enum transfermodes allowtransfer;   /*!< REFER: restriction scheme */
 | |
| 	struct ast_channel *owner;          /*!< Who owns us (if we have an owner) */
 | |
| 	struct sip_route route;             /*!< List of routing steps (fm Record-Route) */
 | |
| 	struct sip_notify *notify;          /*!< Custom notify type */
 | |
| 	struct sip_auth_container *peerauth;/*!< Realm authentication credentials */
 | |
| 	int noncecount;                     /*!< Nonce-count */
 | |
| 	unsigned int stalenonce:1;          /*!< Marks the current nonce as responded too */
 | |
| 	unsigned int ongoing_reinvite:1;    /*!< There is a reinvite in progress that might need to be cleaned up */
 | |
| 	char lastmsg[256];                  /*!< Last Message sent/received */
 | |
| 	int amaflags;                       /*!< AMA Flags */
 | |
| 	uint32_t pendinginvite; /*!< Any pending INVITE or state NOTIFY (in subscribe pvt's) ? (seqno of this) */
 | |
| 	uint32_t glareinvite;      /*!< A invite received while a pending invite is already present is stored here.  Its seqno is the
 | |
| 	                           value. Since this glare invite's seqno is not the same as the pending invite's, it must be
 | |
| 	                           held in order to properly process acknowledgements for our 491 response. */
 | |
| 	struct sip_request initreq;         /*!< Latest request that opened a new transaction
 | |
| 	                                         within this dialog.
 | |
| 	                                         NOT the request that opened the dialog */
 | |
| 
 | |
| 	int initid;                         /*!< Auto-congest ID if appropriate (scheduler) */
 | |
| 	int waitid;                         /*!< Wait ID for scheduler after 491 or other delays */
 | |
| 	int reinviteid;                     /*!< Reinvite in case of provisional, but no final response */
 | |
| 	int autokillid;                     /*!< Auto-kill ID (scheduler) */
 | |
| 	int t38id;                          /*!< T.38 Response ID */
 | |
| 	struct sip_refer *refer;            /*!< REFER: SIP transfer data structure */
 | |
| 	enum subscriptiontype subscribed;   /*!< SUBSCRIBE: Is this dialog a subscription?  */
 | |
| 	int stateid;                        /*!< SUBSCRIBE: ID for devicestate subscriptions */
 | |
| 	int laststate;                      /*!< SUBSCRIBE: Last known extension state */
 | |
| 	struct ao2_container *last_device_state_info; /*!< SUBSCRIBE: last known extended extension state (take care of refs)*/
 | |
| 	struct timeval last_ringing_channel_time; /*!< SUBSCRIBE: channel timestamp of the channel which caused the last early-state notification */
 | |
| 	int last_presence_state;            /*!< SUBSCRIBE: Last known presence state */
 | |
| 	uint32_t dialogver;                 /*!< SUBSCRIBE: Version for subscription dialog-info */
 | |
| 
 | |
| 	struct ast_dsp *dsp;                /*!< Inband DTMF or Fax CNG tone Detection dsp */
 | |
| 
 | |
| 	struct sip_peer *relatedpeer;       /*!< If this dialog is related to a peer, which one
 | |
| 	                                         Used in peerpoke, mwi subscriptions */
 | |
| 	struct sip_registry *registry;      /*!< If this is a REGISTER dialog, to which registry */
 | |
| 	struct ast_rtp_instance *rtp;       /*!< RTP Session */
 | |
| 	struct ast_rtp_instance *vrtp;      /*!< Video RTP session */
 | |
| 	struct ast_rtp_instance *trtp;      /*!< Text RTP session */
 | |
| 	struct sip_pkt *packets;            /*!< Packets scheduled for re-transmission */
 | |
| 	struct sip_history_head *history;   /*!< History of this SIP dialog */
 | |
| 	size_t history_entries;             /*!< Number of entires in the history */
 | |
| 	struct ast_variable *chanvars;      /*!< Channel variables to set for inbound call */
 | |
| 	AST_LIST_HEAD_NOLOCK(, sip_msg_hdr) msg_headers; /*!< Additional MESSAGE headers to send. */
 | |
| 	AST_LIST_HEAD_NOLOCK(request_queue, sip_request) request_queue; /*!< Requests that arrived but could not be processed immediately */
 | |
| 	struct sip_invite_param *options;   /*!< Options for INVITE */
 | |
| 	struct sip_st_dlg *stimer;          /*!< SIP Session-Timers */
 | |
| 	struct ast_sdp_srtp *srtp;              /*!< Structure to hold Secure RTP session data for audio */
 | |
| 	struct ast_sdp_srtp *vsrtp;             /*!< Structure to hold Secure RTP session data for video */
 | |
| 	struct ast_sdp_srtp *tsrtp;             /*!< Structure to hold Secure RTP session data for text */
 | |
| 
 | |
| 	int red;                            /*!< T.140 RTP Redundancy */
 | |
| 	int hangupcause;                    /*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */
 | |
| 
 | |
| 	struct sip_subscription_mwi *mwi;   /*!< If this is a subscription MWI dialog, to which subscription */
 | |
| 	/*! The SIP methods supported by this peer. We get this information from the Allow header of the first
 | |
| 	 * message we receive from an endpoint during a dialog.
 | |
| 	 */
 | |
| 	unsigned int allowed_methods;
 | |
| 	/*! Some peers are not trustworthy with their Allow headers, and so we need to override their wicked
 | |
| 	 * ways through configuration. This is a copy of the peer's disallowed_methods, so that we can apply them
 | |
| 	 * to the sip_pvt at various stages of dialog establishment
 | |
| 	 */
 | |
| 	unsigned int disallowed_methods;
 | |
| 	/*! When receiving an SDP offer, it is important to take note of what media types were offered.
 | |
| 	 * By doing this, even if we don't want to answer a particular media stream with something meaningful, we can
 | |
| 	 * still put an m= line in our answer with the port set to 0.
 | |
| 	 *
 | |
| 	 * The reason for the length being 4 (OFFERED_MEDIA_COUNT) is that in this branch of Asterisk, the only media types supported are
 | |
| 	 * image, audio, text, and video. Therefore we need to keep track of which types of media were offered.
 | |
| 	 * Note that secure RTP defines new types of SDP media.
 | |
| 	 *
 | |
| 	 * If we wanted to be 100% correct, we would keep a list of all media streams offered. That way we could respond
 | |
| 	 * even to unknown media types, and we could respond to multiple streams of the same type. Such large-scale changes
 | |
| 	 * are not a good idea for released branches, though, so we're compromising by just making sure that for the common cases:
 | |
| 	 * audio and video, audio and T.38, and audio and text, we give the appropriate response to both media streams.
 | |
| 	 *
 | |
| 	 * The large-scale changes would be a good idea for implementing during an SDP rewrite.
 | |
| 	 */
 | |
| 	AST_LIST_HEAD_NOLOCK(, offered_media) offered_media;
 | |
| 	struct ast_cc_config_params *cc_params;
 | |
| 	struct sip_epa_entry *epa_entry;
 | |
| 	int fromdomainport;                 /*!< Domain port to show in from field */
 | |
| 
 | |
| 	struct ast_rtp_dtls_cfg dtls_cfg;
 | |
| };
 | |
| 
 | |
| /*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission
 | |
|  * Packets are linked in a list, whose head is in the struct sip_pvt they belong to.
 | |
|  * Each packet holds a reference to the parent struct sip_pvt.
 | |
|  * This structure is allocated in __sip_reliable_xmit() and only for packets that
 | |
|  * require retransmissions.
 | |
|  */
 | |
| struct sip_pkt {
 | |
| 	struct sip_pkt *next;     /*!< Next packet in linked list */
 | |
| 	int retrans;              /*!< Retransmission number */
 | |
| 	int method;               /*!< SIP method for this packet */
 | |
| 	uint32_t seqno;           /*!< Sequence number */
 | |
| 	char is_resp;             /*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
 | |
| 	char is_fatal;            /*!< non-zero if there is a fatal error */
 | |
| 	int response_code;        /*!< If this is a response, the response code */
 | |
| 	struct sip_pvt *owner;    /*!< Owner AST call */
 | |
| 	int retransid;            /*!< Retransmission ID */
 | |
| 	int timer_a;              /*!< SIP timer A, retransmission timer */
 | |
| 	int timer_t1;             /*!< SIP Timer T1, estimated RTT or 500 ms */
 | |
| 	struct timeval time_sent;  /*!< When pkt was sent */
 | |
| 	int64_t retrans_stop_time; /*!< Time in ms after 'now' that retransmission must stop */
 | |
| 	int retrans_stop;         /*!< Timeout is reached, stop retransmission  */
 | |
| 	struct ast_str *data;
 | |
| };
 | |
| 
 | |
| enum sip_mailbox_status {
 | |
| 	SIP_MAILBOX_STATUS_UNKNOWN = 0,
 | |
| 	SIP_MAILBOX_STATUS_EXISTING,
 | |
| 	SIP_MAILBOX_STATUS_NEW,
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief A peer's mailbox
 | |
|  *
 | |
|  * We could use STRINGFIELDS here, but for only one string, its
 | |
|  * too much effort ...
 | |
|  */
 | |
| struct sip_mailbox {
 | |
| 	/*! Associated MWI subscription */
 | |
| 	struct ast_mwi_subscriber *event_sub;
 | |
| 	AST_LIST_ENTRY(sip_mailbox) entry;
 | |
| 	struct sip_peer *peer;
 | |
| 	enum sip_mailbox_status status;
 | |
| 	char id[1];
 | |
| };
 | |
| 
 | |
| /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host)
 | |
| */
 | |
| /* XXX field 'name' must be first otherwise sip_addrcmp() will fail, as will astobj2 hashing of the structure */
 | |
| struct sip_peer {
 | |
| 	char name[80];                          /*!< the unique name of this object */
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(secret);       /*!< Password for inbound auth */
 | |
| 		AST_STRING_FIELD(md5secret);    /*!< Password in MD5 */
 | |
| 		AST_STRING_FIELD(description);	/*!< Description of this peer */
 | |
| 		AST_STRING_FIELD(remotesecret); /*!< Remote secret (trunks, remote devices) */
 | |
| 		AST_STRING_FIELD(context);      /*!< Default context for incoming calls */
 | |
| 		AST_STRING_FIELD(messagecontext); /*!< Default context for outofcall messages. */
 | |
| 		AST_STRING_FIELD(subscribecontext); /*!< Default context for subscriptions */
 | |
| 		AST_STRING_FIELD(username);     /*!< Temporary username until registration */
 | |
| 		AST_STRING_FIELD(accountcode);  /*!< Account code */
 | |
| 		AST_STRING_FIELD(tohost);       /*!< If not dynamic, IP address */
 | |
| 		AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
 | |
| 		AST_STRING_FIELD(fromuser);     /*!< From: user when calling this peer */
 | |
| 		AST_STRING_FIELD(fromdomain);   /*!< From: domain when calling this peer */
 | |
| 		AST_STRING_FIELD(fullcontact);  /*!< Contact registered with us (not in sip.conf) */
 | |
| 		AST_STRING_FIELD(cid_num);      /*!< Caller ID num */
 | |
| 		AST_STRING_FIELD(cid_name);     /*!< Caller ID name */
 | |
| 		AST_STRING_FIELD(cid_tag);      /*!< Caller ID tag */
 | |
| 		AST_STRING_FIELD(vmexten);      /*!< Dialplan extension for MWI notify message*/
 | |
| 		AST_STRING_FIELD(language);     /*!<  Default language for prompts */
 | |
| 		AST_STRING_FIELD(mohinterpret); /*!<  Music on Hold class */
 | |
| 		AST_STRING_FIELD(mohsuggest);   /*!<  Music on Hold class */
 | |
| 		AST_STRING_FIELD(parkinglot);   /*!<  Parkinglot */
 | |
| 		AST_STRING_FIELD(useragent);    /*!<  User agent in SIP request (saved from registration) */
 | |
| 		AST_STRING_FIELD(mwi_from);     /*!< Name to place in From header for outgoing NOTIFY requests */
 | |
| 		AST_STRING_FIELD(engine);       /*!<  RTP Engine to use */
 | |
| 		AST_STRING_FIELD(unsolicited_mailbox);  /*!< Mailbox to store received unsolicited MWI NOTIFY messages information in */
 | |
| 		AST_STRING_FIELD(zone);         /*!< Tonezone for this device */
 | |
| 		AST_STRING_FIELD(record_on_feature); /*!< Feature to use when receiving INFO with record: on during a call */
 | |
| 		AST_STRING_FIELD(record_off_feature); /*!< Feature to use when receiving INFO with record: off during a call */
 | |
| 		AST_STRING_FIELD(callback); /*!< Callback extension */
 | |
| 		);
 | |
| 	struct sip_socket socket;       /*!< Socket used for this peer */
 | |
| 	enum ast_transport default_outbound_transport;   /*!< Peer Registration may change the default outbound transport.
 | |
| 	                                                     If register expires, default should be reset. to this value */
 | |
| 	/* things that don't belong in flags */
 | |
| 	unsigned short transports:5;    /*!< Transports (enum ast_transport) that are acceptable for this peer */
 | |
| 	unsigned short is_realtime:1;   /*!< this is a 'realtime' peer */
 | |
| 	unsigned short rt_fromcontact:1;/*!< copy fromcontact from realtime */
 | |
| 	unsigned short host_dynamic:1;  /*!< Dynamic Peers register with Asterisk */
 | |
| 	unsigned short selfdestruct:1;  /*!< Automatic peers need to destruct themselves */
 | |
| 	unsigned short the_mark:1;      /*!< That which bears the_mark should be deleted! */
 | |
| 	unsigned short autoframing:1;   /*!< Whether to use our local configuration for frame sizes (off)
 | |
| 	                                 *   or respect the other endpoint's request for frame sizes (on)
 | |
| 	                                 *   for incoming calls
 | |
| 	                                 */
 | |
| 	unsigned short deprecated_username:1; /*!< If it's a realtime peer, are they using the deprecated "username" instead of "defaultuser" */
 | |
| 	struct sip_auth_container *auth;/*!< Realm authentication credentials */
 | |
| 	int amaflags;                   /*!< AMA Flags (for billing) */
 | |
| 	int callingpres;                /*!< Calling id presentation */
 | |
| 	int inuse;                      /*!< Number of calls in use */
 | |
| 	int ringing;                    /*!< Number of calls ringing */
 | |
| 	int onhold;                     /*!< Peer has someone on hold */
 | |
| 	int call_limit;                 /*!< Limit of concurrent calls */
 | |
| 	unsigned int t38_maxdatagram;            /*!< T.38 FaxMaxDatagram override */
 | |
| 	int busy_level;                 /*!< Level of active channels where we signal busy */
 | |
| 	int maxforwards;                /*!< SIP Loop prevention */
 | |
| 	enum transfermodes allowtransfer;   /*! SIP Refer restriction scheme */
 | |
| 	int lastmsgssent;				/*!< The last known VM message counts (new/old) */
 | |
| 	unsigned int sipoptions;        /*!<  Supported SIP options */
 | |
| 	struct ast_flags flags[3];      /*!<  SIP_ flags */
 | |
| 
 | |
| 	/*! Mailboxes that this peer cares about */
 | |
| 	AST_LIST_HEAD_NOLOCK(, sip_mailbox) mailboxes;
 | |
| 
 | |
| 	int maxcallbitrate;             /*!<  Maximum Bitrate for a video call */
 | |
| 	int expire;                     /*!<  When to expire this peer registration */
 | |
| 	struct ast_format_cap *caps;            /*!<  Codec capability */
 | |
| 	int rtptimeout;                 /*!<  RTP timeout */
 | |
| 	int rtpholdtimeout;             /*!<  RTP Hold Timeout */
 | |
| 	int rtpkeepalive;               /*!<  Send RTP packets for keepalive */
 | |
| 	ast_group_t callgroup;          /*!<  Call group */
 | |
| 	ast_group_t pickupgroup;        /*!<  Pickup group */
 | |
| 	struct ast_namedgroups *named_callgroups;   /*!< Named call group */
 | |
| 	struct ast_namedgroups *named_pickupgroups; /*!< Named pickup group */
 | |
| 	struct sip_proxy *outboundproxy;/*!< Outbound proxy for this peer */
 | |
| 	struct ast_dnsmgr_entry *dnsmgr;/*!<  DNS refresh manager for peer */
 | |
| 	struct ast_sockaddr addr;        /*!<  IP address of peer */
 | |
| 	unsigned int portinuri:1;       /*!< Whether the port should be included in the URI */
 | |
| 	struct sip_pvt *call;           /*!<  Call pointer */
 | |
| 	int pokeexpire;                 /*!<  Qualification: When to expire poke (qualify= checking) */
 | |
| 	int lastms;                     /*!<  Qualification: How long last response took (in ms), or -1 for no response */
 | |
| 	int maxms;                      /*!<  Qualification: Max ms we will accept for the host to be up, 0 to not monitor */
 | |
| 	int qualifyfreq;                /*!<  Qualification: Qualification: How often to check for the host to be up */
 | |
| 	struct timeval ps;              /*!<  Qualification: Time for sending SIP OPTION in sip_pke_peer() */
 | |
| 	int keepalive;                  /*!<  Keepalive: How often to send keep alive packet */
 | |
| 	int keepalivesend;              /*!<  Keepalive: Scheduled item for sending keep alive packet */
 | |
| 	struct ast_sockaddr defaddr;     /*!<  Default IP address, used until registration */
 | |
| 	struct ast_acl_list *acl;              /*!<  Access control list */
 | |
| 	struct ast_acl_list *contactacl;       /*!<  Restrict what IPs are allowed in the Contact header (for registration) */
 | |
| 	struct ast_acl_list *directmediaacl;   /*!<  Restrict what IPs are allowed to interchange direct media with */
 | |
| 	struct ast_variable *chanvars;  /*!<  Variables to set for channel created by user */
 | |
| 	struct sip_pvt *mwipvt;         /*!<  Subscription for MWI */
 | |
| 	struct sip_st_cfg stimer;       /*!<  SIP Session-Timers */
 | |
| 	int timer_t1;                   /*!<  The maximum T1 value for the peer */
 | |
| 	int timer_b;                    /*!<  The maximum timer B (transaction timeouts) */
 | |
| 	int fromdomainport;             /*!<  The From: domain port */
 | |
| 	struct sip_route path;          /*!<  List of out-of-dialog outgoing routing steps (fm Path headers) */
 | |
| 
 | |
| 	/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
 | |
| 	enum sip_peer_type type; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
 | |
| 	unsigned int disallowed_methods;
 | |
| 	struct ast_cc_config_params *cc_params;
 | |
| 
 | |
| 	struct ast_endpoint *endpoint;
 | |
| 
 | |
| 	struct ast_rtp_dtls_cfg dtls_cfg;
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief Registrations with other SIP proxies
 | |
|  *
 | |
|  * Created by sip_register(), the entry is linked in the 'regl' list,
 | |
|  * and never deleted (other than at 'sip reload' or module unload times).
 | |
|  * The entry always has a pending timeout, either waiting for an ACK to
 | |
|  * the REGISTER message (in which case we have to retransmit the request),
 | |
|  * or waiting for the next REGISTER message to be sent (either the initial one,
 | |
|  * or once the previously completed registration one expires).
 | |
|  * The registration can be in one of many states, though at the moment
 | |
|  * the handling is a bit mixed.
 | |
|  */
 | |
| struct sip_registry {
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(configvalue);/*!< register string from config */
 | |
| 		AST_STRING_FIELD(callid);     /*!< Global Call-ID */
 | |
| 		AST_STRING_FIELD(realm);      /*!< Authorization realm */
 | |
| 		AST_STRING_FIELD(nonce);      /*!< Authorization nonce */
 | |
| 		AST_STRING_FIELD(opaque);     /*!< Opaque nonsense */
 | |
| 		AST_STRING_FIELD(qop);        /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
 | |
| 		AST_STRING_FIELD(authdomain); /*!< Authorization domain */
 | |
| 		AST_STRING_FIELD(regdomain);  /*!< Registration doamin */
 | |
| 		AST_STRING_FIELD(username);   /*!< Who we are registering as */
 | |
| 		AST_STRING_FIELD(authuser);   /*!< Who we *authenticate* as */
 | |
| 		AST_STRING_FIELD(hostname);   /*!< Domain or host we register to */
 | |
| 		AST_STRING_FIELD(secret);     /*!< Password in clear text */
 | |
| 		AST_STRING_FIELD(md5secret);  /*!< Password in md5 */
 | |
| 		AST_STRING_FIELD(callback);   /*!< Contact extension */
 | |
| 		AST_STRING_FIELD(peername);   /*!< Peer registering to */
 | |
| 		AST_STRING_FIELD(localtag);   /*!< Local tag generated same time as callid */
 | |
| 	);
 | |
| 	enum ast_transport transport;   /*!< Transport for this registration UDP, TCP or TLS */
 | |
| 	int portno;                     /*!< Optional port override */
 | |
| 	int regdomainport;              /*!< Port override for domainport */
 | |
| 	int expire;                     /*!< Sched ID of expiration */
 | |
| 	int configured_expiry;          /*!< Configured value to use for the Expires header */
 | |
| 	int expiry;             /*!< Negotiated value used for the Expires header */
 | |
| 	int regattempts;        /*!< Number of attempts (since the last success) */
 | |
| 	int timeout;            /*!< sched id of sip_reg_timeout */
 | |
| 	int refresh;            /*!< How often to refresh */
 | |
| 	struct sip_pvt *call;   /*!< create a sip_pvt structure for each outbound "registration dialog" in progress */
 | |
| 	enum sipregistrystate regstate; /*!< Registration state (see above) */
 | |
| 	struct timeval regtime;         /*!< Last successful registration time */
 | |
| 	int callid_valid;       /*!< 0 means we haven't chosen callid for this registry yet. */
 | |
| 	uint32_t ocseq;         /*!< Sequence number we got to for REGISTERs for this registry */
 | |
| 	struct ast_dnsmgr_entry *dnsmgr;  /*!<  DNS refresh manager for register */
 | |
| 	struct ast_sockaddr us;  /*!< Who the server thinks we are */
 | |
| 	int noncecount;         /*!< Nonce-count */
 | |
| 	char lastmsg[256];      /*!< Last Message sent/received */
 | |
| };
 | |
| 
 | |
| struct tcptls_packet {
 | |
| 	AST_LIST_ENTRY(tcptls_packet) entry;
 | |
| 	struct ast_str *data;
 | |
| 	size_t len;
 | |
| };
 | |
| /*! \brief Definition of a thread that handles a socket */
 | |
| struct sip_threadinfo {
 | |
| 	/*! TRUE if the thread needs to kill itself.  (The module is being unloaded.) */
 | |
| 	int stop;
 | |
| 	int alert_pipe[2];          /*! Used to alert tcptls thread when packet is ready to be written */
 | |
| 	pthread_t threadid;
 | |
| 	struct ast_tcptls_session_instance *tcptls_session;
 | |
| 	enum ast_transport type;    /*!< We keep a copy of the type here so we can display it in the connection list */
 | |
| 	AST_LIST_HEAD_NOLOCK(, tcptls_packet) packet_q;
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief Definition of an MWI subscription to another server
 | |
|  */
 | |
| struct sip_subscription_mwi {
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(username);     /*!< Who we are sending the subscription as */
 | |
| 		AST_STRING_FIELD(authuser);     /*!< Who we *authenticate* as */
 | |
| 		AST_STRING_FIELD(hostname);     /*!< Domain or host we subscribe to */
 | |
| 		AST_STRING_FIELD(secret);       /*!< Password in clear text */
 | |
| 		AST_STRING_FIELD(mailbox);      /*!< Mailbox store to put MWI into */
 | |
| 		);
 | |
| 	enum ast_transport transport;    /*!< Transport to use */
 | |
| 	int portno;                      /*!< Optional port override */
 | |
| 	int resub;                       /*!< Sched ID of resubscription */
 | |
| 	unsigned int subscribed:1;       /*!< Whether we are currently subscribed or not */
 | |
| 	struct sip_pvt *call;            /*!< Outbound subscription dialog */
 | |
| 	struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager for subscription */
 | |
| 	struct ast_sockaddr us;           /*!< Who the server thinks we are */
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * SIP PUBLISH support!
 | |
|  * PUBLISH support was added to chan_sip due to its use in the call-completion
 | |
|  * event package. In order to suspend and unsuspend monitoring of a called party,
 | |
|  * a PUBLISH message must be sent. Rather than try to hack in PUBLISH transmission
 | |
|  * and reception solely for the purposes of handling call-completion-related messages,
 | |
|  * an effort has been made to create a generic framework for handling PUBLISH messages.
 | |
|  *
 | |
|  * There are two main components to the effort, the event publication agent (EPA) and
 | |
|  * the event state compositor (ESC). Both of these terms appear in RFC 3903, and the
 | |
|  * implementation in Asterisk conforms to the defintions there. An EPA is a UAC that
 | |
|  * transmits PUBLISH requests. An ESC is a UAS that receives PUBLISH requests and
 | |
|  * acts appropriately based on the content of those requests.
 | |
|  *
 | |
|  * ESC:
 | |
|  * The main structure in chan_sip is the event_state_compositor. There is an
 | |
|  * event_state_compositor structure for each event package supported (as of Nov 2009
 | |
|  * this is only the call-completion package). The structure contains data which is
 | |
|  * intrinsic to the event package itself, such as the name of the package and a set
 | |
|  * of callbacks for handling incoming PUBLISH requests. In addition, the
 | |
|  * event_state_compositor struct contains an ao2_container of sip_esc_entries.
 | |
|  *
 | |
|  * A sip_esc_entry corresponds to an entity which has sent a PUBLISH to Asterisk. We are
 | |
|  * able to match the incoming PUBLISH to a sip_esc_entry using the Sip-If-Match header
 | |
|  * of the message. Of course, if none is present, then a new sip_esc_entry will be created.
 | |
|  *
 | |
|  * Once it is determined what type of PUBLISH request has come in (from RFC 3903, it may
 | |
|  * be an initial, modify, refresh, or remove), then the event package-specific callbacks
 | |
|  * may be called. If your event package doesn't need to take any specific action for a
 | |
|  * specific PUBLISH type, it is perfectly safe to not define the callback at all. The callback
 | |
|  * only needs to take care of application-specific information. If there is a problem, it is
 | |
|  * up to the callback to take care of sending an appropriate 4xx or 5xx response code. In such
 | |
|  * a case, the callback should return -1. This will tell the function that called the handler
 | |
|  * that an appropriate error response has been sent. If the callback returns 0, however, then
 | |
|  * the caller of the callback will generate a new entity tag and send a 200 OK response.
 | |
|  *
 | |
|  * ESC entries are reference-counted, however as an implementor of a specific event package,
 | |
|  * this should be transparent, since the reference counts are handled by the general ESC
 | |
|  * framework.
 | |
|  *
 | |
|  * EPA:
 | |
|  * The event publication agent in chan_sip is structured quite a bit differently than the
 | |
|  * ESC. With an ESC, an appropriate entry has to be found based on the contents of an incoming
 | |
|  * PUBLISH message. With an EPA, the application interested in sending the PUBLISH can maintain
 | |
|  * a reference to the appropriate EPA entry instead. Similarly, when matching a PUBLISH response
 | |
|  * to an appropriate EPA entry, the sip_pvt can maintain a reference to the corresponding
 | |
|  * EPA entry. The result of this train of thought is that there is no compelling reason to
 | |
|  * maintain a container of these entries.
 | |
|  *
 | |
|  * Instead, there is only the sip_epa_entry structure. Every sip_epa_entry has an entity tag
 | |
|  * that it maintains so that subsequent PUBLISH requests will be identifiable by the ESC on
 | |
|  * the far end. In addition, there is a static_data field which contains information that is
 | |
|  * common to all sip_epa_entries for a specific event package. This static data includes the
 | |
|  * name of the event package and callbacks for handling specific responses for outgoing PUBLISHes.
 | |
|  * Also, there is a field for pointing to instance-specific data. This can include the current
 | |
|  * published state or other identifying information that is specific to an instance of an EPA
 | |
|  * entry of a particular event package.
 | |
|  *
 | |
|  * When an application wishes to send a PUBLISH request, it simply will call create_epa_entry,
 | |
|  * followed by transmit_publish in order to send the PUBLISH. That's all that is necessary.
 | |
|  * Like with ESC entries, sip_epa_entries are reference counted. Unlike ESC entries, though,
 | |
|  * sip_epa_entries reference counts have to be maintained to some degree by the application making
 | |
|  * use of the sip_epa_entry. The application will acquire a reference to the EPA entry when it
 | |
|  * calls create_epa_entry. When the application has finished using the EPA entry (which may not
 | |
|  * be until after several PUBLISH transactions have taken place) it must use ao2_ref to decrease
 | |
|  * the reference count by 1.
 | |
|  */
 | |
| 
 | |
| /*!
 | |
|  * \brief The states that can be represented in a SIP call-completion PUBLISH
 | |
|  */
 | |
| enum sip_cc_publish_state {
 | |
| 	/*! Closed, i.e. unavailable */
 | |
| 	CC_CLOSED,
 | |
| 	/*! Open, i.e. available */
 | |
| 	CC_OPEN,
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief The states that can be represented in a SIP call-completion NOTIFY
 | |
|  */
 | |
| enum sip_cc_notify_state {
 | |
| 	/*! Queued, i.e. unavailable */
 | |
| 	CC_QUEUED,
 | |
| 	/*! Ready, i.e. available */
 | |
| 	CC_READY,
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief The types of PUBLISH messages defined in RFC 3903
 | |
|  */
 | |
| enum sip_publish_type {
 | |
| 	/*!
 | |
| 	 * \brief Unknown
 | |
| 	 *
 | |
| 	 * \details
 | |
| 	 * This actually is not defined in RFC 3903. We use this as a constant
 | |
| 	 * to indicate that an incoming PUBLISH does not fit into any of the
 | |
| 	 * other categories and is thus invalid.
 | |
| 	 */
 | |
| 	SIP_PUBLISH_UNKNOWN,
 | |
| 	/*!
 | |
| 	 * \brief Initial
 | |
| 	 *
 | |
| 	 * \details
 | |
| 	 * The first PUBLISH sent. This will contain a non-zero Expires header
 | |
| 	 * as well as a body that indicates the current state of the endpoint
 | |
| 	 * that has sent the message. The initial PUBLISH is the only type
 | |
| 	 * of PUBLISH to not contain a Sip-If-Match header in it.
 | |
| 	 */
 | |
| 	SIP_PUBLISH_INITIAL,
 | |
| 	/*!
 | |
| 	 * \brief Refresh
 | |
| 	 *
 | |
| 	 * \details
 | |
| 	 * Used to keep a published state from expiring. This will contain a
 | |
| 	 * non-zero Expires header but no body since its purpose is not to
 | |
| 	 * update state.
 | |
| 	 */
 | |
| 	SIP_PUBLISH_REFRESH,
 | |
| 	/*!
 | |
| 	 * \brief Modify
 | |
| 	 *
 | |
| 	 * \details
 | |
| 	 * Used to change state from its previous value. This will contain
 | |
| 	 * a body updating the published state. May or may not contain an
 | |
| 	 * Expires header.
 | |
| 	 */
 | |
| 	SIP_PUBLISH_MODIFY,
 | |
| 	/*!
 | |
| 	 * \brief Remove
 | |
| 	 *
 | |
| 	 * \details
 | |
| 	 * Used to remove published state from an ESC. This will contain
 | |
| 	 * an Expires header set to 0 and likely no body.
 | |
| 	 */
 | |
| 	SIP_PUBLISH_REMOVE,
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * Data which is the same for all instances of an EPA for a
 | |
|  * particular event package
 | |
|  */
 | |
| struct epa_static_data {
 | |
| 	/*! The event type */
 | |
| 	enum subscriptiontype event;
 | |
| 	/*!
 | |
| 	 * The name of the event as it would
 | |
| 	 * appear in a SIP message
 | |
| 	 */
 | |
| 	const char *name;
 | |
| 	/*!
 | |
| 	 * The callback called when a 200 OK is received on an outbound PUBLISH
 | |
| 	 */
 | |
| 	void (*handle_ok)(struct sip_pvt *, struct sip_request *, struct sip_epa_entry *);
 | |
| 	/*!
 | |
| 	 * The callback called when an error response is received on an outbound PUBLISH
 | |
| 	 */
 | |
| 	void (*handle_error)(struct sip_pvt *, const int resp, struct sip_request *, struct sip_epa_entry *);
 | |
| 	/*!
 | |
| 	 * Destructor to call to clean up instance data
 | |
| 	 */
 | |
| 	void (*destructor)(void *instance_data);
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief backend for an event publication agent
 | |
|  */
 | |
| struct epa_backend {
 | |
| 	const struct epa_static_data *static_data;
 | |
| 	AST_LIST_ENTRY(epa_backend) next;
 | |
| };
 | |
| 
 | |
| struct sip_epa_entry {
 | |
| 	/*!
 | |
| 	 * When we are going to send a publish, we need to
 | |
| 	 * know the type of PUBLISH to send.
 | |
| 	 */
 | |
| 	enum sip_publish_type publish_type;
 | |
| 	/*!
 | |
| 	 * When we send a PUBLISH, we have to be
 | |
| 	 * sure to include the entity tag that we
 | |
| 	 * received in the previous response.
 | |
| 	 */
 | |
| 	char entity_tag[SIPBUFSIZE];
 | |
| 	/*!
 | |
| 	 * The destination to which this EPA should send
 | |
| 	 * PUBLISHes. This may be the name of a SIP peer
 | |
| 	 * or a hostname.
 | |
| 	 */
 | |
| 	char destination[SIPBUFSIZE];
 | |
| 	/*!
 | |
| 	 * The body of the most recently-sent PUBLISH message.
 | |
| 	 * This is useful for situations such as authentication,
 | |
| 	 * in which we must send a message identical to the
 | |
| 	 * one previously sent
 | |
| 	 */
 | |
| 	char body[SIPBUFSIZE];
 | |
| 	/*!
 | |
| 	 * Every event package has some constant data and
 | |
| 	 * callbacks that all instances will share. This
 | |
| 	 * data resides in this field.
 | |
| 	 */
 | |
| 	const struct epa_static_data *static_data;
 | |
| 	/*!
 | |
| 	 * In addition to the static data that all instances
 | |
| 	 * of sip_epa_entry will have, each instance will
 | |
| 	 * require its own instance-specific data.
 | |
| 	 */
 | |
| 	void *instance_data;
 | |
| };
 | |
| 
 | |
| /*!
 | |
|  * \brief Instance data for a Call completion EPA entry
 | |
|  */
 | |
| struct cc_epa_entry {
 | |
| 	/*!
 | |
| 	 * The core ID of the CC transaction
 | |
| 	 * for which this EPA entry belongs. This
 | |
| 	 * essentially acts as a unique identifier
 | |
| 	 * for the entry and is used in the hash
 | |
| 	 * and comparison functions
 | |
| 	 */
 | |
| 	int core_id;
 | |
| 	/*!
 | |
| 	 * We keep the last known state of the
 | |
| 	 * device in question handy in case
 | |
| 	 * it needs to be known by a third party.
 | |
| 	 * Also, in the case where for some reason
 | |
| 	 * we get asked to transmit state that we
 | |
| 	 * already sent, we can just ignore the
 | |
| 	 * request.
 | |
| 	 */
 | |
| 	enum sip_cc_publish_state current_state;
 | |
| };
 | |
| 
 | |
| struct event_state_compositor;
 | |
| 
 | |
| /*!
 | |
|  * \brief common ESC items for all event types
 | |
|  *
 | |
|  * The entity_id field serves as a means by which
 | |
|  * A specific entry may be found.
 | |
|  */
 | |
| struct sip_esc_entry {
 | |
| 	/*!
 | |
| 	 * The name of the party who
 | |
| 	 * sent us the PUBLISH. This will more
 | |
| 	 * than likely correspond to a peer name.
 | |
| 	 *
 | |
| 	 * This field's utility isn't really that
 | |
| 	 * great. It's mainly just a user-recognizable
 | |
| 	 * handle that can be printed in debug messages.
 | |
| 	 */
 | |
| 	const char *device_name;
 | |
| 	/*!
 | |
| 	 * The event package for which this esc_entry
 | |
| 	 * exists. Most of the time this isn't really
 | |
| 	 * necessary since you'll have easy access to the
 | |
| 	 * ESC which contains this entry. However, in
 | |
| 	 * some circumstances, we won't have the ESC
 | |
| 	 * available.
 | |
| 	 */
 | |
| 	const char *event;
 | |
| 	/*!
 | |
| 	 * The entity ID used when corresponding
 | |
| 	 * with the EPA on the other side. As the
 | |
| 	 * ESC, we generate an entity ID for each
 | |
| 	 * received PUBLISH and store it in this
 | |
| 	 * structure.
 | |
| 	 */
 | |
| 	char entity_tag[30];
 | |
| 	/*!
 | |
| 	 * The ID for the scheduler. We schedule
 | |
| 	 * destruction of a sip_esc_entry when we
 | |
| 	 * receive a PUBLISH. The destruction is
 | |
| 	 * scheduled for the duration received in
 | |
| 	 * the Expires header.
 | |
| 	 */
 | |
| 	int sched_id;
 | |
| 	/*!
 | |
| 	 * Each ESC entry will be for a specific
 | |
| 	 * event type. Those entries will need to
 | |
| 	 * carry data which is intrinsic to the
 | |
| 	 * ESC entry but which is specific to
 | |
| 	 * the event package
 | |
| 	 */
 | |
| 	void *event_specific_data;
 | |
| };
 | |
| 
 | |
| typedef int (* const esc_publish_callback)(struct sip_pvt *, struct sip_request *, struct event_state_compositor *, struct sip_esc_entry *);
 | |
| 
 | |
| /*!
 | |
|  * \brief Callbacks for SIP ESCs
 | |
|  *
 | |
|  * \details
 | |
|  * The names of the callbacks are self-explanatory. The
 | |
|  * corresponding handler is called whenever the specific
 | |
|  * type of PUBLISH is received.
 | |
|  */
 | |
| struct sip_esc_publish_callbacks {
 | |
| 	const esc_publish_callback initial_handler;
 | |
| 	const esc_publish_callback refresh_handler;
 | |
| 	const esc_publish_callback modify_handler;
 | |
| 	const esc_publish_callback remove_handler;
 | |
| };
 | |
| 
 | |
| struct sip_cc_agent_pvt {
 | |
| 	int offer_timer_id;
 | |
| 	/* A copy of the original call's Call-ID.
 | |
| 	 * We use this as a search key when attempting
 | |
| 	 * to find a particular sip_pvt.
 | |
| 	 */
 | |
| 	char original_callid[SIPBUFSIZE];
 | |
| 	/* A copy of the exten called originally.
 | |
| 	 * We use this to set the proper extension
 | |
| 	 * to dial during the recall since the incoming
 | |
| 	 * request URI is one that was generated just
 | |
| 	 * for the recall
 | |
| 	 */
 | |
| 	char original_exten[SIPBUFSIZE];
 | |
| 	/* A reference to the dialog which we will
 | |
| 	 * be sending a NOTIFY on when it comes time
 | |
| 	 * to send one
 | |
| 	 */
 | |
| 	struct sip_pvt *subscribe_pvt;
 | |
| 	/* When we send a NOTIFY, we include a URI
 | |
| 	 * that should be used by the caller when he
 | |
| 	 * wishes to send a PUBLISH or INVITE to us.
 | |
| 	 * We store that URI here.
 | |
| 	 */
 | |
| 	char notify_uri[SIPBUFSIZE];
 | |
| 	/* When we advertise call completion to a caller,
 | |
| 	 * we provide a URI for the caller to use when
 | |
| 	 * he sends us a SUBSCRIBE. We store it for matching
 | |
| 	 * purposes when we receive the SUBSCRIBE from the
 | |
| 	 * caller.
 | |
| 	 */
 | |
| 	char subscribe_uri[SIPBUFSIZE];
 | |
| 	char is_available;
 | |
| };
 | |
| 
 | |
| struct sip_monitor_instance {
 | |
| 	AST_DECLARE_STRING_FIELDS(
 | |
| 		AST_STRING_FIELD(subscribe_uri);
 | |
| 		AST_STRING_FIELD(notify_uri);
 | |
| 		AST_STRING_FIELD(peername);
 | |
| 		AST_STRING_FIELD(device_name);
 | |
| 	);
 | |
| 	int core_id;
 | |
| 	struct sip_pvt *subscription_pvt;
 | |
| 	struct sip_epa_entry *suspension_entry;
 | |
| };
 | |
| 
 | |
| /*! \brief List of well-known SIP options. If we get this in a require,
 | |
|    we should check the list and answer accordingly. */
 | |
| static const struct cfsip_options {
 | |
| 	int id;             /*!< Bitmap ID */
 | |
| 	int supported;      /*!< Supported by Asterisk ? */
 | |
| 	char * const text;  /*!< Text id, as in standard */
 | |
| } sip_options[] = {	/* XXX used in 3 places */
 | |
| 	/* RFC3262: PRACK 100% reliability */
 | |
| 	{ SIP_OPT_100REL,	NOT_SUPPORTED,	"100rel" },
 | |
| 	/* RFC3959: SIP Early session support */
 | |
| 	{ SIP_OPT_EARLY_SESSION, NOT_SUPPORTED,	"early-session" },
 | |
| 	/* SIMPLE events:  RFC4662 */
 | |
| 	{ SIP_OPT_EVENTLIST,	NOT_SUPPORTED,	"eventlist" },
 | |
| 	/* RFC 4916- Connected line ID updates */
 | |
| 	{ SIP_OPT_FROMCHANGE,	NOT_SUPPORTED,	"from-change" },
 | |
| 	/* GRUU: Globally Routable User Agent URI's */
 | |
| 	{ SIP_OPT_GRUU,		NOT_SUPPORTED,	"gruu" },
 | |
| 	/* RFC4244 History info */
 | |
| 	{ SIP_OPT_HISTINFO,	NOT_SUPPORTED,	"histinfo" },
 | |
| 	/* RFC3911: SIP Join header support */
 | |
| 	{ SIP_OPT_JOIN,		NOT_SUPPORTED,	"join" },
 | |
| 	/* Disable the REFER subscription, RFC 4488 */
 | |
| 	{ SIP_OPT_NOREFERSUB,	NOT_SUPPORTED,	"norefersub" },
 | |
| 	/* SIP outbound - the final NAT battle - draft-sip-outbound */
 | |
| 	{ SIP_OPT_OUTBOUND,	NOT_SUPPORTED,	"outbound" },
 | |
| 	/* RFC3327: Path support */
 | |
| 	{ SIP_OPT_PATH,		NOT_SUPPORTED,	"path" },
 | |
| 	/* RFC3840: Callee preferences */
 | |
| 	{ SIP_OPT_PREF,		NOT_SUPPORTED,	"pref" },
 | |
| 	/* RFC3312: Precondition support */
 | |
| 	{ SIP_OPT_PRECONDITION,	NOT_SUPPORTED,	"precondition" },
 | |
| 	/* RFC3323: Privacy with proxies*/
 | |
| 	{ SIP_OPT_PRIVACY,	NOT_SUPPORTED,	"privacy" },
 | |
| 	/* RFC-ietf-sip-uri-list-conferencing-02.txt conference invite lists */
 | |
| 	{ SIP_OPT_RECLISTINV,	NOT_SUPPORTED,	"recipient-list-invite" },
 | |
| 	/* RFC-ietf-sip-uri-list-subscribe-02.txt - subscription lists */
 | |
| 	{ SIP_OPT_RECLISTSUB,	NOT_SUPPORTED,	"recipient-list-subscribe" },
 | |
| 	/* RFC3891: Replaces: header for transfer */
 | |
| 	{ SIP_OPT_REPLACES,	SUPPORTED,	"replaces" },
 | |
| 	/* One version of Polycom firmware has the wrong label */
 | |
| 	{ SIP_OPT_REPLACES,	SUPPORTED,	"replace" },
 | |
| 	/* RFC4412 Resource priorities */
 | |
| 	{ SIP_OPT_RESPRIORITY,	NOT_SUPPORTED,	"resource-priority" },
 | |
| 	/* RFC3329: Security agreement mechanism */
 | |
| 	{ SIP_OPT_SEC_AGREE,	NOT_SUPPORTED,	"sec_agree" },
 | |
| 	/* RFC4092: Usage of the SDP ANAT Semantics in the SIP */
 | |
| 	{ SIP_OPT_SDP_ANAT,	NOT_SUPPORTED,	"sdp-anat" },
 | |
| 	/* RFC4028: SIP Session-Timers */
 | |
| 	{ SIP_OPT_TIMER,	SUPPORTED,	"timer" },
 | |
| 	/* RFC4538: Target-dialog */
 | |
| 	{ SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED,	"tdialog" },
 | |
| };
 | |
| 
 | |
| struct digestkeys {
 | |
| 	const char *key;
 | |
| 	const char *s;
 | |
| };
 | |
| 
 | |
| AST_THREADSTORAGE(check_auth_buf);
 | |
| 
 | |
| /*----------------------------------------------------------*/
 | |
| /*----                    FUNCTIONS                     ----*/
 | |
| /*----------------------------------------------------------*/
 | |
| 
 | |
| struct sip_peer *sip_find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport);
 | |
| void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader);
 | |
| const char *sip_get_header(const struct sip_request *req, const char *name);
 | |
| const char *sip_get_transport(enum ast_transport t);
 | |
| 
 | |
| #define sip_ref_peer(peer, tag) ao2_t_bump(peer, tag)
 | |
| #define sip_unref_peer(peer, tag) ({ ao2_t_cleanup(peer, tag); (NULL); })
 | |
| 
 | |
| #endif
 |