#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets called with p locked. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
Add realm authentication in list. | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add T.38 Session Description Protocol message. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the SIP dialog list (of sip_pvt's). | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
AST_THREADSTORAGE (check_auth_buf, check_auth_buf_init) | |
AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
A per-thread temporary pvt structure. | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock
| |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
struct ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
The user list: Users and friends. |
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 476 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1843 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 368 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
#define DEC_CALL_LIMIT 0 |
Definition at line 609 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 611 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
#define DEFAULT_ALLOWGUEST TRUE |
#define DEFAULT_AUTOCREATEPEER FALSE |
#define DEFAULT_CALLERID "asterisk" |
#define DEFAULT_COMPACTHEADERS FALSE |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 189 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 204 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 203 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
#define DEFAULT_MAX_EXPIRY 3600 |
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 176 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 202 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
#define DEFAULT_MOHINTERPRET "default" |
#define DEFAULT_MOHSUGGEST "" |
#define DEFAULT_MWITIME 10 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_NOTIFYRINGING TRUE |
#define DEFAULT_PEDANTIC FALSE |
#define DEFAULT_QUALIFY FALSE |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 206 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 514 of file chan_sip.c.
Referenced by reload_config().
#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.
Definition at line 506 of file chan_sip.c.
Referenced by reload_config().
#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.
Definition at line 505 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 507 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 211 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 517 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_VMEXTEN "asterisk" |
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 181 of file chan_sip.c.
Referenced by handle_response_register().
#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.
Definition at line 183 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 187 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 180 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 154 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1027 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
Referenced by __sip_show_channels().
#define INC_CALL_LIMIT 1 |
Definition at line 610 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 220 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 167 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 197 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 212 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1025 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 207 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 236 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 409 of file chan_sip.c.
#define RTP 1 |
Definition at line 235 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 218 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6444 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 716 of file chan_sip.c.
Referenced by handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 757 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 745 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 746 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 731 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 732 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 736 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 734 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 735 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 733 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 762 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_FREE_BIT (1 << 14) |
----
Definition at line 730 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 760 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 723 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 759 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 750 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 749 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), realtime_peer(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 214 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 215 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 216 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 742 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 739 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 740 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 741 of file chan_sip.c.
Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 717 of file chan_sip.c.
Referenced by __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 721 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 756 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 718 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 412 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 413 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 729 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 784 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 783 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 796 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 791 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
23: Inactive hold
Definition at line 794 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 793 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 777 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 779 of file chan_sip.c.
Referenced by reload_config(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 780 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_UDPTL_DESTINATION)
Definition at line 800 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 776 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 786 of file chan_sip.c.
Referenced by update_call_counter().
#define SIP_PAGE2_OUTGOING_CALL (1 << 27) |
27: Is this an outgoing call?
Definition at line 797 of file chan_sip.c.
Referenced by sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 795 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 772 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
Definition at line 771 of file chan_sip.c.
Referenced by expire_register(), realtime_peer(), and reload_config().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 769 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 773 of file chan_sip.c.
Referenced by realtime_update_peer(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 770 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 781 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 775 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 785 of file chan_sip.c.
Referenced by build_peer(), does_peer_need_mwi(), and register_verify().
#define SIP_PAGE2_T38SUPPORT (7 << 20) |
T38 Fax Passthrough Support
Definition at line 787 of file chan_sip.c.
Referenced by create_addr_from_peer(), and sip_alloc().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 789 of file chan_sip.c.
Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
22: T38 Fax Passthrough Support (not implemented)
Definition at line 790 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
20: T38 Fax Passthrough Support
Definition at line 788 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 798 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 782 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), reload_config(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 722 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 805 of file chan_sip.c.
Referenced by handle_request(), handle_request_message(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), initialize_initreq(), and sipsock_read().
#define SIP_PKT_IGNORE (1 << 2) |
This is a re-transmit, ignore it
Definition at line 807 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 806 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 754 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 755 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 720 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 724 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 727 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 747 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 758 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 208 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 725 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 728 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 726 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 161 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 837 of file chan_sip.c.
Referenced by __sip_ack(), __sip_reliable_xmit(), __sip_semi_ack(), add_sip_domain(), build_reply_digest(), check_auth(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_register(), local_attended_transfer(), parse_request(), parse_sip_options(), reqprep(), retrans_pkt(), sip_addheader(), sip_call(), sip_debug_test_addr(), sip_debug_test_pvt(), sip_dump_history(), sip_hangup(), sip_poke_peer(), sip_reregister(), transmit_invite(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and update_call_counter().
#define sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
Definition at line 838 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 839 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 482 of file chan_sip.c.
Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), reload_config(), set_address_from_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
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
Definition at line 408 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 479 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 812 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 831 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_14400 (1 << 13) |
14400 bps t38FaxRate This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate
Definition at line 832 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_2400 (1 << 8) |
2400 bps t38FaxRate
Definition at line 827 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_4800 (1 << 9) |
4800 bps t38FaxRate
Definition at line 828 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_7200 (1 << 10) |
7200 bps t38FaxRate
Definition at line 829 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_9600 (1 << 11) |
9600 bps t38FaxRate
Definition at line 830 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
Unset for transferredTCF (UDPTL), set for localTCF (TPKT)
Definition at line 817 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 816 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_TRANSCODING_JBIG (1 << 2) |
Default: 0 (unset)
Definition at line 814 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 813 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 820 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_NONE (0 << 4) |
two bits, if unset NO t38UDPEC field in T38 SDP
Definition at line 819 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 821 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 823 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 824 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 825 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1603 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 165 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 163 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 344 of file chan_sip.c.
00344 { 00345 AUTH_SUCCESSFUL = 0, 00346 AUTH_CHALLENGE_SENT = 1, 00347 AUTH_SECRET_FAILED = -1, 00348 AUTH_USERNAME_MISMATCH = -2, 00349 AUTH_NOT_FOUND = -3, 00350 AUTH_FAKE_AUTH = -4, 00351 AUTH_UNKNOWN_DOMAIN = -5, 00352 AUTH_PEER_NOT_DYNAMIC = -6, 00353 AUTH_ACL_FAILED = -7, 00354 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 679 of file chan_sip.c.
00679 { 00680 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00681 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00682 };
enum invitestates |
States for the INVITE transaction, not the dialog.
INV_NONE | No state at all, maybe not an INVITE dialog |
INV_CALLING | Invite sent, no answer |
INV_PROCEEDING | We got/sent 1xx message |
INV_EARLY_MEDIA | We got 18x message with to-tag back |
INV_COMPLETED | Got final response with error. Wait for ACK, then CONFIRMED |
INV_CONFIRMED | Confirmed response - we've got an ack (Incoming calls only) |
INV_TERMINATED | 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 | Transaction cancelled by client or server in non-terminated state |
Definition at line 255 of file chan_sip.c.
00255 { 00256 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00257 INV_CALLING = 1, /*!< Invite sent, no answer */ 00258 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00259 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00260 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00261 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00262 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00263 The only way out of this is a BYE from one side */ 00264 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00265 };
Definition at line 282 of file chan_sip.c.
00282 { 00283 PARSE_REGISTER_FAILED, 00284 PARSE_REGISTER_UPDATE, 00285 PARSE_REGISTER_QUERY, 00286 };
enum referstatus |
Parameters to know status of transfer.
REFER_IDLE | No REFER is in progress |
REFER_SENT | Sent REFER to transferee |
REFER_RECEIVED | Received REFER from transferer |
REFER_CONFIRMED | Refer confirmed with a 100 TRYING |
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 |
Definition at line 861 of file chan_sip.c.
00861 { 00862 REFER_IDLE, /*!< No REFER is in progress */ 00863 REFER_SENT, /*!< Sent REFER to transferee */ 00864 REFER_RECEIVED, /*!< Received REFER from transferer */ 00865 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00866 REFER_ACCEPTED, /*!< Accepted by transferee */ 00867 REFER_RINGING, /*!< Target Ringing */ 00868 REFER_200OK, /*!< Answered by transfer target */ 00869 REFER_FAILED, /*!< REFER declined - go on */ 00870 REFER_NOAUTH /*!< We had no auth for REFER */ 00871 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 338 of file chan_sip.c.
00338 { 00339 PROXY_AUTH, 00340 WWW_AUTH, 00341 };
enum sip_result |
Definition at line 247 of file chan_sip.c.
00247 { 00248 AST_SUCCESS = 0, 00249 AST_FAILURE = -1, 00250 };
enum sipmethod |
SIP Request methods known by Asterisk.
SIP_UNKNOWN | |
SIP_RESPONSE | |
SIP_REGISTER | |
SIP_OPTIONS | |
SIP_NOTIFY | |
SIP_INVITE | |
SIP_ACK | |
SIP_PRACK | |
SIP_BYE | |
SIP_REFER | |
SIP_SUBSCRIBE | |
SIP_MESSAGE | |
SIP_UPDATE | |
SIP_INFO | |
SIP_CANCEL | |
SIP_PUBLISH | |
SIP_PING |
Definition at line 313 of file chan_sip.c.
00313 { 00314 SIP_UNKNOWN, /* Unknown response */ 00315 SIP_RESPONSE, /* Not request, response to outbound request */ 00316 SIP_REGISTER, 00317 SIP_OPTIONS, 00318 SIP_NOTIFY, 00319 SIP_INVITE, 00320 SIP_ACK, 00321 SIP_PRACK, /* Not supported at all */ 00322 SIP_BYE, 00323 SIP_REFER, 00324 SIP_SUBSCRIBE, 00325 SIP_MESSAGE, 00326 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00327 SIP_INFO, 00328 SIP_CANCEL, 00329 SIP_PUBLISH, /* Not supported at all */ 00330 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00331 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 357 of file chan_sip.c.
00357 { 00358 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00359 REG_STATE_REGSENT, /*!< Registration request sent */ 00360 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00361 REG_STATE_REGISTERED, /*!< Registred and done */ 00362 REG_STATE_REJECTED, /*!< Registration rejected */ 00363 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00364 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00365 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00366 };
enum subscriptiontype |
Definition at line 288 of file chan_sip.c.
00288 { 00289 NONE = 0, 00290 XPIDF_XML, 00291 DIALOG_INFO_XML, 00292 CPIM_PIDF_XML, 00293 PIDF_XML, 00294 MWI_NOTIFICATION 00295 };
enum t38state |
T38 States for a call.
Definition at line 842 of file chan_sip.c.
00842 { 00843 T38_DISABLED = 0, /*!< Not enabled */ 00844 T38_LOCAL_DIRECT, /*!< Offered from local */ 00845 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00846 T38_PEER_DIRECT, /*!< Offered from peer */ 00847 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00848 T38_ENABLED /*!< Negotiated (enabled) */ 00849 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 241 of file chan_sip.c.
00241 { 00242 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00243 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00244 };
enum xmittype |
XMIT_CRITICAL | Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session |
XMIT_RELIABLE | Transmit SIP message reliably, with re-transmits |
XMIT_UNRELIABLE | Transmit SIP message without bothering with re-transmits |
Definition at line 275 of file chan_sip.c.
00275 { 00276 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00277 If it fails, it's critical and will cause a teardown of the session */ 00278 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00279 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00280 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4254 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04255 { 04256 int pass; 04257 04258 /* 04259 * Technically you can place arbitrary whitespace both before and after the ':' in 04260 * a header, although RFC3261 clearly says you shouldn't before, and place just 04261 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04262 * a good idea to say you can do it, and if you can do it, why in the hell would. 04263 * you say you shouldn't. 04264 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04265 * and we always allow spaces after that for compatibility. 04266 */ 04267 for (pass = 0; name && pass < 2;pass++) { 04268 int x, len = strlen(name); 04269 for (x=*start; x<req->headers; x++) { 04270 if (!strncasecmp(req->header[x], name, len)) { 04271 char *r = req->header[x] + len; /* skip name */ 04272 if (pedanticsipchecking) 04273 r = ast_skip_blanks(r); 04274 04275 if (*r == ':') { 04276 *start = x+1; 04277 return ast_skip_blanks(r+1); 04278 } 04279 } 04280 } 04281 if (pass == 0) /* Try aliases */ 04282 name = find_alias(name, NULL); 04283 } 04284 04285 /* Don't return NULL, so get_header is always a valid pointer */ 04286 return ""; 04287 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2143 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, DEADLOCK_AVOIDANCE, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02144 { 02145 struct sip_pkt *cur, *prev = NULL; 02146 02147 /* Just in case... */ 02148 char *msg; 02149 int res = FALSE; 02150 02151 msg = sip_methods[sipmethod].text; 02152 02153 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02154 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02155 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02156 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02157 if (!resp && (seqno == p->pendinginvite)) { 02158 if (option_debug) 02159 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02160 p->pendinginvite = 0; 02161 } 02162 /* this is our baby */ 02163 res = TRUE; 02164 UNLINK(cur, p->packets, prev); 02165 if (cur->retransid > -1) { 02166 if (sipdebug && option_debug > 3) 02167 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02168 } 02169 /* This odd section is designed to thwart a 02170 * race condition in the packet scheduler. There are 02171 * two conditions under which deleting the packet from the 02172 * scheduler can fail. 02173 * 02174 * 1. The packet has been removed from the scheduler because retransmission 02175 * is being attempted. The problem is that if the packet is currently attempting 02176 * retransmission and we are at this point in the code, then that MUST mean 02177 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02178 * lock temporarily to allow retransmission. 02179 * 02180 * 2. The packet has reached its maximum number of retransmissions and has 02181 * been permanently removed from the packet scheduler. If this is the case, then 02182 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02183 * of the retransid to -1 is ensured since in both cases p's lock is held. 02184 */ 02185 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02186 DEADLOCK_AVOIDANCE(&p->lock); 02187 } 02188 free(cur); 02189 break; 02190 } 02191 } 02192 if (option_debug) 02193 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found"); 02194 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2066 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, MWI_NOTIFICATION, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02067 { 02068 struct sip_pvt *p = (struct sip_pvt *)data; 02069 02070 /* If this is a subscription, tell the phone that we got a timeout */ 02071 if (p->subscribed) { 02072 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02073 p->subscribed = NONE; 02074 append_history(p, "Subscribestatus", "timeout"); 02075 if (option_debug > 2) 02076 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02077 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02078 } 02079 02080 /* If there are packets still waiting for delivery, delay the destruction */ 02081 if (p->packets) { 02082 if (option_debug > 2) 02083 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02084 append_history(p, "ReliableXmit", "timeout"); 02085 return 10000; 02086 } 02087 02088 /* If we're destroying a subscription, dereference peer object too */ 02089 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02090 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02091 02092 /* Reset schedule ID */ 02093 p->autokillid = -1; 02094 02095 if (option_debug) 02096 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02097 append_history(p, "AutoDestroy", "%s", p->callid); 02098 if (p->owner) { 02099 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02100 ast_queue_hangup(p->owner); 02101 } else if (p->refer) { 02102 if (option_debug > 2) 02103 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02104 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02105 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02106 } else 02107 sip_destroy(p); 02108 return 0; 02109 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3069 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::autokillid, sip_registry::call, sip_pvt::chanvars, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), sip_pvt::history, sip_pvt::history_entries, iflist, sip_pvt::initid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pkt::next, sip_pvt::next, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::route, sip_pvt::rtp, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, cfsip_methods::text, sip_pvt::udptl, UNLINK, update_call_counter(), sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03070 { 03071 struct sip_pvt *cur, *prev = NULL; 03072 struct sip_pkt *cp; 03073 03074 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03075 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03076 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03077 return -1; 03078 } 03079 03080 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03081 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03082 return -1; 03083 } 03084 03085 if (sip_debug_test_pvt(p) || option_debug > 2) 03086 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03087 03088 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03089 update_call_counter(p, DEC_CALL_LIMIT); 03090 if (option_debug > 1) 03091 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03092 } 03093 03094 /* Unlink us from the owner if we have one */ 03095 if (p->owner) { 03096 if (lockowner) 03097 ast_channel_lock(p->owner); 03098 if (option_debug) 03099 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03100 p->owner->tech_pvt = NULL; 03101 /* Make sure that the channel knows its backend is going away */ 03102 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03103 if (lockowner) 03104 ast_channel_unlock(p->owner); 03105 /* Give the channel a chance to react before deallocation */ 03106 usleep(1); 03107 } 03108 03109 /* Remove link from peer to subscription of MWI */ 03110 if (p->relatedpeer) { 03111 p->relatedpeer->mwipvt = NULL; 03112 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03113 } 03114 03115 if (dumphistory) 03116 sip_dump_history(p); 03117 03118 if (p->options) 03119 free(p->options); 03120 03121 if (p->stateid > -1) 03122 ast_extension_state_del(p->stateid, NULL); 03123 AST_SCHED_DEL(sched, p->initid); 03124 AST_SCHED_DEL(sched, p->waitid); 03125 AST_SCHED_DEL(sched, p->autokillid); 03126 03127 if (p->rtp) { 03128 ast_rtp_destroy(p->rtp); 03129 } 03130 if (p->vrtp) { 03131 ast_rtp_destroy(p->vrtp); 03132 } 03133 if (p->udptl) 03134 ast_udptl_destroy(p->udptl); 03135 if (p->refer) 03136 free(p->refer); 03137 if (p->route) { 03138 free_old_route(p->route); 03139 p->route = NULL; 03140 } 03141 if (p->registry) { 03142 if (p->registry->call == p) 03143 p->registry->call = NULL; 03144 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03145 } 03146 03147 /* Clear history */ 03148 if (p->history) { 03149 struct sip_history *hist; 03150 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03151 free(hist); 03152 p->history_entries--; 03153 } 03154 free(p->history); 03155 p->history = NULL; 03156 } 03157 03158 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03159 if (cur == p) { 03160 UNLINK(cur, iflist, prev); 03161 break; 03162 } 03163 } 03164 if (!cur) { 03165 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03166 return 0; 03167 } 03168 03169 /* remove all current packets in this dialog */ 03170 while((cp = p->packets)) { 03171 p->packets = p->packets->next; 03172 AST_SCHED_DEL(sched, cp->retransid); 03173 free(cp); 03174 } 03175 if (p->chanvars) { 03176 ast_variables_destroy(p->chanvars); 03177 p->chanvars = NULL; 03178 } 03179 ast_mutex_destroy(&p->lock); 03180 03181 ast_string_field_free_memory(p); 03182 03183 free(p); 03184 return 0; 03185 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7499 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07500 { 07501 int res; 07502 07503 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07504 return res; 07505 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2198 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02199 { 02200 struct sip_pkt *cur = NULL; 02201 02202 while (p->packets) { 02203 int method; 02204 if (cur == p->packets) { 02205 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02206 return; 02207 } 02208 cur = p->packets; 02209 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02210 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02211 } 02212 }
static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
char * | data, | |||
int | len, | |||
int | fatal, | |||
int | sipmethod | |||
) | [static] |
Transmit packet with retransmits.
Definition at line 2019 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sipdebug, sip_pvt::timer_t1, sip_pkt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02020 { 02021 struct sip_pkt *pkt; 02022 int siptimer_a = DEFAULT_RETRANS; 02023 int xmitres = 0; 02024 02025 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02026 return AST_FAILURE; 02027 memcpy(pkt->data, data, len); 02028 pkt->method = sipmethod; 02029 pkt->packetlen = len; 02030 pkt->next = p->packets; 02031 pkt->owner = p; 02032 pkt->seqno = seqno; 02033 if (resp) 02034 ast_set_flag(pkt, FLAG_RESPONSE); 02035 pkt->data[len] = '\0'; 02036 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02037 pkt->retransid = -1; 02038 if (fatal) 02039 ast_set_flag(pkt, FLAG_FATAL); 02040 if (pkt->timer_t1) 02041 siptimer_a = pkt->timer_t1 * 2; 02042 02043 if (option_debug > 3 && sipdebug) 02044 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02045 pkt->retransid = -1; 02046 pkt->next = p->packets; 02047 p->packets = pkt; 02048 if (sipmethod == SIP_INVITE) { 02049 /* Note this is a pending invite */ 02050 p->pendinginvite = seqno; 02051 } 02052 02053 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02054 02055 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02056 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02057 return AST_FAILURE; 02058 } else { 02059 /* Schedule retransmission */ 02060 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02061 return AST_SUCCESS; 02062 } 02063 }
static int __sip_semi_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 2215 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02216 { 02217 struct sip_pkt *cur; 02218 int res = -1; 02219 02220 for (cur = p->packets; cur; cur = cur->next) { 02221 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02222 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02223 /* this is our baby */ 02224 if (cur->retransid > -1) { 02225 if (option_debug > 3 && sipdebug) 02226 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02227 } 02228 AST_SCHED_DEL(sched, cur->retransid); 02229 res = 0; 02230 break; 02231 } 02232 } 02233 if (option_debug) 02234 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 02235 return res; 02236 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10855 of file chan_sip.c.
References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, sip_peer::mailbox, MWI_NOTIFICATION, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, and subscription_type2str().
Referenced by sip_show_channels(), and sip_show_subscriptions().
10856 { 10857 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10858 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10859 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10860 struct sip_pvt *cur; 10861 int numchans = 0; 10862 char *referstatus = NULL; 10863 10864 if (argc != 3) 10865 return RESULT_SHOWUSAGE; 10866 ast_mutex_lock(&iflock); 10867 cur = iflist; 10868 if (!subscriptions) 10869 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10870 else 10871 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10872 for (; cur; cur = cur->next) { 10873 referstatus = ""; 10874 if (cur->refer) { /* SIP transfer in progress */ 10875 referstatus = referstatus2str(cur->refer->status); 10876 } 10877 if (cur->subscribed == NONE && !subscriptions) { 10878 char formatbuf[SIPBUFSIZE/2]; 10879 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10880 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10881 cur->callid, 10882 cur->ocseq, cur->icseq, 10883 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10884 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10885 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10886 cur->lastmsg , 10887 referstatus 10888 ); 10889 numchans++; 10890 } 10891 if (cur->subscribed != NONE && subscriptions) { 10892 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10893 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10894 cur->callid, 10895 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10896 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10897 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10898 subscription_type2str(cur->subscribed), 10899 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10900 ); 10901 numchans++; 10902 } 10903 } 10904 ast_mutex_unlock(&iflock); 10905 if (!subscriptions) 10906 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10907 else 10908 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10909 return RESULT_SUCCESS; 10910 #undef FORMAT 10911 #undef FORMAT2 10912 #undef FORMAT3 10913 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1770 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01771 { 01772 int res; 01773 const struct sockaddr_in *dst = sip_real_dst(p); 01774 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01775 01776 if (res == -1) { 01777 switch (errno) { 01778 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01779 case EHOSTUNREACH: /* Host can't be reached */ 01780 case ENETDOWN: /* Inteface down */ 01781 case ENETUNREACH: /* Network failure */ 01782 case ECONNREFUSED: /* ICMP port unreachable */ 01783 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01784 } 01785 } 01786 if (res != len) 01787 ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno)); 01788 return res; 01789 }
static int __transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Base transmit response function.
Definition at line 6038 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06039 { 06040 struct sip_request resp; 06041 int seqno = 0; 06042 06043 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06044 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06045 return -1; 06046 } 06047 respprep(&resp, p, msg, req); 06048 add_header_contentLength(&resp, 0); 06049 /* If we are cancelling an incoming invite for some reason, add information 06050 about the reason why we are doing this in clear text */ 06051 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06052 char buf[10]; 06053 06054 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06055 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06056 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06057 } 06058 return send_response(p, &resp, reliable, seqno); 06059 }
static int _sip_show_peer | ( | int | type, | |
int | fd, | |||
struct mansession * | s, | |||
const struct message * | m, | |||
int | argc, | |||
const char * | argv[] | |||
) | [static] |
Show one peer in detail (main function).
Definition at line 10413 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10414 { 10415 char status[30] = ""; 10416 char cbuf[256]; 10417 struct sip_peer *peer; 10418 char codec_buf[512]; 10419 struct ast_codec_pref *pref; 10420 struct ast_variable *v; 10421 struct sip_auth *auth; 10422 int x = 0, codec = 0, load_realtime; 10423 int realtimepeers; 10424 10425 realtimepeers = ast_check_realtime("sippeers"); 10426 10427 if (argc < 4) 10428 return RESULT_SHOWUSAGE; 10429 10430 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10431 peer = find_peer(argv[3], NULL, load_realtime); 10432 if (s) { /* Manager */ 10433 if (peer) { 10434 const char *id = astman_get_header(m,"ActionID"); 10435 10436 astman_append(s, "Response: Success\r\n"); 10437 if (!ast_strlen_zero(id)) 10438 astman_append(s, "ActionID: %s\r\n",id); 10439 } else { 10440 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10441 astman_send_error(s, m, cbuf); 10442 return 0; 10443 } 10444 } 10445 if (peer && type==0 ) { /* Normal listing */ 10446 ast_cli(fd,"\n\n"); 10447 ast_cli(fd, " * Name : %s\n", peer->name); 10448 if (realtimepeers) { /* Realtime is enabled */ 10449 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10450 } 10451 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10452 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10453 for (auth = peer->auth; auth; auth = auth->next) { 10454 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10455 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10456 } 10457 ast_cli(fd, " Context : %s\n", peer->context); 10458 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10459 ast_cli(fd, " Language : %s\n", peer->language); 10460 if (!ast_strlen_zero(peer->accountcode)) 10461 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10462 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10463 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10464 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10465 if (!ast_strlen_zero(peer->fromuser)) 10466 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10467 if (!ast_strlen_zero(peer->fromdomain)) 10468 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10469 ast_cli(fd, " Callgroup : "); 10470 print_group(fd, peer->callgroup, 0); 10471 ast_cli(fd, " Pickupgroup : "); 10472 print_group(fd, peer->pickupgroup, 0); 10473 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10474 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10475 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10476 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10477 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10478 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10479 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10480 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10481 ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE))); 10482 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10483 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10484 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10485 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10486 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10487 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10488 #endif 10489 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10490 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10491 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10492 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10493 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10494 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10495 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10496 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10497 10498 /* - is enumerated */ 10499 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10500 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10501 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10502 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 10503 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10504 if (!ast_strlen_zero(global_regcontext)) 10505 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10506 ast_cli(fd, " Def. Username: %s\n", peer->username); 10507 ast_cli(fd, " SIP Options : "); 10508 if (peer->sipoptions) { 10509 int lastoption = -1; 10510 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10511 if (sip_options[x].id != lastoption) { 10512 if (peer->sipoptions & sip_options[x].id) 10513 ast_cli(fd, "%s ", sip_options[x].text); 10514 lastoption = x; 10515 } 10516 } 10517 } else 10518 ast_cli(fd, "(none)"); 10519 10520 ast_cli(fd, "\n"); 10521 ast_cli(fd, " Codecs : "); 10522 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10523 ast_cli(fd, "%s\n", codec_buf); 10524 ast_cli(fd, " Codec Order : ("); 10525 print_codec_to_cli(fd, &peer->prefs); 10526 ast_cli(fd, ")\n"); 10527 10528 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10529 ast_cli(fd, " Status : "); 10530 peer_status(peer, status, sizeof(status)); 10531 ast_cli(fd, "%s\n",status); 10532 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10533 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10534 if (peer->chanvars) { 10535 ast_cli(fd, " Variables :\n"); 10536 for (v = peer->chanvars ; v ; v = v->next) 10537 ast_cli(fd, " %s = %s\n", v->name, v->value); 10538 } 10539 ast_cli(fd,"\n"); 10540 ASTOBJ_UNREF(peer,sip_destroy_peer); 10541 } else if (peer && type == 1) { /* manager listing */ 10542 char buf[256]; 10543 astman_append(s, "Channeltype: SIP\r\n"); 10544 astman_append(s, "ObjectName: %s\r\n", peer->name); 10545 astman_append(s, "ChanObjectType: peer\r\n"); 10546 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10547 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10548 astman_append(s, "Context: %s\r\n", peer->context); 10549 astman_append(s, "Language: %s\r\n", peer->language); 10550 if (!ast_strlen_zero(peer->accountcode)) 10551 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10552 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10553 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10554 if (!ast_strlen_zero(peer->fromuser)) 10555 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10556 if (!ast_strlen_zero(peer->fromdomain)) 10557 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10558 astman_append(s, "Callgroup: "); 10559 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10560 astman_append(s, "Pickupgroup: "); 10561 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10562 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10563 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10564 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10565 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10566 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10567 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10568 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10569 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10570 astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT), ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE))); 10571 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10572 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10573 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10574 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10575 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10576 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10577 10578 /* - is enumerated */ 10579 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10580 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10581 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10582 astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); 10583 astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10584 astman_append(s, "Default-Username: %s\r\n", peer->username); 10585 if (!ast_strlen_zero(global_regcontext)) 10586 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10587 astman_append(s, "Codecs: "); 10588 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10589 astman_append(s, "%s\r\n", codec_buf); 10590 astman_append(s, "CodecOrder: "); 10591 pref = &peer->prefs; 10592 for(x = 0; x < 32 ; x++) { 10593 codec = ast_codec_pref_index(pref,x); 10594 if (!codec) 10595 break; 10596 astman_append(s, "%s", ast_getformatname(codec)); 10597 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10598 astman_append(s, ","); 10599 } 10600 10601 astman_append(s, "\r\n"); 10602 astman_append(s, "Status: "); 10603 peer_status(peer, status, sizeof(status)); 10604 astman_append(s, "%s\r\n", status); 10605 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10606 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10607 if (peer->chanvars) { 10608 for (v = peer->chanvars ; v ; v = v->next) { 10609 astman_append(s, "ChanVariable:\n"); 10610 astman_append(s, " %s,%s\r\n", v->name, v->value); 10611 } 10612 } 10613 10614 ASTOBJ_UNREF(peer,sip_destroy_peer); 10615 10616 } else { 10617 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10618 ast_cli(fd,"\n"); 10619 } 10620 10621 return RESULT_SUCCESS; 10622 }
static int _sip_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const struct message * | m, | |||
int | argc, | |||
const char * | argv[] | |||
) | [static] |
_sip_show_peers: Execute sip show peers command
Definition at line 9963 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09964 { 09965 regex_t regexbuf; 09966 int havepattern = FALSE; 09967 09968 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09969 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09970 09971 char name[256]; 09972 int total_peers = 0; 09973 int peers_mon_online = 0; 09974 int peers_mon_offline = 0; 09975 int peers_unmon_offline = 0; 09976 int peers_unmon_online = 0; 09977 const char *id; 09978 char idtext[256] = ""; 09979 int realtimepeers; 09980 09981 realtimepeers = ast_check_realtime("sippeers"); 09982 09983 if (s) { /* Manager - get ActionID */ 09984 id = astman_get_header(m,"ActionID"); 09985 if (!ast_strlen_zero(id)) 09986 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09987 } 09988 09989 switch (argc) { 09990 case 5: 09991 if (!strcasecmp(argv[3], "like")) { 09992 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09993 return RESULT_SHOWUSAGE; 09994 havepattern = TRUE; 09995 } else 09996 return RESULT_SHOWUSAGE; 09997 case 3: 09998 break; 09999 default: 10000 return RESULT_SHOWUSAGE; 10001 } 10002 10003 if (!s) /* Normal list */ 10004 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10005 10006 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10007 char status[20] = ""; 10008 char srch[2000]; 10009 char pstatus; 10010 10011 ASTOBJ_RDLOCK(iterator); 10012 10013 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10014 ASTOBJ_UNLOCK(iterator); 10015 continue; 10016 } 10017 10018 if (!ast_strlen_zero(iterator->username) && !s) 10019 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10020 else 10021 ast_copy_string(name, iterator->name, sizeof(name)); 10022 10023 pstatus = peer_status(iterator, status, sizeof(status)); 10024 if (pstatus == 1) 10025 peers_mon_online++; 10026 else if (pstatus == 0) 10027 peers_mon_offline++; 10028 else { 10029 if (iterator->addr.sin_port == 0) 10030 peers_unmon_offline++; 10031 else 10032 peers_unmon_online++; 10033 } 10034 10035 snprintf(srch, sizeof(srch), FORMAT, name, 10036 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10037 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10038 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10039 iterator->ha ? " A " : " ", /* permit/deny */ 10040 ntohs(iterator->addr.sin_port), status, 10041 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10042 10043 if (!s) {/* Normal CLI list */ 10044 ast_cli(fd, FORMAT, name, 10045 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10046 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10047 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10048 iterator->ha ? " A " : " ", /* permit/deny */ 10049 10050 ntohs(iterator->addr.sin_port), status, 10051 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10052 } else { /* Manager format */ 10053 /* The names here need to be the same as other channels */ 10054 astman_append(s, 10055 "Event: PeerEntry\r\n%s" 10056 "Channeltype: SIP\r\n" 10057 "ObjectName: %s\r\n" 10058 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10059 "IPaddress: %s\r\n" 10060 "IPport: %d\r\n" 10061 "Dynamic: %s\r\n" 10062 "Natsupport: %s\r\n" 10063 "VideoSupport: %s\r\n" 10064 "ACL: %s\r\n" 10065 "Status: %s\r\n" 10066 "RealtimeDevice: %s\r\n\r\n", 10067 idtext, 10068 iterator->name, 10069 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10070 ntohs(iterator->addr.sin_port), 10071 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10072 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10073 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10074 iterator->ha ? "yes" : "no", /* permit/deny */ 10075 status, 10076 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10077 } 10078 10079 ASTOBJ_UNLOCK(iterator); 10080 10081 total_peers++; 10082 } while(0) ); 10083 10084 if (!s) 10085 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10086 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10087 10088 if (havepattern) 10089 regfree(®exbuf); 10090 10091 if (total) 10092 *total = total_peers; 10093 10094 10095 return RESULT_SUCCESS; 10096 #undef FORMAT 10097 #undef FORMAT2 10098 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14759 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, LOG_ERROR, LOG_WARNING, parse(), ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, sip_pvt::rtp, ast_rtp_quality::rtt, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14760 { 14761 struct ast_rtp_quality qos; 14762 struct sip_pvt *p = chan->tech_pvt; 14763 char *all = "", *parse = ast_strdupa(preparse); 14764 AST_DECLARE_APP_ARGS(args, 14765 AST_APP_ARG(param); 14766 AST_APP_ARG(type); 14767 AST_APP_ARG(field); 14768 ); 14769 AST_STANDARD_APP_ARGS(args, parse); 14770 14771 /* Sanity check */ 14772 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14773 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14774 return 0; 14775 } 14776 14777 if (strcasecmp(args.param, "rtpqos")) 14778 return 0; 14779 14780 /* Default arguments of audio,all */ 14781 if (ast_strlen_zero(args.type)) 14782 args.type = "audio"; 14783 if (ast_strlen_zero(args.field)) 14784 args.field = "all"; 14785 14786 memset(buf, 0, buflen); 14787 memset(&qos, 0, sizeof(qos)); 14788 14789 if (strcasecmp(args.type, "AUDIO") == 0) { 14790 all = ast_rtp_get_quality(p->rtp, &qos); 14791 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14792 all = ast_rtp_get_quality(p->vrtp, &qos); 14793 } 14794 14795 if (strcasecmp(args.field, "local_ssrc") == 0) 14796 snprintf(buf, buflen, "%u", qos.local_ssrc); 14797 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14798 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14799 else if (strcasecmp(args.field, "local_jitter") == 0) 14800 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14801 else if (strcasecmp(args.field, "local_count") == 0) 14802 snprintf(buf, buflen, "%u", qos.local_count); 14803 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14804 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14805 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14806 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14807 else if (strcasecmp(args.field, "remote_jitter") == 0) 14808 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14809 else if (strcasecmp(args.field, "remote_count") == 0) 14810 snprintf(buf, buflen, "%u", qos.remote_count); 14811 else if (strcasecmp(args.field, "rtt") == 0) 14812 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14813 else if (strcasecmp(args.field, "all") == 0) 14814 ast_copy_string(buf, all, buflen); 14815 else { 14816 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14817 return -1; 14818 } 14819 return 0; 14820 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2249 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02250 { 02251 if (!req->lines) { 02252 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02253 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02254 req->len += strlen(req->data + req->len); 02255 } 02256 }
static void add_codec_to_sdp | ( | const struct sip_pvt * | p, | |
int | codec, | |||
int | sample_rate, | |||
char ** | m_buf, | |||
size_t * | m_size, | |||
char ** | a_buf, | |||
size_t * | a_size, | |||
int | debug, | |||
int * | min_packet_size | |||
) | [static] |
Add codec offer to SDP offer/answer body in INVITE or 200 OK.
Definition at line 6243 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06246 { 06247 int rtp_code; 06248 struct ast_format_list fmt; 06249 06250 06251 if (debug) 06252 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06253 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06254 return; 06255 06256 if (p->rtp) { 06257 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06258 fmt = ast_codec_pref_getsize(pref, codec); 06259 } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */ 06260 return; 06261 ast_build_string(m_buf, m_size, " %d", rtp_code); 06262 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06263 ast_rtp_lookup_mime_subtype(1, codec, 06264 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06265 sample_rate); 06266 if (codec == AST_FORMAT_G729A) { 06267 /* Indicate that we don't support VAD (G.729 annex B) */ 06268 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06269 } else if (codec == AST_FORMAT_G723_1) { 06270 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06271 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06272 } else if (codec == AST_FORMAT_ILBC) { 06273 /* Add information about us using only 20/30 ms packetization */ 06274 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06275 } 06276 06277 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06278 *min_packet_size = fmt.cur_ms; 06279 06280 /* Our first codec packetization processed cannot be less than zero */ 06281 if ((*min_packet_size) == 0 && fmt.cur_ms) 06282 *min_packet_size = fmt.cur_ms; 06283 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6211 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06212 { 06213 char tmp[256]; 06214 06215 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06216 add_header(req, "Content-Type", "application/dtmf-relay"); 06217 add_header_contentLength(req, strlen(tmp)); 06218 add_line(req, tmp); 06219 return 0; 06220 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5605 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
05606 { 05607 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05608 05609 if (req->headers == SIP_MAX_HEADERS) { 05610 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05611 return -1; 05612 } 05613 05614 if (req->lines) { 05615 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05616 return -1; 05617 } 05618 05619 if (maxlen <= 0) { 05620 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05621 return -1; 05622 } 05623 05624 req->header[req->headers] = req->data + req->len; 05625 05626 if (compactheaders) 05627 var = find_alias(var, var); 05628 05629 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05630 req->len += strlen(req->header[req->headers]); 05631 req->headers++; 05632 05633 return 0; 05634 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5637 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_t38_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_unsupported(), and transmit_state_notify().
05638 { 05639 char clen[10]; 05640 05641 snprintf(clen, sizeof(clen), "%d", len); 05642 return add_header(req, "Content-Length", clen); 05643 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5646 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.
05647 { 05648 if (req->lines == SIP_MAX_LINES) { 05649 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05650 return -1; 05651 } 05652 if (!req->lines) { 05653 /* Add extra empty return */ 05654 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05655 req->len += strlen(req->data + req->len); 05656 } 05657 if (req->len >= sizeof(req->data) - 4) { 05658 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05659 return -1; 05660 } 05661 req->line[req->lines] = req->data + req->len; 05662 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05663 req->len += strlen(req->line[req->lines]); 05664 req->lines++; 05665 return 0; 05666 }
static void add_noncodec_to_sdp | ( | const struct sip_pvt * | p, | |
int | format, | |||
int | sample_rate, | |||
char ** | m_buf, | |||
size_t * | m_size, | |||
char ** | a_buf, | |||
size_t * | a_size, | |||
int | debug | |||
) | [static] |
Add RFC 2833 DTMF offer to SDP.
Definition at line 6419 of file chan_sip.c.
References ast_build_string(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), and sip_pvt::rtp.
Referenced by add_sdp().
06422 { 06423 int rtp_code; 06424 06425 if (debug) 06426 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06427 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06428 return; 06429 06430 ast_build_string(m_buf, m_size, " %d", rtp_code); 06431 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06432 ast_rtp_lookup_mime_subtype(0, format, 0), 06433 sample_rate); 06434 if (format == AST_RTP_DTMF) 06435 /* Indicate we support DTMF and FLASH... */ 06436 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06437 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static, read] |
Add realm authentication in list.
Definition at line 16377 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, sip_auth::secret, secret, strsep(), sip_auth::username, and username.
Referenced by build_peer(), and reload_config().
16378 { 16379 char authcopy[256]; 16380 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16381 char *stringp; 16382 struct sip_auth *a, *b, *auth; 16383 16384 if (ast_strlen_zero(configuration)) 16385 return authlist; 16386 16387 if (option_debug) 16388 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16389 16390 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16391 stringp = authcopy; 16392 16393 username = stringp; 16394 realm = strrchr(stringp, '@'); 16395 if (realm) 16396 *realm++ = '\0'; 16397 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16398 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16399 return authlist; 16400 } 16401 stringp = username; 16402 username = strsep(&stringp, ":"); 16403 if (username) { 16404 secret = strsep(&stringp, ":"); 16405 if (!secret) { 16406 stringp = username; 16407 md5secret = strsep(&stringp,"#"); 16408 } 16409 } 16410 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16411 return authlist; 16412 16413 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16414 ast_copy_string(auth->username, username, sizeof(auth->username)); 16415 if (secret) 16416 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16417 if (md5secret) 16418 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16419 16420 /* find the end of the list */ 16421 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16422 ; 16423 if (b) 16424 b->next = auth; /* Add structure add end of list */ 16425 else 16426 authlist = auth; 16427 16428 if (option_verbose > 2) 16429 ast_verbose("Added authentication for realm %s\n", realm); 16430 16431 return authlist; 16432 16433 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5767 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05768 { 05769 char r[SIPBUFSIZE*2], *p; 05770 int n, rem = sizeof(r); 05771 05772 if (!route) 05773 return; 05774 05775 p = r; 05776 for (;route ; route = route->next) { 05777 n = strlen(route->hop); 05778 if (rem < n+3) /* we need room for ",<route>" */ 05779 break; 05780 if (p != r) { /* add a separator after fist route */ 05781 *p++ = ','; 05782 --rem; 05783 } 05784 *p++ = '<'; 05785 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05786 p += n; 05787 *p++ = '>'; 05788 rem -= (n+2); 05789 } 05790 *p = '\0'; 05791 add_header(req, "Route", r); 05792 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6447 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06448 { 06449 int len = 0; 06450 int alreadysent = 0; 06451 06452 struct sockaddr_in sin; 06453 struct sockaddr_in vsin; 06454 struct sockaddr_in dest; 06455 struct sockaddr_in vdest = { 0, }; 06456 06457 /* SDP fields */ 06458 char *version = "v=0\r\n"; /* Protocol version */ 06459 char *subject = "s=session\r\n"; /* Subject of the session */ 06460 char owner[256]; /* Session owner/creator */ 06461 char connection[256]; /* Connection data */ 06462 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06463 char bandwidth[256] = ""; /* Max bitrate */ 06464 char *hold; 06465 char m_audio[256]; /* Media declaration line for audio */ 06466 char m_video[256]; /* Media declaration line for video */ 06467 char a_audio[1024]; /* Attributes for audio */ 06468 char a_video[1024]; /* Attributes for video */ 06469 char *m_audio_next = m_audio; 06470 char *m_video_next = m_video; 06471 size_t m_audio_left = sizeof(m_audio); 06472 size_t m_video_left = sizeof(m_video); 06473 char *a_audio_next = a_audio; 06474 char *a_video_next = a_video; 06475 size_t a_audio_left = sizeof(a_audio); 06476 size_t a_video_left = sizeof(a_video); 06477 06478 int x; 06479 int capability; 06480 int needvideo = FALSE; 06481 int debug = sip_debug_test_pvt(p); 06482 int min_audio_packet_size = 0; 06483 int min_video_packet_size = 0; 06484 06485 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06486 06487 if (!p->rtp) { 06488 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06489 return AST_FAILURE; 06490 } 06491 06492 /* Set RTP Session ID and version */ 06493 if (!p->sessionid) { 06494 p->sessionid = getpid(); 06495 p->sessionversion = p->sessionid; 06496 } else 06497 p->sessionversion++; 06498 06499 /* Get our addresses */ 06500 ast_rtp_get_us(p->rtp, &sin); 06501 if (p->vrtp) 06502 ast_rtp_get_us(p->vrtp, &vsin); 06503 06504 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06505 if (p->redirip.sin_addr.s_addr) { 06506 dest.sin_port = p->redirip.sin_port; 06507 dest.sin_addr = p->redirip.sin_addr; 06508 } else { 06509 dest.sin_addr = p->ourip; 06510 dest.sin_port = sin.sin_port; 06511 } 06512 06513 capability = p->jointcapability; 06514 06515 06516 if (option_debug > 1) { 06517 char codecbuf[SIPBUFSIZE]; 06518 ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False"); 06519 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06520 } 06521 06522 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06523 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06524 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06525 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06526 } 06527 #endif 06528 06529 /* Check if we need video in this call */ 06530 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06531 if (p->vrtp) { 06532 needvideo = TRUE; 06533 if (option_debug > 1) 06534 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06535 } else if (option_debug > 1) 06536 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06537 } 06538 06539 06540 /* Ok, we need video. Let's add what we need for video and set codecs. 06541 Video is handled differently than audio since we can not transcode. */ 06542 if (needvideo) { 06543 /* Determine video destination */ 06544 if (p->vredirip.sin_addr.s_addr) { 06545 vdest.sin_addr = p->vredirip.sin_addr; 06546 vdest.sin_port = p->vredirip.sin_port; 06547 } else { 06548 vdest.sin_addr = p->ourip; 06549 vdest.sin_port = vsin.sin_port; 06550 } 06551 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06552 06553 /* Build max bitrate string */ 06554 if (p->maxcallbitrate) 06555 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06556 if (debug) 06557 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06558 } 06559 06560 if (debug) 06561 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06562 06563 /* Start building generic SDP headers */ 06564 06565 /* We break with the "recommendation" and send our IP, in order that our 06566 peer doesn't have to ast_gethostbyname() us */ 06567 06568 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06569 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06570 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06571 06572 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06573 hold = "a=recvonly\r\n"; 06574 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06575 hold = "a=inactive\r\n"; 06576 else 06577 hold = "a=sendrecv\r\n"; 06578 06579 /* Now, start adding audio codecs. These are added in this order: 06580 - First what was requested by the calling channel 06581 - Then preferences in order from sip.conf device config for this peer/user 06582 - Then other codecs in capabilities, including video 06583 */ 06584 06585 /* Prefer the audio codec we were requested to use, first, no matter what 06586 Note that p->prefcodec can include video codecs, so mask them out 06587 */ 06588 if (capability & p->prefcodec) { 06589 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06590 06591 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06592 &m_audio_next, &m_audio_left, 06593 &a_audio_next, &a_audio_left, 06594 debug, &min_audio_packet_size); 06595 alreadysent |= codec; 06596 } 06597 06598 /* Start by sending our preferred audio codecs */ 06599 for (x = 0; x < 32; x++) { 06600 int codec; 06601 06602 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06603 break; 06604 06605 if (!(capability & codec)) 06606 continue; 06607 06608 if (alreadysent & codec) 06609 continue; 06610 06611 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06612 &m_audio_next, &m_audio_left, 06613 &a_audio_next, &a_audio_left, 06614 debug, &min_audio_packet_size); 06615 alreadysent |= codec; 06616 } 06617 06618 /* Now send any other common audio and video codecs, and non-codec formats: */ 06619 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06620 if (!(capability & x)) /* Codec not requested */ 06621 continue; 06622 06623 if (alreadysent & x) /* Already added to SDP */ 06624 continue; 06625 06626 if (x <= AST_FORMAT_MAX_AUDIO) 06627 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06628 &m_audio_next, &m_audio_left, 06629 &a_audio_next, &a_audio_left, 06630 debug, &min_audio_packet_size); 06631 else 06632 add_codec_to_sdp(p, x, 90000, 06633 &m_video_next, &m_video_left, 06634 &a_video_next, &a_video_left, 06635 debug, &min_video_packet_size); 06636 } 06637 06638 /* Now add DTMF RFC2833 telephony-event as a codec */ 06639 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06640 if (!(p->jointnoncodeccapability & x)) 06641 continue; 06642 06643 add_noncodec_to_sdp(p, x, 8000, 06644 &m_audio_next, &m_audio_left, 06645 &a_audio_next, &a_audio_left, 06646 debug); 06647 } 06648 06649 if (option_debug > 2) 06650 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06651 06652 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06653 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06654 06655 if (min_audio_packet_size) 06656 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06657 06658 if (min_video_packet_size) 06659 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06660 06661 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06662 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06663 06664 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06665 if (needvideo) 06666 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06667 06668 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06669 if (needvideo) /* only if video response is appropriate */ 06670 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06671 06672 add_header(resp, "Content-Type", "application/sdp"); 06673 add_header_contentLength(resp, len); 06674 add_line(resp, version); 06675 add_line(resp, owner); 06676 add_line(resp, subject); 06677 add_line(resp, connection); 06678 if (needvideo) /* only if video response is appropriate */ 06679 add_line(resp, bandwidth); 06680 add_line(resp, stime); 06681 add_line(resp, m_audio); 06682 add_line(resp, a_audio); 06683 add_line(resp, hold); 06684 if (needvideo) { /* only if video response is appropriate */ 06685 add_line(resp, m_video); 06686 add_line(resp, a_video); 06687 add_line(resp, hold); /* Repeat hold for the video stream */ 06688 } 06689 06690 /* Update lastrtprx when we send our SDP */ 06691 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06692 06693 if (option_debug > 2) { 06694 char buf[SIPBUFSIZE]; 06695 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06696 } 06697 06698 return AST_SUCCESS; 06699 }
static int add_sip_domain | ( | const char * | domain, | |
const enum domain_mode | mode, | |||
const char * | context | |||
) | [static] |
Add SIP domain to list of domains we are responsible for.
Definition at line 16313 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::context, domain::domain, LOG_DEBUG, LOG_WARNING, domain::mode, and sipdebug.
Referenced by reload_config().
16314 { 16315 struct domain *d; 16316 16317 if (ast_strlen_zero(domain)) { 16318 ast_log(LOG_WARNING, "Zero length domain.\n"); 16319 return 1; 16320 } 16321 16322 if (!(d = ast_calloc(1, sizeof(*d)))) 16323 return 0; 16324 16325 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16326 16327 if (!ast_strlen_zero(context)) 16328 ast_copy_string(d->context, context, sizeof(d->context)); 16329 16330 d->mode = mode; 16331 16332 AST_LIST_LOCK(&domain_list); 16333 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16334 AST_LIST_UNLOCK(&domain_list); 16335 16336 if (sipdebug) 16337 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16338 16339 return 1; 16340 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6322 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06323 { 06324 int len = 0; 06325 int x = 0; 06326 struct sockaddr_in udptlsin; 06327 char v[256] = ""; 06328 char s[256] = ""; 06329 char o[256] = ""; 06330 char c[256] = ""; 06331 char t[256] = ""; 06332 char m_modem[256]; 06333 char a_modem[1024]; 06334 char *m_modem_next = m_modem; 06335 size_t m_modem_left = sizeof(m_modem); 06336 char *a_modem_next = a_modem; 06337 size_t a_modem_left = sizeof(a_modem); 06338 struct sockaddr_in udptldest = { 0, }; 06339 int debug; 06340 06341 debug = sip_debug_test_pvt(p); 06342 len = 0; 06343 if (!p->udptl) { 06344 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06345 return -1; 06346 } 06347 06348 if (!p->sessionid) { 06349 p->sessionid = getpid(); 06350 p->sessionversion = p->sessionid; 06351 } else 06352 p->sessionversion++; 06353 06354 /* Our T.38 end is */ 06355 ast_udptl_get_us(p->udptl, &udptlsin); 06356 06357 /* Determine T.38 UDPTL destination */ 06358 if (p->udptlredirip.sin_addr.s_addr) { 06359 udptldest.sin_port = p->udptlredirip.sin_port; 06360 udptldest.sin_addr = p->udptlredirip.sin_addr; 06361 } else { 06362 udptldest.sin_addr = p->ourip; 06363 udptldest.sin_port = udptlsin.sin_port; 06364 } 06365 06366 if (debug) 06367 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06368 06369 /* We break with the "recommendation" and send our IP, in order that our 06370 peer doesn't have to ast_gethostbyname() us */ 06371 06372 if (debug) { 06373 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06374 p->t38.capability, 06375 p->t38.peercapability, 06376 p->t38.jointcapability); 06377 } 06378 snprintf(v, sizeof(v), "v=0\r\n"); 06379 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06380 snprintf(s, sizeof(s), "s=session\r\n"); 06381 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06382 snprintf(t, sizeof(t), "t=0 0\r\n"); 06383 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06384 06385 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06386 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06387 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06388 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06389 if ((x = t38_get_rate(p->t38.jointcapability))) 06390 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06391 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06392 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06393 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06394 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06395 x = ast_udptl_get_local_max_datagram(p->udptl); 06396 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06397 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06398 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06399 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06400 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06401 add_header(resp, "Content-Type", "application/sdp"); 06402 add_header_contentLength(resp, len); 06403 add_line(resp, v); 06404 add_line(resp, o); 06405 add_line(resp, s); 06406 add_line(resp, c); 06407 add_line(resp, t); 06408 add_line(resp, m_modem); 06409 add_line(resp, a_modem); 06410 06411 /* Update lastrtprx when we send our SDP */ 06412 p->lastrtprx = p->lastrtptx = time(NULL); 06413 06414 return 0; 06415 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6200 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06201 { 06202 /* XXX Convert \n's to \r\n's XXX */ 06203 add_header(req, "Content-Type", "text/plain"); 06204 add_header_contentLength(req, strlen(text)); 06205 add_line(req, text); 06206 return 0; 06207 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6224 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06225 { 06226 const char *xml_is_a_huge_waste_of_space = 06227 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06228 " <media_control>\r\n" 06229 " <vc_primitive>\r\n" 06230 " <to_encoder>\r\n" 06231 " <picture_fast_update>\r\n" 06232 " </picture_fast_update>\r\n" 06233 " </to_encoder>\r\n" 06234 " </vc_primitive>\r\n" 06235 " </media_control>\r\n"; 06236 add_header(req, "Content-Type", "application/media_control+xml"); 06237 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06238 add_line(req, xml_is_a_huge_waste_of_space); 06239 return 0; 06240 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6147 of file chan_sip.c.
References add_header(), and t.
Referenced by build_csv_record(), transmit_invite(), transmit_response_with_date(), and transmit_response_with_unsupported().
06148 { 06149 char tmpdat[256]; 06150 struct tm tm; 06151 time_t t = time(NULL); 06152 06153 gmtime_r(&t, &tm); 06154 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06155 add_header(req, "Date", tmpdat); 06156 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1876 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01877 { 01878 va_list ap; 01879 01880 if (!p) 01881 return; 01882 01883 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01884 && !recordhistory && !dumphistory) { 01885 return; 01886 } 01887 01888 va_start(ap, fmt); 01889 append_history_va(p, fmt, ap); 01890 va_end(ap); 01891 01892 return; 01893 }
static void static void append_history_va | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1849 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, MAX_HISTORY_ENTRIES, and strsep().
Referenced by append_history_full().
01850 { 01851 char buf[80], *c = buf; /* max history length */ 01852 struct sip_history *hist; 01853 int l; 01854 01855 vsnprintf(buf, sizeof(buf), fmt, ap); 01856 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01857 l = strlen(buf) + 1; 01858 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01859 return; 01860 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01861 free(hist); 01862 return; 01863 } 01864 memcpy(hist->event, buf, l); 01865 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01866 struct sip_history *oldest; 01867 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01868 p->history_entries--; 01869 free(oldest); 01870 } 01871 AST_LIST_INSERT_TAIL(p->history, hist, list); 01872 p->history_entries++; 01873 }
AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
sip_history | ||||
) |
history list, entry in sip_pvt
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Session Initiation Protocol (SIP)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 13305 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
13306 { 13307 if (chan && chan->_state == AST_STATE_UP) { 13308 if (ast_test_flag(chan, AST_FLAG_MOH)) 13309 ast_moh_stop(chan); 13310 else if (chan->generatordata) 13311 ast_deactivate_generator(chan); 13312 } 13313 }
static enum sip_result ast_sip_ouraddrfor | ( | struct in_addr * | them, | |
struct in_addr * | us | |||
) | [static] |
NAT fix - decide which IP address to use for ASterisk server?
Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externip or can get away with our internal bindaddr
Definition at line 1809 of file chan_sip.c.
References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01810 { 01811 struct sockaddr_in theirs, ours; 01812 01813 /* Get our local information */ 01814 ast_ouraddrfor(them, us); 01815 theirs.sin_addr = *them; 01816 ours.sin_addr = *us; 01817 01818 if (localaddr && externip.sin_addr.s_addr && 01819 (ast_apply_ha(localaddr, &theirs)) && 01820 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01821 if (externexpire && time(NULL) >= externexpire) { 01822 struct ast_hostent ahp; 01823 struct hostent *hp; 01824 01825 externexpire = time(NULL) + externrefresh; 01826 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01827 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01828 } else 01829 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01830 } 01831 *us = externip.sin_addr; 01832 if (option_debug) { 01833 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01834 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01835 } 01836 } else if (bindaddr.sin_addr.s_addr) 01837 *us = bindaddr.sin_addr; 01838 return AST_SUCCESS; 01839 }
AST_THREADSTORAGE | ( | check_auth_buf | , | |
check_auth_buf_init | ||||
) |
AST_THREADSTORAGE_CUSTOM | ( | ts_temp_pvt | , | |
temp_pvt_init | , | |||
temp_pvt_cleanup | ||||
) |
A per-thread temporary pvt structure.
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13317 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), ast_channel::cdr, sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
13318 { 13319 int res = 0; 13320 struct ast_channel *peera = NULL, 13321 *peerb = NULL, 13322 *peerc = NULL, 13323 *peerd = NULL; 13324 13325 13326 /* We will try to connect the transferee with the target and hangup 13327 all channels to the transferer */ 13328 if (option_debug > 3) { 13329 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13330 if (transferer->chan1) 13331 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13332 else 13333 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13334 if (target->chan1) 13335 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13336 else 13337 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13338 if (transferer->chan2) 13339 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13340 else 13341 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13342 if (target->chan2) 13343 ast_log(LOG_DEBUG, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)"); 13344 else 13345 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13346 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13347 } 13348 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13349 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13350 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13351 peerc = transferer->chan2; /* Asterisk to Transferee */ 13352 peerd = target->chan2; /* Asterisk to Target */ 13353 if (option_debug > 2) 13354 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13355 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13356 peera = target->chan1; /* Transferer to PBX -> target channel */ 13357 peerb = transferer->chan1; /* Transferer to IVR*/ 13358 peerc = target->chan2; /* Asterisk to Target */ 13359 peerd = transferer->chan2; /* Nothing */ 13360 if (option_debug > 2) 13361 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13362 } 13363 13364 if (peera && peerb && peerc && (peerb != peerc)) { 13365 ast_quiet_chan(peera); /* Stop generators */ 13366 ast_quiet_chan(peerb); 13367 ast_quiet_chan(peerc); 13368 if (peerd) 13369 ast_quiet_chan(peerd); 13370 13371 /* Fix CDRs so they're attached to the remaining channel */ 13372 if (peera->cdr && peerb->cdr) 13373 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13374 else if (peera->cdr) 13375 peerb->cdr = peera->cdr; 13376 peera->cdr = NULL; 13377 13378 if (peerb->cdr && peerc->cdr) 13379 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13380 else if (peerc->cdr) 13381 peerb->cdr = peerc->cdr; 13382 peerc->cdr = NULL; 13383 13384 if (option_debug > 3) 13385 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13386 if (ast_channel_masquerade(peerb, peerc)) { 13387 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13388 res = -1; 13389 } else 13390 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13391 return res; 13392 } else { 13393 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13394 if (transferer->chan1) 13395 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13396 if (target->chan1) 13397 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13398 return -2; 13399 } 13400 return 0; 13401 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2932 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, and sip_pvt::owner.
02933 { 02934 struct sip_pvt *p = (struct sip_pvt *)nothing; 02935 02936 ast_mutex_lock(&p->lock); 02937 p->initid = -1; 02938 if (p->owner) { 02939 /* XXX fails on possible deadlock */ 02940 if (!ast_channel_trylock(p->owner)) { 02941 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02942 append_history(p, "Cong", "Auto-congesting (timer)"); 02943 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02944 ast_channel_unlock(p->owner); 02945 } 02946 } 02947 ast_mutex_unlock(&p->lock); 02948 return 0; 02949 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4420 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), sip_pvt::ourip, and S_OR.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
04421 { 04422 char buf[33]; 04423 04424 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04425 04426 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04427 04428 }
static void build_callid_registry | ( | struct sip_registry * | reg, | |
struct in_addr | ourip, | |||
const char * | fromdomain | |||
) | [static] |
Build SIP Call-ID value for a REGISTER transaction.
Definition at line 4431 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04432 { 04433 char buf[33]; 04434 04435 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04436 04437 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04438 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6870 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::ourip, ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06871 { 06872 /* Construct Contact: header */ 06873 if (ourport != STANDARD_SIP_PORT) 06874 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport); 06875 else 06876 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06877 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 16644 of file chan_sip.c.
References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
16645 { 16646 struct sip_peer *peer = NULL; 16647 struct ast_ha *oldha = NULL; 16648 int obproxyfound=0; 16649 int found=0; 16650 int firstpass=1; 16651 int format=0; /* Ama flags */ 16652 time_t regseconds = 0; 16653 char *varname = NULL, *varval = NULL; 16654 struct ast_variable *tmpvar = NULL; 16655 struct ast_flags peerflags[2] = {{(0)}}; 16656 struct ast_flags mask[2] = {{(0)}}; 16657 char fullcontact[sizeof(peer->fullcontact)] = ""; 16658 16659 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16660 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16661 /* We also use a case-sensitive comparison (unlike find_peer) so 16662 that case changes made to the peer name will be properly handled 16663 during reload 16664 */ 16665 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16666 16667 if (peer) { 16668 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16669 found = 1; 16670 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16671 firstpass = 0; 16672 } else { 16673 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16674 return NULL; 16675 16676 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16677 rpeerobjs++; 16678 else 16679 speerobjs++; 16680 ASTOBJ_INIT(peer); 16681 } 16682 /* Note that our peer HAS had its reference count incrased */ 16683 if (firstpass) { 16684 peer->lastmsgssent = -1; 16685 oldha = peer->ha; 16686 peer->ha = NULL; 16687 set_peer_defaults(peer); /* Set peer defaults */ 16688 } 16689 if (!found && name) 16690 ast_copy_string(peer->name, name, sizeof(peer->name)); 16691 16692 /* If we have channel variables, remove them (reload) */ 16693 if (peer->chanvars) { 16694 ast_variables_destroy(peer->chanvars); 16695 peer->chanvars = NULL; 16696 /* XXX should unregister ? */ 16697 } 16698 16699 /* If we have realm authentication information, remove them (reload) */ 16700 clear_realm_authentication(peer->auth); 16701 peer->auth = NULL; 16702 16703 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16704 if (handle_common_options(&peerflags[0], &mask[0], v)) 16705 continue; 16706 if (realtime && !strcasecmp(v->name, "regseconds")) { 16707 ast_get_time_t(v->value, ®seconds, 0, NULL); 16708 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16709 inet_aton(v->value, &(peer->addr.sin_addr)); 16710 } else if (realtime && !strcasecmp(v->name, "name")) 16711 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16712 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16713 /* Reconstruct field, because realtime separates our value at the ';' */ 16714 if (!ast_strlen_zero(fullcontact)) { 16715 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 16716 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 16717 } else { 16718 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 16719 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16720 } 16721 } else if (!strcasecmp(v->name, "secret")) 16722 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16723 else if (!strcasecmp(v->name, "md5secret")) 16724 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16725 else if (!strcasecmp(v->name, "auth")) 16726 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16727 else if (!strcasecmp(v->name, "callerid")) { 16728 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16729 } else if (!strcasecmp(v->name, "fullname")) { 16730 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16731 } else if (!strcasecmp(v->name, "cid_number")) { 16732 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16733 } else if (!strcasecmp(v->name, "context")) { 16734 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16735 } else if (!strcasecmp(v->name, "subscribecontext")) { 16736 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16737 } else if (!strcasecmp(v->name, "fromdomain")) { 16738 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16739 } else if (!strcasecmp(v->name, "usereqphone")) { 16740 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16741 } else if (!strcasecmp(v->name, "fromuser")) { 16742 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16743 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16744 if (!strcasecmp(v->value, "dynamic")) { 16745 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16746 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16747 } else { 16748 /* They'll register with us */ 16749 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16750 /* Initialize stuff if this is a new peer, or if it used to be 16751 * non-dynamic before the reload. */ 16752 memset(&peer->addr.sin_addr, 0, 4); 16753 if (peer->addr.sin_port) { 16754 /* If we've already got a port, make it the default rather than absolute */ 16755 peer->defaddr.sin_port = peer->addr.sin_port; 16756 peer->addr.sin_port = 0; 16757 } 16758 } 16759 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16760 } 16761 } else { 16762 /* Non-dynamic. Make sure we become that way if we're not */ 16763 if (!AST_SCHED_DEL(sched, peer->expire)) { 16764 struct sip_peer *peer_ptr = peer; 16765 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16766 } 16767 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16768 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16769 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16770 ASTOBJ_UNREF(peer, sip_destroy_peer); 16771 return NULL; 16772 } 16773 } 16774 if (!strcasecmp(v->name, "outboundproxy")) 16775 obproxyfound=1; 16776 else { 16777 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16778 if (!peer->addr.sin_port) 16779 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16780 } 16781 } 16782 } else if (!strcasecmp(v->name, "defaultip")) { 16783 if (ast_get_ip(&peer->defaddr, v->value)) { 16784 ASTOBJ_UNREF(peer, sip_destroy_peer); 16785 return NULL; 16786 } 16787 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16788 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16789 } else if (!strcasecmp(v->name, "port")) { 16790 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16791 peer->defaddr.sin_port = htons(atoi(v->value)); 16792 else 16793 peer->addr.sin_port = htons(atoi(v->value)); 16794 } else if (!strcasecmp(v->name, "callingpres")) { 16795 peer->callingpres = ast_parse_caller_presentation(v->value); 16796 if (peer->callingpres == -1) 16797 peer->callingpres = atoi(v->value); 16798 } else if (!strcasecmp(v->name, "username")) { 16799 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16800 } else if (!strcasecmp(v->name, "language")) { 16801 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16802 } else if (!strcasecmp(v->name, "regexten")) { 16803 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16804 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16805 peer->call_limit = atoi(v->value); 16806 if (peer->call_limit < 0) 16807 peer->call_limit = 0; 16808 } else if (!strcasecmp(v->name, "amaflags")) { 16809 format = ast_cdr_amaflags2int(v->value); 16810 if (format < 0) { 16811 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16812 } else { 16813 peer->amaflags = format; 16814 } 16815 } else if (!strcasecmp(v->name, "accountcode")) { 16816 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16817 } else if (!strcasecmp(v->name, "mohinterpret") 16818 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16819 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16820 } else if (!strcasecmp(v->name, "mohsuggest")) { 16821 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16822 } else if (!strcasecmp(v->name, "mailbox")) { 16823 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16824 } else if (!strcasecmp(v->name, "subscribemwi")) { 16825 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16826 } else if (!strcasecmp(v->name, "vmexten")) { 16827 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16828 } else if (!strcasecmp(v->name, "callgroup")) { 16829 peer->callgroup = ast_get_group(v->value); 16830 } else if (!strcasecmp(v->name, "allowtransfer")) { 16831 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16832 } else if (!strcasecmp(v->name, "pickupgroup")) { 16833 peer->pickupgroup = ast_get_group(v->value); 16834 } else if (!strcasecmp(v->name, "allow")) { 16835 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16836 } else if (!strcasecmp(v->name, "disallow")) { 16837 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16838 } else if (!strcasecmp(v->name, "autoframing")) { 16839 peer->autoframing = ast_true(v->value); 16840 } else if (!strcasecmp(v->name, "rtptimeout")) { 16841 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16842 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16843 peer->rtptimeout = global_rtptimeout; 16844 } 16845 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16846 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16847 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16848 peer->rtpholdtimeout = global_rtpholdtimeout; 16849 } 16850 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16851 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16852 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16853 peer->rtpkeepalive = global_rtpkeepalive; 16854 } 16855 } else if (!strcasecmp(v->name, "setvar")) { 16856 /* Set peer channel variable */ 16857 varname = ast_strdupa(v->value); 16858 if ((varval = strchr(varname, '='))) { 16859 *varval++ = '\0'; 16860 if ((tmpvar = ast_variable_new(varname, varval))) { 16861 tmpvar->next = peer->chanvars; 16862 peer->chanvars = tmpvar; 16863 } 16864 } 16865 } else if (!strcasecmp(v->name, "qualify")) { 16866 if (!strcasecmp(v->value, "no")) { 16867 peer->maxms = 0; 16868 } else if (!strcasecmp(v->value, "yes")) { 16869 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16870 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16871 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno); 16872 peer->maxms = 0; 16873 } 16874 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16875 peer->maxcallbitrate = atoi(v->value); 16876 if (peer->maxcallbitrate < 0) 16877 peer->maxcallbitrate = default_maxcallbitrate; 16878 } 16879 } 16880 if (!ast_strlen_zero(fullcontact)) { 16881 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 16882 } 16883 16884 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16885 time_t nowtime = time(NULL); 16886 16887 if ((nowtime - regseconds) > 0) { 16888 destroy_association(peer); 16889 memset(&peer->addr, 0, sizeof(peer->addr)); 16890 if (option_debug) 16891 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16892 } 16893 } 16894 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16895 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16896 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16897 global_allowsubscribe = TRUE; /* No global ban any more */ 16898 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16899 reg_source_db(peer); 16900 ASTOBJ_UNMARK(peer); 16901 ast_free_ha(oldha); 16902 return peer; 16903 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11605 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11606 { 11607 char a1[256]; 11608 char a2[256]; 11609 char a1_hash[256]; 11610 char a2_hash[256]; 11611 char resp[256]; 11612 char resp_hash[256]; 11613 char uri[256]; 11614 char opaque[256] = ""; 11615 char cnonce[80]; 11616 const char *username; 11617 const char *secret; 11618 const char *md5secret; 11619 struct sip_auth *auth = NULL; /* Realm authentication */ 11620 11621 if (!ast_strlen_zero(p->domain)) 11622 ast_copy_string(uri, p->domain, sizeof(uri)); 11623 else if (!ast_strlen_zero(p->uri)) 11624 ast_copy_string(uri, p->uri, sizeof(uri)); 11625 else 11626 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11627 11628 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11629 11630 /* Check if we have separate auth credentials */ 11631 if ((auth = find_realm_authentication(authl, p->realm))) { 11632 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11633 auth->username, p->peername, p->username); 11634 username = auth->username; 11635 secret = auth->secret; 11636 md5secret = auth->md5secret; 11637 if (sipdebug) 11638 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11639 } else { 11640 /* No authentication, use peer or register= config */ 11641 username = p->authname; 11642 secret = p->peersecret; 11643 md5secret = p->peermd5secret; 11644 } 11645 if (ast_strlen_zero(username)) /* We have no authentication */ 11646 return -1; 11647 11648 /* Calculate SIP digest response */ 11649 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11650 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11651 if (!ast_strlen_zero(md5secret)) 11652 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11653 else 11654 ast_md5_hash(a1_hash,a1); 11655 ast_md5_hash(a2_hash,a2); 11656 11657 p->noncecount++; 11658 if (!ast_strlen_zero(p->qop)) 11659 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11660 else 11661 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11662 ast_md5_hash(resp_hash, resp); 11663 11664 /* only include the opaque string if it's set */ 11665 if (!ast_strlen_zero(p->opaque)) { 11666 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11667 } 11668 11669 /* XXX We hard code our qop to "auth" for now. XXX */ 11670 if (!ast_strlen_zero(p->qop)) 11671 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount); 11672 else 11673 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque); 11674 11675 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11676 11677 return 0; 11678 }
static void build_route | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | backwards | |||
) | [static] |
Build route list from Record-Route header.
Definition at line 8297 of file chan_sip.c.
References __get_header(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len, list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
08298 { 08299 struct sip_route *thishop, *head, *tail; 08300 int start = 0; 08301 int len; 08302 const char *rr, *contact, *c; 08303 08304 /* Once a persistant route is set, don't fool with it */ 08305 if (p->route && p->route_persistant) { 08306 if (option_debug) 08307 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08308 return; 08309 } 08310 08311 if (p->route) { 08312 free_old_route(p->route); 08313 p->route = NULL; 08314 } 08315 08316 /* We only want to create the route set the first time this is called */ 08317 p->route_persistant = 1; 08318 08319 /* Build a tailq, then assign it to p->route when done. 08320 * If backwards, we add entries from the head so they end up 08321 * in reverse order. However, we do need to maintain a correct 08322 * tail pointer because the contact is always at the end. 08323 */ 08324 head = NULL; 08325 tail = head; 08326 /* 1st we pass through all the hops in any Record-Route headers */ 08327 for (;;) { 08328 /* Each Record-Route header */ 08329 rr = __get_header(req, "Record-Route", &start); 08330 if (*rr == '\0') 08331 break; 08332 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08333 ++rr; 08334 len = strcspn(rr, ">") + 1; 08335 /* Make a struct route */ 08336 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08337 /* ast_calloc is not needed because all fields are initialized in this block */ 08338 ast_copy_string(thishop->hop, rr, len); 08339 if (option_debug > 1) 08340 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08341 /* Link in */ 08342 if (backwards) { 08343 /* Link in at head so they end up in reverse order */ 08344 thishop->next = head; 08345 head = thishop; 08346 /* If this was the first then it'll be the tail */ 08347 if (!tail) 08348 tail = thishop; 08349 } else { 08350 thishop->next = NULL; 08351 /* Link in at the end */ 08352 if (tail) 08353 tail->next = thishop; 08354 else 08355 head = thishop; 08356 tail = thishop; 08357 } 08358 } 08359 } 08360 } 08361 08362 /* Only append the contact if we are dealing with a strict router */ 08363 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08364 /* 2nd append the Contact: if there is one */ 08365 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08366 contact = get_header(req, "Contact"); 08367 if (!ast_strlen_zero(contact)) { 08368 if (option_debug > 1) 08369 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08370 /* Look for <: delimited address */ 08371 c = strchr(contact, '<'); 08372 if (c) { 08373 /* Take to > */ 08374 ++c; 08375 len = strcspn(c, ">") + 1; 08376 } else { 08377 /* No <> - just take the lot */ 08378 c = contact; 08379 len = strlen(contact) + 1; 08380 } 08381 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08382 /* ast_calloc is not needed because all fields are initialized in this block */ 08383 ast_copy_string(thishop->hop, c, len); 08384 thishop->next = NULL; 08385 /* Goes at the end */ 08386 if (tail) 08387 tail->next = thishop; 08388 else 08389 head = thishop; 08390 } 08391 } 08392 } 08393 08394 /* Store as new route */ 08395 p->route = head; 08396 08397 /* For debugging dump what we ended up with */ 08398 if (sip_debug_test_pvt(p)) 08399 list_route(p->route); 08400 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6880 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06881 { 06882 int send_pres_tags = TRUE; 06883 const char *privacy=NULL; 06884 const char *screen=NULL; 06885 char buf[256]; 06886 const char *clid = default_callerid; 06887 const char *clin = NULL; 06888 const char *fromdomain; 06889 06890 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06891 return; 06892 06893 if (p->owner && p->owner->cid.cid_num) 06894 clid = p->owner->cid.cid_num; 06895 if (p->owner && p->owner->cid.cid_name) 06896 clin = p->owner->cid.cid_name; 06897 if (ast_strlen_zero(clin)) 06898 clin = clid; 06899 06900 switch (p->callingpres) { 06901 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06902 privacy = "off"; 06903 screen = "no"; 06904 break; 06905 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06906 privacy = "off"; 06907 screen = "yes"; 06908 break; 06909 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06910 privacy = "off"; 06911 screen = "no"; 06912 break; 06913 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06914 privacy = "off"; 06915 screen = "yes"; 06916 break; 06917 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06918 privacy = "full"; 06919 screen = "no"; 06920 break; 06921 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06922 privacy = "full"; 06923 screen = "yes"; 06924 break; 06925 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06926 privacy = "full"; 06927 screen = "no"; 06928 break; 06929 case AST_PRES_PROHIB_NETWORK_NUMBER: 06930 privacy = "full"; 06931 screen = "yes"; 06932 break; 06933 case AST_PRES_NUMBER_NOT_AVAILABLE: 06934 send_pres_tags = FALSE; 06935 break; 06936 default: 06937 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06938 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06939 privacy = "full"; 06940 else 06941 privacy = "off"; 06942 screen = "no"; 06943 break; 06944 } 06945 06946 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06947 06948 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06949 if (send_pres_tags) 06950 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06951 ast_string_field_set(p, rpid, buf); 06952 06953 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06954 S_OR(p->fromuser, clid), 06955 fromdomain, p->tag); 06956 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 16464 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
16465 { 16466 struct sip_user *user; 16467 int format; 16468 struct ast_ha *oldha = NULL; 16469 char *varname = NULL, *varval = NULL; 16470 struct ast_variable *tmpvar = NULL; 16471 struct ast_flags userflags[2] = {{(0)}}; 16472 struct ast_flags mask[2] = {{(0)}}; 16473 16474 16475 if (!(user = ast_calloc(1, sizeof(*user)))) 16476 return NULL; 16477 16478 suserobjs++; 16479 ASTOBJ_INIT(user); 16480 ast_copy_string(user->name, name, sizeof(user->name)); 16481 oldha = user->ha; 16482 user->ha = NULL; 16483 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16484 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16485 user->capability = global_capability; 16486 user->allowtransfer = global_allowtransfer; 16487 user->maxcallbitrate = default_maxcallbitrate; 16488 user->autoframing = global_autoframing; 16489 user->prefs = default_prefs; 16490 /* set default context */ 16491 strcpy(user->context, default_context); 16492 strcpy(user->language, default_language); 16493 strcpy(user->mohinterpret, default_mohinterpret); 16494 strcpy(user->mohsuggest, default_mohsuggest); 16495 /* First we walk through the v parameters list and then the alt parameters list */ 16496 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16497 if (handle_common_options(&userflags[0], &mask[0], v)) 16498 continue; 16499 16500 if (!strcasecmp(v->name, "context")) { 16501 ast_copy_string(user->context, v->value, sizeof(user->context)); 16502 } else if (!strcasecmp(v->name, "subscribecontext")) { 16503 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16504 } else if (!strcasecmp(v->name, "setvar")) { 16505 varname = ast_strdupa(v->value); 16506 if ((varval = strchr(varname,'='))) { 16507 *varval++ = '\0'; 16508 if ((tmpvar = ast_variable_new(varname, varval))) { 16509 tmpvar->next = user->chanvars; 16510 user->chanvars = tmpvar; 16511 } 16512 } 16513 } else if (!strcasecmp(v->name, "permit") || 16514 !strcasecmp(v->name, "deny")) { 16515 user->ha = ast_append_ha(v->name, v->value, user->ha); 16516 } else if (!strcasecmp(v->name, "allowtransfer")) { 16517 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16518 } else if (!strcasecmp(v->name, "secret")) { 16519 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16520 } else if (!strcasecmp(v->name, "md5secret")) { 16521 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16522 } else if (!strcasecmp(v->name, "callerid")) { 16523 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16524 } else if (!strcasecmp(v->name, "fullname")) { 16525 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16526 } else if (!strcasecmp(v->name, "cid_number")) { 16527 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16528 } else if (!strcasecmp(v->name, "callgroup")) { 16529 user->callgroup = ast_get_group(v->value); 16530 } else if (!strcasecmp(v->name, "pickupgroup")) { 16531 user->pickupgroup = ast_get_group(v->value); 16532 } else if (!strcasecmp(v->name, "language")) { 16533 ast_copy_string(user->language, v->value, sizeof(user->language)); 16534 } else if (!strcasecmp(v->name, "mohinterpret") 16535 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16536 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16537 } else if (!strcasecmp(v->name, "mohsuggest")) { 16538 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16539 } else if (!strcasecmp(v->name, "accountcode")) { 16540 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16541 } else if (!strcasecmp(v->name, "call-limit")) { 16542 user->call_limit = atoi(v->value); 16543 if (user->call_limit < 0) 16544 user->call_limit = 0; 16545 } else if (!strcasecmp(v->name, "amaflags")) { 16546 format = ast_cdr_amaflags2int(v->value); 16547 if (format < 0) { 16548 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16549 } else { 16550 user->amaflags = format; 16551 } 16552 } else if (!strcasecmp(v->name, "allow")) { 16553 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16554 } else if (!strcasecmp(v->name, "disallow")) { 16555 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16556 } else if (!strcasecmp(v->name, "autoframing")) { 16557 user->autoframing = ast_true(v->value); 16558 } else if (!strcasecmp(v->name, "callingpres")) { 16559 user->callingpres = ast_parse_caller_presentation(v->value); 16560 if (user->callingpres == -1) 16561 user->callingpres = atoi(v->value); 16562 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16563 user->maxcallbitrate = atoi(v->value); 16564 if (user->maxcallbitrate < 0) 16565 user->maxcallbitrate = default_maxcallbitrate; 16566 } 16567 /* We can't just report unknown options here because this may be a 16568 * type=friend entry. All user options are valid for a peer, but not 16569 * the other way around. */ 16570 } 16571 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16572 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16573 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16574 global_allowsubscribe = TRUE; /* No global ban any more */ 16575 ast_free_ha(oldha); 16576 return user; 16577 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1793 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
01794 { 01795 /* Work around buggy UNIDEN UIP200 firmware */ 01796 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01797 01798 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01799 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01800 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01801 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data, | |||
char * | cid_num, | |||
char * | cid_name | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8605 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, sip_pvt::lock, LOG_WARNING, NONE, option_verbose, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe(), and handle_response().
08606 { 08607 struct sip_pvt *p = data; 08608 08609 ast_mutex_lock(&p->lock); 08610 08611 switch(state) { 08612 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08613 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08614 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08615 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08616 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08617 ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); 08618 p->stateid = -1; 08619 p->subscribed = NONE; 08620 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08621 break; 08622 default: /* Tell user */ 08623 p->laststate = state; 08624 break; 08625 } 08626 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08627 if (!p->pendinginvite) { 08628 transmit_state_notify(p, state, 1, FALSE); 08629 } else { 08630 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08631 if many state changes happen meanwhile, we will only send a notification of the last one */ 08632 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08633 } 08634 } 08635 if (option_verbose > 1) 08636 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 08637 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08638 08639 08640 ast_mutex_unlock(&p->lock); 08641 08642 return 0; 08643 }
static void change_hold_state | ( | struct sip_pvt * | dialog, | |
struct sip_request * | req, | |||
int | holdstate, | |||
int | sendonly | |||
) | [static] |
Change hold state for a call.
Definition at line 4989 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), sip_pvt::owner, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
04990 { 04991 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04992 sip_peer_hold(dialog, holdstate); 04993 if (global_callevents) 04994 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04995 "Channel: %s\r\n" 04996 "Uniqueid: %s\r\n", 04997 dialog->owner->name, 04998 dialog->owner->uniqueid); 04999 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05000 if (!holdstate) { /* Put off remote hold */ 05001 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05002 return; 05003 } 05004 /* No address for RTP, we're on hold */ 05005 05006 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05007 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05008 else if (sendonly == 2) /* Inactive stream */ 05009 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05010 else 05011 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05012 return; 05013 }
static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const char * | username, | |||
const char * | secret, | |||
const char * | md5secret, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
int | ignore | |||
) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 8410 of file chan_sip.c.
References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, LOG_WARNING, s, S_OR, sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08413 { 08414 const char *response = "407 Proxy Authentication Required"; 08415 const char *reqheader = "Proxy-Authorization"; 08416 const char *respheader = "Proxy-Authenticate"; 08417 const char *authtoken; 08418 char a1_hash[256]; 08419 char resp_hash[256]=""; 08420 char *c; 08421 int wrongnonce = FALSE; 08422 int good_response; 08423 const char *usednonce = p->randdata; 08424 struct ast_dynamic_str *buf; 08425 int res; 08426 08427 /* table of recognised keywords, and their value in the digest */ 08428 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08429 struct x { 08430 const char *key; 08431 const char *s; 08432 } *i, keys[] = { 08433 [K_RESP] = { "response=", "" }, 08434 [K_URI] = { "uri=", "" }, 08435 [K_USER] = { "username=", "" }, 08436 [K_NONCE] = { "nonce=", "" }, 08437 [K_LAST] = { NULL, NULL} 08438 }; 08439 08440 /* Always OK if no secret */ 08441 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08442 return AUTH_SUCCESSFUL; 08443 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08444 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08445 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08446 different circumstances! What a surprise. */ 08447 response = "401 Unauthorized"; 08448 reqheader = "Authorization"; 08449 respheader = "WWW-Authenticate"; 08450 } 08451 authtoken = get_header(req, reqheader); 08452 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08453 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08454 information */ 08455 if (!reliable) { 08456 /* Resend message if this was NOT a reliable delivery. Otherwise the 08457 retransmission should get it */ 08458 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08459 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08460 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08461 } 08462 return AUTH_CHALLENGE_SENT; 08463 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08464 /* We have no auth, so issue challenge and request authentication */ 08465 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08466 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08467 /* Schedule auto destroy in 32 seconds */ 08468 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08469 return AUTH_CHALLENGE_SENT; 08470 } 08471 08472 /* --- We have auth, so check it */ 08473 08474 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08475 an example in the spec of just what it is you're doing a hash on. */ 08476 08477 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08478 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08479 08480 /* Make a copy of the response and parse it */ 08481 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08482 08483 if (res == AST_DYNSTR_BUILD_FAILED) 08484 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08485 08486 c = buf->str; 08487 08488 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08489 for (i = keys; i->key != NULL; i++) { 08490 const char *separator = ","; /* default */ 08491 08492 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08493 continue; 08494 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08495 c += strlen(i->key); 08496 if (*c == '"') { /* in quotes. Skip first and look for last */ 08497 c++; 08498 separator = "\""; 08499 } 08500 i->s = c; 08501 strsep(&c, separator); 08502 break; 08503 } 08504 if (i->key == NULL) /* not found, jump after space or comma */ 08505 strsep(&c, " ,"); 08506 } 08507 08508 /* Verify that digest username matches the username we auth as */ 08509 if (strcmp(username, keys[K_USER].s)) { 08510 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08511 username, keys[K_USER].s); 08512 /* Oops, we're trying something here */ 08513 return AUTH_USERNAME_MISMATCH; 08514 } 08515 08516 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08517 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08518 wrongnonce = TRUE; 08519 usednonce = keys[K_NONCE].s; 08520 } 08521 08522 if (!ast_strlen_zero(md5secret)) 08523 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08524 else { 08525 char a1[256]; 08526 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08527 ast_md5_hash(a1_hash, a1); 08528 } 08529 08530 /* compute the expected response to compare with what we received */ 08531 { 08532 char a2[256]; 08533 char a2_hash[256]; 08534 char resp[256]; 08535 08536 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08537 S_OR(keys[K_URI].s, uri)); 08538 ast_md5_hash(a2_hash, a2); 08539 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08540 ast_md5_hash(resp_hash, resp); 08541 } 08542 08543 good_response = keys[K_RESP].s && 08544 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08545 if (wrongnonce) { 08546 if (good_response) { 08547 if (sipdebug) 08548 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08549 /* We got working auth token, based on stale nonce . */ 08550 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08551 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08552 } else { 08553 /* Everything was wrong, so give the device one more try with a new challenge */ 08554 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08555 if (sipdebug) 08556 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08557 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08558 } else { 08559 if (sipdebug) 08560 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08561 } 08562 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08563 } 08564 08565 /* Schedule auto destroy in 32 seconds */ 08566 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08567 return AUTH_CHALLENGE_SENT; 08568 } 08569 if (good_response) { 08570 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08571 return AUTH_SUCCESSFUL; 08572 } 08573 08574 /* Ok, we have a bad username/secret pair */ 08575 /* Tell the UAS not to re-send this authentication data, because 08576 it will continue to fail 08577 */ 08578 08579 return AUTH_SECRET_FAILED; 08580 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12073 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lastinvite, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
12074 { 12075 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12076 /* if we can't BYE, then this is really a pending CANCEL */ 12077 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12078 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12079 /* Actually don't destroy us yet, wait for the 487 on our original 12080 INVITE, but do set an autodestruct just in case we never get it. */ 12081 else { 12082 /* We have a pending outbound invite, don't send someting 12083 new in-transaction */ 12084 if (p->pendinginvite) 12085 return; 12086 12087 /* Perhaps there is an SD change INVITE outstanding */ 12088 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12089 } 12090 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12091 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12092 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12093 /* if we can't REINVITE, hold it for later */ 12094 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12095 if (option_debug) 12096 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12097 } else { 12098 if (option_debug) 12099 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12100 /* Didn't get to reinvite yet, so do it now */ 12101 transmit_reinvite_with_sdp(p); 12102 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12103 } 12104 } 12105 }
static int check_sip_domain | ( | const char * | domain, | |
char * | context, | |||
size_t | len | |||
) | [static] |
check_sip_domain: Check if domain part of uri is local to our server
Definition at line 16343 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
16344 { 16345 struct domain *d; 16346 int result = 0; 16347 16348 AST_LIST_LOCK(&domain_list); 16349 AST_LIST_TRAVERSE(&domain_list, d, list) { 16350 if (strcasecmp(d->domain, domain)) 16351 continue; 16352 16353 if (len && !ast_strlen_zero(d->context)) 16354 ast_copy_string(context, d->context, len); 16355 16356 result = 1; 16357 break; 16358 } 16359 AST_LIST_UNLOCK(&domain_list); 16360 16361 return result; 16362 }
static int check_user | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
Definition at line 9709 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09710 { 09711 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09712 }
static enum check_auth_result check_user_full | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
struct sockaddr_in * | sin, | |||
struct sip_peer ** | authpeer | |||
) | [static] |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
Definition at line 9389 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_pvt::allowtransfer, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, sip_pvt::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, domain::context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_pvt::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_pvt::t38, sip_pvt::timer_t1, sip_peer::username, username, and sip_pvt::vrtp.
Referenced by check_user(), and handle_request_subscribe().
09392 { 09393 struct sip_user *user = NULL; 09394 struct sip_peer *peer; 09395 char from[256], *c; 09396 char *of; 09397 char rpid_num[50]; 09398 const char *rpid; 09399 enum check_auth_result res = AUTH_SUCCESSFUL; 09400 char *t; 09401 char calleridname[50]; 09402 int debug=sip_debug_test_addr(sin); 09403 struct ast_variable *tmpvar = NULL, *v = NULL; 09404 char *uri2 = ast_strdupa(uri); 09405 09406 /* Terminate URI */ 09407 t = uri2; 09408 while (*t && *t > 32 && *t != ';') 09409 t++; 09410 *t = '\0'; 09411 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09412 if (pedanticsipchecking) 09413 ast_uri_decode(from); 09414 /* XXX here tries to map the username for invite things */ 09415 memset(calleridname, 0, sizeof(calleridname)); 09416 get_calleridname(from, calleridname, sizeof(calleridname)); 09417 if (calleridname[0]) 09418 ast_string_field_set(p, cid_name, calleridname); 09419 09420 rpid = get_header(req, "Remote-Party-ID"); 09421 memset(rpid_num, 0, sizeof(rpid_num)); 09422 if (!ast_strlen_zero(rpid)) 09423 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09424 09425 of = get_in_brackets(from); 09426 if (ast_strlen_zero(p->exten)) { 09427 t = uri2; 09428 if (!strncasecmp(t, "sip:", 4)) 09429 t+= 4; 09430 ast_string_field_set(p, exten, t); 09431 t = strchr(p->exten, '@'); 09432 if (t) 09433 *t = '\0'; 09434 if (ast_strlen_zero(p->our_contact)) 09435 build_contact(p); 09436 } 09437 /* save the URI part of the From header */ 09438 ast_string_field_set(p, from, of); 09439 if (strncasecmp(of, "sip:", 4)) { 09440 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09441 } else 09442 of += 4; 09443 /* Get just the username part */ 09444 if ((c = strchr(of, '@'))) { 09445 char *tmp; 09446 *c = '\0'; 09447 if ((c = strchr(of, ':'))) 09448 *c = '\0'; 09449 tmp = ast_strdupa(of); 09450 /* We need to be able to handle auth-headers looking like 09451 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09452 */ 09453 tmp = strsep(&tmp, ";"); 09454 if (ast_is_shrinkable_phonenumber(tmp)) 09455 ast_shrink_phone_number(tmp); 09456 ast_string_field_set(p, cid_num, tmp); 09457 } 09458 09459 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09460 user = find_user(of, 1); 09461 09462 /* Find user based on user name in the from header */ 09463 if (user && ast_apply_ha(user->ha, sin)) { 09464 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09465 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09466 /* copy channel vars */ 09467 for (v = user->chanvars ; v ; v = v->next) { 09468 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09469 tmpvar->next = p->chanvars; 09470 p->chanvars = tmpvar; 09471 } 09472 } 09473 p->prefs = user->prefs; 09474 /* Set Frame packetization */ 09475 if (p->rtp) { 09476 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09477 p->autoframing = user->autoframing; 09478 } 09479 /* replace callerid if rpid found, and not restricted */ 09480 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09481 char *tmp; 09482 if (*calleridname) 09483 ast_string_field_set(p, cid_name, calleridname); 09484 tmp = ast_strdupa(rpid_num); 09485 if (ast_is_shrinkable_phonenumber(tmp)) 09486 ast_shrink_phone_number(tmp); 09487 ast_string_field_set(p, cid_num, tmp); 09488 } 09489 09490 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09491 09492 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09493 if (sip_cancel_destroy(p)) 09494 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09495 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09496 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09497 /* Copy SIP extensions profile from INVITE */ 09498 if (p->sipoptions) 09499 user->sipoptions = p->sipoptions; 09500 09501 /* If we have a call limit, set flag */ 09502 if (user->call_limit) 09503 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09504 if (!ast_strlen_zero(user->context)) 09505 ast_string_field_set(p, context, user->context); 09506 if (!ast_strlen_zero(user->cid_num)) { 09507 char *tmp = ast_strdupa(user->cid_num); 09508 if (ast_is_shrinkable_phonenumber(tmp)) 09509 ast_shrink_phone_number(tmp); 09510 ast_string_field_set(p, cid_num, tmp); 09511 } 09512 if (!ast_strlen_zero(user->cid_name)) 09513 ast_string_field_set(p, cid_name, user->cid_name); 09514 ast_string_field_set(p, username, user->name); 09515 ast_string_field_set(p, peername, user->name); 09516 ast_string_field_set(p, peersecret, user->secret); 09517 ast_string_field_set(p, peermd5secret, user->md5secret); 09518 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09519 ast_string_field_set(p, accountcode, user->accountcode); 09520 ast_string_field_set(p, language, user->language); 09521 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09522 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09523 p->allowtransfer = user->allowtransfer; 09524 p->amaflags = user->amaflags; 09525 p->callgroup = user->callgroup; 09526 p->pickupgroup = user->pickupgroup; 09527 if (user->callingpres) /* User callingpres setting will override RPID header */ 09528 p->callingpres = user->callingpres; 09529 09530 /* Set default codec settings for this call */ 09531 p->capability = user->capability; /* User codec choice */ 09532 p->jointcapability = user->capability; /* Our codecs */ 09533 if (p->peercapability) /* AND with peer's codecs */ 09534 p->jointcapability &= p->peercapability; 09535 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09536 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09537 p->noncodeccapability |= AST_RTP_DTMF; 09538 else 09539 p->noncodeccapability &= ~AST_RTP_DTMF; 09540 p->jointnoncodeccapability = p->noncodeccapability; 09541 if (p->t38.peercapability) 09542 p->t38.jointcapability &= p->t38.peercapability; 09543 p->maxcallbitrate = user->maxcallbitrate; 09544 /* If we do not support video, remove video from call structure */ 09545 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09546 ast_rtp_destroy(p->vrtp); 09547 p->vrtp = NULL; 09548 } 09549 } 09550 if (user && debug) 09551 ast_verbose("Found user '%s'\n", user->name); 09552 } else { 09553 if (user) { 09554 if (!authpeer && debug) 09555 ast_verbose("Found user '%s', but fails host access\n", user->name); 09556 ASTOBJ_UNREF(user,sip_destroy_user); 09557 } 09558 user = NULL; 09559 } 09560 09561 if (!user) { 09562 /* If we didn't find a user match, check for peers */ 09563 if (sipmethod == SIP_SUBSCRIBE) 09564 /* For subscribes, match on peer name only */ 09565 peer = find_peer(of, NULL, 1); 09566 else 09567 /* Look for peer based on the IP address we received data from */ 09568 /* If peer is registered from this IP address or have this as a default 09569 IP address, this call is from the peer 09570 */ 09571 peer = find_peer(NULL, &p->recv, 1); 09572 09573 if (peer) { 09574 /* Set Frame packetization */ 09575 if (p->rtp) { 09576 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09577 p->autoframing = peer->autoframing; 09578 } 09579 if (debug) 09580 ast_verbose("Found peer '%s'\n", peer->name); 09581 09582 /* Take the peer */ 09583 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09584 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09585 09586 /* Copy SIP extensions profile to peer */ 09587 if (p->sipoptions) 09588 peer->sipoptions = p->sipoptions; 09589 09590 /* replace callerid if rpid found, and not restricted */ 09591 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09592 char *tmp = ast_strdupa(rpid_num); 09593 if (*calleridname) 09594 ast_string_field_set(p, cid_name, calleridname); 09595 if (ast_is_shrinkable_phonenumber(tmp)) 09596 ast_shrink_phone_number(tmp); 09597 ast_string_field_set(p, cid_num, tmp); 09598 } 09599 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09600 09601 ast_string_field_set(p, peersecret, peer->secret); 09602 ast_string_field_set(p, peermd5secret, peer->md5secret); 09603 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09604 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09605 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09606 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09607 p->callingpres = peer->callingpres; 09608 if (peer->maxms && peer->lastms) 09609 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09610 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09611 /* Pretend there is no required authentication */ 09612 ast_string_field_free(p, peersecret); 09613 ast_string_field_free(p, peermd5secret); 09614 } 09615 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09616 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09617 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09618 /* If we have a call limit, set flag */ 09619 if (peer->call_limit) 09620 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09621 ast_string_field_set(p, peername, peer->name); 09622 ast_string_field_set(p, authname, peer->name); 09623 09624 /* copy channel vars */ 09625 for (v = peer->chanvars ; v ; v = v->next) { 09626 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09627 tmpvar->next = p->chanvars; 09628 p->chanvars = tmpvar; 09629 } 09630 } 09631 if (authpeer) { 09632 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09633 } 09634 09635 if (!ast_strlen_zero(peer->username)) { 09636 ast_string_field_set(p, username, peer->username); 09637 /* Use the default username for authentication on outbound calls */ 09638 /* XXX this takes the name from the caller... can we override ? */ 09639 ast_string_field_set(p, authname, peer->username); 09640 } 09641 if (!ast_strlen_zero(peer->cid_num)) { 09642 char *tmp = ast_strdupa(peer->cid_num); 09643 if (ast_is_shrinkable_phonenumber(tmp)) 09644 ast_shrink_phone_number(tmp); 09645 ast_string_field_set(p, cid_num, tmp); 09646 } 09647 if (!ast_strlen_zero(peer->cid_name)) 09648 ast_string_field_set(p, cid_name, peer->cid_name); 09649 ast_string_field_set(p, fullcontact, peer->fullcontact); 09650 if (!ast_strlen_zero(peer->context)) 09651 ast_string_field_set(p, context, peer->context); 09652 ast_string_field_set(p, peersecret, peer->secret); 09653 ast_string_field_set(p, peermd5secret, peer->md5secret); 09654 ast_string_field_set(p, language, peer->language); 09655 ast_string_field_set(p, accountcode, peer->accountcode); 09656 p->amaflags = peer->amaflags; 09657 p->callgroup = peer->callgroup; 09658 p->pickupgroup = peer->pickupgroup; 09659 p->capability = peer->capability; 09660 p->prefs = peer->prefs; 09661 p->jointcapability = peer->capability; 09662 if (p->peercapability) 09663 p->jointcapability &= p->peercapability; 09664 p->maxcallbitrate = peer->maxcallbitrate; 09665 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09666 ast_rtp_destroy(p->vrtp); 09667 p->vrtp = NULL; 09668 } 09669 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09670 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09671 p->noncodeccapability |= AST_RTP_DTMF; 09672 else 09673 p->noncodeccapability &= ~AST_RTP_DTMF; 09674 p->jointnoncodeccapability = p->noncodeccapability; 09675 if (p->t38.peercapability) 09676 p->t38.jointcapability &= p->t38.peercapability; 09677 } 09678 ASTOBJ_UNREF(peer, sip_destroy_peer); 09679 } else { 09680 if (debug) 09681 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09682 09683 /* do we allow guests? */ 09684 if (!global_allowguest) { 09685 if (global_alwaysauthreject) 09686 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09687 else 09688 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09689 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09690 char *tmp = ast_strdupa(rpid_num); 09691 if (*calleridname) 09692 ast_string_field_set(p, cid_name, calleridname); 09693 if (ast_is_shrinkable_phonenumber(tmp)) 09694 ast_shrink_phone_number(tmp); 09695 ast_string_field_set(p, cid_num, tmp); 09696 } 09697 } 09698 09699 } 09700 09701 if (user) 09702 ASTOBJ_UNREF(user, sip_destroy_user); 09703 return res; 09704 }
static void check_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 9257 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().
09258 { 09259 char via[512]; 09260 char *c, *pt; 09261 struct hostent *hp; 09262 struct ast_hostent ahp; 09263 09264 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09265 09266 /* Work on the leftmost value of the topmost Via header */ 09267 c = strchr(via, ','); 09268 if (c) 09269 *c = '\0'; 09270 09271 /* Check for rport */ 09272 c = strstr(via, ";rport"); 09273 if (c && (c[6] != '=')) /* rport query, not answer */ 09274 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09275 09276 c = strchr(via, ';'); 09277 if (c) 09278 *c = '\0'; 09279 09280 c = strchr(via, ' '); 09281 if (c) { 09282 *c = '\0'; 09283 c = ast_skip_blanks(c+1); 09284 if (strcasecmp(via, "SIP/2.0/UDP")) { 09285 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09286 return; 09287 } 09288 pt = strchr(c, ':'); 09289 if (pt) 09290 *pt++ = '\0'; /* remember port pointer */ 09291 hp = ast_gethostbyname(c, &ahp); 09292 if (!hp) { 09293 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09294 return; 09295 } 09296 memset(&p->sa, 0, sizeof(p->sa)); 09297 p->sa.sin_family = AF_INET; 09298 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09299 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09300 09301 if (sip_debug_test_pvt(p)) { 09302 const struct sockaddr_in *dst = sip_real_dst(p); 09303 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09304 } 09305 } 09306 }
static void cleanup_stale_contexts | ( | char * | new, | |
char * | old | |||
) | [static] |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
Definition at line 10153 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
10154 { 10155 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10156 10157 while ((oldcontext = strsep(&old, "&"))) { 10158 stalecontext = '\0'; 10159 ast_copy_string(newlist, new, sizeof(newlist)); 10160 stringp = newlist; 10161 while ((newcontext = strsep(&stringp, "&"))) { 10162 if (strcmp(newcontext, oldcontext) == 0) { 10163 /* This is not the context you're looking for */ 10164 stalecontext = '\0'; 10165 break; 10166 } else if (strcmp(newcontext, oldcontext)) { 10167 stalecontext = oldcontext; 10168 } 10169 10170 } 10171 if (stalecontext) 10172 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10173 } 10174 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16436 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16437 { 16438 struct sip_auth *a = authlist; 16439 struct sip_auth *b; 16440 16441 while (a) { 16442 b = a; 16443 a = a->next; 16444 free(b); 16445 } 16446 16447 return 1; 16448 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16365 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by reload_config(), and unload_module().
16366 { 16367 struct domain *d; 16368 16369 AST_LIST_LOCK(&domain_list); 16370 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16371 free(d); 16372 AST_LIST_UNLOCK(&domain_list); 16373 }
static char * complete_sip_debug_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip debug peer' CLI.
Definition at line 10965 of file chan_sip.c.
References complete_sip_peer().
10966 { 10967 if (pos == 3) 10968 return complete_sip_peer(word, state, 0); 10969 10970 return NULL; 10971 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10939 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10940 { 10941 char *result = NULL; 10942 int wordlen = strlen(word); 10943 int which = 0; 10944 10945 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10946 /* locking of the object is not required because only the name and flags are being compared */ 10947 if (!strncasecmp(word, iterator->name, wordlen) && 10948 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10949 ++which > state) 10950 result = ast_strdup(iterator->name); 10951 } while(0) ); 10952 return result; 10953 }
static char * complete_sip_prune_realtime_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip prune realtime peer' CLI.
Definition at line 11033 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11034 { 11035 if (pos == 4) 11036 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11037 return NULL; 11038 }
static char * complete_sip_prune_realtime_user | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip prune realtime user' CLI.
Definition at line 11041 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11042 { 11043 if (pos == 4) 11044 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11045 11046 return NULL; 11047 }
static char * complete_sip_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip show peer' CLI.
Definition at line 10956 of file chan_sip.c.
References complete_sip_peer().
10957 { 10958 if (pos == 3) 10959 return complete_sip_peer(word, state, 0); 10960 10961 return NULL; 10962 }
static char * complete_sip_show_user | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip show user' CLI.
Definition at line 10994 of file chan_sip.c.
References complete_sip_user().
10995 { 10996 if (pos == 3) 10997 return complete_sip_user(word, state, 0); 10998 10999 return NULL; 11000 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10974 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10975 { 10976 char *result = NULL; 10977 int wordlen = strlen(word); 10978 int which = 0; 10979 10980 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10981 /* locking of the object is not required because only the name and flags are being compared */ 10982 if (!strncasecmp(word, iterator->name, wordlen)) { 10983 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10984 continue; 10985 if (++which > state) { 10986 result = ast_strdup(iterator->name); 10987 } 10988 } 10989 } while(0) ); 10990 return result; 10991 }
static char * complete_sipch | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip show channel' CLI.
Definition at line 10916 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, iflist, and sip_pvt::next.
10917 { 10918 int which=0; 10919 struct sip_pvt *cur; 10920 char *c = NULL; 10921 int wordlen = strlen(word); 10922 10923 if (pos != 3) { 10924 return NULL; 10925 } 10926 10927 ast_mutex_lock(&iflock); 10928 for (cur = iflist; cur; cur = cur->next) { 10929 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10930 c = ast_strdup(cur->callid); 10931 break; 10932 } 10933 } 10934 ast_mutex_unlock(&iflock); 10935 return c; 10936 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11003 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11004 { 11005 char *c = NULL; 11006 11007 if (pos == 2) { 11008 int which = 0; 11009 char *cat = NULL; 11010 int wordlen = strlen(word); 11011 11012 /* do completion for notify type */ 11013 11014 if (!notify_types) 11015 return NULL; 11016 11017 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11018 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11019 c = ast_strdup(cat); 11020 break; 11021 } 11022 } 11023 return c; 11024 } 11025 11026 if (pos > 2) 11027 return complete_sip_peer(word, state, 0); 11028 11029 return NULL; 11030 }
static int copy_all_header | ( | struct sip_request * | req, | |
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy all headers from one request to another.
Definition at line 5680 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05681 { 05682 int start = 0; 05683 int copied = 0; 05684 for (;;) { 05685 const char *tmp = __get_header(orig, field, &start); 05686 05687 if (ast_strlen_zero(tmp)) 05688 break; 05689 /* Add what we're responding to */ 05690 add_header(req, field, tmp); 05691 copied++; 05692 } 05693 return copied ? 0 : -1; 05694 }
static int copy_header | ( | struct sip_request * | req, | |
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy one header field from one request to another.
Definition at line 5669 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05670 { 05671 const char *tmp = get_header(orig, field); 05672 05673 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05674 return add_header(req, field, tmp); 05675 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05676 return -1; 05677 }
static void copy_request | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
copy SIP request (mostly used to save request for responses)
Definition at line 6723 of file chan_sip.c.
References sip_request::header, sip_request::line, offset, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06724 { 06725 long offset; 06726 int x; 06727 offset = ((void *)dst) - ((void *)src); 06728 /* First copy stuff */ 06729 memcpy(dst, src, sizeof(*dst)); 06730 /* Now fix pointer arithmetic */ 06731 for (x=0; x < src->headers; x++) 06732 dst->header[x] += offset; 06733 for (x=0; x < src->lines; x++) 06734 dst->line[x] += offset; 06735 dst->rlPart1 += offset; 06736 dst->rlPart2 += offset; 06737 }
static int copy_via_headers | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const struct sip_request * | orig, | |||
const char * | field | |||
) | [static] |
Copy SIP VIA Headers from the request to the response.
Definition at line 5702 of file chan_sip.c.
References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.
Referenced by respprep().
05703 { 05704 int copied = 0; 05705 int start = 0; 05706 05707 for (;;) { 05708 char new[512]; 05709 const char *oh = __get_header(orig, field, &start); 05710 05711 if (ast_strlen_zero(oh)) 05712 break; 05713 05714 if (!copied) { /* Only check for empty rport in topmost via header */ 05715 char leftmost[512], *others, *rport; 05716 05717 /* Only work on leftmost value */ 05718 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05719 others = strchr(leftmost, ','); 05720 if (others) 05721 *others++ = '\0'; 05722 05723 /* Find ;rport; (empty request) */ 05724 rport = strstr(leftmost, ";rport"); 05725 if (rport && *(rport+6) == '=') 05726 rport = NULL; /* We already have a parameter to rport */ 05727 05728 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05729 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05730 /* We need to add received port - rport */ 05731 char *end; 05732 05733 rport = strstr(leftmost, ";rport"); 05734 05735 if (rport) { 05736 end = strchr(rport + 1, ';'); 05737 if (end) 05738 memmove(rport, end, strlen(end) + 1); 05739 else 05740 *rport = '\0'; 05741 } 05742 05743 /* Add rport to first VIA header if requested */ 05744 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05745 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05746 ntohs(p->recv.sin_port), 05747 others ? "," : "", others ? others : ""); 05748 } else { 05749 /* We should *always* add a received to the topmost via */ 05750 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05751 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05752 others ? "," : "", others ? others : ""); 05753 } 05754 oh = new; /* the header to copy */ 05755 } /* else add the following via headers untouched */ 05756 add_header(req, field, oh); 05757 copied++; 05758 } 05759 if (!copied) { 05760 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05761 return -1; 05762 } 05763 return 0; 05764 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer | |||
) | [static] |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 2882 of file chan_sip.c.
References ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02883 { 02884 struct hostent *hp; 02885 struct ast_hostent ahp; 02886 struct sip_peer *p; 02887 char *port; 02888 int portno; 02889 char host[MAXHOSTNAMELEN], *hostn; 02890 char peer[256]; 02891 02892 ast_copy_string(peer, opeer, sizeof(peer)); 02893 port = strchr(peer, ':'); 02894 if (port) 02895 *port++ = '\0'; 02896 dialog->sa.sin_family = AF_INET; 02897 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02898 p = find_peer(peer, NULL, 1); 02899 02900 if (p) { 02901 int res = create_addr_from_peer(dialog, p); 02902 ASTOBJ_UNREF(p, sip_destroy_peer); 02903 return res; 02904 } 02905 hostn = peer; 02906 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02907 if (srvlookup) { 02908 char service[MAXHOSTNAMELEN]; 02909 int tportno; 02910 int ret; 02911 02912 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02913 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02914 if (ret > 0) { 02915 hostn = host; 02916 portno = tportno; 02917 } 02918 } 02919 hp = ast_gethostbyname(hostn, &ahp); 02920 if (!hp) { 02921 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02922 return -1; 02923 } 02924 ast_string_field_set(dialog, tohost, peer); 02925 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02926 dialog->sa.sin_port = htons(portno); 02927 dialog->recv = dialog->sa; 02928 return 0; 02929 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2774 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, domain::context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02775 { 02776 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02777 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02778 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02779 dialog->recv = dialog->sa; 02780 } else 02781 return -1; 02782 02783 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02784 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02785 dialog->capability = peer->capability; 02786 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02787 ast_rtp_destroy(dialog->vrtp); 02788 dialog->vrtp = NULL; 02789 } 02790 dialog->prefs = peer->prefs; 02791 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02792 dialog->t38.capability = global_t38_capability; 02793 if (dialog->udptl) { 02794 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02795 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02796 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02797 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02798 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02799 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02800 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02801 if (option_debug > 1) 02802 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02803 } 02804 dialog->t38.jointcapability = dialog->t38.capability; 02805 } else if (dialog->udptl) { 02806 ast_udptl_destroy(dialog->udptl); 02807 dialog->udptl = NULL; 02808 } 02809 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02810 02811 if (dialog->rtp) { 02812 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02813 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02814 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02815 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02816 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02817 /* Set Frame packetization */ 02818 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02819 dialog->autoframing = peer->autoframing; 02820 } 02821 if (dialog->vrtp) { 02822 ast_rtp_setdtmf(dialog->vrtp, 0); 02823 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02824 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02825 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02826 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02827 } 02828 02829 ast_string_field_set(dialog, peername, peer->name); 02830 ast_string_field_set(dialog, authname, peer->username); 02831 ast_string_field_set(dialog, username, peer->username); 02832 ast_string_field_set(dialog, peersecret, peer->secret); 02833 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02834 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02835 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02836 ast_string_field_set(dialog, tohost, peer->tohost); 02837 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02838 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02839 char *tmpcall; 02840 char *c; 02841 tmpcall = ast_strdupa(dialog->callid); 02842 c = strchr(tmpcall, '@'); 02843 if (c) { 02844 *c = '\0'; 02845 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02846 } 02847 } 02848 if (ast_strlen_zero(dialog->tohost)) 02849 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02850 if (!ast_strlen_zero(peer->fromdomain)) 02851 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02852 if (!ast_strlen_zero(peer->fromuser)) 02853 ast_string_field_set(dialog, fromuser, peer->fromuser); 02854 if (!ast_strlen_zero(peer->language)) 02855 ast_string_field_set(dialog, language, peer->language); 02856 dialog->maxtime = peer->maxms; 02857 dialog->callgroup = peer->callgroup; 02858 dialog->pickupgroup = peer->pickupgroup; 02859 dialog->allowtransfer = peer->allowtransfer; 02860 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02861 /* Minimum is settable or default to 100 ms */ 02862 if (peer->maxms && peer->lastms) 02863 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02864 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02865 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02866 dialog->noncodeccapability |= AST_RTP_DTMF; 02867 else 02868 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02869 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02870 ast_string_field_set(dialog, context, peer->context); 02871 dialog->rtptimeout = peer->rtptimeout; 02872 if (peer->call_limit) 02873 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02874 dialog->maxcallbitrate = peer->maxcallbitrate; 02875 02876 return 0; 02877 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7903 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07904 { 07905 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07906 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07907 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07908 else 07909 ast_db_del("SIP/Registry", peer->name); 07910 } 07911 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6767 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06768 { 06769 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06770 06771 if (!*e) 06772 return -1; 06773 req->rlPart1 = e; /* method or protocol */ 06774 e = ast_skip_nonblanks(e); 06775 if (*e) 06776 *e++ = '\0'; 06777 /* Get URI or status code */ 06778 e = ast_skip_blanks(e); 06779 if ( !*e ) 06780 return -1; 06781 ast_trim_blanks(e); 06782 06783 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06784 if (strlen(e) < 3) /* status code is 3 digits */ 06785 return -1; 06786 req->rlPart2 = e; 06787 } else { /* We have a request */ 06788 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06789 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06790 e++; 06791 if (!*e) 06792 return -1; 06793 } 06794 req->rlPart2 = e; /* URI */ 06795 e = ast_skip_nonblanks(e); 06796 if (*e) 06797 *e++ = '\0'; 06798 e = ast_skip_blanks(e); 06799 if (strcasecmp(e, "SIP/2.0") ) { 06800 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06801 return -1; 06802 } 06803 } 06804 return 1; 06805 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15654 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, DEADLOCK_AVOIDANCE, does_peer_need_mwi(), FALSE, iflist, LOG_DEBUG, LOG_NOTICE, sip_pvt::next, option_debug, option_verbose, peerl, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, and VERBOSE_PREFIX_1.
15655 { 15656 int res; 15657 struct sip_pvt *sip; 15658 struct sip_peer *peer = NULL; 15659 time_t t; 15660 int fastrestart = FALSE; 15661 int lastpeernum = -1; 15662 int curpeernum; 15663 int reloading; 15664 15665 /* Add an I/O event to our SIP UDP socket */ 15666 if (sipsock > -1) 15667 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15668 15669 /* From here on out, we die whenever asked */ 15670 for(;;) { 15671 /* Check for a reload request */ 15672 ast_mutex_lock(&sip_reload_lock); 15673 reloading = sip_reloading; 15674 sip_reloading = FALSE; 15675 ast_mutex_unlock(&sip_reload_lock); 15676 if (reloading) { 15677 if (option_verbose > 0) 15678 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15679 sip_do_reload(sip_reloadreason); 15680 15681 /* Change the I/O fd of our UDP socket */ 15682 if (sipsock > -1) { 15683 if (sipsock_read_id) 15684 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15685 else 15686 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15687 } else if (sipsock_read_id) { 15688 ast_io_remove(io, sipsock_read_id); 15689 sipsock_read_id = NULL; 15690 } 15691 } 15692 restartsearch: 15693 /* Check for interfaces needing to be killed */ 15694 ast_mutex_lock(&iflock); 15695 t = time(NULL); 15696 /* don't scan the interface list if it hasn't been a reasonable period 15697 of time since the last time we did it (when MWI is being sent, we can 15698 get back to this point every millisecond or less) 15699 */ 15700 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15701 /*! \note If we can't get a lock on an interface, skip it and come 15702 * back later. Note that there is the possibility of a deadlock with 15703 * sip_hangup otherwise, because sip_hangup is called with the channel 15704 * locked first, and the iface lock is attempted second. 15705 */ 15706 if (ast_mutex_trylock(&sip->lock)) 15707 continue; 15708 15709 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15710 if (sip->rtp && sip->owner && 15711 (sip->owner->_state == AST_STATE_UP) && 15712 !sip->redirip.sin_addr.s_addr && 15713 sip->t38.state != T38_ENABLED) { 15714 if (sip->lastrtptx && 15715 ast_rtp_get_rtpkeepalive(sip->rtp) && 15716 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15717 /* Need to send an empty RTP packet */ 15718 sip->lastrtptx = time(NULL); 15719 ast_rtp_sendcng(sip->rtp, 0); 15720 } 15721 if (sip->lastrtprx && 15722 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15723 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15724 /* Might be a timeout now -- see if we're on hold */ 15725 struct sockaddr_in sin; 15726 ast_rtp_get_peer(sip->rtp, &sin); 15727 if (sin.sin_addr.s_addr || 15728 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15729 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15730 /* Needs a hangup */ 15731 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15732 while (sip->owner && ast_channel_trylock(sip->owner)) { 15733 DEADLOCK_AVOIDANCE(&sip->lock); 15734 } 15735 if (sip->owner) { 15736 ast_log(LOG_NOTICE, 15737 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15738 sip->owner->name, 15739 (long) (t - sip->lastrtprx)); 15740 /* Issue a softhangup */ 15741 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15742 ast_channel_unlock(sip->owner); 15743 /* forget the timeouts for this call, since a hangup 15744 has already been requested and we don't want to 15745 repeatedly request hangups 15746 */ 15747 ast_rtp_set_rtptimeout(sip->rtp, 0); 15748 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15749 if (sip->vrtp) { 15750 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15751 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15752 } 15753 } 15754 } 15755 } 15756 } 15757 } 15758 /* If we have sessions that needs to be destroyed, do it now */ 15759 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15760 !sip->owner) { 15761 ast_mutex_unlock(&sip->lock); 15762 __sip_destroy(sip, 1); 15763 ast_mutex_unlock(&iflock); 15764 usleep(1); 15765 goto restartsearch; 15766 } 15767 ast_mutex_unlock(&sip->lock); 15768 } 15769 ast_mutex_unlock(&iflock); 15770 15771 pthread_testcancel(); 15772 /* Wait for sched or io */ 15773 res = ast_sched_wait(sched); 15774 if ((res < 0) || (res > 1000)) 15775 res = 1000; 15776 /* If we might need to send more mailboxes, don't wait long at all.*/ 15777 if (fastrestart) 15778 res = 1; 15779 res = ast_io_wait(io, res); 15780 if (option_debug && res > 20) 15781 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15782 ast_mutex_lock(&monlock); 15783 if (res >= 0) { 15784 res = ast_sched_runq(sched); 15785 if (option_debug && res >= 20) 15786 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15787 } 15788 15789 /* Send MWI notifications to peers - static and cached realtime peers */ 15790 t = time(NULL); 15791 fastrestart = FALSE; 15792 curpeernum = 0; 15793 peer = NULL; 15794 /* Find next peer that needs mwi */ 15795 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15796 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15797 fastrestart = TRUE; 15798 lastpeernum = curpeernum; 15799 peer = ASTOBJ_REF(iterator); 15800 }; 15801 curpeernum++; 15802 } while (0) 15803 ); 15804 /* Send MWI to the peer */ 15805 if (peer) { 15806 ASTOBJ_WRLOCK(peer); 15807 sip_send_mwi_to_peer(peer); 15808 ASTOBJ_UNLOCK(peer); 15809 ASTOBJ_UNREF(peer,sip_destroy_peer); 15810 } else { 15811 /* Reset where we come from */ 15812 lastpeernum = -1; 15813 } 15814 ast_mutex_unlock(&monlock); 15815 } 15816 /* Never reached */ 15817 return NULL; 15818 15819 }
static int do_proxy_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader, | |||
int | sipmethod, | |||
int | init | |||
) | [static] |
Add authentication on outbound SIP packet.
Definition at line 11506 of file chan_sip.c.
References ast_calloc, ast_log(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::authtries, LOG_DEBUG, option_debug, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite().
Referenced by handle_response(), handle_response_invite(), and handle_response_refer().
11507 { 11508 char digest[1024]; 11509 11510 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11511 return -2; 11512 11513 p->authtries++; 11514 if (option_debug > 1) 11515 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11516 memset(digest, 0, sizeof(digest)); 11517 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11518 /* No way to authenticate */ 11519 return -1; 11520 } 11521 /* Now we have a reply digest */ 11522 p->options->auth = digest; 11523 p->options->authheader = respheader; 11524 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11525 }
static int do_register_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
char * | respheader | |||
) | [static] |
Authenticate for outbound registration.
Definition at line 11485 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
11486 { 11487 char digest[1024]; 11488 p->authtries++; 11489 memset(digest,0,sizeof(digest)); 11490 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11491 /* There's nothing to use for authentication */ 11492 /* No digest challenge in request */ 11493 if (sip_debug_test_pvt(p) && p->registry) 11494 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11495 /* No old challenge */ 11496 return -1; 11497 } 11498 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11499 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11500 if (sip_debug_test_pvt(p) && p->registry) 11501 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11502 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11503 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2750 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, domain::mode, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02751 { 02752 const char *mode = natflags ? "On" : "Off"; 02753 02754 if (p->rtp) { 02755 if (option_debug) 02756 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02757 ast_rtp_setnat(p->rtp, natflags); 02758 } 02759 if (p->vrtp) { 02760 if (option_debug) 02761 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02762 ast_rtp_setnat(p->vrtp, natflags); 02763 } 02764 if (p->udptl) { 02765 if (option_debug) 02766 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02767 ast_udptl_setnat(p->udptl, natflags); 02768 } 02769 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15633 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.
Referenced by do_monitor().
15634 { 15635 time_t t = time(NULL); 15636 15637 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15638 !peer->mwipvt) { /* We don't have a subscription */ 15639 peer->lastmsgcheck = t; /* Reset timer */ 15640 return FALSE; 15641 } 15642 15643 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15644 return TRUE; 15645 15646 return FALSE; 15647 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10342 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10343 { 10344 switch (mode) { 10345 case SIP_DOMAIN_AUTO: 10346 return "[Automatic]"; 10347 case SIP_DOMAIN_CONFIG: 10348 return "[Configured]"; 10349 } 10350 10351 return ""; 10352 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 10122 of file chan_sip.c.
References SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, and SIP_DTMF_RFC2833.
Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().
10123 { 10124 switch (mode) { 10125 case SIP_DTMF_RFC2833: 10126 return "rfc2833"; 10127 case SIP_DTMF_INFO: 10128 return "info"; 10129 case SIP_DTMF_INBAND: 10130 return "inband"; 10131 case SIP_DTMF_AUTO: 10132 return "auto"; 10133 } 10134 return "<error>"; 10135 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7914 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().
07915 { 07916 struct sip_peer *peer = (struct sip_peer *)data; 07917 07918 if (!peer) /* Hmmm. We have no peer. Weird. */ 07919 return 0; 07920 07921 memset(&peer->addr, 0, sizeof(peer->addr)); 07922 07923 destroy_association(peer); /* remove registration data from storage */ 07924 07925 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07926 register_peer_exten(peer, FALSE); /* Remove regexten */ 07927 peer->expire = -1; 07928 ast_device_state_changed("SIP/%s", peer->name); 07929 07930 /* Do we need to release this peer from memory? 07931 Only for realtime peers and autocreated peers 07932 */ 07933 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07934 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07935 struct sip_peer *peer_ptr = peer_ptr; 07936 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 07937 if (peer_ptr) { 07938 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 07939 } 07940 } 07941 07942 ASTOBJ_UNREF(peer, sip_destroy_peer); 07943 07944 return 0; 07945 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6857 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), SIPBUFSIZE, and strsep().
Referenced by handle_request(), and handle_request_invite().
06858 { 06859 char stripped[SIPBUFSIZE]; 06860 char *c; 06861 06862 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06863 c = get_in_brackets(stripped); 06864 c = strsep(&c, ";"); /* trim ; and beyond */ 06865 if (!ast_strlen_zero(c)) 06866 ast_string_field_set(p, uri, c); 06867 }
static const char * find_alias | ( | const char * | name, | |
const char * | _default | |||
) | [static] |
Find compressed SIP alias.
Structure for conversion between compressed SIP and "normal" SIP
Definition at line 4217 of file chan_sip.c.
References aliases.
04218 { 04219 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04220 static const struct cfalias { 04221 char * const fullname; 04222 char * const shortname; 04223 } aliases[] = { 04224 { "Content-Type", "c" }, 04225 { "Content-Encoding", "e" }, 04226 { "From", "f" }, 04227 { "Call-ID", "i" }, 04228 { "Contact", "m" }, 04229 { "Content-Length", "l" }, 04230 { "Subject", "s" }, 04231 { "To", "t" }, 04232 { "Supported", "k" }, 04233 { "Refer-To", "r" }, 04234 { "Referred-By", "b" }, 04235 { "Allow-Events", "u" }, 04236 { "Event", "o" }, 04237 { "Via", "v" }, 04238 { "Accept-Contact", "a" }, 04239 { "Reject-Contact", "j" }, 04240 { "Request-Disposition", "d" }, 04241 { "Session-Expires", "x" }, 04242 { "Identity", "y" }, 04243 { "Identity-Info", "n" }, 04244 }; 04245 int x; 04246 04247 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04248 if (!strcasecmp(aliases[x].fullname, name)) 04249 return aliases[x].shortname; 04250 04251 return _default; 04252 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static, read] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4576 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, FALSE, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_ACK, sip_alloc(), sip_methods, SIP_NOTIFY, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, and transmit_response_using_temp().
Referenced by sipsock_read().
04577 { 04578 struct sip_pvt *p = NULL; 04579 char *tag = ""; /* note, tag is never NULL */ 04580 char totag[128]; 04581 char fromtag[128]; 04582 const char *callid = get_header(req, "Call-ID"); 04583 const char *from = get_header(req, "From"); 04584 const char *to = get_header(req, "To"); 04585 const char *cseq = get_header(req, "Cseq"); 04586 04587 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04588 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04589 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04590 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04591 return NULL; /* Invalid packet */ 04592 04593 if (pedanticsipchecking) { 04594 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04595 we need more to identify a branch - so we have to check branch, from 04596 and to tags to identify a call leg. 04597 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04598 in sip.conf 04599 */ 04600 if (gettag(req, "To", totag, sizeof(totag))) 04601 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04602 gettag(req, "From", fromtag, sizeof(fromtag)); 04603 04604 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04605 04606 if (option_debug > 4 ) 04607 ast_log(LOG_DEBUG, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag); 04608 } 04609 04610 ast_mutex_lock(&iflock); 04611 for (p = iflist; p; p = p->next) { 04612 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04613 int found = FALSE; 04614 if (ast_strlen_zero(p->callid)) 04615 continue; 04616 if (req->method == SIP_REGISTER) 04617 found = (!strcmp(p->callid, callid)); 04618 else 04619 found = (!strcmp(p->callid, callid) && 04620 (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04621 04622 if (option_debug > 4) 04623 ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag); 04624 04625 /* If we get a new request within an existing to-tag - check the to tag as well */ 04626 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04627 if (p->tag[0] == '\0' && totag[0]) { 04628 /* We have no to tag, but they have. Wrong dialog */ 04629 found = FALSE; 04630 } else if (totag[0]) { /* Both have tags, compare them */ 04631 if (strcmp(totag, p->tag)) { 04632 found = FALSE; /* This is not our packet */ 04633 } 04634 } 04635 if (!found && option_debug > 4) 04636 ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text); 04637 } 04638 04639 04640 if (found) { 04641 /* Found the call */ 04642 ast_mutex_lock(&p->lock); 04643 ast_mutex_unlock(&iflock); 04644 return p; 04645 } 04646 } 04647 ast_mutex_unlock(&iflock); 04648 04649 /* See if the method is capable of creating a dialog */ 04650 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04651 if (intended_method == SIP_REFER) { 04652 /* We do support REFER, but not outside of a dialog yet */ 04653 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04654 } else if (intended_method == SIP_NOTIFY) { 04655 /* We do not support out-of-dialog NOTIFY either, 04656 like voicemail notification, so cancel that early */ 04657 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04658 } else { 04659 /* Ok, time to create a new SIP dialog object, a pvt */ 04660 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04661 /* Ok, we've created a dialog, let's go and process it */ 04662 ast_mutex_lock(&p->lock); 04663 } else { 04664 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04665 getting a dialog from sip_alloc. 04666 04667 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04668 send an error message. 04669 04670 Sorry, we apologize for the inconvienience 04671 */ 04672 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04673 if (option_debug > 3) 04674 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04675 } 04676 } 04677 return p; 04678 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04679 /* A method we do not support, let's take it on the volley */ 04680 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04681 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04682 /* This is a request outside of a dialog that we don't know about 04683 ...never reply to an ACK! 04684 */ 04685 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04686 } 04687 /* We do not respond to responses for dialogs that we don't know about, we just drop 04688 the session quickly */ 04689 04690 return p; 04691 }
static const char* find_closing_quote | ( | const char * | start, | |
const char * | lim | |||
) | [static] |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
Definition at line 2313 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02314 { 02315 char last_char = '\0'; 02316 const char *s; 02317 for (s = start; *s && s != lim; last_char = *s++) { 02318 if (*s == '"' && last_char != '\\') 02319 break; 02320 } 02321 return s; 02322 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static, read] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2662 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02663 { 02664 struct sip_peer *p = NULL; 02665 02666 if (peer) 02667 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02668 else 02669 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02670 02671 if (!p && realtime) 02672 p = realtime_peer(peer, sin); 02673 02674 return p; 02675 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static, read] |
Find authentication for a specific realm.
Definition at line 16451 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16452 { 16453 struct sip_auth *a; 16454 16455 for (a = authlist; a; a = a->next) { 16456 if (!strcasecmp(a->realm, realm)) 16457 break; 16458 } 16459 16460 return a; 16461 }
static int find_sdp | ( | struct sip_request * | req | ) | [static] |
Determine whether a SIP message contains an SDP in its body.
req | the SIP request to process |
Definition at line 4897 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, LOG_WARNING, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
04898 { 04899 const char *content_type; 04900 const char *content_length; 04901 const char *search; 04902 char *boundary; 04903 unsigned int x; 04904 int boundaryisquoted = FALSE; 04905 int found_application_sdp = FALSE; 04906 int found_end_of_headers = FALSE; 04907 04908 content_length = get_header(req, "Content-Length"); 04909 04910 if (!ast_strlen_zero(content_length)) { 04911 if (sscanf(content_length, "%ud", &x) != 1) { 04912 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04913 return 0; 04914 } 04915 04916 /* Content-Length of zero means there can't possibly be an 04917 SDP here, even if the Content-Type says there is */ 04918 if (x == 0) 04919 return 0; 04920 } 04921 04922 content_type = get_header(req, "Content-Type"); 04923 04924 /* if the body contains only SDP, this is easy */ 04925 if (!strcasecmp(content_type, "application/sdp")) { 04926 req->sdp_start = 0; 04927 req->sdp_end = req->lines; 04928 return req->lines ? 1 : 0; 04929 } 04930 04931 /* if it's not multipart/mixed, there cannot be an SDP */ 04932 if (strncasecmp(content_type, "multipart/mixed", 15)) 04933 return 0; 04934 04935 /* if there is no boundary marker, it's invalid */ 04936 if ((search = strcasestr(content_type, ";boundary="))) 04937 search += 10; 04938 else if ((search = strcasestr(content_type, "; boundary="))) 04939 search += 11; 04940 else 04941 return 0; 04942 04943 if (ast_strlen_zero(search)) 04944 return 0; 04945 04946 /* If the boundary is quoted with ", remove quote */ 04947 if (*search == '\"') { 04948 search++; 04949 boundaryisquoted = TRUE; 04950 } 04951 04952 /* make a duplicate of the string, with two extra characters 04953 at the beginning */ 04954 boundary = ast_strdupa(search - 2); 04955 boundary[0] = boundary[1] = '-'; 04956 /* Remove final quote */ 04957 if (boundaryisquoted) 04958 boundary[strlen(boundary) - 1] = '\0'; 04959 04960 /* search for the boundary marker, the empty line delimiting headers from 04961 sdp part and the end boundry if it exists */ 04962 04963 for (x = 0; x < (req->lines ); x++) { 04964 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04965 if(found_application_sdp && found_end_of_headers){ 04966 req->sdp_end = x-1; 04967 return 1; 04968 } 04969 found_application_sdp = FALSE; 04970 } 04971 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04972 found_application_sdp = TRUE; 04973 04974 if(strlen(req->line[x]) == 0 ){ 04975 if(found_application_sdp && !found_end_of_headers){ 04976 req->sdp_start = x; 04977 found_end_of_headers = TRUE; 04978 } 04979 } 04980 } 04981 if(found_application_sdp && found_end_of_headers) { 04982 req->sdp_end = x; 04983 return TRUE; 04984 } 04985 return FALSE; 04986 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1678 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01679 { 01680 int i, res = 0; 01681 01682 if (ast_strlen_zero(msg)) 01683 return 0; 01684 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01685 if (method_match(i, msg)) 01686 res = sip_methods[i].id; 01687 } 01688 return res; 01689 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 10830 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10831 { 10832 int i; 10833 10834 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10835 if (subscription_types[i].type == subtype) { 10836 return &subscription_types[i]; 10837 } 10838 } 10839 return &subscription_types[0]; 10840 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2741 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02742 { 02743 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02744 if (!u && realtime) 02745 u = realtime_user(name); 02746 return u; 02747 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8274 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08275 { 08276 struct sip_route *next; 08277 08278 while (route) { 08279 next = route->next; 08280 free(route); 08281 route = next; 08282 } 08283 }
static int func_check_sipdomain | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Dial plan function to check if domain is local.
Definition at line 11839 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11840 { 11841 if (ast_strlen_zero(data)) { 11842 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11843 return -1; 11844 } 11845 if (check_sip_domain(data, NULL, 0)) 11846 ast_copy_string(buf, data, len); 11847 else 11848 buf[0] = '\0'; 11849 return 0; 11850 }
static int func_header_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Read SIP header (dialplan function).
Definition at line 11775 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11776 { 11777 struct sip_pvt *p; 11778 const char *content = NULL; 11779 AST_DECLARE_APP_ARGS(args, 11780 AST_APP_ARG(header); 11781 AST_APP_ARG(number); 11782 ); 11783 int i, number, start = 0; 11784 11785 if (ast_strlen_zero(data)) { 11786 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11787 return -1; 11788 } 11789 11790 ast_channel_lock(chan); 11791 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11792 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11793 ast_channel_unlock(chan); 11794 return -1; 11795 } 11796 11797 AST_STANDARD_APP_ARGS(args, data); 11798 if (!args.number) { 11799 number = 1; 11800 } else { 11801 sscanf(args.number, "%d", &number); 11802 if (number < 1) 11803 number = 1; 11804 } 11805 11806 p = chan->tech_pvt; 11807 11808 /* If there is no private structure, this channel is no longer alive */ 11809 if (!p) { 11810 ast_channel_unlock(chan); 11811 return -1; 11812 } 11813 11814 for (i = 0; i < number; i++) 11815 content = __get_header(&p->initreq, args.header, &start); 11816 11817 if (ast_strlen_zero(content)) { 11818 ast_channel_unlock(chan); 11819 return -1; 11820 } 11821 11822 ast_copy_string(buf, content, len); 11823 ast_channel_unlock(chan); 11824 11825 return 0; 11826 }
static int function_sipchaninfo_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${SIPCHANINFO()} Dialplan function - reads sip channel data
Definition at line 11954 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.
11955 { 11956 struct sip_pvt *p; 11957 11958 *buf = 0; 11959 11960 if (!data) { 11961 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11962 return -1; 11963 } 11964 11965 ast_channel_lock(chan); 11966 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11967 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11968 ast_channel_unlock(chan); 11969 return -1; 11970 } 11971 11972 p = chan->tech_pvt; 11973 11974 /* If there is no private structure, this channel is no longer alive */ 11975 if (!p) { 11976 ast_channel_unlock(chan); 11977 return -1; 11978 } 11979 11980 if (!strcasecmp(data, "peerip")) { 11981 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11982 } else if (!strcasecmp(data, "recvip")) { 11983 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11984 } else if (!strcasecmp(data, "from")) { 11985 ast_copy_string(buf, p->from, len); 11986 } else if (!strcasecmp(data, "uri")) { 11987 ast_copy_string(buf, p->uri, len); 11988 } else if (!strcasecmp(data, "useragent")) { 11989 ast_copy_string(buf, p->useragent, len); 11990 } else if (!strcasecmp(data, "peername")) { 11991 ast_copy_string(buf, p->peername, len); 11992 } else if (!strcasecmp(data, "t38passthrough")) { 11993 if (p->t38.state == T38_DISABLED) 11994 ast_copy_string(buf, "0", sizeof("0")); 11995 else /* T38 is offered or enabled in this call */ 11996 ast_copy_string(buf, "1", sizeof("1")); 11997 } else { 11998 ast_channel_unlock(chan); 11999 return -1; 12000 } 12001 ast_channel_unlock(chan); 12002 12003 return 0; 12004 }
static int function_sippeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${SIPPEER()} Dialplan function - reads peer data
Definition at line 11864 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, strsep(), and sip_peer::useragent.
11865 { 11866 struct sip_peer *peer; 11867 char *colname; 11868 11869 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11870 *colname++ = '\0'; 11871 else if ((colname = strchr(data, '|'))) 11872 *colname++ = '\0'; 11873 else 11874 colname = "ip"; 11875 11876 if (!(peer = find_peer(data, NULL, 1))) 11877 return -1; 11878 11879 if (!strcasecmp(colname, "ip")) { 11880 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11881 } else if (!strcasecmp(colname, "status")) { 11882 peer_status(peer, buf, len); 11883 } else if (!strcasecmp(colname, "language")) { 11884 ast_copy_string(buf, peer->language, len); 11885 } else if (!strcasecmp(colname, "regexten")) { 11886 ast_copy_string(buf, peer->regexten, len); 11887 } else if (!strcasecmp(colname, "limit")) { 11888 snprintf(buf, len, "%d", peer->call_limit); 11889 } else if (!strcasecmp(colname, "curcalls")) { 11890 snprintf(buf, len, "%d", peer->inUse); 11891 } else if (!strcasecmp(colname, "accountcode")) { 11892 ast_copy_string(buf, peer->accountcode, len); 11893 } else if (!strcasecmp(colname, "useragent")) { 11894 ast_copy_string(buf, peer->useragent, len); 11895 } else if (!strcasecmp(colname, "mailbox")) { 11896 ast_copy_string(buf, peer->mailbox, len); 11897 } else if (!strcasecmp(colname, "context")) { 11898 ast_copy_string(buf, peer->context, len); 11899 } else if (!strcasecmp(colname, "expire")) { 11900 snprintf(buf, len, "%d", peer->expire); 11901 } else if (!strcasecmp(colname, "dynamic")) { 11902 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11903 } else if (!strcasecmp(colname, "callerid_name")) { 11904 ast_copy_string(buf, peer->cid_name, len); 11905 } else if (!strcasecmp(colname, "callerid_num")) { 11906 ast_copy_string(buf, peer->cid_num, len); 11907 } else if (!strcasecmp(colname, "codecs")) { 11908 ast_getformatname_multiple(buf, len -1, peer->capability); 11909 } else if (!strncasecmp(colname, "codec[", 6)) { 11910 char *codecnum; 11911 int index = 0, codec = 0; 11912 11913 codecnum = colname + 6; /* move past the '[' */ 11914 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11915 index = atoi(codecnum); 11916 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11917 ast_copy_string(buf, ast_getformatname(codec), len); 11918 } 11919 } 11920 11921 ASTOBJ_UNREF(peer, sip_destroy_peer); 11922 11923 return 0; 11924 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4407 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04408 { 04409 long val[4]; 04410 int x; 04411 04412 for (x=0; x<4; x++) 04413 val[x] = ast_random(); 04414 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04415 04416 return buf; 04417 }
static int get_also_info | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Call transfer support (old way, deprecated by the IETF)--.
Definition at line 9197 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), domain::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
09198 { 09199 char tmp[256] = "", *c, *a; 09200 struct sip_request *req = oreq ? oreq : &p->initreq; 09201 struct sip_refer *referdata = NULL; 09202 const char *transfer_context = NULL; 09203 09204 if (!p->refer && !sip_refer_allocate(p)) 09205 return -1; 09206 09207 referdata = p->refer; 09208 09209 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09210 c = get_in_brackets(tmp); 09211 09212 if (pedanticsipchecking) 09213 ast_uri_decode(c); 09214 09215 if (strncasecmp(c, "sip:", 4)) { 09216 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09217 return -1; 09218 } 09219 c += 4; 09220 if ((a = strchr(c, ';'))) /* Remove arguments */ 09221 *a = '\0'; 09222 09223 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09224 *a++ = '\0'; 09225 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09226 } 09227 09228 if (sip_debug_test_pvt(p)) 09229 ast_verbose("Looking for %s in %s\n", c, p->context); 09230 09231 if (p->owner) /* Mimic behaviour in res_features.c */ 09232 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09233 09234 /* By default, use the context in the channel sending the REFER */ 09235 if (ast_strlen_zero(transfer_context)) { 09236 transfer_context = S_OR(p->owner->macrocontext, 09237 S_OR(p->context, default_context)); 09238 } 09239 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09240 /* This is a blind transfer */ 09241 if (option_debug) 09242 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09243 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09244 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09245 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09246 referdata->refer_call = NULL; 09247 /* Set new context */ 09248 ast_string_field_set(p, context, transfer_context); 09249 return 0; 09250 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09251 return 1; 09252 } 09253 09254 return -1; 09255 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4201 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04202 { 04203 int x; 04204 int len = strlen(name); 04205 char *r; 04206 04207 for (x = 0; x < req->lines; x++) { 04208 r = get_body_by_line(req->line[x], name, len); 04209 if (r[0] != '\0') 04210 return r; 04211 } 04212 04213 return ""; 04214 }
static char* get_body_by_line | ( | const char * | line, | |
const char * | name, | |||
int | nameLen | |||
) | [static] |
Reads one line of SIP message body.
Definition at line 4167 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04168 { 04169 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04170 return ast_skip_blanks(line + nameLen + 1); 04171 04172 return ""; 04173 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9309 of file chan_sip.c.
Referenced by check_user_full().
09310 { 09311 const char *end = strchr(input,'<'); /* first_bracket */ 09312 const char *tmp = strchr(input,'"'); /* first quote */ 09313 int bytes = 0; 09314 int maxbytes = outputsize - 1; 09315 09316 if (!end || end == input) /* we require a part in brackets */ 09317 return NULL; 09318 09319 end--; /* move just before "<" */ 09320 09321 if (tmp && tmp <= end) { 09322 /* The quote (tmp) precedes the bracket (end+1). 09323 * Find the matching quote and return the content. 09324 */ 09325 end = strchr(tmp+1, '"'); 09326 if (!end) 09327 return NULL; 09328 bytes = (int) (end - tmp); 09329 /* protect the output buffer */ 09330 if (bytes > maxbytes) 09331 bytes = maxbytes; 09332 ast_copy_string(output, tmp + 1, bytes); 09333 } else { 09334 /* No quoted string, or it is inside brackets. */ 09335 /* clear the empty characters in the begining*/ 09336 input = ast_skip_blanks(input); 09337 /* clear the empty characters in the end */ 09338 while(*end && *end < 33 && end > input) 09339 end--; 09340 if (end >= input) { 09341 bytes = (int) (end - input) + 2; 09342 /* protect the output buffer */ 09343 if (bytes > maxbytes) 09344 bytes = maxbytes; 09345 ast_copy_string(output, input, bytes); 09346 } else 09347 return NULL; 09348 } 09349 return output; 09350 }
static int get_destination | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Find out who the call is for We use the INVITE uri to find out.
Definition at line 8854 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), domain::context, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08855 { 08856 char tmp[256] = "", *uri, *a; 08857 char tmpf[256] = "", *from; 08858 struct sip_request *req; 08859 char *colon; 08860 08861 req = oreq; 08862 if (!req) 08863 req = &p->initreq; 08864 08865 /* Find the request URI */ 08866 if (req->rlPart2) 08867 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08868 08869 if (pedanticsipchecking) 08870 ast_uri_decode(tmp); 08871 08872 uri = get_in_brackets(tmp); 08873 08874 if (strncasecmp(uri, "sip:", 4)) { 08875 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08876 return -1; 08877 } 08878 uri += 4; 08879 08880 /* Now find the From: caller ID and name */ 08881 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08882 if (!ast_strlen_zero(tmpf)) { 08883 if (pedanticsipchecking) 08884 ast_uri_decode(tmpf); 08885 from = get_in_brackets(tmpf); 08886 } else { 08887 from = NULL; 08888 } 08889 08890 if (!ast_strlen_zero(from)) { 08891 if (strncasecmp(from, "sip:", 4)) { 08892 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08893 return -1; 08894 } 08895 from += 4; 08896 if ((a = strchr(from, '@'))) 08897 *a++ = '\0'; 08898 else 08899 a = from; /* just a domain */ 08900 from = strsep(&from, ";"); /* Remove userinfo options */ 08901 a = strsep(&a, ";"); /* Remove URI options */ 08902 ast_string_field_set(p, fromdomain, a); 08903 } 08904 08905 /* Skip any options and find the domain */ 08906 08907 /* Get the target domain */ 08908 if ((a = strchr(uri, '@'))) { 08909 *a++ = '\0'; 08910 } else { /* No username part */ 08911 a = uri; 08912 uri = "s"; /* Set extension to "s" */ 08913 } 08914 colon = strchr(a, ':'); /* Remove :port */ 08915 if (colon) 08916 *colon = '\0'; 08917 08918 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08919 a = strsep(&a, ";"); /* Remove URI options */ 08920 08921 ast_string_field_set(p, domain, a); 08922 08923 if (!AST_LIST_EMPTY(&domain_list)) { 08924 char domain_context[AST_MAX_EXTENSION]; 08925 08926 domain_context[0] = '\0'; 08927 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08928 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08929 if (option_debug) 08930 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08931 return -2; 08932 } 08933 } 08934 /* If we have a context defined, overwrite the original context */ 08935 if (!ast_strlen_zero(domain_context)) 08936 ast_string_field_set(p, context, domain_context); 08937 } 08938 08939 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 08940 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 08941 ast_string_field_set(p, context, p->subscribecontext); 08942 08943 if (sip_debug_test_pvt(p)) 08944 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08945 08946 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 08947 if (req->method == SIP_SUBSCRIBE) { 08948 char hint[AST_MAX_EXTENSION]; 08949 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 08950 } else { 08951 /* Check the dialplan for the username part of the request URI, 08952 the domain will be stored in the SIPDOMAIN variable 08953 Since extensions.conf can have unescaped characters, try matching a decoded 08954 uri in addition to the non-decoded uri 08955 Return 0 if we have a matching extension */ 08956 char *decoded_uri = ast_strdupa(uri); 08957 ast_uri_decode(decoded_uri); 08958 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) || 08959 !strcmp(uri, ast_pickup_ext())) { 08960 if (!oreq) 08961 ast_string_field_set(p, exten, uri); 08962 return 0; 08963 } 08964 } 08965 08966 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08967 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08968 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 08969 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08970 return 1; 08971 } 08972 08973 return -1; 08974 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4290 of file chan_sip.c.
References __get_header().
04291 { 04292 int start = 0; 04293 return __get_header(req, name, &start); 04294 }
static char * get_in_brackets | ( | char * | tmp | ) | [static] |
Pick out text in brackets from character string.
tmp | input string that will be modified Examples: |
Definition at line 2335 of file chan_sip.c.
References ast_log(), find_closing_quote(), LOG_WARNING, and parse().
Referenced by check_user_full(), extract_uri(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), register_verify(), reqprep(), transmit_refer(), and transmit_state_notify().
02336 { 02337 const char *parse = tmp; 02338 char *first_bracket; 02339 02340 /* 02341 * Skip any quoted text until we find the part in brackets. 02342 * On any error give up and return the full string. 02343 */ 02344 while ( (first_bracket = strchr(parse, '<')) ) { 02345 char *first_quote = strchr(parse, '"'); 02346 02347 if (!first_quote || first_quote > first_bracket) 02348 break; /* no need to look at quoted part */ 02349 /* the bracket is within quotes, so ignore it */ 02350 parse = find_closing_quote(first_quote + 1, NULL); 02351 if (!*parse) { /* not found, return full string ? */ 02352 /* XXX or be robust and return in-bracket part ? */ 02353 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02354 break; 02355 } 02356 parse++; 02357 } 02358 if (first_bracket) { 02359 char *second_bracket = strchr(first_bracket + 1, '>'); 02360 if (second_bracket) { 02361 *second_bracket = '\0'; 02362 tmp = first_bracket + 1; 02363 } else { 02364 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02365 } 02366 } 02367 return tmp; 02368 }
static int get_msg_text | ( | char * | buf, | |
int | len, | |||
struct sip_request * | req | |||
) | [static] |
Get text out of a SIP MESSAGE packet.
Definition at line 9715 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09716 { 09717 int x; 09718 int y; 09719 09720 buf[0] = '\0'; 09721 y = len - strlen(buf) - 5; 09722 if (y < 0) 09723 y = 0; 09724 for (x=0;x<req->lines;x++) { 09725 strncat(buf, req->line[x], y); /* safe */ 09726 y -= strlen(req->line[x]) + 1; 09727 if (y < 0) 09728 y = 0; 09729 if (y != 0) 09730 strcat(buf, "\n"); /* safe */ 09731 } 09732 return 0; 09733 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8825 of file chan_sip.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08826 { 08827 char tmp[256], *c, *a; 08828 struct sip_request *req; 08829 08830 req = oreq; 08831 if (!req) 08832 req = &p->initreq; 08833 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08834 if (ast_strlen_zero(tmp)) 08835 return 0; 08836 c = get_in_brackets(tmp); 08837 if (strncasecmp(c, "sip:", 4)) { 08838 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08839 return -1; 08840 } 08841 c += 4; 08842 a = c; 08843 strsep(&a, "@;"); /* trim anything after @ or ; */ 08844 if (sip_debug_test_pvt(p)) 08845 ast_verbose("RDNIS is %s\n", c); 08846 ast_string_field_set(p, rdnis, c); 08847 08848 return 0; 08849 }
static int get_refer_info | ( | struct sip_pvt * | transferer, | |
struct sip_request * | outgoing_req | |||
) | [static] |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
Definition at line 9031 of file chan_sip.c.
References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
09032 { 09033 09034 const char *p_referred_by = NULL; 09035 char *h_refer_to = NULL; 09036 char *h_referred_by = NULL; 09037 char *refer_to; 09038 const char *p_refer_to; 09039 char *referred_by_uri = NULL; 09040 char *ptr; 09041 struct sip_request *req = NULL; 09042 const char *transfer_context = NULL; 09043 struct sip_refer *referdata; 09044 09045 09046 req = outgoing_req; 09047 referdata = transferer->refer; 09048 09049 if (!req) 09050 req = &transferer->initreq; 09051 09052 p_refer_to = get_header(req, "Refer-To"); 09053 if (ast_strlen_zero(p_refer_to)) { 09054 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09055 return -2; /* Syntax error */ 09056 } 09057 h_refer_to = ast_strdupa(p_refer_to); 09058 refer_to = get_in_brackets(h_refer_to); 09059 if (pedanticsipchecking) 09060 ast_uri_decode(refer_to); 09061 09062 if (strncasecmp(refer_to, "sip:", 4)) { 09063 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09064 return -3; 09065 } 09066 refer_to += 4; /* Skip sip: */ 09067 09068 /* Get referred by header if it exists */ 09069 p_referred_by = get_header(req, "Referred-By"); 09070 if (!ast_strlen_zero(p_referred_by)) { 09071 char *lessthan; 09072 h_referred_by = ast_strdupa(p_referred_by); 09073 if (pedanticsipchecking) 09074 ast_uri_decode(h_referred_by); 09075 09076 /* Store referrer's caller ID name */ 09077 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09078 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09079 *(lessthan - 1) = '\0'; /* Space */ 09080 } 09081 09082 referred_by_uri = get_in_brackets(h_referred_by); 09083 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09084 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09085 referred_by_uri = (char *) NULL; 09086 } else { 09087 referred_by_uri += 4; /* Skip sip: */ 09088 } 09089 } 09090 09091 /* Check for arguments in the refer_to header */ 09092 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09093 *ptr++ = '\0'; 09094 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09095 char *to = NULL, *from = NULL; 09096 09097 /* This is an attended transfer */ 09098 referdata->attendedtransfer = 1; 09099 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09100 ast_uri_decode(referdata->replaces_callid); 09101 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09102 *ptr++ = '\0'; 09103 } 09104 09105 if (ptr) { 09106 /* Find the different tags before we destroy the string */ 09107 to = strcasestr(ptr, "to-tag="); 09108 from = strcasestr(ptr, "from-tag="); 09109 } 09110 09111 /* Grab the to header */ 09112 if (to) { 09113 ptr = to + 7; 09114 if ((to = strchr(ptr, '&'))) 09115 *to = '\0'; 09116 if ((to = strchr(ptr, ';'))) 09117 *to = '\0'; 09118 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09119 } 09120 09121 if (from) { 09122 ptr = from + 9; 09123 if ((to = strchr(ptr, '&'))) 09124 *to = '\0'; 09125 if ((to = strchr(ptr, ';'))) 09126 *to = '\0'; 09127 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09128 } 09129 09130 if (option_debug > 1) { 09131 if (!pedanticsipchecking) 09132 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09133 else 09134 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" ); 09135 } 09136 } 09137 } 09138 09139 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09140 char *urioption = NULL, *domain; 09141 *ptr++ = '\0'; 09142 09143 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09144 *urioption++ = '\0'; 09145 09146 domain = ptr; 09147 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09148 *ptr = '\0'; 09149 09150 /* Save the domain for the dial plan */ 09151 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09152 if (urioption) 09153 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09154 } 09155 09156 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09157 *ptr = '\0'; 09158 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09159 09160 if (referred_by_uri) { 09161 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09162 *ptr = '\0'; 09163 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09164 } else { 09165 referdata->referred_by[0] = '\0'; 09166 } 09167 09168 /* Determine transfer context */ 09169 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09170 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09171 09172 /* By default, use the context in the channel sending the REFER */ 09173 if (ast_strlen_zero(transfer_context)) { 09174 transfer_context = S_OR(transferer->owner->macrocontext, 09175 S_OR(transferer->context, default_context)); 09176 } 09177 09178 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09179 09180 /* Either an existing extension or the parking extension */ 09181 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09182 if (sip_debug_test_pvt(transferer)) { 09183 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09184 } 09185 /* We are ready to transfer to the extension */ 09186 return 0; 09187 } 09188 if (sip_debug_test_pvt(transferer)) 09189 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09190 09191 /* Failure, we can't find this extension */ 09192 return -1; 09193 }
static int get_rpid_num | ( | const char * | input, | |
char * | output, | |||
int | maxlen | |||
) | [static] |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
Definition at line 9356 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09357 { 09358 char *start; 09359 char *end; 09360 09361 start = strchr(input,':'); 09362 if (!start) { 09363 output[0] = '\0'; 09364 return 0; 09365 } 09366 start++; 09367 09368 /* we found "number" */ 09369 ast_copy_string(output,start,maxlen); 09370 output[maxlen-1] = '\0'; 09371 09372 end = strchr(output,'@'); 09373 if (end) 09374 *end = '\0'; 09375 else 09376 output[0] = '\0'; 09377 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09378 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09379 09380 return 0; 09381 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4193 of file chan_sip.c.
References get_sdp_iterate().
04194 { 04195 int dummy = 0; 04196 04197 return get_sdp_iterate(&dummy, req, name); 04198 }
static const char * get_sdp_iterate | ( | int * | start, | |
struct sip_request * | req, | |||
const char * | name | |||
) | [static] |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
Definition at line 4179 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04180 { 04181 int len = strlen(name); 04182 04183 while (*start < req->sdp_end) { 04184 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04185 if (r[0] != '\0') 04186 return r; 04187 } 04188 04189 return ""; 04190 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static, read] |
Lock interface lock and find matching pvt lock
Definition at line 8981 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_OUTGOING, and sip_pvt::tag.
Referenced by handle_request_invite(), and local_attended_transfer().
08982 { 08983 struct sip_pvt *sip_pvt_ptr; 08984 08985 ast_mutex_lock(&iflock); 08986 08987 if (option_debug > 3 && totag) 08988 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08989 08990 /* Search interfaces and find the match */ 08991 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08992 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08993 int match = 1; 08994 char *ourtag = sip_pvt_ptr->tag; 08995 08996 /* Go ahead and lock it (and its owner) before returning */ 08997 ast_mutex_lock(&sip_pvt_ptr->lock); 08998 08999 /* Check if tags match. If not, this is not the call we want 09000 (With a forking SIP proxy, several call legs share the 09001 call id, but have different tags) 09002 */ 09003 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 09004 match = 0; 09005 09006 if (!match) { 09007 ast_mutex_unlock(&sip_pvt_ptr->lock); 09008 continue; 09009 } 09010 09011 if (option_debug > 3 && totag) 09012 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09013 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 09014 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09015 09016 /* deadlock avoidance... */ 09017 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09018 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09019 } 09020 break; 09021 } 09022 } 09023 ast_mutex_unlock(&iflock); 09024 if (option_debug > 3 && !sip_pvt_ptr) 09025 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09026 return sip_pvt_ptr; 09027 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13408 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13409 { 13410 const char *thetag; 13411 13412 if (!tagbuf) 13413 return NULL; 13414 tagbuf[0] = '\0'; /* reset the buffer */ 13415 thetag = get_header(req, header); 13416 thetag = strcasestr(thetag, ";tag="); 13417 if (thetag) { 13418 thetag += 5; 13419 ast_copy_string(tagbuf, thetag, tagbufsize); 13420 return strsep(&tagbuf, ";"); 13421 } 13422 return NULL; 13423 }
static int handle_common_options | ( | struct ast_flags * | flags, | |
struct ast_flags * | mask, | |||
struct ast_variable * | v | |||
) | [static] |
Handle flag-type options common to configuration of devices - users and peers.
flags | array of two struct ast_flags | |
mask | array of two struct ast_flags | |
v | linked list of config variables to process |
Definition at line 16200 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_UDPTL_DESTINATION, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
16201 { 16202 int res = 1; 16203 16204 if (!strcasecmp(v->name, "trustrpid")) { 16205 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16206 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16207 } else if (!strcasecmp(v->name, "sendrpid")) { 16208 ast_set_flag(&mask[0], SIP_SENDRPID); 16209 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16210 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16211 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16212 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16213 } else if (!strcasecmp(v->name, "useclientcode")) { 16214 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16215 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16216 } else if (!strcasecmp(v->name, "dtmfmode")) { 16217 ast_set_flag(&mask[0], SIP_DTMF); 16218 ast_clear_flag(&flags[0], SIP_DTMF); 16219 if (!strcasecmp(v->value, "inband")) 16220 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16221 else if (!strcasecmp(v->value, "rfc2833")) 16222 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16223 else if (!strcasecmp(v->value, "info")) 16224 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16225 else if (!strcasecmp(v->value, "auto")) 16226 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16227 else { 16228 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16229 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16230 } 16231 } else if (!strcasecmp(v->name, "nat")) { 16232 ast_set_flag(&mask[0], SIP_NAT); 16233 ast_clear_flag(&flags[0], SIP_NAT); 16234 if (!strcasecmp(v->value, "never")) 16235 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16236 else if (!strcasecmp(v->value, "route")) 16237 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16238 else if (ast_true(v->value)) 16239 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16240 else 16241 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16242 } else if (!strcasecmp(v->name, "canreinvite")) { 16243 ast_set_flag(&mask[0], SIP_REINVITE); 16244 ast_clear_flag(&flags[0], SIP_REINVITE); 16245 if(ast_true(v->value)) { 16246 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16247 } else if (!ast_false(v->value)) { 16248 char buf[64]; 16249 char *word, *next = buf; 16250 16251 ast_copy_string(buf, v->value, sizeof(buf)); 16252 while ((word = strsep(&next, ","))) { 16253 if(!strcasecmp(word, "update")) { 16254 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16255 } else if(!strcasecmp(word, "nonat")) { 16256 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16257 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16258 } else { 16259 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16260 } 16261 } 16262 } 16263 } else if (!strcasecmp(v->name, "insecure")) { 16264 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16265 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16266 set_insecure_flags(flags, v->value, v->lineno); 16267 } else if (!strcasecmp(v->name, "progressinband")) { 16268 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16269 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16270 if (ast_true(v->value)) 16271 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16272 else if (strcasecmp(v->value, "never")) 16273 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16274 } else if (!strcasecmp(v->name, "promiscredir")) { 16275 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16276 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16277 } else if (!strcasecmp(v->name, "videosupport")) { 16278 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16279 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16280 } else if (!strcasecmp(v->name, "allowoverlap")) { 16281 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16282 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16283 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16284 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16285 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16286 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16287 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16288 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16289 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16290 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16291 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16292 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16293 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16294 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16295 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16296 #endif 16297 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16298 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16299 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16300 } else if (!strcasecmp(v->name, "buggymwi")) { 16301 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16302 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16303 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16304 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16305 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16306 } else 16307 res = 0; 16308 16309 return res; 16310 }
static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
Definition at line 13587 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13588 { 13589 struct ast_frame *f; 13590 int earlyreplace = 0; 13591 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13592 struct ast_channel *c = p->owner; /* Our incoming call */ 13593 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13594 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13595 13596 /* Check if we're in ring state */ 13597 if (replacecall->_state == AST_STATE_RING) 13598 earlyreplace = 1; 13599 13600 /* Check if we have a bridge */ 13601 if (!(targetcall = ast_bridged_channel(replacecall))) { 13602 /* We have no bridge */ 13603 if (!earlyreplace) { 13604 if (option_debug > 1) 13605 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13606 oneleggedreplace = 1; 13607 } 13608 } 13609 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13610 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13611 13612 if (option_debug > 3) { 13613 if (targetcall) 13614 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 13615 else 13616 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13617 } 13618 13619 if (ignore) { 13620 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13621 /* We should answer something here. If we are here, the 13622 call we are replacing exists, so an accepted 13623 can't harm */ 13624 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13625 /* Do something more clever here */ 13626 ast_channel_unlock(c); 13627 ast_mutex_unlock(&p->refer->refer_call->lock); 13628 return 1; 13629 } 13630 if (!c) { 13631 /* What to do if no channel ??? */ 13632 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13633 transmit_response_reliable(p, "503 Service Unavailable", req); 13634 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13635 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13636 ast_mutex_unlock(&p->refer->refer_call->lock); 13637 return 1; 13638 } 13639 append_history(p, "Xfer", "INVITE/Replace received"); 13640 /* We have three channels to play with 13641 channel c: New incoming call 13642 targetcall: Call from PBX to target 13643 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13644 replacecall: The owner of the previous 13645 We need to masq C into refer_call to connect to 13646 targetcall; 13647 If we are talking to internal audio stream, target call is null. 13648 */ 13649 13650 /* Fake call progress */ 13651 transmit_response(p, "100 Trying", req); 13652 ast_setstate(c, AST_STATE_RING); 13653 13654 /* Masquerade the new call into the referred call to connect to target call 13655 Targetcall is not touched by the masq */ 13656 13657 /* Answer the incoming call and set channel to UP state */ 13658 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13659 13660 ast_setstate(c, AST_STATE_UP); 13661 13662 /* Stop music on hold and other generators */ 13663 ast_quiet_chan(replacecall); 13664 ast_quiet_chan(targetcall); 13665 if (option_debug > 3) 13666 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13667 /* Unlock clone, but not original (replacecall) */ 13668 if (!oneleggedreplace) 13669 ast_channel_unlock(c); 13670 13671 /* Unlock PVT */ 13672 ast_mutex_unlock(&p->refer->refer_call->lock); 13673 13674 /* Make sure that the masq does not free our PVT for the old call */ 13675 if (! earlyreplace && ! oneleggedreplace ) 13676 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13677 13678 /* Prepare the masquerade - if this does not happen, we will be gone */ 13679 if(ast_channel_masquerade(replacecall, c)) 13680 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13681 else if (option_debug > 3) 13682 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13683 13684 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13685 13686 /* C should now be in place of replacecall */ 13687 /* ast_read needs to lock channel */ 13688 ast_channel_unlock(c); 13689 13690 if (earlyreplace || oneleggedreplace ) { 13691 /* Force the masq to happen */ 13692 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13693 ast_frfree(f); 13694 f = NULL; 13695 if (option_debug > 3) 13696 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13697 } else { 13698 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13699 } 13700 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13701 if (!oneleggedreplace) 13702 ast_channel_unlock(replacecall); 13703 } else { /* Bridged call, UP channel */ 13704 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13705 /* Masq ok */ 13706 ast_frfree(f); 13707 f = NULL; 13708 if (option_debug > 2) 13709 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13710 } else { 13711 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13712 } 13713 ast_channel_unlock(replacecall); 13714 } 13715 ast_mutex_unlock(&p->refer->refer_call->lock); 13716 13717 ast_setstate(c, AST_STATE_DOWN); 13718 if (option_debug > 3) { 13719 struct ast_channel *test; 13720 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13721 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13722 if (replacecall) 13723 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13724 if (p->owner) { 13725 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13726 test = ast_bridged_channel(p->owner); 13727 if (test) 13728 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13729 else 13730 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13731 } else 13732 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13733 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13734 } 13735 13736 ast_channel_unlock(p->owner); /* Unlock new owner */ 13737 if (!oneleggedreplace) 13738 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13739 13740 /* The call should be down with no ast_channel, so hang it up */ 13741 c->tech_pvt = NULL; 13742 ast_hangup(c); 13743 return 0; 13744 }
static int handle_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Handle incoming SIP requests (methods).
Definition at line 15258 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_pvt::lastnoninvite, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
15259 { 15260 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15261 relatively static */ 15262 const char *cmd; 15263 const char *cseq; 15264 const char *useragent; 15265 int seqno; 15266 int len; 15267 int ignore = FALSE; 15268 int respid; 15269 int res = 0; 15270 int debug = sip_debug_test_pvt(p); 15271 char *e; 15272 int error = 0; 15273 15274 /* Get Method and Cseq */ 15275 cseq = get_header(req, "Cseq"); 15276 cmd = req->header[0]; 15277 15278 /* Must have Cseq */ 15279 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15280 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15281 error = 1; 15282 } 15283 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15284 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15285 error = 1; 15286 } 15287 if (error) { 15288 if (!p->initreq.headers) /* New call */ 15289 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15290 return -1; 15291 } 15292 /* Get the command XXX */ 15293 15294 cmd = req->rlPart1; 15295 e = req->rlPart2; 15296 15297 /* Save useragent of the client */ 15298 useragent = get_header(req, "User-Agent"); 15299 if (!ast_strlen_zero(useragent)) 15300 ast_string_field_set(p, useragent, useragent); 15301 15302 /* Find out SIP method for incoming request */ 15303 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15304 /* Response to our request -- Do some sanity checks */ 15305 if (!p->initreq.headers) { 15306 if (option_debug) 15307 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15308 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15309 return 0; 15310 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15311 if (option_debug) 15312 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15313 return -1; 15314 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15315 /* ignore means "don't do anything with it" but still have to 15316 respond appropriately */ 15317 ignore = TRUE; 15318 ast_set_flag(req, SIP_PKT_IGNORE); 15319 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15320 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15321 } else if (e) { 15322 e = ast_skip_blanks(e); 15323 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15324 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15325 } else { 15326 if (respid <= 0) { 15327 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15328 return 0; 15329 } 15330 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15331 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15332 extract_uri(p, req); 15333 handle_response(p, respid, e + len, req, ignore, seqno); 15334 } 15335 } 15336 return 0; 15337 } 15338 15339 /* New SIP request coming in 15340 (could be new request in existing SIP dialog as well...) 15341 */ 15342 15343 p->method = req->method; /* Find out which SIP method they are using */ 15344 if (option_debug > 3) 15345 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15346 15347 if (p->icseq && (p->icseq > seqno) ) { 15348 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15349 if (option_debug > 2) 15350 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15351 } else { 15352 if (option_debug) 15353 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15354 if (req->method != SIP_ACK) 15355 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15356 return -1; 15357 } 15358 } else if (p->icseq && 15359 p->icseq == seqno && 15360 req->method != SIP_ACK && 15361 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15362 /* ignore means "don't do anything with it" but still have to 15363 respond appropriately. We do this if we receive a repeat of 15364 the last sequence number */ 15365 ignore = 2; 15366 ast_set_flag(req, SIP_PKT_IGNORE); 15367 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15368 if (option_debug > 2) 15369 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15370 } 15371 15372 if (seqno >= p->icseq) 15373 /* Next should follow monotonically (but not necessarily 15374 incrementally -- thanks again to the genius authors of SIP -- 15375 increasing */ 15376 p->icseq = seqno; 15377 15378 /* Find their tag if we haven't got it */ 15379 if (ast_strlen_zero(p->theirtag)) { 15380 char tag[128]; 15381 15382 gettag(req, "From", tag, sizeof(tag)); 15383 ast_string_field_set(p, theirtag, tag); 15384 } 15385 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15386 15387 if (pedanticsipchecking) { 15388 /* If this is a request packet without a from tag, it's not 15389 correct according to RFC 3261 */ 15390 /* Check if this a new request in a new dialog with a totag already attached to it, 15391 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15392 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15393 /* If this is a first request and it got a to-tag, it is not for us */ 15394 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15395 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15396 /* Will cease to exist after ACK */ 15397 } else if (req->method != SIP_ACK) { 15398 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15399 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15400 } 15401 return res; 15402 } 15403 } 15404 15405 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15406 transmit_response(p, "400 Bad request", req); 15407 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15408 return -1; 15409 } 15410 15411 /* Handle various incoming SIP methods in requests */ 15412 switch (p->method) { 15413 case SIP_OPTIONS: 15414 res = handle_request_options(p, req); 15415 break; 15416 case SIP_INVITE: 15417 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15418 break; 15419 case SIP_REFER: 15420 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15421 break; 15422 case SIP_CANCEL: 15423 res = handle_request_cancel(p, req); 15424 break; 15425 case SIP_BYE: 15426 res = handle_request_bye(p, req); 15427 break; 15428 case SIP_MESSAGE: 15429 res = handle_request_message(p, req); 15430 break; 15431 case SIP_SUBSCRIBE: 15432 res = handle_request_subscribe(p, req, sin, seqno, e); 15433 break; 15434 case SIP_REGISTER: 15435 res = handle_request_register(p, req, sin, e); 15436 break; 15437 case SIP_INFO: 15438 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15439 ast_verbose("Receiving INFO!\n"); 15440 if (!ignore) 15441 handle_request_info(p, req); 15442 else /* if ignoring, transmit response */ 15443 transmit_response(p, "200 OK", req); 15444 break; 15445 case SIP_NOTIFY: 15446 res = handle_request_notify(p, req, sin, seqno, e); 15447 break; 15448 case SIP_ACK: 15449 /* Make sure we don't ignore this */ 15450 if (seqno == p->pendinginvite) { 15451 p->invitestate = INV_TERMINATED; 15452 p->pendinginvite = 0; 15453 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15454 if (find_sdp(req)) { 15455 if (process_sdp(p, req)) 15456 return -1; 15457 } 15458 check_pendings(p); 15459 } 15460 /* Got an ACK that we did not match. Ignore silently */ 15461 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15462 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15463 break; 15464 default: 15465 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15466 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15467 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15468 /* If this is some new method, and we don't have a call, destroy it now */ 15469 if (!p->initreq.headers) 15470 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15471 break; 15472 } 15473 return res; 15474 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14823 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
14824 { 14825 struct ast_channel *c=NULL; 14826 int res; 14827 struct ast_channel *bridged_to; 14828 14829 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14830 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14831 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14832 14833 p->invitestate = INV_TERMINATED; 14834 14835 copy_request(&p->initreq, req); 14836 check_via(p, req); 14837 sip_alreadygone(p); 14838 14839 /* Get RTCP quality before end of call */ 14840 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14841 char *audioqos, *videoqos; 14842 if (p->rtp) { 14843 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14844 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14845 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14846 if (p->owner) 14847 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14848 } 14849 if (p->vrtp) { 14850 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14851 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14852 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14853 if (p->owner) 14854 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14855 } 14856 } 14857 14858 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14859 14860 if (!ast_strlen_zero(get_header(req, "Also"))) { 14861 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14862 ast_inet_ntoa(p->recv.sin_addr)); 14863 if (ast_strlen_zero(p->context)) 14864 ast_string_field_set(p, context, default_context); 14865 res = get_also_info(p, req); 14866 if (!res) { 14867 c = p->owner; 14868 if (c) { 14869 bridged_to = ast_bridged_channel(c); 14870 if (bridged_to) { 14871 /* Don't actually hangup here... */ 14872 ast_queue_control(c, AST_CONTROL_UNHOLD); 14873 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14874 } else 14875 ast_queue_hangup(p->owner); 14876 } 14877 } else { 14878 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14879 if (p->owner) 14880 ast_queue_hangup(p->owner); 14881 } 14882 } else if (p->owner) { 14883 ast_queue_hangup(p->owner); 14884 if (option_debug > 2) 14885 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14886 } else { 14887 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14888 if (option_debug > 2) 14889 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14890 } 14891 transmit_response(p, "200 OK", req); 14892 14893 return 1; 14894 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14717 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::initreq, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
14718 { 14719 14720 check_via(p, req); 14721 sip_alreadygone(p); 14722 14723 /* At this point, we could have cancelled the invite at the same time 14724 as the other side sends a CANCEL. Our final reply with error code 14725 might not have been received by the other side before the CANCEL 14726 was sent, so let's just give up retransmissions and waiting for 14727 ACK on our error code. The call is hanging up any way. */ 14728 if (p->invitestate == INV_TERMINATED) 14729 __sip_pretend_ack(p); 14730 else 14731 p->invitestate = INV_CANCELLED; 14732 14733 if (p->owner && p->owner->_state == AST_STATE_UP) { 14734 /* This call is up, cancel is ignored, we need a bye */ 14735 transmit_response(p, "200 OK", req); 14736 if (option_debug) 14737 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14738 return 0; 14739 } 14740 14741 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14742 update_call_counter(p, DEC_CALL_LIMIT); 14743 14744 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14745 if (p->owner) 14746 ast_queue_hangup(p->owner); 14747 else 14748 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14749 if (p->initreq.len > 0) { 14750 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14751 transmit_response(p, "200 OK", req); 14752 return 1; 14753 } else { 14754 transmit_response(p, "481 Call Leg Does Not Exist", req); 14755 return 0; 14756 } 14757 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11188 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().
Referenced by handle_request().
11189 { 11190 char buf[1024]; 11191 unsigned int event; 11192 const char *c = get_header(req, "Content-Type"); 11193 11194 /* Need to check the media/type */ 11195 if (!strcasecmp(c, "application/dtmf-relay") || 11196 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11197 unsigned int duration = 0; 11198 11199 /* Try getting the "signal=" part */ 11200 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11201 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11202 transmit_response(p, "200 OK", req); /* Should return error */ 11203 return; 11204 } else { 11205 ast_copy_string(buf, c, sizeof(buf)); 11206 } 11207 11208 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11209 duration = atoi(c); 11210 if (!duration) 11211 duration = 100; /* 100 ms */ 11212 11213 if (!p->owner) { /* not a PBX call */ 11214 transmit_response(p, "481 Call leg/transaction does not exist", req); 11215 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11216 return; 11217 } 11218 11219 if (ast_strlen_zero(buf)) { 11220 transmit_response(p, "200 OK", req); 11221 return; 11222 } 11223 11224 if (buf[0] == '*') 11225 event = 10; 11226 else if (buf[0] == '#') 11227 event = 11; 11228 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11229 event = 12 + buf[0] - 'A'; 11230 else 11231 event = atoi(buf); 11232 if (event == 16) { 11233 /* send a FLASH event */ 11234 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11235 ast_queue_frame(p->owner, &f); 11236 if (sipdebug) 11237 ast_verbose("* DTMF-relay event received: FLASH\n"); 11238 } else { 11239 /* send a DTMF event */ 11240 struct ast_frame f = { AST_FRAME_DTMF, }; 11241 if (event < 10) { 11242 f.subclass = '0' + event; 11243 } else if (event < 11) { 11244 f.subclass = '*'; 11245 } else if (event < 12) { 11246 f.subclass = '#'; 11247 } else if (event < 16) { 11248 f.subclass = 'A' + (event - 12); 11249 } 11250 f.len = duration; 11251 ast_queue_frame(p->owner, &f); 11252 if (sipdebug) 11253 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11254 } 11255 transmit_response(p, "200 OK", req); 11256 return; 11257 } else if (!strcasecmp(c, "application/media_control+xml")) { 11258 /* Eh, we'll just assume it's a fast picture update for now */ 11259 if (p->owner) 11260 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11261 transmit_response(p, "200 OK", req); 11262 return; 11263 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11264 /* Client code (from SNOM phone) */ 11265 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11266 if (p->owner && p->owner->cdr) 11267 ast_cdr_setuserfield(p->owner, c); 11268 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11269 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11270 transmit_response(p, "200 OK", req); 11271 } else { 11272 transmit_response(p, "403 Unauthorized", req); 11273 } 11274 return; 11275 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11276 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11277 transmit_response(p, "200 OK", req); 11278 return; 11279 } 11280 11281 /* Other type of INFO message, not really understood by Asterisk */ 11282 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11283 11284 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11285 transmit_response(p, "415 Unsupported media type", req); 11286 return; 11287 }
static int handle_request_invite | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
char * | e, | |||
int * | nounlock | |||
) | [static] |
Handle incoming INVITE request.
XXX: we should also check here does the other side supports t38 at all !!! XXX
Definition at line 13753 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_SRCCHANGE, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
13754 { 13755 int res = 1; 13756 int gotdest; 13757 const char *p_replaces; 13758 char *replace_id = NULL; 13759 const char *required; 13760 unsigned int required_profile = 0; 13761 struct ast_channel *c = NULL; /* New channel */ 13762 int reinvite = 0; 13763 13764 /* Find out what they support */ 13765 if (!p->sipoptions) { 13766 const char *supported = get_header(req, "Supported"); 13767 if (!ast_strlen_zero(supported)) 13768 parse_sip_options(p, supported); 13769 } 13770 13771 /* Find out what they require */ 13772 required = get_header(req, "Require"); 13773 if (!ast_strlen_zero(required)) { 13774 required_profile = parse_sip_options(NULL, required); 13775 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13776 /* At this point we only support REPLACES */ 13777 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13778 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13779 p->invitestate = INV_COMPLETED; 13780 if (!p->lastinvite) 13781 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13782 return -1; 13783 } 13784 } 13785 13786 /* Check if this is a loop */ 13787 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13788 /* This is a call to ourself. Send ourselves an error code and stop 13789 processing immediately, as SIP really has no good mechanism for 13790 being able to call yourself */ 13791 /* If pedantic is on, we need to check the tags. If they're different, this is 13792 in fact a forked call through a SIP proxy somewhere. */ 13793 transmit_response(p, "482 Loop Detected", req); 13794 p->invitestate = INV_COMPLETED; 13795 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13796 return 0; 13797 } 13798 13799 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13800 /* We already have a pending invite. Sorry. You are on hold. */ 13801 transmit_response(p, "491 Request Pending", req); 13802 if (option_debug) 13803 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13804 /* Don't destroy dialog here */ 13805 return 0; 13806 } 13807 13808 p_replaces = get_header(req, "Replaces"); 13809 if (!ast_strlen_zero(p_replaces)) { 13810 /* We have a replaces header */ 13811 char *ptr; 13812 char *fromtag = NULL; 13813 char *totag = NULL; 13814 char *start, *to; 13815 int error = 0; 13816 13817 if (p->owner) { 13818 if (option_debug > 2) 13819 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13820 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13821 /* Do not destroy existing call */ 13822 return -1; 13823 } 13824 13825 if (sipdebug && option_debug > 2) 13826 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13827 /* Create a buffer we can manipulate */ 13828 replace_id = ast_strdupa(p_replaces); 13829 ast_uri_decode(replace_id); 13830 13831 if (!p->refer && !sip_refer_allocate(p)) { 13832 transmit_response(p, "500 Server Internal Error", req); 13833 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13834 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13835 p->invitestate = INV_COMPLETED; 13836 return -1; 13837 } 13838 13839 /* Todo: (When we find phones that support this) 13840 if the replaces header contains ";early-only" 13841 we can only replace the call in early 13842 stage, not after it's up. 13843 13844 If it's not in early mode, 486 Busy. 13845 */ 13846 13847 /* Skip leading whitespace */ 13848 replace_id = ast_skip_blanks(replace_id); 13849 13850 start = replace_id; 13851 while ( (ptr = strsep(&start, ";")) ) { 13852 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13853 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13854 totag = to + 7; /* skip the keyword */ 13855 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13856 fromtag = to + 9; /* skip the keyword */ 13857 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13858 } 13859 } 13860 13861 if (sipdebug && option_debug > 3) 13862 ast_log(LOG_DEBUG,"Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", replace_id, fromtag ? fromtag : "<no from tag>", totag ? totag : "<no to tag>"); 13863 13864 13865 /* Try to find call that we are replacing 13866 If we have a Replaces header, we need to cancel that call if we succeed with this call 13867 */ 13868 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13869 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13870 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13871 error = 1; 13872 } 13873 13874 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13875 13876 /* The matched call is the call from the transferer to Asterisk . 13877 We want to bridge the bridged part of the call to the 13878 incoming invite, thus taking over the refered call */ 13879 13880 if (p->refer->refer_call == p) { 13881 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13882 p->refer->refer_call = NULL; 13883 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13884 error = 1; 13885 } 13886 13887 if (!error && !p->refer->refer_call->owner) { 13888 /* Oops, someting wrong anyway, no owner, no call */ 13889 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13890 /* Check for better return code */ 13891 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13892 error = 1; 13893 } 13894 13895 if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) { 13896 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13897 transmit_response(p, "603 Declined (Replaces)", req); 13898 error = 1; 13899 } 13900 13901 if (error) { /* Give up this dialog */ 13902 append_history(p, "Xfer", "INVITE/Replace Failed."); 13903 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13904 ast_mutex_unlock(&p->lock); 13905 if (p->refer->refer_call) { 13906 ast_mutex_unlock(&p->refer->refer_call->lock); 13907 ast_channel_unlock(p->refer->refer_call->owner); 13908 } 13909 p->invitestate = INV_COMPLETED; 13910 return -1; 13911 } 13912 } 13913 13914 13915 /* Check if this is an INVITE that sets up a new dialog or 13916 a re-invite in an existing dialog */ 13917 13918 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13919 int newcall = (p->initreq.headers ? TRUE : FALSE); 13920 13921 if (sip_cancel_destroy(p)) 13922 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13923 /* This also counts as a pending invite */ 13924 p->pendinginvite = seqno; 13925 check_via(p, req); 13926 13927 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13928 if (!p->owner) { /* Not a re-invite */ 13929 if (debug) 13930 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13931 if (newcall) 13932 append_history(p, "Invite", "New call: %s", p->callid); 13933 parse_ok_contact(p, req); 13934 } else { /* Re-invite on existing call */ 13935 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13936 /* Handle SDP here if we already have an owner */ 13937 if (find_sdp(req)) { 13938 if (process_sdp(p, req)) { 13939 transmit_response(p, "488 Not acceptable here", req); 13940 if (!p->lastinvite) 13941 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13942 return -1; 13943 } 13944 ast_queue_control(p->owner, AST_CONTROL_SRCCHANGE); 13945 } else { 13946 p->jointcapability = p->capability; 13947 if (option_debug > 2) 13948 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13949 /* Some devices signal they want to be put off hold by sending a re-invite 13950 *without* an SDP, which is supposed to mean "Go back to your state" 13951 and since they put os on remote hold, we go back to off hold */ 13952 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13953 change_hold_state(p, req, FALSE, 0); 13954 } 13955 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13956 append_history(p, "ReInv", "Re-invite received"); 13957 } 13958 } else if (debug) 13959 ast_verbose("Ignoring this INVITE request\n"); 13960 13961 13962 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13963 /* This is a new invite */ 13964 /* Handle authentication if this is our first invite */ 13965 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13966 if (res == AUTH_CHALLENGE_SENT) { 13967 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13968 return 0; 13969 } 13970 if (res < 0) { /* Something failed in authentication */ 13971 if (res == AUTH_FAKE_AUTH) { 13972 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13973 transmit_fake_auth_response(p, req, 1); 13974 } else { 13975 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13976 transmit_response_reliable(p, "403 Forbidden", req); 13977 } 13978 p->invitestate = INV_COMPLETED; 13979 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13980 ast_string_field_free(p, theirtag); 13981 return 0; 13982 } 13983 13984 /* We have a succesful authentication, process the SDP portion if there is one */ 13985 if (find_sdp(req)) { 13986 if (process_sdp(p, req)) { 13987 /* Unacceptable codecs */ 13988 transmit_response_reliable(p, "488 Not acceptable here", req); 13989 p->invitestate = INV_COMPLETED; 13990 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13991 if (option_debug) 13992 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13993 return -1; 13994 } 13995 } else { /* No SDP in invite, call control session */ 13996 p->jointcapability = p->capability; 13997 if (option_debug > 1) 13998 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13999 } 14000 14001 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14002 /* This seems redundant ... see !p-owner above */ 14003 if (p->owner) 14004 ast_queue_frame(p->owner, &ast_null_frame); 14005 14006 14007 /* Initialize the context if it hasn't been already */ 14008 if (ast_strlen_zero(p->context)) 14009 ast_string_field_set(p, context, default_context); 14010 14011 14012 /* Check number of concurrent calls -vs- incoming limit HERE */ 14013 if (option_debug) 14014 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14015 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14016 if (res < 0) { 14017 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14018 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14019 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14020 p->invitestate = INV_COMPLETED; 14021 } 14022 return 0; 14023 } 14024 gotdest = get_destination(p, NULL); /* Get destination right away */ 14025 get_rdnis(p, NULL); /* Get redirect information */ 14026 extract_uri(p, req); /* Get the Contact URI */ 14027 build_contact(p); /* Build our contact header */ 14028 14029 if (p->rtp) { 14030 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14031 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14032 } 14033 14034 if (!replace_id && gotdest) { /* No matching extension found */ 14035 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14036 transmit_response_reliable(p, "484 Address Incomplete", req); 14037 else { 14038 transmit_response_reliable(p, "404 Not Found", req); 14039 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14040 " '%s' rejected because extension not found.\n", 14041 S_OR(p->username, p->peername), p->exten); 14042 } 14043 p->invitestate = INV_COMPLETED; 14044 update_call_counter(p, DEC_CALL_LIMIT); 14045 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14046 return 0; 14047 } else { 14048 /* If no extension was specified, use the s one */ 14049 /* Basically for calling to IP/Host name only */ 14050 if (ast_strlen_zero(p->exten)) 14051 ast_string_field_set(p, exten, "s"); 14052 /* Initialize our tag */ 14053 14054 make_our_tag(p->tag, sizeof(p->tag)); 14055 /* First invitation - create the channel */ 14056 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14057 *recount = 1; 14058 14059 /* Save Record-Route for any later requests we make on this dialogue */ 14060 build_route(p, req, 0); 14061 14062 if (c) { 14063 /* Pre-lock the call */ 14064 ast_channel_lock(c); 14065 } 14066 } 14067 } else { 14068 if (option_debug > 1 && sipdebug) { 14069 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14070 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14071 else 14072 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14073 } 14074 reinvite = 1; 14075 c = p->owner; 14076 } 14077 14078 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14079 p->lastinvite = seqno; 14080 14081 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14082 /* Go and take over the target call */ 14083 if (sipdebug && option_debug > 3) 14084 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14085 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14086 } 14087 14088 14089 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14090 switch(c->_state) { 14091 case AST_STATE_DOWN: 14092 if (option_debug > 1) 14093 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14094 transmit_response(p, "100 Trying", req); 14095 p->invitestate = INV_PROCEEDING; 14096 ast_setstate(c, AST_STATE_RING); 14097 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14098 enum ast_pbx_result res; 14099 14100 res = ast_pbx_start(c); 14101 14102 switch(res) { 14103 case AST_PBX_FAILED: 14104 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14105 p->invitestate = INV_COMPLETED; 14106 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14107 transmit_response(p, "503 Unavailable", req); 14108 else 14109 transmit_response_reliable(p, "503 Unavailable", req); 14110 break; 14111 case AST_PBX_CALL_LIMIT: 14112 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14113 p->invitestate = INV_COMPLETED; 14114 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14115 transmit_response(p, "480 Temporarily Unavailable", req); 14116 else 14117 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14118 break; 14119 case AST_PBX_SUCCESS: 14120 /* nothing to do */ 14121 break; 14122 } 14123 14124 if (res) { 14125 14126 /* Unlock locks so ast_hangup can do its magic */ 14127 ast_mutex_unlock(&c->lock); 14128 ast_mutex_unlock(&p->lock); 14129 ast_hangup(c); 14130 ast_mutex_lock(&p->lock); 14131 c = NULL; 14132 } 14133 } else { /* Pickup call in call group */ 14134 ast_channel_unlock(c); 14135 *nounlock = 1; 14136 if (ast_pickup_call(c)) { 14137 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14138 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14139 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14140 else 14141 transmit_response_reliable(p, "503 Unavailable", req); 14142 sip_alreadygone(p); 14143 /* Unlock locks so ast_hangup can do its magic */ 14144 ast_mutex_unlock(&p->lock); 14145 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14146 } else { 14147 ast_mutex_unlock(&p->lock); 14148 ast_setstate(c, AST_STATE_DOWN); 14149 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14150 } 14151 p->invitestate = INV_COMPLETED; 14152 ast_hangup(c); 14153 ast_mutex_lock(&p->lock); 14154 c = NULL; 14155 } 14156 break; 14157 case AST_STATE_RING: 14158 transmit_response(p, "100 Trying", req); 14159 p->invitestate = INV_PROCEEDING; 14160 break; 14161 case AST_STATE_RINGING: 14162 transmit_response(p, "180 Ringing", req); 14163 p->invitestate = INV_PROCEEDING; 14164 break; 14165 case AST_STATE_UP: 14166 if (option_debug > 1) 14167 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14168 14169 transmit_response(p, "100 Trying", req); 14170 14171 if (p->t38.state == T38_PEER_REINVITE) { 14172 struct ast_channel *bridgepeer = NULL; 14173 struct sip_pvt *bridgepvt = NULL; 14174 14175 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14176 /* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/ 14177 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14178 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14179 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14180 if (bridgepvt->t38.state == T38_DISABLED) { 14181 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14182 /* Send re-invite to the bridged channel */ 14183 sip_handle_t38_reinvite(bridgepeer, p, 1); 14184 } else { /* Something is wrong with peers udptl struct */ 14185 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14186 ast_mutex_lock(&bridgepvt->lock); 14187 bridgepvt->t38.state = T38_DISABLED; 14188 ast_mutex_unlock(&bridgepvt->lock); 14189 if (option_debug > 1) 14190 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14191 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14192 transmit_response(p, "488 Not acceptable here", req); 14193 else 14194 transmit_response_reliable(p, "488 Not acceptable here", req); 14195 14196 } 14197 } else { 14198 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14199 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14200 p->t38.state = T38_ENABLED; 14201 if (option_debug) 14202 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14203 } 14204 } else { 14205 /* Other side is not a SIP channel */ 14206 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14207 transmit_response(p, "488 Not acceptable here", req); 14208 else 14209 transmit_response_reliable(p, "488 Not acceptable here", req); 14210 p->t38.state = T38_DISABLED; 14211 if (option_debug > 1) 14212 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14213 14214 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14215 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14216 } 14217 } else { 14218 /* we are not bridged in a call */ 14219 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14220 p->t38.state = T38_ENABLED; 14221 if (option_debug) 14222 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14223 } 14224 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14225 int sendok = TRUE; 14226 14227 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14228 /* so handle it here (re-invite other party to RTP) */ 14229 struct ast_channel *bridgepeer = NULL; 14230 struct sip_pvt *bridgepvt = NULL; 14231 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14232 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14233 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14234 /* Does the bridged peer have T38 ? */ 14235 if (bridgepvt->t38.state == T38_ENABLED) { 14236 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14237 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14238 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14239 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14240 else 14241 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14242 sendok = FALSE; 14243 } 14244 /* No bridged peer with T38 enabled*/ 14245 } 14246 } 14247 /* Respond to normal re-invite */ 14248 if (sendok) 14249 /* If this is not a re-invite or something to ignore - it's critical */ 14250 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14251 } 14252 p->invitestate = INV_TERMINATED; 14253 break; 14254 default: 14255 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14256 transmit_response(p, "100 Trying", req); 14257 break; 14258 } 14259 } else { 14260 if (p && (p->autokillid == -1)) { 14261 const char *msg; 14262 14263 if (!p->jointcapability) 14264 msg = "488 Not Acceptable Here (codec error)"; 14265 else { 14266 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14267 msg = "503 Unavailable"; 14268 } 14269 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14270 transmit_response(p, msg, req); 14271 else 14272 transmit_response_reliable(p, msg, req); 14273 p->invitestate = INV_COMPLETED; 14274 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14275 } 14276 } 14277 return res; 14278 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14897 of file chan_sip.c.
References ast_test_flag, ast_verbose(), receive_message(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, and transmit_response().
Referenced by handle_request().
14898 { 14899 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14900 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14901 ast_verbose("Receiving message!\n"); 14902 receive_message(p, req); 14903 } else 14904 transmit_response(p, "202 Accepted", req); 14905 return 1; 14906 }
static int handle_request_notify | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int | seqno, | |||
char * | e | |||
) | [static] |
Handle incoming notifications.
Definition at line 13426 of file chan_sip.c.
References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13427 { 13428 /* This is mostly a skeleton for future improvements */ 13429 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13430 int res = 0; 13431 const char *event = get_header(req, "Event"); 13432 char *eventid = NULL; 13433 char *sep; 13434 13435 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13436 *sep++ = '\0'; 13437 eventid = sep; 13438 } 13439 13440 if (option_debug > 1 && sipdebug) 13441 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13442 13443 if (strcmp(event, "refer")) { 13444 /* We don't understand this event. */ 13445 /* Here's room to implement incoming voicemail notifications :-) */ 13446 transmit_response(p, "489 Bad event", req); 13447 res = -1; 13448 } else { 13449 /* Save nesting depth for now, since there might be other events we will 13450 support in the future */ 13451 13452 /* Handle REFER notifications */ 13453 13454 char buf[1024]; 13455 char *cmd, *code; 13456 int respcode; 13457 int success = TRUE; 13458 13459 /* EventID for each transfer... EventID is basically the REFER cseq 13460 13461 We are getting notifications on a call that we transfered 13462 We should hangup when we are getting a 200 OK in a sipfrag 13463 Check if we have an owner of this event */ 13464 13465 /* Check the content type */ 13466 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13467 /* We need a sipfrag */ 13468 transmit_response(p, "400 Bad request", req); 13469 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13470 return -1; 13471 } 13472 13473 /* Get the text of the attachment */ 13474 if (get_msg_text(buf, sizeof(buf), req)) { 13475 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13476 transmit_response(p, "400 Bad request", req); 13477 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13478 return -1; 13479 } 13480 13481 /* 13482 From the RFC... 13483 A minimal, but complete, implementation can respond with a single 13484 NOTIFY containing either the body: 13485 SIP/2.0 100 Trying 13486 13487 if the subscription is pending, the body: 13488 SIP/2.0 200 OK 13489 if the reference was successful, the body: 13490 SIP/2.0 503 Service Unavailable 13491 if the reference failed, or the body: 13492 SIP/2.0 603 Declined 13493 13494 if the REFER request was accepted before approval to follow the 13495 reference could be obtained and that approval was subsequently denied 13496 (see Section 2.4.7). 13497 13498 If there are several REFERs in the same dialog, we need to 13499 match the ID of the event header... 13500 */ 13501 if (option_debug > 2) 13502 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13503 cmd = ast_skip_blanks(buf); 13504 code = cmd; 13505 /* We are at SIP/2.0 */ 13506 while(*code && (*code > 32)) { /* Search white space */ 13507 code++; 13508 } 13509 *code++ = '\0'; 13510 code = ast_skip_blanks(code); 13511 sep = code; 13512 sep++; 13513 while(*sep && (*sep > 32)) { /* Search white space */ 13514 sep++; 13515 } 13516 *sep++ = '\0'; /* Response string */ 13517 respcode = atoi(code); 13518 switch (respcode) { 13519 case 100: /* Trying: */ 13520 case 101: /* dialog establishment */ 13521 /* Don't do anything yet */ 13522 break; 13523 case 183: /* Ringing: */ 13524 /* Don't do anything yet */ 13525 break; 13526 case 200: /* OK: The new call is up, hangup this call */ 13527 /* Hangup the call that we are replacing */ 13528 break; 13529 case 301: /* Moved permenantly */ 13530 case 302: /* Moved temporarily */ 13531 /* Do we get the header in the packet in this case? */ 13532 success = FALSE; 13533 break; 13534 case 503: /* Service Unavailable: The new call failed */ 13535 /* Cancel transfer, continue the call */ 13536 success = FALSE; 13537 break; 13538 case 603: /* Declined: Not accepted */ 13539 /* Cancel transfer, continue the current call */ 13540 success = FALSE; 13541 break; 13542 } 13543 if (!success) { 13544 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13545 } 13546 13547 /* Confirm that we received this packet */ 13548 transmit_response(p, "200 OK", req); 13549 }; 13550 13551 if (!p->lastinvite) 13552 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13553 13554 return res; 13555 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13558 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
13559 { 13560 int res; 13561 13562 res = get_destination(p, req); 13563 build_contact(p); 13564 13565 /* XXX Should we authenticate OPTIONS? XXX */ 13566 13567 if (ast_strlen_zero(p->context)) 13568 ast_string_field_set(p, context, default_context); 13569 13570 if (ast_shutting_down()) 13571 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13572 else if (res < 0) 13573 transmit_response_with_allow(p, "404 Not Found", req, 0); 13574 else 13575 transmit_response_with_allow(p, "200 OK", req, 0); 13576 13577 /* Destroy if this OPTIONS was the opening request, but not if 13578 it's in the middle of a normal call flow. */ 13579 if (!p->lastinvite) 13580 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13581 13582 return res; 13583 }
static int handle_request_refer | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
int * | nounlock | |||
) | [static] |
Definition at line 14446 of file chan_sip.c.
References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
14447 { 14448 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14449 /* Chan2: Call between asterisk and transferee */ 14450 14451 int res = 0; 14452 14453 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14454 ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller"); 14455 14456 if (!p->owner) { 14457 /* This is a REFER outside of an existing SIP dialog */ 14458 /* We can't handle that, so decline it */ 14459 if (option_debug > 2) 14460 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14461 transmit_response(p, "603 Declined (No dialog)", req); 14462 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14463 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14464 sip_alreadygone(p); 14465 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14466 } 14467 return 0; 14468 } 14469 14470 14471 /* Check if transfer is allowed from this device */ 14472 if (p->allowtransfer == TRANSFER_CLOSED ) { 14473 /* Transfer not allowed, decline */ 14474 transmit_response(p, "603 Declined (policy)", req); 14475 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14476 /* Do not destroy SIP session */ 14477 return 0; 14478 } 14479 14480 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14481 /* Already have a pending REFER */ 14482 transmit_response(p, "491 Request pending", req); 14483 append_history(p, "Xfer", "Refer failed. Request pending."); 14484 return 0; 14485 } 14486 14487 /* Allocate memory for call transfer data */ 14488 if (!p->refer && !sip_refer_allocate(p)) { 14489 transmit_response(p, "500 Internal Server Error", req); 14490 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14491 return -3; 14492 } 14493 14494 res = get_refer_info(p, req); /* Extract headers */ 14495 14496 p->refer->status = REFER_SENT; 14497 14498 if (res != 0) { 14499 switch (res) { 14500 case -2: /* Syntax error */ 14501 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14502 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14503 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14504 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14505 break; 14506 case -3: 14507 transmit_response(p, "603 Declined (Non sip: uri)", req); 14508 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14509 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14510 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14511 break; 14512 default: 14513 /* Refer-to extension not found, fake a failed transfer */ 14514 transmit_response(p, "202 Accepted", req); 14515 append_history(p, "Xfer", "Refer failed. Bad extension."); 14516 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14517 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14518 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14519 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14520 break; 14521 } 14522 return 0; 14523 } 14524 if (ast_strlen_zero(p->context)) 14525 ast_string_field_set(p, context, default_context); 14526 14527 /* If we do not support SIP domains, all transfers are local */ 14528 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14529 p->refer->localtransfer = 1; 14530 if (sipdebug && option_debug > 2) 14531 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14532 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14533 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14534 p->refer->localtransfer = 1; 14535 } else if (sipdebug && option_debug > 2) 14536 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14537 14538 /* Is this a repeat of a current request? Ignore it */ 14539 /* Don't know what else to do right now. */ 14540 if (ignore) 14541 return res; 14542 14543 /* If this is a blind transfer, we have the following 14544 channels to work with: 14545 - chan1, chan2: The current call between transferer and transferee (2 channels) 14546 - target_channel: A new call from the transferee to the target (1 channel) 14547 We need to stay tuned to what happens in order to be able 14548 to bring back the call to the transferer */ 14549 14550 /* If this is a attended transfer, we should have all call legs within reach: 14551 - chan1, chan2: The call between the transferer and transferee (2 channels) 14552 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14553 We want to bridge chan2 with targetcall_pvt! 14554 14555 The replaces call id in the refer message points 14556 to the call leg between Asterisk and the transferer. 14557 So we need to connect the target and the transferee channel 14558 and hangup the two other channels silently 14559 14560 If the target is non-local, the call ID could be on a remote 14561 machine and we need to send an INVITE with replaces to the 14562 target. We basically handle this as a blind transfer 14563 and let the sip_call function catch that we need replaces 14564 header in the INVITE. 14565 */ 14566 14567 14568 /* Get the transferer's channel */ 14569 current.chan1 = p->owner; 14570 14571 /* Find the other part of the bridge (2) - transferee */ 14572 current.chan2 = ast_bridged_channel(current.chan1); 14573 14574 if (sipdebug && option_debug > 2) 14575 ast_log(LOG_DEBUG, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>"); 14576 14577 if (!current.chan2 && !p->refer->attendedtransfer) { 14578 /* No bridged channel, propably IVR or echo or similar... */ 14579 /* Guess we should masquerade or something here */ 14580 /* Until we figure it out, refuse transfer of such calls */ 14581 if (sipdebug && option_debug > 2) 14582 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14583 p->refer->status = REFER_FAILED; 14584 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14585 transmit_response(p, "603 Declined", req); 14586 return -1; 14587 } 14588 14589 if (current.chan2) { 14590 if (sipdebug && option_debug > 3) 14591 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14592 14593 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14594 } 14595 14596 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14597 14598 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14599 if (p->refer->attendedtransfer) { 14600 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14601 return res; /* We're done with the transfer */ 14602 /* Fall through for remote transfers that we did not find locally */ 14603 if (sipdebug && option_debug > 3) 14604 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14605 /* Fallthrough if we can't find the call leg internally */ 14606 } 14607 14608 14609 /* Parking a call */ 14610 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14611 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14612 *nounlock = 1; 14613 ast_channel_unlock(current.chan1); 14614 copy_request(¤t.req, req); 14615 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14616 p->refer->status = REFER_200OK; 14617 append_history(p, "Xfer", "REFER to call parking."); 14618 if (sipdebug && option_debug > 3) 14619 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14620 sip_park(current.chan2, current.chan1, req, seqno); 14621 return res; 14622 } 14623 14624 /* Blind transfers and remote attended xfers */ 14625 transmit_response(p, "202 Accepted", req); 14626 14627 if (current.chan1 && current.chan2) { 14628 if (option_debug > 2) 14629 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14630 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14631 } 14632 if (current.chan2) { 14633 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14634 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14635 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14636 /* One for the new channel */ 14637 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14638 /* Attended transfer to remote host, prepare headers for the INVITE */ 14639 if (p->refer->referred_by) 14640 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14641 } 14642 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14643 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14644 char tempheader[SIPBUFSIZE]; 14645 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14646 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14647 p->refer->replaces_callid_totag, 14648 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14649 p->refer->replaces_callid_fromtag); 14650 if (current.chan2) 14651 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14652 } 14653 /* Must release lock now, because it will not longer 14654 be accessible after the transfer! */ 14655 *nounlock = 1; 14656 ast_channel_unlock(current.chan1); 14657 14658 /* Connect the call */ 14659 14660 /* FAKE ringing if not attended transfer */ 14661 if (!p->refer->attendedtransfer) 14662 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14663 14664 /* For blind transfer, this will lead to a new call */ 14665 /* For attended transfer to remote host, this will lead to 14666 a new SIP call with a replaces header, if the dial plan allows it 14667 */ 14668 if (!current.chan2) { 14669 /* We have no bridge, so we're talking with Asterisk somehow */ 14670 /* We need to masquerade this call */ 14671 /* What to do to fix this situation: 14672 * Set up the new call in a new channel 14673 * Let the new channel masq into this channel 14674 Please add that code here :-) 14675 */ 14676 p->refer->status = REFER_FAILED; 14677 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14678 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14679 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14680 return -1; 14681 } 14682 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14683 14684 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14685 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14686 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14687 14688 if (!res) { 14689 /* Success - we have a new channel */ 14690 if (option_debug > 2) 14691 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14692 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14693 if (p->refer->localtransfer) 14694 p->refer->status = REFER_200OK; 14695 if (p->owner) 14696 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14697 append_history(p, "Xfer", "Refer succeeded."); 14698 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14699 /* Do not hangup call, the other side do that when we say 200 OK */ 14700 /* We could possibly implement a timer here, auto congestion */ 14701 res = 0; 14702 } else { 14703 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14704 if (option_debug > 2) 14705 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14706 append_history(p, "Xfer", "Refer failed."); 14707 /* Failure of some kind */ 14708 p->refer->status = REFER_FAILED; 14709 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14710 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14711 res = -1; 14712 } 14713 return res; 14714 }
static int handle_request_register | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
char * | e | |||
) | [static] |
Handle incoming REGISTER request.
Definition at line 15205 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().
Referenced by handle_request().
15206 { 15207 enum check_auth_result res; 15208 15209 /* Use this as the basis */ 15210 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15211 ast_verbose("Using latest REGISTER request as basis request\n"); 15212 copy_request(&p->initreq, req); 15213 check_via(p, req); 15214 if ((res = register_verify(p, sin, req, e)) < 0) { 15215 const char *reason; 15216 15217 switch (res) { 15218 case AUTH_SECRET_FAILED: 15219 reason = "Wrong password"; 15220 break; 15221 case AUTH_USERNAME_MISMATCH: 15222 reason = "Username/auth name mismatch"; 15223 break; 15224 case AUTH_NOT_FOUND: 15225 reason = "No matching peer found"; 15226 break; 15227 case AUTH_UNKNOWN_DOMAIN: 15228 reason = "Not a local domain"; 15229 break; 15230 case AUTH_PEER_NOT_DYNAMIC: 15231 reason = "Peer is not supposed to register"; 15232 break; 15233 case AUTH_ACL_FAILED: 15234 reason = "Device does not match ACL"; 15235 break; 15236 default: 15237 reason = "Unknown failure"; 15238 break; 15239 } 15240 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15241 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15242 reason); 15243 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15244 } else 15245 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15246 15247 if (res < 1) { 15248 /* Destroy the session, but keep us around for just a bit in case they don't 15249 get our 200 OK */ 15250 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15251 } 15252 return res; 15253 }
static int handle_request_subscribe | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int | seqno, | |||
char * | e | |||
) | [static] |
Handle incoming SUBSCRIBE request.
Definition at line 14909 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.
Referenced by handle_request().
14910 { 14911 int gotdest; 14912 int res = 0; 14913 int firststate = AST_EXTENSION_REMOVED; 14914 struct sip_peer *authpeer = NULL; 14915 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14916 const char *accept = get_header(req, "Accept"); 14917 int resubscribe = (p->subscribed != NONE); 14918 char *temp, *event; 14919 14920 if (p->initreq.headers) { 14921 /* We already have a dialog */ 14922 if (p->initreq.method != SIP_SUBSCRIBE) { 14923 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14924 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14925 transmit_response(p, "403 Forbidden (within dialog)", req); 14926 /* Do not destroy session, since we will break the call if we do */ 14927 if (option_debug) 14928 ast_log(LOG_DEBUG, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text); 14929 return 0; 14930 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14931 if (option_debug) { 14932 if (resubscribe) 14933 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14934 else 14935 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14936 } 14937 } 14938 } 14939 14940 /* Check if we have a global disallow setting on subscriptions. 14941 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14942 */ 14943 if (!global_allowsubscribe) { 14944 transmit_response(p, "403 Forbidden (policy)", req); 14945 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14946 return 0; 14947 } 14948 14949 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14950 const char *to = get_header(req, "To"); 14951 char totag[128]; 14952 14953 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 14954 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 14955 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14956 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 14957 transmit_response(p, "481 Subscription does not exist", req); 14958 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14959 return 0; 14960 } 14961 14962 /* Use this as the basis */ 14963 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14964 ast_verbose("Creating new subscription\n"); 14965 14966 copy_request(&p->initreq, req); 14967 check_via(p, req); 14968 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14969 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14970 14971 /* Find parameters to Event: header value and remove them for now */ 14972 if (ast_strlen_zero(eventheader)) { 14973 transmit_response(p, "489 Bad Event", req); 14974 if (option_debug > 1) 14975 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14976 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14977 return 0; 14978 } 14979 14980 if ( (strchr(eventheader, ';'))) { 14981 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14982 temp = strchr(event, ';'); 14983 *temp = '\0'; /* Remove any options for now */ 14984 /* We might need to use them later :-) */ 14985 } else 14986 event = (char *) eventheader; /* XXX is this legal ? */ 14987 14988 /* Handle authentication */ 14989 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14990 /* if an authentication response was sent, we are done here */ 14991 if (res == AUTH_CHALLENGE_SENT) { 14992 if (authpeer) 14993 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14994 return 0; 14995 } 14996 if (res < 0) { 14997 if (res == AUTH_FAKE_AUTH) { 14998 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14999 transmit_fake_auth_response(p, req, 1); 15000 } else { 15001 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15002 transmit_response_reliable(p, "403 Forbidden", req); 15003 } 15004 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15005 if (authpeer) 15006 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15007 return 0; 15008 } 15009 15010 /* Check if this user/peer is allowed to subscribe at all */ 15011 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15012 transmit_response(p, "403 Forbidden (policy)", req); 15013 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15014 if (authpeer) 15015 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15016 return 0; 15017 } 15018 15019 /* Get destination right away */ 15020 gotdest = get_destination(p, NULL); 15021 15022 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15023 parse_ok_contact(p, req); 15024 15025 build_contact(p); 15026 if (strcmp(event, "message-summary") && gotdest) { 15027 transmit_response(p, "404 Not Found", req); 15028 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15029 if (authpeer) 15030 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15031 return 0; 15032 } 15033 15034 /* Initialize tag for new subscriptions */ 15035 if (ast_strlen_zero(p->tag)) 15036 make_our_tag(p->tag, sizeof(p->tag)); 15037 15038 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15039 if (authpeer) /* No need for authpeer here */ 15040 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15041 15042 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15043 /* Polycom phones only handle xpidf+xml, even if they say they can 15044 handle pidf+xml as well 15045 */ 15046 if (strstr(p->useragent, "Polycom")) { 15047 p->subscribed = XPIDF_XML; 15048 } else if (strstr(accept, "application/pidf+xml")) { 15049 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15050 } else if (strstr(accept, "application/dialog-info+xml")) { 15051 p->subscribed = DIALOG_INFO_XML; 15052 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15053 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15054 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15055 } else if (strstr(accept, "application/xpidf+xml")) { 15056 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15057 } else if (ast_strlen_zero(accept)) { 15058 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15059 transmit_response(p, "489 Bad Event", req); 15060 15061 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15062 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15063 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15064 return 0; 15065 } 15066 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15067 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15068 } else { 15069 /* Can't find a format for events that we know about */ 15070 char mybuf[200]; 15071 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15072 transmit_response(p, mybuf, req); 15073 15074 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15075 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15076 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15077 return 0; 15078 } 15079 } else if (!strcmp(event, "message-summary")) { 15080 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15081 /* Format requested that we do not support */ 15082 transmit_response(p, "406 Not Acceptable", req); 15083 if (option_debug > 1) 15084 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15085 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15086 if (authpeer) /* No need for authpeer here */ 15087 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15088 return 0; 15089 } 15090 /* Looks like they actually want a mailbox status 15091 This version of Asterisk supports mailbox subscriptions 15092 The subscribed URI needs to exist in the dial plan 15093 In most devices, this is configurable to the voicemailmain extension you use 15094 */ 15095 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15096 transmit_response(p, "404 Not found (no mailbox)", req); 15097 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15098 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15099 if (authpeer) /* No need for authpeer here */ 15100 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15101 return 0; 15102 } 15103 15104 p->subscribed = MWI_NOTIFICATION; 15105 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15106 /* We only allow one subscription per peer */ 15107 sip_destroy(authpeer->mwipvt); 15108 authpeer->mwipvt = p; /* Link from peer to pvt */ 15109 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15110 } else { /* At this point, Asterisk does not understand the specified event */ 15111 transmit_response(p, "489 Bad Event", req); 15112 if (option_debug > 1) 15113 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15114 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15115 if (authpeer) /* No need for authpeer here */ 15116 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15117 return 0; 15118 } 15119 15120 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15121 if (p->stateid > -1) 15122 ast_extension_state_del(p->stateid, cb_extensionstate); 15123 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15124 } 15125 15126 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15127 p->lastinvite = seqno; 15128 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15129 p->expiry = atoi(get_header(req, "Expires")); 15130 15131 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15132 if (p->expiry > max_expiry) 15133 p->expiry = max_expiry; 15134 if (p->expiry < min_expiry && p->expiry > 0) 15135 p->expiry = min_expiry; 15136 15137 if (sipdebug || option_debug > 1) { 15138 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15139 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15140 else 15141 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15142 } 15143 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15144 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15145 if (p->expiry > 0) 15146 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15147 15148 if (p->subscribed == MWI_NOTIFICATION) { 15149 transmit_response(p, "200 OK", req); 15150 if (p->relatedpeer) { /* Send first notification */ 15151 ASTOBJ_WRLOCK(p->relatedpeer); 15152 sip_send_mwi_to_peer(p->relatedpeer); 15153 ASTOBJ_UNLOCK(p->relatedpeer); 15154 } 15155 } else { 15156 struct sip_pvt *p_old; 15157 15158 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15159 15160 ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_inet_ntoa(p->sa.sin_addr)); 15161 transmit_response(p, "404 Not found", req); 15162 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15163 return 0; 15164 } 15165 15166 transmit_response(p, "200 OK", req); 15167 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15168 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15169 /* hide the 'complete' exten/context in the refer_to field for later display */ 15170 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15171 15172 /* remove any old subscription from this peer for the same exten/context, 15173 as the peer has obviously forgotten about it and it's wasteful to wait 15174 for it to expire and send NOTIFY messages to the peer only to have them 15175 ignored (or generate errors) 15176 */ 15177 ast_mutex_lock(&iflock); 15178 for (p_old = iflist; p_old; p_old = p_old->next) { 15179 if (p_old == p) 15180 continue; 15181 if (p_old->initreq.method != SIP_SUBSCRIBE) 15182 continue; 15183 if (p_old->subscribed == NONE) 15184 continue; 15185 ast_mutex_lock(&p_old->lock); 15186 if (!strcmp(p_old->username, p->username)) { 15187 if (!strcmp(p_old->exten, p->exten) && 15188 !strcmp(p_old->context, p->context)) { 15189 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15190 ast_mutex_unlock(&p_old->lock); 15191 break; 15192 } 15193 } 15194 ast_mutex_unlock(&p_old->lock); 15195 } 15196 ast_mutex_unlock(&iflock); 15197 } 15198 if (!p->expiry) 15199 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15200 } 15201 return 1; 15202 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 12711 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::authtries, cb_extensionstate(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initreq, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12712 { 12713 struct ast_channel *owner; 12714 int sipmethod; 12715 int res = 1; 12716 const char *c = get_header(req, "Cseq"); 12717 const char *msg = strchr(c, ' '); 12718 12719 if (!msg) 12720 msg = ""; 12721 else 12722 msg++; 12723 sipmethod = find_sip_method(msg); 12724 12725 owner = p->owner; 12726 if (owner) 12727 owner->hangupcause = hangup_sip2cause(resp); 12728 12729 /* Acknowledge whatever it is destined for */ 12730 if ((resp >= 100) && (resp <= 199)) 12731 __sip_semi_ack(p, seqno, 0, sipmethod); 12732 else 12733 __sip_ack(p, seqno, 0, sipmethod); 12734 12735 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12736 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12737 p->pendinginvite = 0; 12738 12739 /* Get their tag if we haven't already */ 12740 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12741 char tag[128]; 12742 12743 gettag(req, "To", tag, sizeof(tag)); 12744 ast_string_field_set(p, theirtag, tag); 12745 } 12746 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12747 /* We don't really care what the response is, just that it replied back. 12748 Well, as long as it's not a 100 response... since we might 12749 need to hang around for something more "definitive" */ 12750 if (resp != 100) 12751 handle_response_peerpoke(p, resp, req); 12752 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12753 switch(resp) { 12754 case 100: /* 100 Trying */ 12755 case 101: /* 101 Dialog establishment */ 12756 if (sipmethod == SIP_INVITE) 12757 handle_response_invite(p, resp, rest, req, seqno); 12758 break; 12759 case 183: /* 183 Session Progress */ 12760 if (sipmethod == SIP_INVITE) 12761 handle_response_invite(p, resp, rest, req, seqno); 12762 break; 12763 case 180: /* 180 Ringing */ 12764 if (sipmethod == SIP_INVITE) 12765 handle_response_invite(p, resp, rest, req, seqno); 12766 break; 12767 case 182: /* 182 Queued */ 12768 if (sipmethod == SIP_INVITE) 12769 handle_response_invite(p, resp, rest, req, seqno); 12770 break; 12771 case 200: /* 200 OK */ 12772 p->authtries = 0; /* Reset authentication counter */ 12773 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12774 /* We successfully transmitted a message 12775 or a video update request in INFO */ 12776 /* Nothing happens here - the message is inside a dialog */ 12777 } else if (sipmethod == SIP_INVITE) { 12778 handle_response_invite(p, resp, rest, req, seqno); 12779 } else if (sipmethod == SIP_NOTIFY) { 12780 /* They got the notify, this is the end */ 12781 if (p->owner) { 12782 if (!p->refer) { 12783 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12784 ast_queue_hangup(p->owner); 12785 } else if (option_debug > 3) 12786 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12787 } else { 12788 if (p->subscribed == NONE) 12789 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12790 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12791 /* Ready to send the next state we have on queue */ 12792 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12793 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 12794 } 12795 } 12796 } else if (sipmethod == SIP_REGISTER) 12797 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12798 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12799 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12800 break; 12801 case 202: /* Transfer accepted */ 12802 if (sipmethod == SIP_REFER) 12803 handle_response_refer(p, resp, rest, req, seqno); 12804 break; 12805 case 401: /* Not www-authorized on SIP method */ 12806 if (sipmethod == SIP_INVITE) 12807 handle_response_invite(p, resp, rest, req, seqno); 12808 else if (sipmethod == SIP_REFER) 12809 handle_response_refer(p, resp, rest, req, seqno); 12810 else if (p->registry && sipmethod == SIP_REGISTER) 12811 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12812 else if (sipmethod == SIP_BYE) { 12813 if (ast_strlen_zero(p->authname)) { 12814 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12815 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12816 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12817 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12818 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12819 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12820 /* We fail to auth bye on our own call, but still needs to tear down the call. 12821 Life, they call it. */ 12822 } 12823 } else { 12824 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12825 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12826 } 12827 break; 12828 case 403: /* Forbidden - we failed authentication */ 12829 if (sipmethod == SIP_INVITE) 12830 handle_response_invite(p, resp, rest, req, seqno); 12831 else if (p->registry && sipmethod == SIP_REGISTER) 12832 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12833 else { 12834 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12835 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12836 } 12837 break; 12838 case 404: /* Not found */ 12839 if (p->registry && sipmethod == SIP_REGISTER) 12840 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12841 else if (sipmethod == SIP_INVITE) 12842 handle_response_invite(p, resp, rest, req, seqno); 12843 else if (owner) 12844 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12845 break; 12846 case 407: /* Proxy auth required */ 12847 if (sipmethod == SIP_INVITE) 12848 handle_response_invite(p, resp, rest, req, seqno); 12849 else if (sipmethod == SIP_REFER) 12850 handle_response_refer(p, resp, rest, req, seqno); 12851 else if (p->registry && sipmethod == SIP_REGISTER) 12852 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12853 else if (sipmethod == SIP_BYE) { 12854 if (ast_strlen_zero(p->authname)) { 12855 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12856 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12857 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12858 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12859 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12860 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12861 } 12862 } else /* We can't handle this, giving up in a bad way */ 12863 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12864 12865 break; 12866 case 408: /* Request timeout - terminate dialog */ 12867 if (sipmethod == SIP_INVITE) 12868 handle_response_invite(p, resp, rest, req, seqno); 12869 else if (sipmethod == SIP_REGISTER) 12870 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12871 else if (sipmethod == SIP_BYE) { 12872 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12873 if (option_debug) 12874 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12875 } else { 12876 if (owner) 12877 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12878 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12879 } 12880 break; 12881 case 481: /* Call leg does not exist */ 12882 if (sipmethod == SIP_INVITE) { 12883 handle_response_invite(p, resp, rest, req, seqno); 12884 } else if (sipmethod == SIP_REFER) { 12885 handle_response_refer(p, resp, rest, req, seqno); 12886 } else if (sipmethod == SIP_BYE) { 12887 /* The other side has no transaction to bye, 12888 just assume it's all right then */ 12889 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12890 } else if (sipmethod == SIP_CANCEL) { 12891 /* The other side has no transaction to cancel, 12892 just assume it's all right then */ 12893 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12894 } else { 12895 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12896 /* Guessing that this is not an important request */ 12897 } 12898 break; 12899 case 487: 12900 if (sipmethod == SIP_INVITE) 12901 handle_response_invite(p, resp, rest, req, seqno); 12902 break; 12903 case 488: /* Not acceptable here - codec error */ 12904 if (sipmethod == SIP_INVITE) 12905 handle_response_invite(p, resp, rest, req, seqno); 12906 break; 12907 case 491: /* Pending */ 12908 if (sipmethod == SIP_INVITE) 12909 handle_response_invite(p, resp, rest, req, seqno); 12910 else { 12911 if (option_debug) 12912 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12913 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12914 } 12915 break; 12916 case 501: /* Not Implemented */ 12917 if (sipmethod == SIP_INVITE) 12918 handle_response_invite(p, resp, rest, req, seqno); 12919 else if (sipmethod == SIP_REFER) 12920 handle_response_refer(p, resp, rest, req, seqno); 12921 else 12922 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12923 break; 12924 case 603: /* Declined transfer */ 12925 if (sipmethod == SIP_REFER) { 12926 handle_response_refer(p, resp, rest, req, seqno); 12927 break; 12928 } 12929 /* Fallthrough */ 12930 default: 12931 if ((resp >= 300) && (resp < 700)) { 12932 /* Fatal response */ 12933 if ((option_verbose > 2) && (resp != 487)) 12934 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12935 12936 if (sipmethod == SIP_INVITE) 12937 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12938 12939 /* XXX Locking issues?? XXX */ 12940 switch(resp) { 12941 case 300: /* Multiple Choices */ 12942 case 301: /* Moved permenantly */ 12943 case 302: /* Moved temporarily */ 12944 case 305: /* Use Proxy */ 12945 parse_moved_contact(p, req); 12946 /* Fall through */ 12947 case 486: /* Busy here */ 12948 case 600: /* Busy everywhere */ 12949 case 603: /* Decline */ 12950 if (p->owner) 12951 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12952 break; 12953 case 482: /* 12954 \note SIP is incapable of performing a hairpin call, which 12955 is yet another failure of not having a layer 2 (again, YAY 12956 IETF for thinking ahead). So we treat this as a call 12957 forward and hope we end up at the right place... */ 12958 if (option_debug) 12959 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12960 if (p->owner) 12961 ast_string_field_build(p->owner, call_forward, 12962 "Local/%s@%s", p->username, p->context); 12963 /* Fall through */ 12964 case 480: /* Temporarily Unavailable */ 12965 case 404: /* Not Found */ 12966 case 410: /* Gone */ 12967 case 400: /* Bad Request */ 12968 case 500: /* Server error */ 12969 if (sipmethod == SIP_REFER) { 12970 handle_response_refer(p, resp, rest, req, seqno); 12971 break; 12972 } 12973 /* Fall through */ 12974 case 502: /* Bad gateway */ 12975 case 503: /* Service Unavailable */ 12976 case 504: /* Server Timeout */ 12977 if (owner) 12978 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12979 break; 12980 default: 12981 /* Send hangup */ 12982 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12983 ast_queue_hangup(p->owner); 12984 break; 12985 } 12986 /* ACK on invite */ 12987 if (sipmethod == SIP_INVITE) 12988 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12989 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12990 sip_alreadygone(p); 12991 if (!p->owner) 12992 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12993 } else if ((resp >= 100) && (resp < 200)) { 12994 if (sipmethod == SIP_INVITE) { 12995 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 12996 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12997 if (find_sdp(req)) 12998 process_sdp(p, req); 12999 if (p->owner) { 13000 /* Queue a progress frame */ 13001 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13002 } 13003 } 13004 } else 13005 ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr)); 13006 } 13007 } else { 13008 /* Responses to OUTGOING SIP requests on INCOMING calls 13009 get handled here. As well as out-of-call message responses */ 13010 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13011 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13012 13013 if (sipmethod == SIP_INVITE && resp == 200) { 13014 /* Tags in early session is replaced by the tag in 200 OK, which is 13015 the final reply to our INVITE */ 13016 char tag[128]; 13017 13018 gettag(req, "To", tag, sizeof(tag)); 13019 ast_string_field_set(p, theirtag, tag); 13020 } 13021 13022 switch(resp) { 13023 case 200: 13024 if (sipmethod == SIP_INVITE) { 13025 handle_response_invite(p, resp, rest, req, seqno); 13026 } else if (sipmethod == SIP_CANCEL) { 13027 if (option_debug) 13028 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13029 13030 /* Wait for 487, then destroy */ 13031 } else if (sipmethod == SIP_NOTIFY) { 13032 /* They got the notify, this is the end */ 13033 if (p->owner) { 13034 if (p->refer) { 13035 if (option_debug) 13036 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13037 } else 13038 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13039 /* ast_queue_hangup(p->owner); Disabled */ 13040 } else { 13041 if (!p->subscribed && !p->refer) 13042 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13043 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13044 /* Ready to send the next state we have on queue */ 13045 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13046 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 13047 } 13048 } 13049 } else if (sipmethod == SIP_BYE) 13050 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13051 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13052 /* We successfully transmitted a message or 13053 a video update request in INFO */ 13054 ; 13055 else if (sipmethod == SIP_BYE) 13056 /* Ok, we're ready to go */ 13057 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13058 break; 13059 case 202: /* Transfer accepted */ 13060 if (sipmethod == SIP_REFER) 13061 handle_response_refer(p, resp, rest, req, seqno); 13062 break; 13063 case 401: /* www-auth */ 13064 case 407: 13065 if (sipmethod == SIP_REFER) 13066 handle_response_refer(p, resp, rest, req, seqno); 13067 else if (sipmethod == SIP_INVITE) 13068 handle_response_invite(p, resp, rest, req, seqno); 13069 else if (sipmethod == SIP_BYE) { 13070 char *auth, *auth2; 13071 13072 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13073 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13074 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13075 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13076 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13077 } 13078 } 13079 break; 13080 case 481: /* Call leg does not exist */ 13081 if (sipmethod == SIP_INVITE) { 13082 /* Re-invite failed */ 13083 handle_response_invite(p, resp, rest, req, seqno); 13084 } else if (sipmethod == SIP_BYE) { 13085 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13086 } else if (sipdebug) { 13087 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13088 } 13089 break; 13090 case 501: /* Not Implemented */ 13091 if (sipmethod == SIP_INVITE) 13092 handle_response_invite(p, resp, rest, req, seqno); 13093 else if (sipmethod == SIP_REFER) 13094 handle_response_refer(p, resp, rest, req, seqno); 13095 break; 13096 case 603: /* Declined transfer */ 13097 if (sipmethod == SIP_REFER) { 13098 handle_response_refer(p, resp, rest, req, seqno); 13099 break; 13100 } 13101 /* Fallthrough */ 13102 default: /* Errors without handlers */ 13103 if ((resp >= 100) && (resp < 200)) { 13104 if (sipmethod == SIP_INVITE) { /* re-invite */ 13105 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13106 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13107 } 13108 } 13109 if ((resp >= 300) && (resp < 700)) { 13110 if ((option_verbose > 2) && (resp != 487)) 13111 ast_verbose(VERBOSE_PREFIX_3 "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13112 switch(resp) { 13113 case 488: /* Not acceptable here - codec error */ 13114 case 603: /* Decline */ 13115 case 500: /* Server error */ 13116 case 502: /* Bad gateway */ 13117 case 503: /* Service Unavailable */ 13118 case 504: /* Server timeout */ 13119 13120 /* re-invite failed */ 13121 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13122 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13123 break; 13124 } 13125 } 13126 break; 13127 } 13128 } 13129 }
static void handle_response_invite | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle SIP response to INVITE dialogue.
Definition at line 12122 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
12123 { 12124 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12125 int res = 0; 12126 int xmitres = 0; 12127 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12128 struct ast_channel *bridgepeer = NULL; 12129 12130 if (option_debug > 3) { 12131 if (reinvite) 12132 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12133 else 12134 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12135 } 12136 12137 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12138 if (option_debug) 12139 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12140 return; 12141 } 12142 12143 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12144 /* Don't auto congest anymore since we've gotten something useful back */ 12145 AST_SCHED_DEL(sched, p->initid); 12146 12147 /* RFC3261 says we must treat every 1xx response (but not 100) 12148 that we don't recognize as if it was 183. 12149 */ 12150 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12151 resp = 183; 12152 12153 /* Any response between 100 and 199 is PROCEEDING */ 12154 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12155 p->invitestate = INV_PROCEEDING; 12156 12157 /* Final response, not 200 ? */ 12158 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12159 p->invitestate = INV_COMPLETED; 12160 12161 12162 switch (resp) { 12163 case 100: /* Trying */ 12164 case 101: /* Dialog establishment */ 12165 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12166 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12167 check_pendings(p); 12168 break; 12169 12170 case 180: /* 180 Ringing */ 12171 case 182: /* 182 Queued */ 12172 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12173 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12174 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12175 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12176 if (p->owner->_state != AST_STATE_UP) { 12177 ast_setstate(p->owner, AST_STATE_RINGING); 12178 } 12179 } 12180 if (find_sdp(req)) { 12181 if (p->invitestate != INV_CANCELLED) 12182 p->invitestate = INV_EARLY_MEDIA; 12183 res = process_sdp(p, req); 12184 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12185 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12186 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12187 } 12188 } 12189 check_pendings(p); 12190 break; 12191 12192 case 183: /* Session progress */ 12193 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12194 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12195 /* Ignore 183 Session progress without SDP */ 12196 if (find_sdp(req)) { 12197 if (p->invitestate != INV_CANCELLED) 12198 p->invitestate = INV_EARLY_MEDIA; 12199 res = process_sdp(p, req); 12200 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12201 /* Queue a progress frame */ 12202 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12203 } 12204 } 12205 check_pendings(p); 12206 break; 12207 12208 case 200: /* 200 OK on invite - someone's answering our call */ 12209 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12210 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12211 p->authtries = 0; 12212 if (find_sdp(req)) { 12213 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12214 if (!reinvite) 12215 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12216 /* For re-invites, we try to recover */ 12217 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12218 } 12219 12220 /* Parse contact header for continued conversation */ 12221 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12222 /* This is important when we have a SIP proxy between us and the phone */ 12223 if (outgoing) { 12224 update_call_counter(p, DEC_CALL_RINGING); 12225 parse_ok_contact(p, req); 12226 if(set_address_from_contact(p)) { 12227 /* Bad contact - we don't know how to reach this device */ 12228 /* We need to ACK, but then send a bye */ 12229 /* OEJ: Possible issue that may need a check: 12230 If we have a proxy route between us and the device, 12231 should we care about resolving the contact 12232 or should we just send it? 12233 */ 12234 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12235 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12236 } 12237 12238 /* Save Record-Route for any later requests we make on this dialogue */ 12239 if (!reinvite) 12240 build_route(p, req, 1); 12241 } 12242 12243 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12244 struct sip_pvt *bridgepvt = NULL; 12245 12246 if (!bridgepeer->tech) { 12247 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12248 break; 12249 } 12250 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12251 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12252 if (bridgepvt->udptl) { 12253 if (p->t38.state == T38_PEER_REINVITE) { 12254 sip_handle_t38_reinvite(bridgepeer, p, 0); 12255 ast_rtp_set_rtptimers_onhold(p->rtp); 12256 if (p->vrtp) 12257 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12258 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12259 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12260 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12261 /* XXXX Should we really destroy this session here, without any response at all??? */ 12262 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12263 } 12264 } else { 12265 if (option_debug > 1) 12266 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12267 ast_mutex_lock(&bridgepvt->lock); 12268 bridgepvt->t38.state = T38_DISABLED; 12269 ast_mutex_unlock(&bridgepvt->lock); 12270 if (option_debug) 12271 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12272 p->t38.state = T38_DISABLED; 12273 if (option_debug > 1) 12274 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12275 } 12276 } else { 12277 /* Other side is not a SIP channel */ 12278 if (option_debug > 1) 12279 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12280 p->t38.state = T38_DISABLED; 12281 if (option_debug > 1) 12282 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12283 } 12284 } 12285 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12286 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12287 p->t38.state = T38_ENABLED; 12288 if (option_debug) 12289 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12290 } 12291 12292 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12293 if (!reinvite) { 12294 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12295 } else { /* RE-invite */ 12296 ast_queue_frame(p->owner, &ast_null_frame); 12297 } 12298 } else { 12299 /* It's possible we're getting an 200 OK after we've tried to disconnect 12300 by sending CANCEL */ 12301 /* First send ACK, then send bye */ 12302 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12303 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12304 } 12305 /* If I understand this right, the branch is different for a non-200 ACK only */ 12306 p->invitestate = INV_TERMINATED; 12307 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12308 check_pendings(p); 12309 break; 12310 case 407: /* Proxy authentication */ 12311 case 401: /* Www auth */ 12312 /* First we ACK */ 12313 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12314 if (p->options) 12315 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12316 12317 /* Then we AUTH */ 12318 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12319 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12320 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12321 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12322 if (p->authtries < MAX_AUTHTRIES) 12323 p->invitestate = INV_CALLING; 12324 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12325 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12326 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12327 sip_alreadygone(p); 12328 if (p->owner) 12329 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12330 } 12331 } 12332 break; 12333 12334 case 403: /* Forbidden */ 12335 /* First we ACK */ 12336 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12337 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12338 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12339 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12340 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12341 sip_alreadygone(p); 12342 break; 12343 12344 case 404: /* Not found */ 12345 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12346 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12347 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12348 sip_alreadygone(p); 12349 break; 12350 12351 case 408: /* Request timeout */ 12352 case 481: /* Call leg does not exist */ 12353 /* Could be REFER caused INVITE with replaces */ 12354 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12355 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12356 if (p->owner) 12357 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12358 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12359 break; 12360 case 487: /* Cancelled transaction */ 12361 /* We have sent CANCEL on an outbound INVITE 12362 This transaction is already scheduled to be killed by sip_hangup(). 12363 */ 12364 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12365 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12366 ast_queue_hangup(p->owner); 12367 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12368 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12369 update_call_counter(p, DEC_CALL_LIMIT); 12370 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12371 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12372 sip_alreadygone(p); 12373 } 12374 break; 12375 case 488: /* Not acceptable here */ 12376 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12377 if (reinvite && p->udptl) { 12378 /* If this is a T.38 call, we should go back to 12379 audio. If this is an audio call - something went 12380 terribly wrong since we don't renegotiate codecs, 12381 only IP/port . 12382 */ 12383 p->t38.state = T38_DISABLED; 12384 /* Try to reset RTP timers */ 12385 ast_rtp_set_rtptimers_onhold(p->rtp); 12386 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12387 12388 /*! \bug Is there any way we can go back to the audio call on both 12389 sides here? 12390 */ 12391 /* While figuring that out, hangup the call */ 12392 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12393 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12394 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12395 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12396 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12397 right now we can't fall back to audio so totally abort. 12398 */ 12399 p->t38.state = T38_DISABLED; 12400 /* Try to reset RTP timers */ 12401 ast_rtp_set_rtptimers_onhold(p->rtp); 12402 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12403 12404 /* The dialog is now terminated */ 12405 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12406 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12407 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12408 sip_alreadygone(p); 12409 } else { 12410 /* We can't set up this call, so give up */ 12411 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12412 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12413 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12414 /* If there's no dialog to end, then mark p as already gone */ 12415 if (!reinvite) 12416 sip_alreadygone(p); 12417 } 12418 break; 12419 case 491: /* Pending */ 12420 /* we really should have to wait a while, then retransmit 12421 * We should support the retry-after at some point 12422 * At this point, we treat this as a congestion if the call is not in UP state 12423 */ 12424 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12425 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12426 if (p->owner->_state != AST_STATE_UP) { 12427 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12428 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12429 } else { 12430 /* This is a re-invite that failed. 12431 * Reset the flag after a while 12432 */ 12433 int wait = 3 + ast_random() % 5; 12434 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12435 if (option_debug > 2) 12436 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12437 } 12438 } 12439 break; 12440 12441 case 501: /* Not implemented */ 12442 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12443 if (p->owner) 12444 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12445 break; 12446 } 12447 if (xmitres == XMIT_ERROR) 12448 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12449 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12644 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12645 { 12646 struct sip_peer *peer = p->relatedpeer; 12647 int statechanged, is_reachable, was_reachable; 12648 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12649 12650 /* 12651 * Compute the response time to a ping (goes in peer->lastms.) 12652 * -1 means did not respond, 0 means unknown, 12653 * 1..maxms is a valid response, >maxms means late response. 12654 */ 12655 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12656 pingtime = 1; 12657 12658 /* Now determine new state and whether it has changed. 12659 * Use some helper variables to simplify the writing 12660 * of the expressions. 12661 */ 12662 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12663 is_reachable = pingtime <= peer->maxms; 12664 statechanged = peer->lastms == 0 /* yes, unknown before */ 12665 || was_reachable != is_reachable; 12666 12667 peer->lastms = pingtime; 12668 peer->call = NULL; 12669 if (statechanged) { 12670 const char *s = is_reachable ? "Reachable" : "Lagged"; 12671 12672 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12673 peer->name, s, pingtime, peer->maxms); 12674 ast_device_state_changed("SIP/%s", peer->name); 12675 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12676 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12677 peer->name, s, pingtime); 12678 } 12679 12680 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12681 struct sip_peer *peer_ptr = peer; 12682 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12683 } 12684 12685 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12686 12687 /* Try again eventually */ 12688 peer->pokeexpire = ast_sched_add(sched, 12689 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12690 sip_poke_peer_s, ASTOBJ_REF(peer)); 12691 12692 if (peer->pokeexpire == -1) { 12693 ASTOBJ_UNREF(peer, sip_destroy_peer); 12694 } 12695 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12454 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
12455 { 12456 char *auth = "Proxy-Authenticate"; 12457 char *auth2 = "Proxy-Authorization"; 12458 12459 /* If no refer structure exists, then do nothing */ 12460 if (!p->refer) 12461 return; 12462 12463 switch (resp) { 12464 case 202: /* Transfer accepted */ 12465 /* We need to do something here */ 12466 /* The transferee is now sending INVITE to target */ 12467 p->refer->status = REFER_ACCEPTED; 12468 /* Now wait for next message */ 12469 if (option_debug > 2) 12470 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12471 /* We should hang along, waiting for NOTIFY's here */ 12472 break; 12473 12474 case 401: /* Not www-authorized on SIP method */ 12475 case 407: /* Proxy auth */ 12476 if (ast_strlen_zero(p->authname)) { 12477 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12478 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12479 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12480 } 12481 if (resp == 401) { 12482 auth = "WWW-Authenticate"; 12483 auth2 = "Authorization"; 12484 } 12485 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12486 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12487 p->refer->status = REFER_NOAUTH; 12488 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12489 } 12490 break; 12491 case 481: /* Call leg does not exist */ 12492 12493 /* A transfer with Replaces did not work */ 12494 /* OEJ: We should Set flag, cancel the REFER, go back 12495 to original call - but right now we can't */ 12496 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12497 if (p->owner) 12498 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12499 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12500 break; 12501 12502 case 500: /* Server error */ 12503 case 501: /* Method not implemented */ 12504 /* Return to the current call onhold */ 12505 /* Status flag needed to be reset */ 12506 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12507 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12508 p->refer->status = REFER_FAILED; 12509 break; 12510 case 603: /* Transfer declined */ 12511 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12512 p->refer->status = REFER_FAILED; 12513 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12514 break; 12515 } 12516 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 12519 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12520 { 12521 int expires, expires_ms; 12522 struct sip_registry *r; 12523 r=p->registry; 12524 12525 switch (resp) { 12526 case 401: /* Unauthorized */ 12527 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12528 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12529 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12530 } 12531 break; 12532 case 403: /* Forbidden */ 12533 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12534 if (global_regattempts_max) 12535 p->registry->regattempts = global_regattempts_max+1; 12536 AST_SCHED_DEL(sched, r->timeout); 12537 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12538 break; 12539 case 404: /* Not found */ 12540 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12541 if (global_regattempts_max) 12542 p->registry->regattempts = global_regattempts_max+1; 12543 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12544 r->call = NULL; 12545 AST_SCHED_DEL(sched, r->timeout); 12546 break; 12547 case 407: /* Proxy auth */ 12548 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12549 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12550 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12551 } 12552 break; 12553 case 408: /* Request timeout */ 12554 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12555 r->call = NULL; 12556 AST_SCHED_DEL(sched, r->timeout); 12557 break; 12558 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12559 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12560 if (global_regattempts_max) 12561 p->registry->regattempts = global_regattempts_max+1; 12562 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12563 r->call = NULL; 12564 AST_SCHED_DEL(sched, r->timeout); 12565 break; 12566 case 200: /* 200 OK */ 12567 if (!r) { 12568 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12569 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12570 return 0; 12571 } 12572 12573 r->regstate = REG_STATE_REGISTERED; 12574 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12575 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12576 r->regattempts = 0; 12577 if (option_debug) 12578 ast_log(LOG_DEBUG, "Registration successful\n"); 12579 if (r->timeout > -1) { 12580 if (option_debug) 12581 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12582 } 12583 AST_SCHED_DEL(sched, r->timeout); 12584 r->call = NULL; 12585 p->registry = NULL; 12586 /* Let this one hang around until we have all the responses */ 12587 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12588 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12589 12590 /* set us up for re-registering */ 12591 /* figure out how long we got registered for */ 12592 AST_SCHED_DEL(sched, r->expire); 12593 /* according to section 6.13 of RFC, contact headers override 12594 expires headers, so check those first */ 12595 expires = 0; 12596 12597 /* XXX todo: try to save the extra call */ 12598 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12599 const char *contact = NULL; 12600 const char *tmptmp = NULL; 12601 int start = 0; 12602 for(;;) { 12603 contact = __get_header(req, "Contact", &start); 12604 /* this loop ensures we get a contact header about our register request */ 12605 if(!ast_strlen_zero(contact)) { 12606 if( (tmptmp=strstr(contact, p->our_contact))) { 12607 contact=tmptmp; 12608 break; 12609 } 12610 } else 12611 break; 12612 } 12613 tmptmp = strcasestr(contact, "expires="); 12614 if (tmptmp) { 12615 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12616 expires = 0; 12617 } 12618 12619 } 12620 if (!expires) 12621 expires=atoi(get_header(req, "expires")); 12622 if (!expires) 12623 expires=default_expiry; 12624 12625 expires_ms = expires * 1000; 12626 if (expires <= EXPIRY_GUARD_LIMIT) 12627 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12628 else 12629 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12630 if (sipdebug) 12631 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12632 12633 r->refresh= (int) expires_ms / 1000; 12634 12635 /* Schedule re-registration before we expire */ 12636 AST_SCHED_DEL(sched, r->expire); 12637 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12638 ASTOBJ_UNREF(r, sip_registry_destroy); 12639 } 12640 return 1; 12641 }
static const char * hangup_cause2sip | ( | int | cause | ) | [static] |
Convert Asterisk hangup causes to SIP codes.
Possible values from causes.h AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY AST_CAUSE_FAILURE AST_CAUSE_CONGESTION AST_CAUSE_UNALLOCATED In addition to these, a lot of PRI codes is defined in causes.h ...should we take care of them too ? Quote RFC 3398 ISUP Cause value SIP response ---------------- ------------ 1 unallocated number 404 Not Found 2 no route to network 404 Not found 3 no route to destination 404 Not found 16 normal call clearing --- (*) 17 user busy 486 Busy here 18 no user responding 408 Request Timeout 19 no answer from the user 480 Temporarily unavailable 20 subscriber absent 480 Temporarily unavailable 21 call rejected 403 Forbidden (+) 22 number changed (w/o diagnostic) 410 Gone 22 number changed (w/ diagnostic) 301 Moved Permanently 23 redirection to new destination 410 Gone 26 non-selected user clearing 404 Not Found (=) 27 destination out of order 502 Bad Gateway 28 address incomplete 484 Address incomplete 29 facility rejected 501 Not implemented 31 normal unspecified 480 Temporarily unavailable
Definition at line 3437 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03438 { 03439 switch (cause) { 03440 case AST_CAUSE_UNALLOCATED: /* 1 */ 03441 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03442 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03443 return "404 Not Found"; 03444 case AST_CAUSE_CONGESTION: /* 34 */ 03445 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03446 return "503 Service Unavailable"; 03447 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03448 return "408 Request Timeout"; 03449 case AST_CAUSE_NO_ANSWER: /* 19 */ 03450 return "480 Temporarily unavailable"; 03451 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03452 return "403 Forbidden"; 03453 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03454 return "410 Gone"; 03455 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03456 return "480 Temporarily unavailable"; 03457 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03458 return "484 Address incomplete"; 03459 case AST_CAUSE_USER_BUSY: 03460 return "486 Busy here"; 03461 case AST_CAUSE_FAILURE: 03462 return "500 Server internal failure"; 03463 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03464 return "501 Not Implemented"; 03465 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03466 return "503 Service Unavailable"; 03467 /* Used in chan_iax2 */ 03468 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03469 return "502 Bad Gateway"; 03470 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03471 return "488 Not Acceptable Here"; 03472 03473 case AST_CAUSE_NOTDEFINED: 03474 default: 03475 if (option_debug) 03476 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03477 return NULL; 03478 } 03479 03480 /* Never reached */ 03481 return 0; 03482 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3325 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by handle_response().
03326 { 03327 /* Possible values taken from causes.h */ 03328 03329 switch(cause) { 03330 case 401: /* Unauthorized */ 03331 return AST_CAUSE_CALL_REJECTED; 03332 case 403: /* Not found */ 03333 return AST_CAUSE_CALL_REJECTED; 03334 case 404: /* Not found */ 03335 return AST_CAUSE_UNALLOCATED; 03336 case 405: /* Method not allowed */ 03337 return AST_CAUSE_INTERWORKING; 03338 case 407: /* Proxy authentication required */ 03339 return AST_CAUSE_CALL_REJECTED; 03340 case 408: /* No reaction */ 03341 return AST_CAUSE_NO_USER_RESPONSE; 03342 case 409: /* Conflict */ 03343 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03344 case 410: /* Gone */ 03345 return AST_CAUSE_UNALLOCATED; 03346 case 411: /* Length required */ 03347 return AST_CAUSE_INTERWORKING; 03348 case 413: /* Request entity too large */ 03349 return AST_CAUSE_INTERWORKING; 03350 case 414: /* Request URI too large */ 03351 return AST_CAUSE_INTERWORKING; 03352 case 415: /* Unsupported media type */ 03353 return AST_CAUSE_INTERWORKING; 03354 case 420: /* Bad extension */ 03355 return AST_CAUSE_NO_ROUTE_DESTINATION; 03356 case 480: /* No answer */ 03357 return AST_CAUSE_NO_ANSWER; 03358 case 481: /* No answer */ 03359 return AST_CAUSE_INTERWORKING; 03360 case 482: /* Loop detected */ 03361 return AST_CAUSE_INTERWORKING; 03362 case 483: /* Too many hops */ 03363 return AST_CAUSE_NO_ANSWER; 03364 case 484: /* Address incomplete */ 03365 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03366 case 485: /* Ambigous */ 03367 return AST_CAUSE_UNALLOCATED; 03368 case 486: /* Busy everywhere */ 03369 return AST_CAUSE_BUSY; 03370 case 487: /* Request terminated */ 03371 return AST_CAUSE_INTERWORKING; 03372 case 488: /* No codecs approved */ 03373 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03374 case 491: /* Request pending */ 03375 return AST_CAUSE_INTERWORKING; 03376 case 493: /* Undecipherable */ 03377 return AST_CAUSE_INTERWORKING; 03378 case 500: /* Server internal failure */ 03379 return AST_CAUSE_FAILURE; 03380 case 501: /* Call rejected */ 03381 return AST_CAUSE_FACILITY_REJECTED; 03382 case 502: 03383 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03384 case 503: /* Service unavailable */ 03385 return AST_CAUSE_CONGESTION; 03386 case 504: /* Gateway timeout */ 03387 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03388 case 505: /* SIP version not supported */ 03389 return AST_CAUSE_INTERWORKING; 03390 case 600: /* Busy everywhere */ 03391 return AST_CAUSE_USER_BUSY; 03392 case 603: /* Decline */ 03393 return AST_CAUSE_CALL_REJECTED; 03394 case 604: /* Does not exist anywhere */ 03395 return AST_CAUSE_UNALLOCATED; 03396 case 606: /* Not acceptable */ 03397 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03398 default: 03399 return AST_CAUSE_NORMAL; 03400 } 03401 /* Never reached */ 03402 return 0; 03403 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5872 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, sip_methods, and cfsip_methods::text.
05873 { 05874 /* Initialize a request */ 05875 memset(req, 0, sizeof(*req)); 05876 req->method = sipmethod; 05877 req->header[0] = req->data; 05878 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05879 req->len = strlen(req->header[0]); 05880 req->headers++; 05881 return 0; 05882 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5859 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
05860 { 05861 /* Initialize a response */ 05862 memset(resp, 0, sizeof(*resp)); 05863 resp->method = SIP_RESPONSE; 05864 resp->header[0] = resp->data; 05865 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05866 resp->len = strlen(resp->header[0]); 05867 resp->headers++; 05868 return 0; 05869 }
static void initialize_initreq | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
Definition at line 1642 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_sip_request().
01643 { 01644 if (p->initreq.headers && option_debug) { 01645 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01646 } 01647 /* Use this as the basis */ 01648 copy_request(&p->initreq, req); 01649 parse_request(&p->initreq); 01650 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01651 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01652 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6959 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::ourip, ourport, sip_pvt::owner, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_invite_param::uri_options, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
06960 { 06961 char invite_buf[256] = ""; 06962 char *invite = invite_buf; 06963 size_t invite_max = sizeof(invite_buf); 06964 char from[256]; 06965 char to[256]; 06966 char tmp[SIPBUFSIZE/2]; 06967 char tmp2[SIPBUFSIZE/2]; 06968 const char *l = NULL, *n = NULL; 06969 const char *urioptions = ""; 06970 06971 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06972 const char *s = p->username; /* being a string field, cannot be NULL */ 06973 06974 /* Test p->username against allowed characters in AST_DIGIT_ANY 06975 If it matches the allowed characters list, then sipuser = ";user=phone" 06976 If not, then sipuser = "" 06977 */ 06978 /* + is allowed in first position in a tel: uri */ 06979 if (*s == '+') 06980 s++; 06981 for (; *s; s++) { 06982 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06983 break; 06984 } 06985 /* If we have only digits, add ;user=phone to the uri */ 06986 if (*s) 06987 urioptions = ";user=phone"; 06988 } 06989 06990 06991 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06992 06993 if (p->owner) { 06994 l = p->owner->cid.cid_num; 06995 n = p->owner->cid.cid_name; 06996 } 06997 /* if we are not sending RPID and user wants his callerid restricted */ 06998 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06999 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07000 l = CALLERID_UNKNOWN; 07001 n = l; 07002 } 07003 if (ast_strlen_zero(l)) 07004 l = default_callerid; 07005 if (ast_strlen_zero(n)) 07006 n = l; 07007 /* Allow user to be overridden */ 07008 if (!ast_strlen_zero(p->fromuser)) 07009 l = p->fromuser; 07010 else /* Save for any further attempts */ 07011 ast_string_field_set(p, fromuser, l); 07012 07013 /* Allow user to be overridden */ 07014 if (!ast_strlen_zero(p->fromname)) 07015 n = p->fromname; 07016 else /* Save for any further attempts */ 07017 ast_string_field_set(p, fromname, n); 07018 07019 if (pedanticsipchecking) { 07020 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07021 n = tmp; 07022 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07023 l = tmp2; 07024 } 07025 07026 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07027 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag); 07028 else 07029 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07030 07031 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07032 if (!ast_strlen_zero(p->fullcontact)) { 07033 /* If we have full contact, trust it */ 07034 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07035 } else { 07036 /* Otherwise, use the username while waiting for registration */ 07037 ast_build_string(&invite, &invite_max, "sip:"); 07038 if (!ast_strlen_zero(p->username)) { 07039 n = p->username; 07040 if (pedanticsipchecking) { 07041 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07042 n = tmp; 07043 } 07044 ast_build_string(&invite, &invite_max, "%s@", n); 07045 } 07046 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07047 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07048 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07049 ast_build_string(&invite, &invite_max, "%s", urioptions); 07050 } 07051 07052 /* If custom URI options have been provided, append them */ 07053 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07054 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07055 07056 ast_string_field_set(p, uri, invite_buf); 07057 07058 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07059 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07060 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07061 } else if (p->options && p->options->vxml_url) { 07062 /* If there is a VXML URL append it to the SIP URL */ 07063 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07064 } else 07065 snprintf(to, sizeof(to), "<%s>", p->uri); 07066 07067 init_req(req, sipmethod, p->uri); 07068 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07069 07070 add_header(req, "Via", p->via); 07071 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07072 * OTOH, then we won't have anything in p->route anyway */ 07073 /* Build Remote Party-ID and From */ 07074 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07075 build_rpid(p); 07076 add_header(req, "From", p->rpid_from); 07077 } else 07078 add_header(req, "From", from); 07079 add_header(req, "To", to); 07080 ast_string_field_set(p, exten, l); 07081 build_contact(p); 07082 add_header(req, "Contact", p->our_contact); 07083 add_header(req, "Call-ID", p->callid); 07084 add_header(req, "CSeq", tmp); 07085 if (!ast_strlen_zero(global_useragent)) 07086 add_header(req, "User-Agent", global_useragent); 07087 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07088 if (!ast_strlen_zero(p->rpid)) 07089 add_header(req, "Remote-Party-ID", p->rpid); 07090 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 10138 of file chan_sip.c.
Referenced by _sip_show_peer().
10139 { 10140 if (port && invite) 10141 return "port,invite"; 10142 else if (port) 10143 return "port"; 10144 else if (invite) 10145 return "invite"; 10146 else 10147 return "no"; 10148 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8286 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08287 { 08288 if (!route) 08289 ast_verbose("list_route: no route\n"); 08290 else { 08291 for (;route; route = route->next) 08292 ast_verbose("list_route: hop: <%s>\n", route->hop); 08293 } 08294 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18139 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, EVENT_FLAG_SYSTEM, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, and userl.
18140 { 18141 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18142 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18143 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18144 18145 if (!(sched = sched_context_create())) { 18146 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18147 return AST_MODULE_LOAD_FAILURE; 18148 } 18149 18150 if (!(io = io_context_create())) { 18151 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18152 sched_context_destroy(sched); 18153 return AST_MODULE_LOAD_FAILURE; 18154 } 18155 18156 sip_reloadreason = CHANNEL_MODULE_LOAD; 18157 18158 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18159 return AST_MODULE_LOAD_DECLINE; 18160 18161 /* Make sure we can register our sip channel type */ 18162 if (ast_channel_register(&sip_tech)) { 18163 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18164 io_context_destroy(io); 18165 sched_context_destroy(sched); 18166 return AST_MODULE_LOAD_FAILURE; 18167 } 18168 18169 /* Register all CLI functions for SIP */ 18170 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18171 18172 /* Tell the RTP subdriver that we're here */ 18173 ast_rtp_proto_register(&sip_rtp); 18174 18175 /* Tell the UDPTL subdriver that we're here */ 18176 ast_udptl_proto_register(&sip_udptl); 18177 18178 /* Register dialplan applications */ 18179 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18180 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18181 18182 /* Register dialplan functions */ 18183 ast_custom_function_register(&sip_header_function); 18184 ast_custom_function_register(&sippeer_function); 18185 ast_custom_function_register(&sipchaninfo_function); 18186 ast_custom_function_register(&checksipdomain_function); 18187 18188 /* Register manager commands */ 18189 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18190 "List SIP peers (text format)", mandescr_show_peers); 18191 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18192 "Show SIP peer (text format)", mandescr_show_peer); 18193 18194 sip_poke_all_peers(); 18195 sip_send_all_registers(); 18196 18197 /* And start the monitor for the first time */ 18198 restart_monitor(); 18199 18200 return AST_MODULE_LOAD_SUCCESS; 18201 }
static int local_attended_transfer | ( | struct sip_pvt * | transferer, | |
struct sip_dual * | current, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Find all call legs and bridge transferee with target called from handle_request_refer.
Definition at line 14282 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request_refer().
14283 { 14284 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14285 /* Chan 2: Call from Asterisk to target */ 14286 int res = 0; 14287 struct sip_pvt *targetcall_pvt; 14288 14289 /* Check if the call ID of the replaces header does exist locally */ 14290 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14291 transferer->refer->replaces_callid_fromtag))) { 14292 if (transferer->refer->localtransfer) { 14293 /* We did not find the refered call. Sorry, can't accept then */ 14294 transmit_response(transferer, "202 Accepted", req); 14295 /* Let's fake a response from someone else in order 14296 to follow the standard */ 14297 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14298 append_history(transferer, "Xfer", "Refer failed"); 14299 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14300 transferer->refer->status = REFER_FAILED; 14301 return -1; 14302 } 14303 /* Fall through for remote transfers that we did not find locally */ 14304 if (option_debug > 2) 14305 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14306 return 0; 14307 } 14308 14309 /* Ok, we can accept this transfer */ 14310 transmit_response(transferer, "202 Accepted", req); 14311 append_history(transferer, "Xfer", "Refer accepted"); 14312 if (!targetcall_pvt->owner) { /* No active channel */ 14313 if (option_debug > 3) 14314 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14315 /* Cancel transfer */ 14316 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14317 append_history(transferer, "Xfer", "Refer failed"); 14318 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14319 transferer->refer->status = REFER_FAILED; 14320 ast_mutex_unlock(&targetcall_pvt->lock); 14321 ast_channel_unlock(current->chan1); 14322 return -1; 14323 } 14324 14325 /* We have a channel, find the bridge */ 14326 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14327 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14328 14329 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14330 /* Wrong state of new channel */ 14331 if (option_debug > 3) { 14332 if (target.chan2) 14333 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14334 else if (target.chan1->_state != AST_STATE_RING) 14335 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14336 else 14337 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14338 } 14339 } 14340 14341 /* Transfer */ 14342 if (option_debug > 3 && sipdebug) { 14343 if (current->chan2) /* We have two bridges */ 14344 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14345 else /* One bridge, propably transfer of IVR/voicemail etc */ 14346 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14347 } 14348 14349 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14350 14351 /* Perform the transfer */ 14352 res = attempt_transfer(current, &target); 14353 ast_mutex_unlock(&targetcall_pvt->lock); 14354 if (res) { 14355 /* Failed transfer */ 14356 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14357 append_history(transferer, "Xfer", "Refer failed"); 14358 transferer->refer->status = REFER_FAILED; 14359 if (targetcall_pvt->owner) 14360 ast_channel_unlock(targetcall_pvt->owner); 14361 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14362 if (res != -2) 14363 ast_hangup(transferer->owner); 14364 else 14365 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14366 } else { 14367 /* Transfer succeeded! */ 14368 14369 /* Tell transferer that we're done. */ 14370 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14371 append_history(transferer, "Xfer", "Refer succeeded"); 14372 transferer->refer->status = REFER_200OK; 14373 if (targetcall_pvt->owner) { 14374 if (option_debug) 14375 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14376 ast_channel_unlock(targetcall_pvt->owner); 14377 } 14378 } 14379 return 1; 14380 }
static int lws2sws | ( | char * | msgbuf, | |
int | len | |||
) | [static] |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
Definition at line 4772 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04773 { 04774 int h = 0, t = 0; 04775 int lws = 0; 04776 04777 for (; h < len;) { 04778 /* Eliminate all CRs */ 04779 if (msgbuf[h] == '\r') { 04780 h++; 04781 continue; 04782 } 04783 /* Check for end-of-line */ 04784 if (msgbuf[h] == '\n') { 04785 /* Check for end-of-message */ 04786 if (h + 1 == len) 04787 break; 04788 /* Check for a continuation line */ 04789 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04790 /* Merge continuation line */ 04791 h++; 04792 continue; 04793 } 04794 /* Propagate LF and start new line */ 04795 msgbuf[t++] = msgbuf[h++]; 04796 lws = 0; 04797 continue; 04798 } 04799 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04800 if (lws) { 04801 h++; 04802 continue; 04803 } 04804 msgbuf[t++] = msgbuf[h++]; 04805 lws = 1; 04806 continue; 04807 } 04808 msgbuf[t++] = msgbuf[h++]; 04809 if (lws) 04810 lws = 0; 04811 } 04812 msgbuf[t] = '\0'; 04813 return t; 04814 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4441 of file chan_sip.c.
References ast_random().
Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().
04442 { 04443 snprintf(tagbuf, len, "as%08lx", ast_random()); 04444 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10383 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
10384 { 10385 const char *a[4]; 10386 const char *peer; 10387 int ret; 10388 10389 peer = astman_get_header(m,"Peer"); 10390 if (ast_strlen_zero(peer)) { 10391 astman_send_error(s, m, "Peer: <name> missing.\n"); 10392 return 0; 10393 } 10394 a[0] = "sip"; 10395 a[1] = "show"; 10396 a[2] = "peer"; 10397 a[3] = peer; 10398 10399 ret = _sip_show_peer(1, -1, s, m, 4, a); 10400 astman_append(s, "\r\n\r\n" ); 10401 return ret; 10402 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9934 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), and total.
Referenced by load_module().
09935 { 09936 const char *id = astman_get_header(m,"ActionID"); 09937 const char *a[] = {"sip", "show", "peers"}; 09938 char idtext[256] = ""; 09939 int total = 0; 09940 09941 if (!ast_strlen_zero(id)) 09942 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09943 09944 astman_send_ack(s, m, "Peer status list will follow"); 09945 /* List the peers in separate manager events */ 09946 _sip_show_peers(-1, &total, s, m, 3, a); 09947 /* Send final confirmation */ 09948 astman_append(s, 09949 "Event: PeerlistComplete\r\n" 09950 "ListItems: %d\r\n" 09951 "%s" 09952 "\r\n", total, idtext); 09953 return 0; 09954 }
static int method_match | ( | enum sipmethod | id, | |
const char * | name | |||
) | [static] |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
Definition at line 1668 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01669 { 01670 int len = strlen(sip_methods[id].text); 01671 int l_name = name ? strlen(name) : 0; 01672 /* true if the string is long enough, and ends with whitespace, and matches */ 01673 return (l_name >= len && name[len] < 33 && 01674 !strncasecmp(sip_methods[id].text, name, len)); 01675 }
static char * nat2str | ( | int | nat | ) | [static] |
Convert NAT setting to text string.
Definition at line 9837 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().
09838 { 09839 switch(nat) { 09840 case SIP_NAT_NEVER: 09841 return "No"; 09842 case SIP_NAT_ROUTE: 09843 return "Route"; 09844 case SIP_NAT_ALWAYS: 09845 return "Always"; 09846 case SIP_NAT_RFC3581: 09847 return "RFC3581"; 09848 default: 09849 return "Unknown"; 09850 } 09851 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2240 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02241 { 02242 memset(dst, 0, sizeof(*dst)); 02243 memcpy(dst->data, src->data, sizeof(dst->data)); 02244 dst->len = src->len; 02245 parse_request(dst); 02246 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12023 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, SIPBUFSIZE, and t.
Referenced by handle_response().
12024 { 12025 char tmp[SIPBUFSIZE]; 12026 char *s, *e, *uri, *t; 12027 char *domain; 12028 12029 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12030 if ((t = strchr(tmp, ','))) 12031 *t = '\0'; 12032 s = get_in_brackets(tmp); 12033 uri = ast_strdupa(s); 12034 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12035 if (!strncasecmp(s, "sip:", 4)) 12036 s += 4; 12037 e = strchr(s, ';'); 12038 if (e) 12039 *e = '\0'; 12040 if (option_debug) 12041 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12042 if (p->owner) 12043 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12044 } else { 12045 e = strchr(tmp, '@'); 12046 if (e) { 12047 *e++ = '\0'; 12048 domain = e; 12049 } else { 12050 /* No username part */ 12051 domain = tmp; 12052 } 12053 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12054 if (e) 12055 *e = '\0'; 12056 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12057 if (e) 12058 *e = '\0'; 12059 12060 if (!strncasecmp(s, "sip:", 4)) 12061 s += 4; 12062 if (option_debug > 1) 12063 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12064 if (p->owner) { 12065 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12066 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12067 ast_string_field_set(p->owner, call_forward, s); 12068 } 12069 } 12070 }
static int parse_ok_contact | ( | struct sip_pvt * | pvt, | |
struct sip_request * | req | |||
) | [static] |
Save contact header for 200 OK on INVITE.
Definition at line 8034 of file chan_sip.c.
References ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
08035 { 08036 char contact[SIPBUFSIZE]; 08037 char *c; 08038 08039 /* Look for brackets */ 08040 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08041 c = get_in_brackets(contact); 08042 08043 /* Save full contact to call pvt for later bye or re-invite */ 08044 ast_string_field_set(pvt, fullcontact, c); 08045 08046 /* Save URI for later ACKs, BYE or RE-invites */ 08047 ast_string_field_set(pvt, okcontacturi, c); 08048 08049 /* We should return false for URI:s we can't handle, 08050 like sips:, tel:, mailto:,ldap: etc */ 08051 return TRUE; 08052 }
static enum parse_register_result parse_register_contact | ( | struct sip_pvt * | pvt, | |
struct sip_peer * | p, | |||
struct sip_request * | req | |||
) | [static] |
Parse contact header and save registration (peer registration).
Definition at line 8118 of file chan_sip.c.
References sip_peer::addr, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08119 { 08120 char contact[SIPBUFSIZE]; 08121 char data[SIPBUFSIZE]; 08122 const char *expires = get_header(req, "Expires"); 08123 int expiry = atoi(expires); 08124 char *curi, *n, *pt; 08125 int port; 08126 const char *useragent; 08127 struct hostent *hp; 08128 struct ast_hostent ahp; 08129 struct sockaddr_in oldsin; 08130 08131 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08132 08133 if (ast_strlen_zero(expires)) { /* No expires header */ 08134 expires = strcasestr(contact, ";expires="); 08135 if (expires) { 08136 /* XXX bug here, we overwrite the string */ 08137 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08138 if (sscanf(expires + 9, "%d", &expiry) != 1) 08139 expiry = default_expiry; 08140 } else { 08141 /* Nothing has been specified */ 08142 expiry = default_expiry; 08143 } 08144 } 08145 08146 /* Look for brackets */ 08147 curi = contact; 08148 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08149 strsep(&curi, ";"); /* This is Header options, not URI options */ 08150 curi = get_in_brackets(contact); 08151 08152 /* if they did not specify Contact: or Expires:, they are querying 08153 what we currently have stored as their contact address, so return 08154 it 08155 */ 08156 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08157 /* If we have an active registration, tell them when the registration is going to expire */ 08158 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08159 pvt->expiry = ast_sched_when(sched, peer->expire); 08160 return PARSE_REGISTER_QUERY; 08161 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08162 /* This means remove all registrations and return OK */ 08163 memset(&peer->addr, 0, sizeof(peer->addr)); 08164 if (!AST_SCHED_DEL(sched, peer->expire)) { 08165 struct sip_peer *peer_ptr = peer; 08166 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08167 } 08168 08169 destroy_association(peer); 08170 08171 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08172 peer->fullcontact[0] = '\0'; 08173 peer->useragent[0] = '\0'; 08174 peer->sipoptions = 0; 08175 peer->lastms = 0; 08176 08177 if (option_verbose > 2) 08178 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08179 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08180 return PARSE_REGISTER_UPDATE; 08181 } 08182 08183 /* Store whatever we got as a contact from the client */ 08184 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08185 08186 /* For the 200 OK, we should use the received contact */ 08187 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08188 08189 /* Make sure it's a SIP URL */ 08190 if (strncasecmp(curi, "sip:", 4)) { 08191 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08192 } else 08193 curi += 4; 08194 /* Ditch q */ 08195 curi = strsep(&curi, ";"); 08196 /* Grab host */ 08197 n = strchr(curi, '@'); 08198 if (!n) { 08199 n = curi; 08200 curi = NULL; 08201 } else 08202 *n++ = '\0'; 08203 pt = strchr(n, ':'); 08204 if (pt) { 08205 *pt++ = '\0'; 08206 port = atoi(pt); 08207 } else 08208 port = STANDARD_SIP_PORT; 08209 oldsin = peer->addr; 08210 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08211 /* XXX This could block for a long time XXX */ 08212 hp = ast_gethostbyname(n, &ahp); 08213 if (!hp) { 08214 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08215 return PARSE_REGISTER_FAILED; 08216 } 08217 peer->addr.sin_family = AF_INET; 08218 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08219 peer->addr.sin_port = htons(port); 08220 } else { 08221 /* Don't trust the contact field. Just use what they came to us 08222 with */ 08223 peer->addr = pvt->recv; 08224 } 08225 08226 /* Save SIP options profile */ 08227 peer->sipoptions = pvt->sipoptions; 08228 08229 if (curi && ast_strlen_zero(peer->username)) 08230 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08231 08232 if (!AST_SCHED_DEL(sched, peer->expire)) { 08233 struct sip_peer *peer_ptr = peer; 08234 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08235 } 08236 if (expiry > max_expiry) 08237 expiry = max_expiry; 08238 if (expiry < min_expiry) 08239 expiry = min_expiry; 08240 if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) { 08241 peer->expire = -1; 08242 } else { 08243 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08244 if (peer->expire == -1) { 08245 struct sip_peer *peer_ptr = peer; 08246 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08247 } 08248 } 08249 pvt->expiry = expiry; 08250 snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry, peer->username, peer->fullcontact); 08251 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08252 ast_db_put("SIP/Registry", peer->name, data); 08253 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08254 08255 /* Is this a new IP address for us? */ 08256 if (inaddrcmp(&peer->addr, &oldsin)) { 08257 sip_poke_peer(peer); 08258 if (option_verbose > 2) 08259 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry); 08260 register_peer_exten(peer, 1); 08261 } 08262 08263 /* Save User agent */ 08264 useragent = get_header(req, "User-Agent"); 08265 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08266 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08267 if (option_verbose > 3) 08268 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08269 } 08270 return PARSE_REGISTER_UPDATE; 08271 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4819 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04820 { 04821 /* Divide fields by NULL's */ 04822 char *c; 04823 int f = 0; 04824 04825 c = req->data; 04826 04827 /* First header starts immediately */ 04828 req->header[f] = c; 04829 while(*c) { 04830 if (*c == '\n') { 04831 /* We've got a new header */ 04832 *c = 0; 04833 04834 if (sipdebug && option_debug > 3) 04835 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04836 if (ast_strlen_zero(req->header[f])) { 04837 /* Line by itself means we're now in content */ 04838 c++; 04839 break; 04840 } 04841 if (f >= SIP_MAX_HEADERS - 1) { 04842 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04843 } else 04844 f++; 04845 req->header[f] = c + 1; 04846 } else if (*c == '\r') { 04847 /* Ignore but eliminate \r's */ 04848 *c = 0; 04849 } 04850 c++; 04851 } 04852 /* Check for last header */ 04853 if (!ast_strlen_zero(req->header[f])) { 04854 if (sipdebug && option_debug > 3) 04855 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04856 f++; 04857 } 04858 req->headers = f; 04859 /* Now we process any mime content */ 04860 f = 0; 04861 req->line[f] = c; 04862 while(*c) { 04863 if (*c == '\n') { 04864 /* We've got a new line */ 04865 *c = 0; 04866 if (sipdebug && option_debug > 3) 04867 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04868 if (f >= SIP_MAX_LINES - 1) { 04869 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04870 } else 04871 f++; 04872 req->line[f] = c + 1; 04873 } else if (*c == '\r') { 04874 /* Ignore and eliminate \r's */ 04875 *c = 0; 04876 } 04877 c++; 04878 } 04879 /* Check for last line */ 04880 if (!ast_strlen_zero(req->line[f])) 04881 f++; 04882 req->lines = f; 04883 if (*c) 04884 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04885 /* Split up the first line parts */ 04886 return determine_firstline_parts(req); 04887 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1692 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01693 { 01694 char *next, *sep; 01695 char *temp; 01696 unsigned int profile = 0; 01697 int i, found; 01698 01699 if (ast_strlen_zero(supported) ) 01700 return 0; 01701 temp = ast_strdupa(supported); 01702 01703 if (option_debug > 2 && sipdebug) 01704 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01705 01706 for (next = temp; next; next = sep) { 01707 found = FALSE; 01708 if ( (sep = strchr(next, ',')) != NULL) 01709 *sep++ = '\0'; 01710 next = ast_skip_blanks(next); 01711 if (option_debug > 2 && sipdebug) 01712 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01713 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01714 if (!strcasecmp(next, sip_options[i].text)) { 01715 profile |= sip_options[i].id; 01716 found = TRUE; 01717 if (option_debug > 2 && sipdebug) 01718 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01719 break; 01720 } 01721 } 01722 if (!found && option_debug > 2 && sipdebug) { 01723 if (!strncasecmp(next, "x-", 2)) 01724 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01725 else 01726 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01727 } 01728 } 01729 01730 if (pvt) 01731 pvt->sipoptions = profile; 01732 return profile; 01733 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9856 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09857 { 09858 int res = 0; 09859 if (peer->maxms) { 09860 if (peer->lastms < 0) { 09861 ast_copy_string(status, "UNREACHABLE", statuslen); 09862 } else if (peer->lastms > peer->maxms) { 09863 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09864 res = 1; 09865 } else if (peer->lastms) { 09866 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09867 res = 1; 09868 } else { 09869 ast_copy_string(status, "UNKNOWN", statuslen); 09870 } 09871 } else { 09872 ast_copy_string(status, "Unmonitored", statuslen); 09873 /* Checking if port is 0 */ 09874 res = -1; 09875 } 09876 return res; 09877 }
static void print_codec_to_cli | ( | int | fd, | |
struct ast_codec_pref * | pref | |||
) | [static] |
Print codec list from preference to CLI/manager.
Definition at line 10324 of file chan_sip.c.
References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.
Referenced by _sip_show_peer(), sip_show_settings(), and sip_show_user().
10325 { 10326 int x, codec; 10327 10328 for(x = 0; x < 32 ; x++) { 10329 codec = ast_codec_pref_index(pref, x); 10330 if (!codec) 10331 break; 10332 ast_cli(fd, "%s", ast_getformatname(codec)); 10333 ast_cli(fd, ":%d", pref->framing[x]); 10334 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10335 ast_cli(fd, ","); 10336 } 10337 if (!x) 10338 ast_cli(fd, "none"); 10339 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10115 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10116 { 10117 char buf[256]; 10118 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10119 }
static int process_sdp | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP Audio port number
< RTP Video port number
< media socket address
< Video socket address
< RTP Audio host IP
< RTP video host IP
Definition at line 5020 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, sip_pvt::capability, t38properties::capability, change_hold_state(), debug, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LONG_MAX, LONG_MIN, MAX_RTP_PT, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
05021 { 05022 const char *m; /* SDP media offer */ 05023 const char *c; 05024 const char *a; 05025 char host[258]; 05026 int len = -1; 05027 int portno = -1; /*!< RTP Audio port number */ 05028 int vportno = -1; /*!< RTP Video port number */ 05029 int udptlportno = -1; 05030 int peert38capability = 0; 05031 char s[256]; 05032 int old = 0; 05033 05034 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05035 int peercapability = 0, peernoncodeccapability = 0; 05036 int vpeercapability = 0, vpeernoncodeccapability = 0; 05037 struct sockaddr_in sin; /*!< media socket address */ 05038 struct sockaddr_in vsin; /*!< Video socket address */ 05039 05040 const char *codecs; 05041 struct hostent *hp; /*!< RTP Audio host IP */ 05042 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05043 struct ast_hostent audiohp; 05044 struct ast_hostent videohp; 05045 int codec; 05046 int destiterator = 0; 05047 int iterator; 05048 int sendonly = -1; 05049 int numberofports; 05050 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05051 int newjointcapability; /* Negotiated capability */ 05052 int newpeercapability; 05053 int newnoncodeccapability; 05054 int numberofmediastreams = 0; 05055 int debug = sip_debug_test_pvt(p); 05056 05057 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05058 int last_rtpmap_codec=0; 05059 05060 if (!p->rtp) { 05061 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05062 return -1; 05063 } 05064 05065 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05066 newaudiortp = alloca(ast_rtp_alloc_size()); 05067 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05068 ast_rtp_new_init(newaudiortp); 05069 ast_rtp_pt_clear(newaudiortp); 05070 05071 newvideortp = alloca(ast_rtp_alloc_size()); 05072 memset(newvideortp, 0, ast_rtp_alloc_size()); 05073 ast_rtp_new_init(newvideortp); 05074 ast_rtp_pt_clear(newvideortp); 05075 05076 /* Update our last rtprx when we receive an SDP, too */ 05077 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05078 05079 05080 /* Try to find first media stream */ 05081 m = get_sdp(req, "m"); 05082 destiterator = req->sdp_start; 05083 c = get_sdp_iterate(&destiterator, req, "c"); 05084 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05085 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05086 return -1; 05087 } 05088 05089 /* Check for IPv4 address (not IPv6 yet) */ 05090 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05091 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05092 return -1; 05093 } 05094 05095 /* XXX This could block for a long time, and block the main thread! XXX */ 05096 hp = ast_gethostbyname(host, &audiohp); 05097 if (!hp) { 05098 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05099 return -1; 05100 } 05101 vhp = hp; /* Copy to video address as default too */ 05102 05103 iterator = req->sdp_start; 05104 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05105 05106 05107 /* Find media streams in this SDP offer */ 05108 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05109 int x; 05110 int audio = FALSE; 05111 05112 numberofports = 1; 05113 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05114 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05115 audio = TRUE; 05116 numberofmediastreams++; 05117 /* Found audio stream in this media definition */ 05118 portno = x; 05119 /* Scan through the RTP payload types specified in a "m=" line: */ 05120 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05121 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05122 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05123 return -1; 05124 } 05125 if (debug) 05126 ast_verbose("Found RTP audio format %d\n", codec); 05127 ast_rtp_set_m_type(newaudiortp, codec); 05128 } 05129 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05130 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05131 /* If it is not audio - is it video ? */ 05132 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05133 numberofmediastreams++; 05134 vportno = x; 05135 /* Scan through the RTP payload types specified in a "m=" line: */ 05136 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05137 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05138 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05139 return -1; 05140 } 05141 if (debug) 05142 ast_verbose("Found RTP video format %d\n", codec); 05143 ast_rtp_set_m_type(newvideortp, codec); 05144 } 05145 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05146 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05147 if (debug) 05148 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05149 udptlportno = x; 05150 numberofmediastreams++; 05151 05152 if (p->owner && p->lastinvite) { 05153 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05154 if (option_debug > 1) 05155 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05156 } else { 05157 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05158 if (option_debug > 1) 05159 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05160 } 05161 } else 05162 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05163 if (numberofports > 1) 05164 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05165 05166 05167 /* Check for Media-description-level-address for audio */ 05168 c = get_sdp_iterate(&destiterator, req, "c"); 05169 if (!ast_strlen_zero(c)) { 05170 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05171 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05172 } else { 05173 /* XXX This could block for a long time, and block the main thread! XXX */ 05174 if (audio) { 05175 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05176 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05177 return -2; 05178 } 05179 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05180 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05181 return -2; 05182 } 05183 } 05184 05185 } 05186 } 05187 if (portno == -1 && vportno == -1 && udptlportno == -1) 05188 /* No acceptable offer found in SDP - we have no ports */ 05189 /* Do not change RTP or VRTP if this is a re-invite */ 05190 return -2; 05191 05192 if (numberofmediastreams > 2) 05193 /* We have too many fax, audio and/or video media streams, fail this offer */ 05194 return -3; 05195 05196 /* RTP addresses and ports for audio and video */ 05197 sin.sin_family = AF_INET; 05198 vsin.sin_family = AF_INET; 05199 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05200 if (vhp) 05201 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05202 05203 /* Setup UDPTL port number */ 05204 if (p->udptl) { 05205 if (udptlportno > 0) { 05206 sin.sin_port = htons(udptlportno); 05207 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05208 struct sockaddr_in peer; 05209 ast_rtp_get_peer(p->rtp, &peer); 05210 if (peer.sin_addr.s_addr) { 05211 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(&sin.sin_addr)); 05212 if (debug) { 05213 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(sin.sin_addr)); 05214 } 05215 } 05216 } 05217 ast_udptl_set_peer(p->udptl, &sin); 05218 if (debug) 05219 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05220 } else { 05221 ast_udptl_stop(p->udptl); 05222 if (debug) 05223 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05224 } 05225 } 05226 05227 05228 if (p->rtp) { 05229 if (portno > 0) { 05230 sin.sin_port = htons(portno); 05231 ast_rtp_set_peer(p->rtp, &sin); 05232 if (debug) 05233 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05234 } else { 05235 if (udptlportno > 0) { 05236 if (debug) 05237 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05238 } else { 05239 ast_rtp_stop(p->rtp); 05240 if (debug) 05241 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05242 } 05243 } 05244 } 05245 /* Setup video port number */ 05246 if (vportno != -1) 05247 vsin.sin_port = htons(vportno); 05248 05249 /* Next, scan through each "a=rtpmap:" line, noting each 05250 * specified RTP payload type (with corresponding MIME subtype): 05251 */ 05252 /* XXX This needs to be done per media stream, since it's media stream specific */ 05253 iterator = req->sdp_start; 05254 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05255 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05256 if (option_debug > 1) { 05257 int breakout = FALSE; 05258 05259 /* If we're debugging, check for unsupported sdp options */ 05260 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05261 if (debug) 05262 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05263 breakout = TRUE; 05264 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05265 /* Format parameters: Not supported */ 05266 /* Note: This is used for codec parameters, like bitrate for 05267 G722 and video formats for H263 and H264 05268 See RFC2327 for an example */ 05269 if (debug) 05270 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05271 breakout = TRUE; 05272 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05273 /* Video stuff: Not supported */ 05274 if (debug) 05275 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05276 breakout = TRUE; 05277 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05278 /* Video stuff: Not supported */ 05279 if (debug) 05280 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05281 breakout = TRUE; 05282 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05283 /* SRTP stuff, not yet supported */ 05284 if (debug) 05285 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05286 breakout = TRUE; 05287 } 05288 if (breakout) /* We have a match, skip to next header */ 05289 continue; 05290 } 05291 if (!strcasecmp(a, "sendonly")) { 05292 if (sendonly == -1) 05293 sendonly = 1; 05294 continue; 05295 } else if (!strcasecmp(a, "inactive")) { 05296 if (sendonly == -1) 05297 sendonly = 2; 05298 continue; 05299 } else if (!strcasecmp(a, "sendrecv")) { 05300 if (sendonly == -1) 05301 sendonly = 0; 05302 continue; 05303 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05304 char *tmp = strrchr(a, ':'); 05305 long int framing = 0; 05306 if (tmp) { 05307 tmp++; 05308 framing = strtol(tmp, NULL, 10); 05309 if (framing == LONG_MIN || framing == LONG_MAX) { 05310 framing = 0; 05311 if (option_debug) 05312 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05313 } 05314 } 05315 if (framing && p->autoframing) { 05316 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05317 int codec_n; 05318 int format = 0; 05319 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05320 format = ast_rtp_codec_getformat(codec_n); 05321 if (!format) /* non-codec or not found */ 05322 continue; 05323 if (option_debug) 05324 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05325 ast_codec_pref_setsize(pref, format, framing); 05326 } 05327 ast_rtp_codec_setpref(p->rtp, pref); 05328 } 05329 continue; 05330 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05331 /* We have a rtpmap to handle */ 05332 int found = FALSE; 05333 /* We should propably check if this is an audio or video codec 05334 so we know where to look */ 05335 05336 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05337 /* Note: should really look at the 'freq' and '#chans' params too */ 05338 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05339 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05340 if (debug) 05341 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05342 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05343 last_rtpmap_codec++; 05344 found = TRUE; 05345 05346 } else if (p->vrtp) { 05347 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05348 if (debug) 05349 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05350 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05351 last_rtpmap_codec++; 05352 found = TRUE; 05353 } 05354 } 05355 } else { 05356 if (debug) 05357 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05358 } 05359 05360 if (!found) { 05361 /* Remove this codec since it's an unknown media type for us */ 05362 /* XXX This is buggy since the media line for audio and video can have the 05363 same numbers. We need to check as described above, but for testing this works... */ 05364 ast_rtp_unset_m_type(newaudiortp, codec); 05365 ast_rtp_unset_m_type(newvideortp, codec); 05366 if (debug) 05367 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05368 } 05369 } 05370 } 05371 05372 if (udptlportno != -1) { 05373 int found = 0, x; 05374 05375 old = 0; 05376 05377 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05378 iterator = req->sdp_start; 05379 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05380 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05381 found = 1; 05382 if (option_debug > 2) 05383 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05384 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05385 found = 1; 05386 if (option_debug > 2) 05387 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05388 switch (x) { 05389 case 14400: 05390 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05391 break; 05392 case 12000: 05393 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05394 break; 05395 case 9600: 05396 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05397 break; 05398 case 7200: 05399 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05400 break; 05401 case 4800: 05402 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05403 break; 05404 case 2400: 05405 peert38capability |= T38FAX_RATE_2400; 05406 break; 05407 } 05408 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05409 found = 1; 05410 if (option_debug > 2) 05411 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05412 if (x == 0) 05413 peert38capability |= T38FAX_VERSION_0; 05414 else if (x == 1) 05415 peert38capability |= T38FAX_VERSION_1; 05416 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05417 found = 1; 05418 if (option_debug > 2) 05419 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05420 ast_udptl_set_far_max_datagram(p->udptl, x); 05421 ast_udptl_set_local_max_datagram(p->udptl, x); 05422 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05423 found = 1; 05424 if (option_debug > 2) 05425 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05426 if (x == 1) 05427 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05428 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05429 found = 1; 05430 if (option_debug > 2) 05431 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05432 if (x == 1) 05433 peert38capability |= T38FAX_TRANSCODING_MMR; 05434 } 05435 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05436 found = 1; 05437 if (option_debug > 2) 05438 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05439 if (x == 1) 05440 peert38capability |= T38FAX_TRANSCODING_JBIG; 05441 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05442 found = 1; 05443 if (option_debug > 2) 05444 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05445 if (!strcasecmp(s, "localTCF")) 05446 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05447 else if (!strcasecmp(s, "transferredTCF")) 05448 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05449 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05450 found = 1; 05451 if (option_debug > 2) 05452 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05453 if (!strcasecmp(s, "t38UDPRedundancy")) { 05454 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05455 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05456 } else if (!strcasecmp(s, "t38UDPFEC")) { 05457 peert38capability |= T38FAX_UDP_EC_FEC; 05458 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05459 } else { 05460 peert38capability |= T38FAX_UDP_EC_NONE; 05461 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05462 } 05463 } 05464 } 05465 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05466 p->t38.peercapability = peert38capability; 05467 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05468 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05469 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05470 } 05471 if (debug) 05472 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05473 p->t38.capability, 05474 p->t38.peercapability, 05475 p->t38.jointcapability); 05476 } else { 05477 p->t38.state = T38_DISABLED; 05478 if (option_debug > 2) 05479 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05480 } 05481 05482 /* Now gather all of the codecs that we are asked for: */ 05483 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05484 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05485 05486 newjointcapability = p->capability & (peercapability | vpeercapability); 05487 newpeercapability = (peercapability | vpeercapability); 05488 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05489 05490 05491 if (debug) { 05492 /* shame on whoever coded this.... */ 05493 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05494 05495 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05496 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05497 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05498 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05499 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05500 05501 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05502 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05503 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05504 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05505 } 05506 if (!newjointcapability) { 05507 /* If T.38 was not negotiated either, totally bail out... */ 05508 if (!p->t38.jointcapability || !udptlportno) { 05509 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05510 /* Do NOT Change current setting */ 05511 return -1; 05512 } else { 05513 if (option_debug > 2) 05514 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05515 return 0; 05516 } 05517 } 05518 05519 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05520 they are acceptable */ 05521 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05522 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05523 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05524 05525 ast_rtp_pt_copy(p->rtp, newaudiortp); 05526 if (p->vrtp) 05527 ast_rtp_pt_copy(p->vrtp, newvideortp); 05528 05529 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05530 ast_clear_flag(&p->flags[0], SIP_DTMF); 05531 if (newnoncodeccapability & AST_RTP_DTMF) { 05532 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05533 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05534 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05535 ast_rtp_setdtmf(p->rtp, 1); 05536 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05537 } else { 05538 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05539 } 05540 } 05541 05542 /* Setup audio port number */ 05543 if (p->rtp && sin.sin_port) { 05544 ast_rtp_set_peer(p->rtp, &sin); 05545 if (debug) 05546 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05547 } 05548 05549 /* Setup video port number */ 05550 if (p->vrtp && vsin.sin_port) { 05551 ast_rtp_set_peer(p->vrtp, &vsin); 05552 if (debug) 05553 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05554 } 05555 05556 /* Ok, we're going with this offer */ 05557 if (option_debug > 1) { 05558 char buf[SIPBUFSIZE]; 05559 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05560 } 05561 05562 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05563 return 0; 05564 05565 if (option_debug > 3) 05566 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05567 05568 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05569 if (debug) { 05570 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05571 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05572 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05573 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05574 } 05575 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05576 ast_set_read_format(p->owner, p->owner->readformat); 05577 ast_set_write_format(p->owner, p->owner->writeformat); 05578 } 05579 05580 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05581 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05582 /* Activate a re-invite */ 05583 ast_queue_frame(p->owner, &ast_null_frame); 05584 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05585 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05586 S_OR(p->mohsuggest, NULL), 05587 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05588 if (sendonly) 05589 ast_rtp_stop(p->rtp); 05590 /* RTCP needs to go ahead, even if we're on hold!!! */ 05591 /* Activate a re-invite */ 05592 ast_queue_frame(p->owner, &ast_null_frame); 05593 } 05594 05595 /* Manager Hold and Unhold events must be generated, if necessary */ 05596 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05597 change_hold_state(p, req, FALSE, sendonly); 05598 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05599 change_hold_state(p, req, TRUE, sendonly); 05600 return 0; 05601 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2505 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, ASTOBJ_REF, ASTOBJ_UNREF, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, hp, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), sip_destroy_peer(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.
02506 { 02507 struct sip_peer *peer=NULL; 02508 struct ast_variable *var = NULL; 02509 struct ast_config *peerlist = NULL; 02510 struct ast_variable *tmp; 02511 struct ast_flags flags = {0}; 02512 const char *iabuf = NULL; 02513 char portstring[6]; /*up to five digits plus null terminator*/ 02514 const char *insecure; 02515 char *cat = NULL; 02516 unsigned short portnum; 02517 02518 /* First check on peer name */ 02519 if (newpeername) { 02520 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02521 if (!var && sin) 02522 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02523 if (!var) { 02524 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02525 /*!\note 02526 * If this one loaded something, then we need to ensure that the host 02527 * field matched. The only reason why we can't have this as a criteria 02528 * is because we only have the IP address and the host field might be 02529 * set as a name (and the reverse PTR might not match). 02530 */ 02531 if (var && sin) { 02532 for (tmp = var; tmp; tmp = tmp->next) { 02533 if (!strcasecmp(tmp->name, "host")) { 02534 struct hostent *hp; 02535 struct ast_hostent ahp; 02536 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02537 /* No match */ 02538 ast_variables_destroy(var); 02539 var = NULL; 02540 } 02541 break; 02542 } 02543 } 02544 } 02545 } 02546 } 02547 02548 if (!var && sin) { /* Then check on IP address */ 02549 iabuf = ast_inet_ntoa(sin->sin_addr); 02550 portnum = ntohs(sin->sin_port); 02551 sprintf(portstring, "%d", portnum); 02552 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02553 if (!var) 02554 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02555 if (!var) { 02556 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02557 if(peerlist){ 02558 while((cat = ast_category_browse(peerlist, cat))) 02559 { 02560 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02561 set_insecure_flags(&flags, insecure, -1); 02562 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02563 var = ast_category_root(peerlist, cat); 02564 break; 02565 } 02566 } 02567 } 02568 if(!var) { 02569 ast_config_destroy(peerlist); 02570 peerlist = NULL; /*for safety's sake*/ 02571 cat = NULL; 02572 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02573 if(peerlist) { 02574 while((cat = ast_category_browse(peerlist, cat))) 02575 { 02576 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02577 set_insecure_flags(&flags, insecure, -1); 02578 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02579 var = ast_category_root(peerlist, cat); 02580 break; 02581 } 02582 } 02583 } 02584 } 02585 } 02586 } 02587 02588 if (!var) { 02589 if(peerlist) 02590 ast_config_destroy(peerlist); 02591 return NULL; 02592 } 02593 02594 for (tmp = var; tmp; tmp = tmp->next) { 02595 /* If this is type=user, then skip this object. */ 02596 if (!strcasecmp(tmp->name, "type") && 02597 !strcasecmp(tmp->value, "user")) { 02598 ast_variables_destroy(var); 02599 return NULL; 02600 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02601 newpeername = tmp->value; 02602 } 02603 } 02604 02605 if (!newpeername) { /* Did not find peer in realtime */ 02606 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02607 if(peerlist) 02608 ast_config_destroy(peerlist); 02609 else 02610 ast_variables_destroy(var); 02611 return NULL; 02612 } 02613 02614 /* Peer found in realtime, now build it in memory */ 02615 peer = build_peer(newpeername, var, NULL, 1); 02616 if (!peer) { 02617 if(peerlist) 02618 ast_config_destroy(peerlist); 02619 else 02620 ast_variables_destroy(var); 02621 return NULL; 02622 } 02623 02624 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02625 /* Cache peer */ 02626 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02627 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02628 if (!AST_SCHED_DEL(sched, peer->expire)) { 02629 struct sip_peer *peer_ptr = peer; 02630 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02631 } 02632 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02633 if (peer->expire == -1) { 02634 struct sip_peer *peer_ptr = peer; 02635 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02636 } 02637 } 02638 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02639 } else { 02640 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02641 } 02642 if(peerlist) 02643 ast_config_destroy(peerlist); 02644 else 02645 ast_variables_destroy(var); 02646 return peer; 02647 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey | |||
) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 2394 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02395 { 02396 char port[10]; 02397 char ipaddr[INET_ADDRSTRLEN]; 02398 char regseconds[20]; 02399 02400 char *sysname = ast_config_AST_SYSTEM_NAME; 02401 char *syslabel = NULL; 02402 02403 time_t nowtime = time(NULL) + expirey; 02404 const char *fc = fullcontact ? "fullcontact" : NULL; 02405 02406 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02407 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02408 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02409 02410 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02411 sysname = NULL; 02412 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02413 syslabel = "regserver"; 02414 02415 if (fc) 02416 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02417 "port", port, "regseconds", regseconds, 02418 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02419 else 02420 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02421 "port", port, "regseconds", regseconds, 02422 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02423 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static, read] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2697 of file chan_sip.c.
References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, userl, ast_variable::value, and var.
02698 { 02699 struct ast_variable *var; 02700 struct ast_variable *tmp; 02701 struct sip_user *user = NULL; 02702 02703 var = ast_load_realtime("sipusers", "name", username, NULL); 02704 02705 if (!var) 02706 return NULL; 02707 02708 for (tmp = var; tmp; tmp = tmp->next) { 02709 if (!strcasecmp(tmp->name, "type") && 02710 !strcasecmp(tmp->value, "peer")) { 02711 ast_variables_destroy(var); 02712 return NULL; 02713 } 02714 } 02715 02716 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02717 02718 if (!user) { /* No user found */ 02719 ast_variables_destroy(var); 02720 return NULL; 02721 } 02722 02723 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02724 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02725 suserobjs++; 02726 ASTOBJ_CONTAINER_LINK(&userl,user); 02727 } else { 02728 /* Move counter from s to r... */ 02729 suserobjs--; 02730 ruserobjs++; 02731 ast_set_flag(&user->flags[0], SIP_REALTIME); 02732 } 02733 ast_variables_destroy(var); 02734 return user; 02735 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9739 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
09740 { 09741 char buf[1024]; 09742 struct ast_frame f; 09743 const char *content_type = get_header(req, "Content-Type"); 09744 09745 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09746 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09747 if (!p->owner) 09748 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09749 return; 09750 } 09751 09752 if (get_msg_text(buf, sizeof(buf), req)) { 09753 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09754 transmit_response(p, "202 Accepted", req); 09755 if (!p->owner) 09756 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09757 return; 09758 } 09759 09760 if (p->owner) { 09761 if (sip_debug_test_pvt(p)) 09762 ast_verbose("Message received: '%s'\n", buf); 09763 memset(&f, 0, sizeof(f)); 09764 f.frametype = AST_FRAME_TEXT; 09765 f.subclass = 0; 09766 f.offset = 0; 09767 f.data = buf; 09768 f.datalen = strlen(buf); 09769 ast_queue_frame(p->owner, &f); 09770 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09771 } else { /* Message outside of a call, we do not support that */ 09772 ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf); 09773 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09774 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09775 } 09776 return; 09777 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1627 of file chan_sip.c.
References referstatusstrings, and c_referstatusstring::text.
Referenced by __sip_show_channels().
01628 { 01629 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01630 int x; 01631 01632 for (x = 0; x < i; x++) { 01633 if (referstatusstrings[x].status == rstatus) 01634 return (char *) referstatusstrings[x].text; 01635 } 01636 return ""; 01637 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7962 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07963 { 07964 char data[256]; 07965 struct in_addr in; 07966 int expiry; 07967 int port; 07968 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07969 07970 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07971 return; 07972 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07973 return; 07974 07975 scan = data; 07976 addr = strsep(&scan, ":"); 07977 port_str = strsep(&scan, ":"); 07978 expiry_str = strsep(&scan, ":"); 07979 username = strsep(&scan, ":"); 07980 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07981 07982 if (!inet_aton(addr, &in)) 07983 return; 07984 07985 if (port_str) 07986 port = atoi(port_str); 07987 else 07988 return; 07989 07990 if (expiry_str) 07991 expiry = atoi(expiry_str); 07992 else 07993 return; 07994 07995 if (username) 07996 ast_copy_string(peer->username, username, sizeof(peer->username)); 07997 if (contact) 07998 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07999 08000 if (option_debug > 1) 08001 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08002 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08003 08004 memset(&peer->addr, 0, sizeof(peer->addr)); 08005 peer->addr.sin_family = AF_INET; 08006 peer->addr.sin_addr = in; 08007 peer->addr.sin_port = htons(port); 08008 if (sipsock < 0) { 08009 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08010 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08011 struct sip_peer *peer_ptr = peer; 08012 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08013 } 08014 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08015 if (peer->pokeexpire == -1) { 08016 struct sip_peer *peer_ptr = peer; 08017 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08018 } 08019 } else 08020 sip_poke_peer(peer); 08021 if (!AST_SCHED_DEL(sched, peer->expire)) { 08022 struct sip_peer *peer_ptr = peer; 08023 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08024 } 08025 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08026 if (peer->expire == -1) { 08027 struct sip_peer *peer_ptr = peer; 08028 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08029 } 08030 register_peer_exten(peer, TRUE); 08031 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2426 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), domain::context, ext, LOG_WARNING, sip_peer::regexten, S_OR, and strsep().
02427 { 02428 char multi[256]; 02429 char *stringp, *ext, *context; 02430 02431 /* XXX note that global_regcontext is both a global 'enable' flag and 02432 * the name of the global regexten context, if not specified 02433 * individually. 02434 */ 02435 if (ast_strlen_zero(global_regcontext)) 02436 return; 02437 02438 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02439 stringp = multi; 02440 while ((ext = strsep(&stringp, "&"))) { 02441 if ((context = strchr(ext, '@'))) { 02442 *context++ = '\0'; /* split ext@context */ 02443 if (!ast_context_find(context)) { 02444 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02445 continue; 02446 } 02447 } else { 02448 context = global_regcontext; 02449 } 02450 if (onoff) 02451 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02452 ast_strdup(peer->name), ast_free, "SIP"); 02453 else 02454 ast_context_remove_extension(context, ext, 1, NULL); 02455 } 02456 }
static enum check_auth_result register_verify | ( | struct sip_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct sip_request * | req, | |||
char * | uri | |||
) | [static] |
Verify registration of user
Definition at line 8659 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08661 { 08662 enum check_auth_result res = AUTH_NOT_FOUND; 08663 struct sip_peer *peer; 08664 char tmp[256]; 08665 char *name, *c; 08666 char *t; 08667 char *domain; 08668 08669 /* Terminate URI */ 08670 t = uri; 08671 while(*t && (*t > 32) && (*t != ';')) 08672 t++; 08673 *t = '\0'; 08674 08675 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08676 if (pedanticsipchecking) 08677 ast_uri_decode(tmp); 08678 08679 c = get_in_brackets(tmp); 08680 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08681 08682 if (!strncasecmp(c, "sip:", 4)) { 08683 name = c + 4; 08684 } else { 08685 name = c; 08686 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08687 } 08688 08689 /* Strip off the domain name */ 08690 if ((c = strchr(name, '@'))) { 08691 *c++ = '\0'; 08692 domain = c; 08693 if ((c = strchr(domain, ':'))) /* Remove :port */ 08694 *c = '\0'; 08695 if (!AST_LIST_EMPTY(&domain_list)) { 08696 if (!check_sip_domain(domain, NULL, 0)) { 08697 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08698 return AUTH_UNKNOWN_DOMAIN; 08699 } 08700 } 08701 } 08702 08703 ast_string_field_set(p, exten, name); 08704 build_contact(p); 08705 peer = find_peer(name, NULL, 1); 08706 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08707 /* Peer fails ACL check */ 08708 if (peer) { 08709 ASTOBJ_UNREF(peer, sip_destroy_peer); 08710 res = AUTH_ACL_FAILED; 08711 } else 08712 res = AUTH_NOT_FOUND; 08713 } 08714 if (peer) { 08715 /* Set Frame packetization */ 08716 if (p->rtp) { 08717 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08718 p->autoframing = peer->autoframing; 08719 } 08720 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08721 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08722 res = AUTH_PEER_NOT_DYNAMIC; 08723 } else { 08724 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08725 transmit_response(p, "100 Trying", req); 08726 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08727 if (sip_cancel_destroy(p)) 08728 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08729 08730 /* We have a succesful registration attemp with proper authentication, 08731 now, update the peer */ 08732 switch (parse_register_contact(p, peer, req)) { 08733 case PARSE_REGISTER_FAILED: 08734 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08735 transmit_response_with_date(p, "400 Bad Request", req); 08736 peer->lastmsgssent = -1; 08737 res = 0; 08738 break; 08739 case PARSE_REGISTER_QUERY: 08740 transmit_response_with_date(p, "200 OK", req); 08741 peer->lastmsgssent = -1; 08742 res = 0; 08743 break; 08744 case PARSE_REGISTER_UPDATE: 08745 update_peer(peer, p->expiry); 08746 /* Say OK and ask subsystem to retransmit msg counter */ 08747 transmit_response_with_date(p, "200 OK", req); 08748 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08749 peer->lastmsgssent = -1; 08750 res = 0; 08751 break; 08752 } 08753 } 08754 } 08755 } 08756 if (!peer && autocreatepeer) { 08757 /* Create peer if we have autocreate mode enabled */ 08758 peer = temp_peer(name); 08759 if (peer) { 08760 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08761 if (sip_cancel_destroy(p)) 08762 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08763 switch (parse_register_contact(p, peer, req)) { 08764 case PARSE_REGISTER_FAILED: 08765 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08766 transmit_response_with_date(p, "400 Bad Request", req); 08767 peer->lastmsgssent = -1; 08768 res = 0; 08769 break; 08770 case PARSE_REGISTER_QUERY: 08771 transmit_response_with_date(p, "200 OK", req); 08772 peer->lastmsgssent = -1; 08773 res = 0; 08774 break; 08775 case PARSE_REGISTER_UPDATE: 08776 /* Say OK and ask subsystem to retransmit msg counter */ 08777 transmit_response_with_date(p, "200 OK", req); 08778 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08779 peer->lastmsgssent = -1; 08780 res = 0; 08781 break; 08782 } 08783 } 08784 } 08785 if (!res) { 08786 ast_device_state_changed("SIP/%s", peer->name); 08787 } 08788 if (res < 0) { 08789 switch (res) { 08790 case AUTH_SECRET_FAILED: 08791 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08792 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08793 break; 08794 case AUTH_USERNAME_MISMATCH: 08795 /* Username and digest username does not match. 08796 Asterisk uses the From: username for authentication. We need the 08797 users to use the same authentication user name until we support 08798 proper authentication by digest auth name */ 08799 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08800 break; 08801 case AUTH_NOT_FOUND: 08802 case AUTH_PEER_NOT_DYNAMIC: 08803 case AUTH_ACL_FAILED: 08804 if (global_alwaysauthreject) { 08805 transmit_fake_auth_response(p, &p->initreq, 1); 08806 } else { 08807 /* URI not found */ 08808 if (res == AUTH_PEER_NOT_DYNAMIC) 08809 transmit_response(p, "403 Forbidden", &p->initreq); 08810 else 08811 transmit_response(p, "404 Not found", &p->initreq); 08812 } 08813 break; 08814 default: 08815 break; 08816 } 08817 } 08818 if (peer) 08819 ASTOBJ_UNREF(peer, sip_destroy_peer); 08820 08821 return res; 08822 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 7451 of file chan_sip.c.
References REG_STATE_AUTHSENT, REG_STATE_FAILED, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
07452 { 07453 switch(regstate) { 07454 case REG_STATE_FAILED: 07455 return "Failed"; 07456 case REG_STATE_UNREGISTERED: 07457 return "Unregistered"; 07458 case REG_STATE_REGSENT: 07459 return "Request Sent"; 07460 case REG_STATE_AUTHSENT: 07461 return "Auth. Sent"; 07462 case REG_STATE_REGISTERED: 07463 return "Registered"; 07464 case REG_STATE_REJECTED: 07465 return "Rejected"; 07466 case REG_STATE_TIMEOUT: 07467 return "Timeout"; 07468 case REG_STATE_NOAUTH: 07469 return "No Authentication"; 07470 default: 07471 return "Unknown"; 07472 } 07473 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18025 of file chan_sip.c.
References sip_reload().
18026 { 18027 return sip_reload(0, 0, NULL); 18028 }
static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Default DTMF setting: RFC2833
< NAT support if requested by device with rport
< Allow re-invites
Definition at line 16911 of file chan_sip.c.
References __ourip, add_realm_authentication(), add_sip_domain(), ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_flags, ast_device_state_changed(), ast_enable_packet_fragmentation(), ast_find_ourip(), AST_FLAGS_ALL, ast_free_ha(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_tos2str(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, authl, bindaddr, build_peer(), build_user(), channelreloadreason2txt(), cleanup_stale_contexts(), clear_realm_authentication(), clear_sip_domains(), context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_DEFAULT_EXPIRY, DEFAULT_EXPIRY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, gen, global_jbconf, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_variable::name, ast_variable::next, notify_types, option_debug, option_verbose, ourport, outboundproxyip, peerl, regl, secret, SIP_CAN_REINVITE, sip_destroy(), sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, sip_register(), sip_registry_destroy(), SIP_USEREQPHONE, sipsock, STANDARD_SIP_PORT, strsep(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, userl, username, ast_variable::value, and VERBOSE_PREFIX_2.
16912 { 16913 struct ast_config *cfg, *ucfg; 16914 struct ast_variable *v; 16915 struct sip_peer *peer; 16916 struct sip_user *user; 16917 struct ast_hostent ahp; 16918 char *cat, *stringp, *context, *oldregcontext; 16919 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16920 struct hostent *hp; 16921 int format; 16922 struct ast_flags dummy[2]; 16923 int auto_sip_domains = FALSE; 16924 struct sockaddr_in old_bindaddr = bindaddr; 16925 int registry_count = 0, peer_count = 0, user_count = 0; 16926 unsigned int temp_tos = 0; 16927 struct ast_flags debugflag = {0}; 16928 16929 cfg = ast_config_load(config); 16930 16931 /* We *must* have a config file otherwise stop immediately */ 16932 if (!cfg) { 16933 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16934 return -1; 16935 } 16936 16937 if (option_debug > 3) 16938 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 16939 16940 clear_realm_authentication(authl); 16941 clear_sip_domains(); 16942 authl = NULL; 16943 16944 /* First, destroy all outstanding registry calls */ 16945 /* This is needed, since otherwise active registry entries will not be destroyed */ 16946 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16947 ASTOBJ_RDLOCK(iterator); 16948 if (iterator->call) { 16949 if (option_debug > 2) 16950 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 16951 /* This will also remove references to the registry */ 16952 sip_destroy(iterator->call); 16953 } 16954 ASTOBJ_UNLOCK(iterator); 16955 16956 } while(0)); 16957 16958 /* Then, actually destroy users and registry */ 16959 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 16960 if (option_debug > 3) 16961 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 16962 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 16963 if (option_debug > 3) 16964 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 16965 ASTOBJ_CONTAINER_MARKALL(&peerl); 16966 16967 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16968 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16969 oldregcontext = oldcontexts; 16970 16971 /* Clear all flags before setting default values */ 16972 /* Preserve debugging settings for console */ 16973 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16974 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16975 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16976 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16977 16978 /* Reset IP addresses */ 16979 memset(&bindaddr, 0, sizeof(bindaddr)); 16980 ast_free_ha(localaddr); 16981 memset(&localaddr, 0, sizeof(localaddr)); 16982 memset(&externip, 0, sizeof(externip)); 16983 memset(&default_prefs, 0 , sizeof(default_prefs)); 16984 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16985 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16986 ourport = STANDARD_SIP_PORT; 16987 srvlookup = DEFAULT_SRVLOOKUP; 16988 global_tos_sip = DEFAULT_TOS_SIP; 16989 global_tos_audio = DEFAULT_TOS_AUDIO; 16990 global_tos_video = DEFAULT_TOS_VIDEO; 16991 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16992 externexpire = 0; /* Expiration for DNS re-issuing */ 16993 externrefresh = 10; 16994 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16995 16996 /* Reset channel settings to default before re-configuring */ 16997 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16998 global_regcontext[0] = '\0'; 16999 expiry = DEFAULT_EXPIRY; 17000 global_notifyringing = DEFAULT_NOTIFYRINGING; 17001 global_limitonpeers = FALSE; 17002 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17003 global_notifyhold = FALSE; 17004 global_alwaysauthreject = 0; 17005 global_allowsubscribe = FALSE; 17006 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17007 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17008 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17009 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17010 else 17011 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17012 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17013 compactheaders = DEFAULT_COMPACTHEADERS; 17014 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17015 global_regattempts_max = 0; 17016 pedanticsipchecking = DEFAULT_PEDANTIC; 17017 global_mwitime = DEFAULT_MWITIME; 17018 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17019 global_autoframing = 0; 17020 global_allowguest = DEFAULT_ALLOWGUEST; 17021 global_rtptimeout = 0; 17022 global_rtpholdtimeout = 0; 17023 global_rtpkeepalive = 0; 17024 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17025 global_rtautoclear = 120; 17026 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17027 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17028 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17029 17030 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17031 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17032 default_subscribecontext[0] = '\0'; 17033 default_language[0] = '\0'; 17034 default_fromdomain[0] = '\0'; 17035 default_qualify = DEFAULT_QUALIFY; 17036 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17037 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17038 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17039 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17040 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17041 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17042 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17043 17044 /* Debugging settings, always default to off */ 17045 dumphistory = FALSE; 17046 recordhistory = FALSE; 17047 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17048 17049 /* Misc settings for the channel */ 17050 global_relaxdtmf = FALSE; 17051 global_callevents = FALSE; 17052 global_t1min = DEFAULT_T1MIN; 17053 17054 global_matchexterniplocally = FALSE; 17055 17056 /* Copy the default jb config over global_jbconf */ 17057 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17058 17059 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17060 17061 /* Read the [general] config section of sip.conf (or from realtime config) */ 17062 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17063 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17064 continue; 17065 /* handle jb conf */ 17066 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17067 continue; 17068 17069 /* Create the interface list */ 17070 if (!strcasecmp(v->name, "context")) { 17071 ast_copy_string(default_context, v->value, sizeof(default_context)); 17072 } else if (!strcasecmp(v->name, "subscribecontext")) { 17073 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17074 } else if (!strcasecmp(v->name, "allowguest")) { 17075 global_allowguest = ast_true(v->value) ? 1 : 0; 17076 } else if (!strcasecmp(v->name, "realm")) { 17077 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17078 } else if (!strcasecmp(v->name, "useragent")) { 17079 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17080 if (option_debug) 17081 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17082 } else if (!strcasecmp(v->name, "allowtransfer")) { 17083 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17084 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17085 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17086 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17087 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17088 } else if (!strcasecmp(v->name, "rtupdate")) { 17089 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17090 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17091 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17092 } else if (!strcasecmp(v->name, "t1min")) { 17093 global_t1min = atoi(v->value); 17094 } else if (!strcasecmp(v->name, "rtautoclear")) { 17095 int i = atoi(v->value); 17096 if (i > 0) 17097 global_rtautoclear = i; 17098 else 17099 i = 0; 17100 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17101 } else if (!strcasecmp(v->name, "usereqphone")) { 17102 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17103 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17104 global_relaxdtmf = ast_true(v->value); 17105 } else if (!strcasecmp(v->name, "checkmwi")) { 17106 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17107 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17108 global_mwitime = DEFAULT_MWITIME; 17109 } 17110 } else if (!strcasecmp(v->name, "vmexten")) { 17111 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17112 } else if (!strcasecmp(v->name, "rtptimeout")) { 17113 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17114 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17115 global_rtptimeout = 0; 17116 } 17117 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17118 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17119 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17120 global_rtpholdtimeout = 0; 17121 } 17122 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17123 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17124 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17125 global_rtpkeepalive = 0; 17126 } 17127 } else if (!strcasecmp(v->name, "compactheaders")) { 17128 compactheaders = ast_true(v->value); 17129 } else if (!strcasecmp(v->name, "notifymimetype")) { 17130 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17131 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17132 global_limitonpeers = ast_true(v->value); 17133 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17134 global_directrtpsetup = ast_true(v->value); 17135 } else if (!strcasecmp(v->name, "notifyringing")) { 17136 global_notifyringing = ast_true(v->value); 17137 } else if (!strcasecmp(v->name, "notifyhold")) { 17138 global_notifyhold = ast_true(v->value); 17139 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17140 global_alwaysauthreject = ast_true(v->value); 17141 } else if (!strcasecmp(v->name, "mohinterpret") 17142 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17143 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17144 } else if (!strcasecmp(v->name, "mohsuggest")) { 17145 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17146 } else if (!strcasecmp(v->name, "language")) { 17147 ast_copy_string(default_language, v->value, sizeof(default_language)); 17148 } else if (!strcasecmp(v->name, "regcontext")) { 17149 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17150 stringp = newcontexts; 17151 /* Let's remove any contexts that are no longer defined in regcontext */ 17152 cleanup_stale_contexts(stringp, oldregcontext); 17153 /* Create contexts if they don't exist already */ 17154 while ((context = strsep(&stringp, "&"))) { 17155 if (!ast_context_find(context)) 17156 ast_context_create(NULL, context,"SIP"); 17157 } 17158 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17159 } else if (!strcasecmp(v->name, "callerid")) { 17160 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17161 } else if (!strcasecmp(v->name, "fromdomain")) { 17162 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17163 } else if (!strcasecmp(v->name, "outboundproxy")) { 17164 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17165 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17166 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17167 /* Port needs to be after IP */ 17168 sscanf(v->value, "%d", &format); 17169 outboundproxyip.sin_port = htons(format); 17170 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17171 autocreatepeer = ast_true(v->value); 17172 } else if (!strcasecmp(v->name, "srvlookup")) { 17173 srvlookup = ast_true(v->value); 17174 } else if (!strcasecmp(v->name, "pedantic")) { 17175 pedanticsipchecking = ast_true(v->value); 17176 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17177 max_expiry = atoi(v->value); 17178 if (max_expiry < 1) 17179 max_expiry = DEFAULT_MAX_EXPIRY; 17180 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17181 min_expiry = atoi(v->value); 17182 if (min_expiry < 1) 17183 min_expiry = DEFAULT_MIN_EXPIRY; 17184 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17185 default_expiry = atoi(v->value); 17186 if (default_expiry < 1) 17187 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17188 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17189 if (ast_true(v->value)) 17190 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17191 } else if (!strcasecmp(v->name, "dumphistory")) { 17192 dumphistory = ast_true(v->value); 17193 } else if (!strcasecmp(v->name, "recordhistory")) { 17194 recordhistory = ast_true(v->value); 17195 } else if (!strcasecmp(v->name, "registertimeout")) { 17196 global_reg_timeout = atoi(v->value); 17197 if (global_reg_timeout < 1) 17198 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17199 } else if (!strcasecmp(v->name, "registerattempts")) { 17200 global_regattempts_max = atoi(v->value); 17201 } else if (!strcasecmp(v->name, "bindaddr")) { 17202 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17203 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17204 } else { 17205 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17206 } 17207 } else if (!strcasecmp(v->name, "localnet")) { 17208 struct ast_ha *na; 17209 if (!(na = ast_append_ha("d", v->value, localaddr))) 17210 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17211 else 17212 localaddr = na; 17213 } else if (!strcasecmp(v->name, "localmask")) { 17214 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17215 } else if (!strcasecmp(v->name, "externip")) { 17216 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17217 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17218 else 17219 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17220 externexpire = 0; 17221 } else if (!strcasecmp(v->name, "externhost")) { 17222 ast_copy_string(externhost, v->value, sizeof(externhost)); 17223 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17224 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17225 else 17226 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17227 externexpire = time(NULL); 17228 } else if (!strcasecmp(v->name, "externrefresh")) { 17229 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17230 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17231 externrefresh = 10; 17232 } 17233 } else if (!strcasecmp(v->name, "allow")) { 17234 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17235 } else if (!strcasecmp(v->name, "disallow")) { 17236 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17237 } else if (!strcasecmp(v->name, "autoframing")) { 17238 global_autoframing = ast_true(v->value); 17239 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17240 allow_external_domains = ast_true(v->value); 17241 } else if (!strcasecmp(v->name, "autodomain")) { 17242 auto_sip_domains = ast_true(v->value); 17243 } else if (!strcasecmp(v->name, "domain")) { 17244 char *domain = ast_strdupa(v->value); 17245 char *context = strchr(domain, ','); 17246 17247 if (context) 17248 *context++ = '\0'; 17249 17250 if (option_debug && ast_strlen_zero(context)) 17251 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17252 if (ast_strlen_zero(domain)) 17253 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17254 else 17255 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17256 } else if (!strcasecmp(v->name, "register")) { 17257 if (sip_register(v->value, v->lineno) == 0) 17258 registry_count++; 17259 } else if (!strcasecmp(v->name, "tos")) { 17260 if (!ast_str2tos(v->value, &temp_tos)) { 17261 global_tos_sip = temp_tos; 17262 global_tos_audio = temp_tos; 17263 global_tos_video = temp_tos; 17264 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17265 } else 17266 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17267 } else if (!strcasecmp(v->name, "tos_sip")) { 17268 if (ast_str2tos(v->value, &global_tos_sip)) 17269 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17270 } else if (!strcasecmp(v->name, "tos_audio")) { 17271 if (ast_str2tos(v->value, &global_tos_audio)) 17272 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17273 } else if (!strcasecmp(v->name, "tos_video")) { 17274 if (ast_str2tos(v->value, &global_tos_video)) 17275 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17276 } else if (!strcasecmp(v->name, "bindport")) { 17277 if (sscanf(v->value, "%d", &ourport) == 1) { 17278 bindaddr.sin_port = htons(ourport); 17279 } else { 17280 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17281 } 17282 } else if (!strcasecmp(v->name, "qualify")) { 17283 if (!strcasecmp(v->value, "no")) { 17284 default_qualify = 0; 17285 } else if (!strcasecmp(v->value, "yes")) { 17286 default_qualify = DEFAULT_MAXMS; 17287 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17288 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17289 default_qualify = 0; 17290 } 17291 } else if (!strcasecmp(v->name, "callevents")) { 17292 global_callevents = ast_true(v->value); 17293 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17294 default_maxcallbitrate = atoi(v->value); 17295 if (default_maxcallbitrate < 0) 17296 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17297 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17298 global_matchexterniplocally = ast_true(v->value); 17299 } 17300 } 17301 17302 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17303 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17304 allow_external_domains = 1; 17305 } 17306 17307 /* Build list of authentication to various SIP realms, i.e. service providers */ 17308 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17309 /* Format for authentication is auth = username:password@realm */ 17310 if (!strcasecmp(v->name, "auth")) 17311 authl = add_realm_authentication(authl, v->value, v->lineno); 17312 } 17313 17314 ucfg = ast_config_load("users.conf"); 17315 if (ucfg) { 17316 struct ast_variable *gen; 17317 int genhassip, genregistersip; 17318 const char *hassip, *registersip; 17319 17320 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17321 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17322 gen = ast_variable_browse(ucfg, "general"); 17323 cat = ast_category_browse(ucfg, NULL); 17324 while (cat) { 17325 if (strcasecmp(cat, "general")) { 17326 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17327 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17328 if (ast_true(hassip) || (!hassip && genhassip)) { 17329 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17330 if (user) { 17331 ASTOBJ_CONTAINER_LINK(&userl,user); 17332 ASTOBJ_UNREF(user, sip_destroy_user); 17333 user_count++; 17334 } 17335 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17336 if (peer) { 17337 ast_device_state_changed("SIP/%s", peer->name); 17338 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17339 ASTOBJ_UNREF(peer, sip_destroy_peer); 17340 peer_count++; 17341 } 17342 } 17343 if (ast_true(registersip) || (!registersip && genregistersip)) { 17344 char tmp[256]; 17345 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17346 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17347 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17348 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17349 if (!host) 17350 host = ast_variable_retrieve(ucfg, "general", "host"); 17351 if (!username) 17352 username = ast_variable_retrieve(ucfg, "general", "username"); 17353 if (!secret) 17354 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17355 if (!contact) 17356 contact = "s"; 17357 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17358 if (!ast_strlen_zero(secret)) 17359 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17360 else 17361 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17362 if (sip_register(tmp, 0) == 0) 17363 registry_count++; 17364 } 17365 } 17366 } 17367 cat = ast_category_browse(ucfg, cat); 17368 } 17369 ast_config_destroy(ucfg); 17370 } 17371 17372 17373 /* Load peers, users and friends */ 17374 cat = NULL; 17375 while ( (cat = ast_category_browse(cfg, cat)) ) { 17376 const char *utype; 17377 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17378 continue; 17379 utype = ast_variable_retrieve(cfg, cat, "type"); 17380 if (!utype) { 17381 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17382 continue; 17383 } else { 17384 int is_user = 0, is_peer = 0; 17385 if (!strcasecmp(utype, "user")) 17386 is_user = 1; 17387 else if (!strcasecmp(utype, "friend")) 17388 is_user = is_peer = 1; 17389 else if (!strcasecmp(utype, "peer")) 17390 is_peer = 1; 17391 else { 17392 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17393 continue; 17394 } 17395 if (is_user) { 17396 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17397 if (user) { 17398 ASTOBJ_CONTAINER_LINK(&userl,user); 17399 ASTOBJ_UNREF(user, sip_destroy_user); 17400 user_count++; 17401 } 17402 } 17403 if (is_peer) { 17404 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17405 if (peer) { 17406 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17407 ASTOBJ_UNREF(peer, sip_destroy_peer); 17408 peer_count++; 17409 } 17410 } 17411 } 17412 } 17413 if (ast_find_ourip(&__ourip, bindaddr)) { 17414 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17415 ast_config_destroy(cfg); 17416 return 0; 17417 } 17418 if (!ntohs(bindaddr.sin_port)) 17419 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17420 bindaddr.sin_family = AF_INET; 17421 ast_mutex_lock(&netlock); 17422 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17423 close(sipsock); 17424 sipsock = -1; 17425 } 17426 if (sipsock < 0) { 17427 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17428 if (sipsock < 0) { 17429 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17430 ast_config_destroy(cfg); 17431 return -1; 17432 } else { 17433 /* Allow SIP clients on the same host to access us: */ 17434 const int reuseFlag = 1; 17435 17436 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17437 (const char*)&reuseFlag, 17438 sizeof reuseFlag); 17439 17440 ast_enable_packet_fragmentation(sipsock); 17441 17442 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17443 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17444 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17445 strerror(errno)); 17446 close(sipsock); 17447 sipsock = -1; 17448 } else { 17449 if (option_verbose > 1) { 17450 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17451 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17452 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17453 } 17454 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17455 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17456 } 17457 } 17458 } 17459 ast_mutex_unlock(&netlock); 17460 17461 /* Add default domains - host name, IP address and IP:port */ 17462 /* Only do this if user added any sip domain with "localdomains" */ 17463 /* In order to *not* break backwards compatibility */ 17464 /* Some phones address us at IP only, some with additional port number */ 17465 if (auto_sip_domains) { 17466 char temp[MAXHOSTNAMELEN]; 17467 17468 /* First our default IP address */ 17469 if (bindaddr.sin_addr.s_addr) 17470 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17471 else 17472 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17473 17474 /* Our extern IP address, if configured */ 17475 if (externip.sin_addr.s_addr) 17476 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17477 17478 /* Extern host name (NAT traversal support) */ 17479 if (!ast_strlen_zero(externhost)) 17480 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17481 17482 /* Our host name */ 17483 if (!gethostname(temp, sizeof(temp))) 17484 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17485 } 17486 17487 /* Release configuration from memory */ 17488 ast_config_destroy(cfg); 17489 17490 /* Load the list of manual NOTIFY types to support */ 17491 if (notify_types) 17492 ast_config_destroy(notify_types); 17493 notify_types = ast_config_load(notify_config); 17494 17495 /* Done, tell the manager */ 17496 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count); 17497 17498 return 0; 17499 }
static int reply_digest | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
char * | header, | |||
int | sipmethod, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
reply to authentication for outbound registrations
Definition at line 11531 of file chan_sip.c.
References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), keys, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11532 { 11533 char tmp[512]; 11534 char *c; 11535 char oldnonce[256]; 11536 11537 /* table of recognised keywords, and places where they should be copied */ 11538 const struct x { 11539 const char *key; 11540 int field_index; 11541 } *i, keys[] = { 11542 { "realm=", ast_string_field_index(p, realm) }, 11543 { "nonce=", ast_string_field_index(p, nonce) }, 11544 { "opaque=", ast_string_field_index(p, opaque) }, 11545 { "qop=", ast_string_field_index(p, qop) }, 11546 { "domain=", ast_string_field_index(p, domain) }, 11547 { NULL, 0 }, 11548 }; 11549 11550 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11551 if (ast_strlen_zero(tmp)) 11552 return -1; 11553 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11554 ast_log(LOG_WARNING, "missing Digest.\n"); 11555 return -1; 11556 } 11557 c = tmp + strlen("Digest "); 11558 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11559 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11560 for (i = keys; i->key != NULL; i++) { 11561 char *src, *separator; 11562 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11563 continue; 11564 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11565 c += strlen(i->key); 11566 if (*c == '"') { 11567 src = ++c; 11568 separator = "\""; 11569 } else { 11570 src = c; 11571 separator = ","; 11572 } 11573 strsep(&c, separator); /* clear separator and move ptr */ 11574 ast_string_field_index_set(p, i->field_index, src); 11575 break; 11576 } 11577 if (i->key == NULL) /* not found, try ',' */ 11578 strsep(&c, ","); 11579 } 11580 /* Reset nonce count */ 11581 if (strcmp(p->nonce, oldnonce)) 11582 p->noncecount = 0; 11583 11584 /* Save auth data for following registrations */ 11585 if (p->registry) { 11586 struct sip_registry *r = p->registry; 11587 11588 if (strcmp(r->nonce, p->nonce)) { 11589 ast_string_field_set(r, realm, p->realm); 11590 ast_string_field_set(r, nonce, p->nonce); 11591 ast_string_field_set(r, domain, p->domain); 11592 ast_string_field_set(r, opaque, p->opaque); 11593 ast_string_field_set(r, qop, p->qop); 11594 r->noncecount = 0; 11595 } 11596 } 11597 return build_reply_digest(p, sipmethod, digest, digest_len); 11598 }
static int reqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod, | |||
int | seqno, | |||
int | newbranch | |||
) | [static] |
Initialize a SIP request message (not the initial one in a dialog).
< Strict routing flag
Definition at line 5934 of file chan_sip.c.
References add_header(), add_route(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_request::rlPart2, sip_pvt::route, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, strcasestr(), strsep(), sip_pvt::tag, text, cfsip_methods::text, and TRUE.
05935 { 05936 struct sip_request *orig = &p->initreq; 05937 char stripped[80]; 05938 char tmp[80]; 05939 char newto[256]; 05940 const char *c; 05941 const char *ot, *of; 05942 int is_strict = FALSE; /*!< Strict routing flag */ 05943 05944 memset(req, 0, sizeof(struct sip_request)); 05945 05946 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05947 05948 if (!seqno) { 05949 p->ocseq++; 05950 seqno = p->ocseq; 05951 } 05952 05953 if (newbranch) { 05954 p->branch ^= ast_random(); 05955 build_via(p); 05956 } 05957 05958 /* Check for strict or loose router */ 05959 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05960 is_strict = TRUE; 05961 if (sipdebug) 05962 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05963 } 05964 05965 if (sipmethod == SIP_CANCEL) 05966 c = p->initreq.rlPart2; /* Use original URI */ 05967 else if (sipmethod == SIP_ACK) { 05968 /* Use URI from Contact: in 200 OK (if INVITE) 05969 (we only have the contacturi on INVITEs) */ 05970 if (!ast_strlen_zero(p->okcontacturi)) 05971 c = is_strict ? p->route->hop : p->okcontacturi; 05972 else 05973 c = p->initreq.rlPart2; 05974 } else if (!ast_strlen_zero(p->okcontacturi)) 05975 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05976 else if (!ast_strlen_zero(p->uri)) 05977 c = p->uri; 05978 else { 05979 char *n; 05980 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05981 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05982 sizeof(stripped)); 05983 n = get_in_brackets(stripped); 05984 c = strsep(&n, ";"); /* trim ; and beyond */ 05985 } 05986 init_req(req, sipmethod, c); 05987 05988 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05989 05990 add_header(req, "Via", p->via); 05991 if (p->route) { 05992 set_destination(p, p->route->hop); 05993 add_route(req, is_strict ? p->route->next : p->route); 05994 } 05995 05996 ot = get_header(orig, "To"); 05997 of = get_header(orig, "From"); 05998 05999 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06000 as our original request, including tag (or presumably lack thereof) */ 06001 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06002 /* Add the proper tag if we don't have it already. If they have specified 06003 their tag, use it. Otherwise, use our own tag */ 06004 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06005 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06006 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06007 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06008 else 06009 snprintf(newto, sizeof(newto), "%s", ot); 06010 ot = newto; 06011 } 06012 06013 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06014 add_header(req, "From", of); 06015 add_header(req, "To", ot); 06016 } else { 06017 add_header(req, "From", ot); 06018 add_header(req, "To", of); 06019 } 06020 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06021 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06022 add_header(req, "Contact", p->our_contact); 06023 06024 copy_header(req, orig, "Call-ID"); 06025 add_header(req, "CSeq", tmp); 06026 06027 if (!ast_strlen_zero(global_useragent)) 06028 add_header(req, "User-Agent", global_useragent); 06029 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06030 06031 if (!ast_strlen_zero(p->rpid)) 06032 add_header(req, "Remote-Party-ID", p->rpid); 06033 06034 return 0; 06035 }
static int respprep | ( | struct sip_request * | resp, | |
struct sip_pvt * | p, | |||
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Prepare SIP response packet.
Definition at line 5886 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.
05887 { 05888 char newto[256]; 05889 const char *ot; 05890 05891 init_resp(resp, msg); 05892 copy_via_headers(p, resp, req, "Via"); 05893 if (msg[0] == '1' || msg[0] == '2') 05894 copy_all_header(resp, req, "Record-Route"); 05895 copy_header(resp, req, "From"); 05896 ot = get_header(req, "To"); 05897 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05898 /* Add the proper tag if we don't have it already. If they have specified 05899 their tag, use it. Otherwise, use our own tag */ 05900 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05901 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05902 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05903 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05904 else 05905 ast_copy_string(newto, ot, sizeof(newto)); 05906 ot = newto; 05907 } 05908 add_header(resp, "To", ot); 05909 copy_header(resp, req, "Call-ID"); 05910 copy_header(resp, req, "CSeq"); 05911 if (!ast_strlen_zero(global_useragent)) 05912 add_header(resp, "User-Agent", global_useragent); 05913 add_header(resp, "Allow", ALLOWED_METHODS); 05914 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05915 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05916 /* For registration responses, we also need expiry and 05917 contact info */ 05918 char tmp[256]; 05919 05920 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05921 add_header(resp, "Expires", tmp); 05922 if (p->expiry) { /* Only add contact if we have an expiry time */ 05923 char contact[SIPBUFSIZE]; 05924 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05925 add_header(resp, "Contact", contact); /* Not when we unregister */ 05926 } 05927 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05928 add_header(resp, "Contact", p->our_contact); 05929 } 05930 return 0; 05931 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15822 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
15823 { 15824 /* If we're supposed to be stopped -- stay stopped */ 15825 if (monitor_thread == AST_PTHREADT_STOP) 15826 return 0; 15827 ast_mutex_lock(&monlock); 15828 if (monitor_thread == pthread_self()) { 15829 ast_mutex_unlock(&monlock); 15830 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15831 return -1; 15832 } 15833 if (monitor_thread != AST_PTHREADT_NULL) { 15834 /* Wake up the thread */ 15835 pthread_kill(monitor_thread, SIGURG); 15836 } else { 15837 /* Start a new monitor */ 15838 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15839 ast_mutex_unlock(&monlock); 15840 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15841 return -1; 15842 } 15843 } 15844 ast_mutex_unlock(&monlock); 15845 return 0; 15846 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1896 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEADLOCK_AVOIDANCE, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01897 { 01898 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01899 int reschedule = DEFAULT_RETRANS; 01900 int xmitres = 0; 01901 01902 /* Lock channel PVT */ 01903 ast_mutex_lock(&pkt->owner->lock); 01904 01905 if (pkt->retrans < MAX_RETRANS) { 01906 pkt->retrans++; 01907 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01908 if (sipdebug && option_debug > 3) 01909 ast_log(LOG_DEBUG, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method); 01910 } else { 01911 int siptimer_a; 01912 01913 if (sipdebug && option_debug > 3) 01914 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01915 if (!pkt->timer_a) 01916 pkt->timer_a = 2 ; 01917 else 01918 pkt->timer_a = 2 * pkt->timer_a; 01919 01920 /* For non-invites, a maximum of 4 secs */ 01921 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01922 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01923 siptimer_a = 4000; 01924 01925 /* Reschedule re-transmit */ 01926 reschedule = siptimer_a; 01927 if (option_debug > 3) 01928 ast_log(LOG_DEBUG, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid); 01929 } 01930 01931 if (sip_debug_test_pvt(pkt->owner)) { 01932 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01933 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01934 pkt->retrans, sip_nat_mode(pkt->owner), 01935 ast_inet_ntoa(dst->sin_addr), 01936 ntohs(dst->sin_port), pkt->data); 01937 } 01938 01939 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01940 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01941 ast_mutex_unlock(&pkt->owner->lock); 01942 if (xmitres == XMIT_ERROR) 01943 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01944 else 01945 return reschedule; 01946 } 01947 /* Too many retries */ 01948 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01949 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01950 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request"); 01951 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01952 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01953 } 01954 if (xmitres == XMIT_ERROR) { 01955 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01956 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01957 } else 01958 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01959 01960 pkt->retransid = -1; 01961 01962 if (ast_test_flag(pkt, FLAG_FATAL)) { 01963 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01964 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01965 } 01966 01967 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01968 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01969 01970 if (pkt->owner->owner) { 01971 sip_alreadygone(pkt->owner); 01972 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01973 ast_queue_hangup(pkt->owner->owner); 01974 ast_channel_unlock(pkt->owner->owner); 01975 } else { 01976 /* If no channel owner, destroy now */ 01977 01978 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01979 if (pkt->method != SIP_OPTIONS) { 01980 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01981 sip_alreadygone(pkt->owner); 01982 if (option_debug) 01983 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01984 } 01985 } 01986 } 01987 01988 if (pkt->method == SIP_BYE) { 01989 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01990 if (pkt->owner->owner) 01991 ast_channel_unlock(pkt->owner->owner); 01992 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01993 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01994 } 01995 01996 /* In any case, go ahead and remove the packet */ 01997 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01998 if (cur == pkt) 01999 break; 02000 } 02001 if (cur) { 02002 if (prev) 02003 prev->next = cur->next; 02004 else 02005 pkt->owner->packets = cur->next; 02006 ast_mutex_unlock(&pkt->owner->lock); 02007 free(cur); 02008 pkt = NULL; 02009 } else 02010 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02011 if (pkt) 02012 ast_mutex_unlock(&pkt->owner->lock); 02013 return 0; 02014 }
static int send_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | seqno | |||
) | [static] |
Send SIP Request to the other part of the dialogue.
Definition at line 2287 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.
02288 { 02289 int res; 02290 02291 add_blank(req); 02292 if (sip_debug_test_pvt(p)) { 02293 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02294 ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); 02295 else 02296 ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); 02297 } 02298 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02299 struct sip_request tmp; 02300 parse_copy(&tmp, req); 02301 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02302 } 02303 res = (reliable) ? 02304 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02305 __sip_xmit(p, req->data, req->len); 02306 return res; 02307 }
static int send_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | seqno | |||
) | [static] |
Transmit response on SIP request.
Definition at line 2259 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_request::rlPart2, sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02260 { 02261 int res; 02262 02263 add_blank(req); 02264 if (sip_debug_test_pvt(p)) { 02265 const struct sockaddr_in *dst = sip_real_dst(p); 02266 02267 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02268 reliable ? "Reliably " : "", sip_nat_mode(p), 02269 ast_inet_ntoa(dst->sin_addr), 02270 ntohs(dst->sin_port), req->data); 02271 } 02272 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02273 struct sip_request tmp; 02274 parse_copy(&tmp, req); 02275 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02276 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02277 } 02278 res = (reliable) ? 02279 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02280 __sip_xmit(p, req->data, req->len); 02281 if (res > 0) 02282 return 0; 02283 return res; 02284 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8055 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
08056 { 08057 struct hostent *hp; 08058 struct ast_hostent ahp; 08059 int port; 08060 char *c, *host, *pt; 08061 char contact_buf[256]; 08062 char *contact; 08063 08064 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08065 /* NAT: Don't trust the contact field. Just use what they came to us 08066 with. */ 08067 pvt->sa = pvt->recv; 08068 return 0; 08069 } 08070 08071 /* Work on a copy */ 08072 ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); 08073 contact = contact_buf; 08074 08075 /* Make sure it's a SIP URL */ 08076 if (strncasecmp(contact, "sip:", 4)) { 08077 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08078 } else 08079 contact += 4; 08080 08081 /* Ditch arguments */ 08082 /* XXX this code is replicated also shortly below */ 08083 08084 /* Grab host */ 08085 host = strchr(contact, '@'); 08086 if (!host) { /* No username part */ 08087 host = contact; 08088 c = NULL; 08089 } else { 08090 *host++ = '\0'; 08091 } 08092 pt = strchr(host, ':'); 08093 if (pt) { 08094 *pt++ = '\0'; 08095 port = atoi(pt); 08096 } else 08097 port = STANDARD_SIP_PORT; 08098 08099 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08100 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08101 08102 /* XXX This could block for a long time XXX */ 08103 /* We should only do this if it's a name, not an IP */ 08104 hp = ast_gethostbyname(host, &ahp); 08105 if (!hp) { 08106 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08107 return -1; 08108 } 08109 pvt->sa.sin_family = AF_INET; 08110 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08111 pvt->sa.sin_port = htons(port); 08112 08113 return 0; 08114 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5795 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05796 { 05797 char *h, *maddr, hostname[256]; 05798 int port, hn; 05799 struct hostent *hp; 05800 struct ast_hostent ahp; 05801 int debug=sip_debug_test_pvt(p); 05802 05803 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05804 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05805 05806 if (debug) 05807 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05808 05809 /* Find and parse hostname */ 05810 h = strchr(uri, '@'); 05811 if (h) 05812 ++h; 05813 else { 05814 h = uri; 05815 if (strncasecmp(h, "sip:", 4) == 0) 05816 h += 4; 05817 else if (strncasecmp(h, "sips:", 5) == 0) 05818 h += 5; 05819 } 05820 hn = strcspn(h, ":;>") + 1; 05821 if (hn > sizeof(hostname)) 05822 hn = sizeof(hostname); 05823 ast_copy_string(hostname, h, hn); 05824 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05825 h += hn - 1; 05826 05827 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05828 if (*h == ':') { 05829 /* Parse port */ 05830 ++h; 05831 port = strtol(h, &h, 10); 05832 } 05833 else 05834 port = STANDARD_SIP_PORT; 05835 05836 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05837 maddr = strstr(h, "maddr="); 05838 if (maddr) { 05839 maddr += 6; 05840 hn = strspn(maddr, "0123456789.") + 1; 05841 if (hn > sizeof(hostname)) 05842 hn = sizeof(hostname); 05843 ast_copy_string(hostname, maddr, hn); 05844 } 05845 05846 hp = ast_gethostbyname(hostname, &ahp); 05847 if (hp == NULL) { 05848 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05849 return; 05850 } 05851 p->sa.sin_family = AF_INET; 05852 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05853 p->sa.sin_port = htons(port); 05854 if (debug) 05855 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05856 }
static void set_insecure_flags | ( | struct ast_flags * | flags, | |
const char * | value, | |||
int | lineno | |||
) | [static] |
Parse the "insecure" setting from sip.conf or from realtime.
flags | a pointer to an ast_flags structure | |
value | the value of the SIP insecure setting | |
lineno | linenumber in sip.conf or -1 for realtime |
Definition at line 16149 of file chan_sip.c.
References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options(), and realtime_peer().
16150 { 16151 static int dep_insecure_very = 0; 16152 static int dep_insecure_yes = 0; 16153 16154 if (ast_strlen_zero(value)) 16155 return; 16156 16157 if (!strcasecmp(value, "very")) { 16158 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16159 if(!dep_insecure_very) { 16160 if(lineno != -1) 16161 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16162 else 16163 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16164 dep_insecure_very = 1; 16165 } 16166 } 16167 else if (ast_true(value)) { 16168 ast_set_flag(flags, SIP_INSECURE_PORT); 16169 if(!dep_insecure_yes) { 16170 if(lineno != -1) 16171 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16172 else 16173 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16174 dep_insecure_yes = 1; 16175 } 16176 } 16177 else if (!ast_false(value)) { 16178 char buf[64]; 16179 char *word, *next; 16180 ast_copy_string(buf, value, sizeof(buf)); 16181 next = buf; 16182 while ((word = strsep(&next, ","))) { 16183 if (!strcasecmp(word, "port")) 16184 ast_set_flag(flags, SIP_INSECURE_PORT); 16185 else if (!strcasecmp(word, "invite")) 16186 ast_set_flag(flags, SIP_INSECURE_INVITE); 16187 else 16188 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16189 } 16190 } 16191 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16580 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
16581 { 16582 if (peer->expire == 0) { 16583 /* Don't reset expire or port time during reload 16584 if we have an active registration 16585 */ 16586 peer->expire = -1; 16587 peer->pokeexpire = -1; 16588 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16589 } 16590 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16591 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16592 strcpy(peer->context, default_context); 16593 strcpy(peer->subscribecontext, default_subscribecontext); 16594 strcpy(peer->language, default_language); 16595 strcpy(peer->mohinterpret, default_mohinterpret); 16596 strcpy(peer->mohsuggest, default_mohsuggest); 16597 peer->addr.sin_family = AF_INET; 16598 peer->defaddr.sin_family = AF_INET; 16599 peer->capability = global_capability; 16600 peer->maxcallbitrate = default_maxcallbitrate; 16601 peer->rtptimeout = global_rtptimeout; 16602 peer->rtpholdtimeout = global_rtpholdtimeout; 16603 peer->rtpkeepalive = global_rtpkeepalive; 16604 peer->allowtransfer = global_allowtransfer; 16605 peer->autoframing = global_autoframing; 16606 strcpy(peer->vmexten, default_vmexten); 16607 peer->secret[0] = '\0'; 16608 peer->md5secret[0] = '\0'; 16609 peer->cid_num[0] = '\0'; 16610 peer->cid_name[0] = '\0'; 16611 peer->fromdomain[0] = '\0'; 16612 peer->fromuser[0] = '\0'; 16613 peer->regexten[0] = '\0'; 16614 peer->mailbox[0] = '\0'; 16615 peer->callgroup = 0; 16616 peer->pickupgroup = 0; 16617 peer->maxms = default_qualify; 16618 peer->prefs = default_prefs; 16619 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17838 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
17839 { 17840 int no = 0; 17841 int ok = FALSE; 17842 char varbuf[30]; 17843 char *inbuf = (char *) data; 17844 17845 if (ast_strlen_zero(inbuf)) { 17846 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17847 return 0; 17848 } 17849 ast_channel_lock(chan); 17850 17851 /* Check for headers */ 17852 while (!ok && no <= 50) { 17853 no++; 17854 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17855 17856 /* Compare without the leading underscore */ 17857 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17858 ok = TRUE; 17859 } 17860 if (ok) { 17861 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17862 if (sipdebug) 17863 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17864 } else { 17865 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17866 } 17867 ast_channel_unlock(chan); 17868 return 0; 17869 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2650 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02651 { 02652 /* We know name is the first field, so we can cast */ 02653 struct sip_peer *p = (struct sip_peer *) name; 02654 return !(!inaddrcmp(&p->addr, sin) || 02655 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02656 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02657 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static, read] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4447 of file chan_sip.c.
References __ourip, sip_pvt::allowtransfer, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), sip_pvt::autoframing, sip_pvt::autokillid, bindaddr, sip_pvt::branch, build_callid_pvt(), build_via(), t38properties::capability, sip_pvt::capability, sip_pvt::chanvars, domain::context, default_prefs, do_setnat(), errno, sip_pvt::flags, free, global_t38_capability, iflist, INITIAL_CSEQ, sip_pvt::initid, t38properties::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ocseq, option_debug, sip_pvt::ourip, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::tag, text, sip_pvt::timer_t1, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04449 { 04450 struct sip_pvt *p; 04451 04452 if (!(p = ast_calloc(1, sizeof(*p)))) 04453 return NULL; 04454 04455 if (ast_string_field_init(p, 512)) { 04456 free(p); 04457 return NULL; 04458 } 04459 04460 ast_mutex_init(&p->lock); 04461 04462 p->method = intended_method; 04463 p->initid = -1; 04464 p->waitid = -1; 04465 p->autokillid = -1; 04466 p->subscribed = NONE; 04467 p->stateid = -1; 04468 p->prefs = default_prefs; /* Set default codecs for this call */ 04469 04470 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04471 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04472 04473 if (sin) { 04474 p->sa = *sin; 04475 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04476 p->ourip = __ourip; 04477 } else 04478 p->ourip = __ourip; 04479 04480 /* Copy global flags to this PVT at setup. */ 04481 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04482 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04483 04484 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04485 04486 p->branch = ast_random(); 04487 make_our_tag(p->tag, sizeof(p->tag)); 04488 p->ocseq = INITIAL_CSEQ; 04489 04490 if (sip_methods[intended_method].need_rtp) { 04491 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04492 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04493 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04494 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04495 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04496 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04497 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04498 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04499 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04500 ast_mutex_destroy(&p->lock); 04501 if (p->chanvars) { 04502 ast_variables_destroy(p->chanvars); 04503 p->chanvars = NULL; 04504 } 04505 free(p); 04506 return NULL; 04507 } 04508 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04509 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04510 ast_rtp_settos(p->rtp, global_tos_audio); 04511 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04512 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04513 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04514 if (p->vrtp) { 04515 ast_rtp_settos(p->vrtp, global_tos_video); 04516 ast_rtp_setdtmf(p->vrtp, 0); 04517 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04518 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04519 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04520 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04521 } 04522 if (p->udptl) 04523 ast_udptl_settos(p->udptl, global_tos_audio); 04524 p->maxcallbitrate = default_maxcallbitrate; 04525 p->autoframing = global_autoframing; 04526 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04527 } 04528 04529 if (useglobal_nat && sin) { 04530 /* Setup NAT structure according to global settings if we have an address */ 04531 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04532 p->recv = *sin; 04533 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04534 } 04535 04536 if (p->method != SIP_REGISTER) 04537 ast_string_field_set(p, fromdomain, default_fromdomain); 04538 build_via(p); 04539 if (!callid) 04540 build_callid_pvt(p); 04541 else 04542 ast_string_field_set(p, callid, callid); 04543 /* Assign default music on hold class */ 04544 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04545 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04546 p->capability = global_capability; 04547 p->allowtransfer = global_allowtransfer; 04548 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04549 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04550 p->noncodeccapability |= AST_RTP_DTMF; 04551 if (p->udptl) { 04552 p->t38.capability = global_t38_capability; 04553 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04554 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04555 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04556 p->t38.capability |= T38FAX_UDP_EC_FEC; 04557 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04558 p->t38.capability |= T38FAX_UDP_EC_NONE; 04559 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04560 p->t38.jointcapability = p->t38.capability; 04561 } 04562 ast_string_field_set(p, context, default_context); 04563 04564 /* Add to active dialog list */ 04565 ast_mutex_lock(&iflock); 04566 p->next = iflist; 04567 iflist = p; 04568 ast_mutex_unlock(&iflock); 04569 if (option_debug) 04570 ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP"); 04571 return p; 04572 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1654 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
01655 { 01656 if (option_debug > 2) 01657 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01658 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01659 }
static int sip_answer | ( | struct ast_channel * | ast | ) | [static] |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
Definition at line 3672 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, option_debug, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03673 { 03674 int res = 0; 03675 struct sip_pvt *p = ast->tech_pvt; 03676 03677 ast_mutex_lock(&p->lock); 03678 if (ast->_state != AST_STATE_UP) { 03679 try_suggested_sip_codec(p); 03680 03681 ast_setstate(ast, AST_STATE_UP); 03682 if (option_debug) 03683 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03684 if (p->t38.state == T38_PEER_DIRECT) { 03685 p->t38.state = T38_ENABLED; 03686 if (option_debug > 1) 03687 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03688 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03689 } else { 03690 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03691 } 03692 } 03693 ast_mutex_unlock(&p->lock); 03694 return res; 03695 }
static int sip_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Initiate SIP call from PBX used from the dial() application.
Definition at line 2954 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
02955 { 02956 int res, xmitres = 0; 02957 struct sip_pvt *p; 02958 struct varshead *headp; 02959 struct ast_var_t *current; 02960 const char *referer = NULL; /* SIP refererer */ 02961 02962 p = ast->tech_pvt; 02963 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02964 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02965 return -1; 02966 } 02967 02968 /* Check whether there is vxml_url, distinctive ring variables */ 02969 headp=&ast->varshead; 02970 AST_LIST_TRAVERSE(headp,current,entries) { 02971 /* Check whether there is a VXML_URL variable */ 02972 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02973 p->options->vxml_url = ast_var_value(current); 02974 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02975 p->options->uri_options = ast_var_value(current); 02976 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02977 /* Check whether there is a ALERT_INFO variable */ 02978 p->options->distinctive_ring = ast_var_value(current); 02979 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02980 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02981 p->options->addsipheaders = 1; 02982 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02983 /* This is a transfered call */ 02984 p->options->transfer = 1; 02985 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02986 /* This is the referer */ 02987 referer = ast_var_value(current); 02988 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02989 /* We're replacing a call. */ 02990 p->options->replaces = ast_var_value(current); 02991 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02992 p->t38.state = T38_LOCAL_DIRECT; 02993 if (option_debug) 02994 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02995 } 02996 02997 } 02998 02999 res = 0; 03000 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03001 03002 if (p->options->transfer) { 03003 char buf[SIPBUFSIZE/2]; 03004 03005 if (referer) { 03006 if (sipdebug && option_debug > 2) 03007 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03008 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03009 } else 03010 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03011 ast_string_field_set(p, cid_name, buf); 03012 } 03013 if (option_debug) 03014 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03015 03016 res = update_call_counter(p, INC_CALL_RINGING); 03017 if ( res != -1 ) { 03018 p->callingpres = ast->cid.cid_pres; 03019 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03020 p->jointnoncodeccapability = p->noncodeccapability; 03021 03022 /* If there are no audio formats left to offer, punt */ 03023 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03024 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03025 res = -1; 03026 } else { 03027 p->t38.jointcapability = p->t38.capability; 03028 if (option_debug > 1) 03029 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03030 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03031 if (xmitres == XMIT_ERROR) 03032 return -1; /* Transmission error */ 03033 03034 p->invitestate = INV_CALLING; 03035 03036 /* Initialize auto-congest time */ 03037 AST_SCHED_DEL(sched, p->initid); 03038 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03039 } 03040 } 03041 return res; 03042 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2129 of file chan_sip.c.
References append_history, ast_sched_del(), and sip_pvt::autokillid.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02130 { 02131 int res = 0; 02132 if (p->autokillid > -1) { 02133 if (!(res = ast_sched_del(sched, p->autokillid))) { 02134 append_history(p, "CancelDestroy", ""); 02135 p->autokillid = -1; 02136 } 02137 } 02138 return res; 02139 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1736 of file chan_sip.c.
References debugaddr, and sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01737 { 01738 if (!sipdebug) 01739 return 0; 01740 if (debugaddr.sin_addr.s_addr) { 01741 if (((ntohs(debugaddr.sin_port) != 0) 01742 && (debugaddr.sin_port != addr->sin_port)) 01743 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01744 return 0; 01745 } 01746 return 1; 01747 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1762 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), add_t38_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01763 { 01764 if (!sipdebug) 01765 return 0; 01766 return sip_debug_test_addr(sip_real_dst(p)); 01767 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3315 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, and option_debug.
Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03316 { 03317 ast_mutex_lock(&iflock); 03318 if (option_debug > 2) 03319 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03320 __sip_destroy(p, 1); 03321 ast_mutex_unlock(&iflock); 03322 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2459 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().
02460 { 02461 if (option_debug > 2) 02462 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02463 02464 /* Delete it, it needs to disappear */ 02465 if (peer->call) 02466 sip_destroy(peer->call); 02467 02468 if (peer->mwipvt) /* We have an active subscription, delete it */ 02469 sip_destroy(peer->mwipvt); 02470 02471 if (peer->chanvars) { 02472 ast_variables_destroy(peer->chanvars); 02473 peer->chanvars = NULL; 02474 } 02475 02476 register_peer_exten(peer, FALSE); 02477 ast_free_ha(peer->ha); 02478 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02479 apeerobjs--; 02480 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02481 rpeerobjs--; 02482 else 02483 speerobjs--; 02484 clear_realm_authentication(peer->auth); 02485 peer->auth = NULL; 02486 free(peer); 02487 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2678 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), reload_config(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter().
02679 { 02680 if (option_debug > 2) 02681 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02682 ast_free_ha(user->ha); 02683 if (user->chanvars) { 02684 ast_variables_destroy(user->chanvars); 02685 user->chanvars = NULL; 02686 } 02687 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02688 ruserobjs--; 02689 else 02690 suserobjs--; 02691 free(user); 02692 }
static int sip_devicestate | ( | void * | data | ) | [static] |
Part of PBX channel interface.
For peers with call limit:
For peers without call limit:
Peers that does not have a known call and can't be reached by OPTIONS
If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.
The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID
When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN
Definition at line 15991 of file chan_sip.c.
References sip_peer::addr, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
15992 { 15993 char *host; 15994 char *tmp; 15995 15996 struct hostent *hp; 15997 struct ast_hostent ahp; 15998 struct sip_peer *p; 15999 16000 int res = AST_DEVICE_INVALID; 16001 16002 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16003 host = ast_strdupa(data ? data : ""); 16004 if ((tmp = strchr(host, '@'))) 16005 host = tmp + 1; 16006 16007 if (option_debug > 2) 16008 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16009 16010 if ((p = find_peer(host, NULL, 1))) { 16011 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16012 /* we have an address for the peer */ 16013 16014 /* Check status in this order 16015 - Hold 16016 - Ringing 16017 - Busy (enforced only by call limit) 16018 - Inuse (we have a call) 16019 - Unreachable (qualify) 16020 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16021 for registered devices */ 16022 16023 if (p->onHold) 16024 /* First check for hold or ring states */ 16025 res = AST_DEVICE_ONHOLD; 16026 else if (p->inRinging) { 16027 if (p->inRinging == p->inUse) 16028 res = AST_DEVICE_RINGING; 16029 else 16030 res = AST_DEVICE_RINGINUSE; 16031 } else if (p->call_limit && (p->inUse == p->call_limit)) 16032 /* check call limit */ 16033 res = AST_DEVICE_BUSY; 16034 else if (p->call_limit && p->inUse) 16035 /* Not busy, but we do have a call */ 16036 res = AST_DEVICE_INUSE; 16037 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16038 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16039 res = AST_DEVICE_UNAVAILABLE; 16040 else /* Default reply if we're registered and have no other data */ 16041 res = AST_DEVICE_NOT_INUSE; 16042 } else { 16043 /* there is no address, it's unavailable */ 16044 res = AST_DEVICE_UNAVAILABLE; 16045 } 16046 ASTOBJ_UNREF(p,sip_destroy_peer); 16047 } else { 16048 char *port = strchr(host, ':'); 16049 if (port) 16050 *port = '\0'; 16051 hp = ast_gethostbyname(host, &ahp); 16052 if (hp) 16053 res = AST_DEVICE_UNKNOWN; 16054 } 16055 16056 return res; 16057 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11344 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11345 { 11346 int oldsipdebug = sipdebug_console; 11347 if (argc != 3) { 11348 if (argc != 5) 11349 return RESULT_SHOWUSAGE; 11350 else if (strcmp(argv[3], "ip") == 0) 11351 return sip_do_debug_ip(fd, argc, argv); 11352 else if (strcmp(argv[3], "peer") == 0) 11353 return sip_do_debug_peer(fd, argc, argv); 11354 else 11355 return RESULT_SHOWUSAGE; 11356 } 11357 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11358 memset(&debugaddr, 0, sizeof(debugaddr)); 11359 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11360 return RESULT_SUCCESS; 11361 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11363 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11364 { 11365 int oldsipdebug = sipdebug_console; 11366 char *newargv[6] = { "sip", "set", "debug", NULL }; 11367 if (argc != 2) { 11368 if (argc != 4) 11369 return RESULT_SHOWUSAGE; 11370 else if (strcmp(argv[2], "ip") == 0) { 11371 newargv[3] = argv[2]; 11372 newargv[4] = argv[3]; 11373 return sip_do_debug_ip(fd, argc + 1, newargv); 11374 } else if (strcmp(argv[2], "peer") == 0) { 11375 newargv[3] = argv[2]; 11376 newargv[4] = argv[3]; 11377 return sip_do_debug_peer(fd, argc + 1, newargv); 11378 } else 11379 return RESULT_SHOWUSAGE; 11380 } 11381 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11382 memset(&debugaddr, 0, sizeof(debugaddr)); 11383 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11384 return RESULT_SUCCESS; 11385 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11290 of file chan_sip.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11291 { 11292 struct hostent *hp; 11293 struct ast_hostent ahp; 11294 int port = 0; 11295 char *p, *arg; 11296 11297 /* sip set debug ip <ip> */ 11298 if (argc != 5) 11299 return RESULT_SHOWUSAGE; 11300 p = arg = argv[4]; 11301 strsep(&p, ":"); 11302 if (p) 11303 port = atoi(p); 11304 hp = ast_gethostbyname(arg, &ahp); 11305 if (hp == NULL) 11306 return RESULT_SHOWUSAGE; 11307 11308 debugaddr.sin_family = AF_INET; 11309 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11310 debugaddr.sin_port = htons(port); 11311 if (port == 0) 11312 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11313 else 11314 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11315 11316 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11317 11318 return RESULT_SUCCESS; 11319 }
static int sip_do_debug_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
sip_do_debug_peer: Turn on SIP debugging with peer mask
Definition at line 11322 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11323 { 11324 struct sip_peer *peer; 11325 if (argc != 5) 11326 return RESULT_SHOWUSAGE; 11327 peer = find_peer(argv[4], NULL, 1); 11328 if (peer) { 11329 if (peer->addr.sin_addr.s_addr) { 11330 debugaddr.sin_family = AF_INET; 11331 debugaddr.sin_addr = peer->addr.sin_addr; 11332 debugaddr.sin_port = peer->addr.sin_port; 11333 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11334 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11335 } else 11336 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11337 ASTOBJ_UNREF(peer,sip_destroy_peer); 11338 } else 11339 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11340 return RESULT_SUCCESS; 11341 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11463 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11464 { 11465 if (argc != 2) { 11466 return RESULT_SHOWUSAGE; 11467 } 11468 recordhistory = TRUE; 11469 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11470 return RESULT_SUCCESS; 11471 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17984 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, option_debug, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
17985 { 17986 reload_config(reason); 17987 17988 /* Prune peers who still are supposed to be deleted */ 17989 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17990 if (option_debug > 3) 17991 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17992 17993 /* Send qualify (OPTIONS) to all peers */ 17994 sip_poke_all_peers(); 17995 17996 /* Register with all services */ 17997 sip_send_all_registers(); 17998 17999 if (option_debug > 3) 18000 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18001 18002 return 0; 18003 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17783 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
17784 { 17785 struct sip_pvt *p; 17786 char *mode; 17787 if (data) 17788 mode = (char *)data; 17789 else { 17790 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17791 return 0; 17792 } 17793 ast_channel_lock(chan); 17794 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17795 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17796 ast_channel_unlock(chan); 17797 return 0; 17798 } 17799 p = chan->tech_pvt; 17800 if (!p) { 17801 ast_channel_unlock(chan); 17802 return 0; 17803 } 17804 ast_mutex_lock(&p->lock); 17805 if (!strcasecmp(mode,"info")) { 17806 ast_clear_flag(&p->flags[0], SIP_DTMF); 17807 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17808 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17809 } else if (!strcasecmp(mode,"rfc2833")) { 17810 ast_clear_flag(&p->flags[0], SIP_DTMF); 17811 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17812 p->jointnoncodeccapability |= AST_RTP_DTMF; 17813 } else if (!strcasecmp(mode,"inband")) { 17814 ast_clear_flag(&p->flags[0], SIP_DTMF); 17815 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17816 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17817 } else 17818 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17819 if (p->rtp) 17820 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17821 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17822 if (!p->vad) { 17823 p->vad = ast_dsp_new(); 17824 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17825 } 17826 } else { 17827 if (p->vad) { 17828 ast_dsp_free(p->vad); 17829 p->vad = NULL; 17830 } 17831 } 17832 ast_mutex_unlock(&p->lock); 17833 ast_channel_unlock(chan); 17834 return 0; 17835 }
static void sip_dump_history | ( | struct sip_pvt * | dialog | ) | [static] |
Dump SIP history to debug log file at end of lifespan for SIP dialog.
Definition at line 11155 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::history, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
11156 { 11157 int x = 0; 11158 struct sip_history *hist; 11159 static int errmsg = 0; 11160 11161 if (!dialog) 11162 return; 11163 11164 if (!option_debug && !sipdebug) { 11165 if (!errmsg) { 11166 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11167 errmsg = 1; 11168 } 11169 return; 11170 } 11171 11172 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11173 if (dialog->subscribed) 11174 ast_log(LOG_DEBUG, " * Subscription\n"); 11175 else 11176 ast_log(LOG_DEBUG, " * SIP Call\n"); 11177 if (dialog->history) 11178 AST_LIST_TRAVERSE(dialog->history, hist, list) 11179 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11180 if (!x) 11181 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11182 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11183 }
static int sip_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
Definition at line 3776 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
03777 { 03778 int ret = -1; 03779 struct sip_pvt *p; 03780 03781 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03782 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03783 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03784 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03785 03786 if (!newchan || !newchan->tech_pvt) { 03787 if (!newchan) 03788 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03789 else 03790 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03791 return -1; 03792 } 03793 p = newchan->tech_pvt; 03794 03795 if (!p) { 03796 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03797 return -1; 03798 } 03799 03800 ast_mutex_lock(&p->lock); 03801 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03802 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03803 if (p->owner != oldchan) 03804 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03805 else { 03806 p->owner = newchan; 03807 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03808 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03809 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03810 redirect of both channels). Note that a channel can not be masqueraded *into* 03811 a native bridge. So there is no danger that this breaks a native bridge that 03812 should stay up. */ 03813 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03814 ret = 0; 03815 } 03816 if (option_debug > 2) 03817 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03818 03819 ast_mutex_unlock(&p->lock); 03820 return ret; 03821 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17928 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17929 { 17930 struct sip_pvt *p = chan->tech_pvt; 17931 return p->peercapability ? p->peercapability : p->capability; 17932 }
static enum ast_rtp_get_result sip_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Returns null if we can't reinvite audio (part of RTP interface).
Definition at line 17636 of file chan_sip.c.
References AST_JB_FORCED, ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, ast_rtp_getnat(), AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, global_jbconf, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, and ast_channel::tech_pvt.
17637 { 17638 struct sip_pvt *p = NULL; 17639 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17640 17641 if (!(p = chan->tech_pvt)) 17642 return AST_RTP_GET_FAILED; 17643 17644 ast_mutex_lock(&p->lock); 17645 if (!(p->rtp)) { 17646 ast_mutex_unlock(&p->lock); 17647 return AST_RTP_GET_FAILED; 17648 } 17649 17650 *rtp = p->rtp; 17651 17652 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17653 res = AST_RTP_TRY_PARTIAL; 17654 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17655 res = AST_RTP_TRY_NATIVE; 17656 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17657 res = AST_RTP_GET_FAILED; 17658 17659 ast_mutex_unlock(&p->lock); 17660 17661 return res; 17662 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 17501 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::udptl.
17502 { 17503 struct sip_pvt *p; 17504 struct ast_udptl *udptl = NULL; 17505 17506 p = chan->tech_pvt; 17507 if (!p) 17508 return NULL; 17509 17510 ast_mutex_lock(&p->lock); 17511 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17512 udptl = p->udptl; 17513 ast_mutex_unlock(&p->lock); 17514 return udptl; 17515 }
static enum ast_rtp_get_result sip_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Returns null if we can't reinvite video (part of RTP interface).
Definition at line 17665 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
17666 { 17667 struct sip_pvt *p = NULL; 17668 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17669 17670 if (!(p = chan->tech_pvt)) 17671 return AST_RTP_GET_FAILED; 17672 17673 ast_mutex_lock(&p->lock); 17674 if (!(p->vrtp)) { 17675 ast_mutex_unlock(&p->lock); 17676 return AST_RTP_GET_FAILED; 17677 } 17678 17679 *rtp = p->vrtp; 17680 17681 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17682 res = AST_RTP_TRY_NATIVE; 17683 17684 ast_mutex_unlock(&p->lock); 17685 17686 return res; 17687 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
T38 negotiation helper function
Definition at line 17553 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
17554 { 17555 struct sip_pvt *p; 17556 int flag = 0; 17557 17558 p = chan->tech_pvt; 17559 if (!p || !pvt->udptl) 17560 return -1; 17561 17562 /* Setup everything on the other side like offered/responded from first side */ 17563 ast_mutex_lock(&p->lock); 17564 17565 /*! \todo check if this is not set earlier when setting up the PVT. If not 17566 maybe it should move there. */ 17567 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17568 17569 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17570 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17571 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17572 17573 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17574 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17575 not really T38 re-invites which are different. In this 17576 case it's used properly, to see if we can reinvite over 17577 NAT 17578 */ 17579 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17580 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17581 flag =1; 17582 } else { 17583 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17584 } 17585 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17586 if (!p->pendinginvite) { 17587 if (option_debug > 2) { 17588 if (flag) 17589 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 17590 else 17591 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 17592 } 17593 transmit_reinvite_with_t38_sdp(p); 17594 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17595 if (option_debug > 2) { 17596 if (flag) 17597 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 17598 else 17599 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 17600 } 17601 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17602 } 17603 } 17604 /* Reset lastrtprx timer */ 17605 p->lastrtprx = p->lastrtptx = time(NULL); 17606 ast_mutex_unlock(&p->lock); 17607 return 0; 17608 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17609 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17610 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17611 flag = 1; 17612 } else { 17613 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17614 } 17615 if (option_debug > 2) { 17616 if (flag) 17617 ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port)); 17618 else 17619 ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip)); 17620 } 17621 pvt->t38.state = T38_ENABLED; 17622 p->t38.state = T38_ENABLED; 17623 if (option_debug > 1) { 17624 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17625 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17626 } 17627 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17628 p->lastrtprx = p->lastrtptx = time(NULL); 17629 ast_mutex_unlock(&p->lock); 17630 return 0; 17631 } 17632 }
static int sip_hangup | ( | struct ast_channel * | ast | ) | [static] |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
Definition at line 3487 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, sip_pvt::rtp, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, sip_pvt::vrtp, sip_pvt::waitid, and XMIT_RELIABLE.
03488 { 03489 struct sip_pvt *p = ast->tech_pvt; 03490 int needcancel = FALSE; 03491 int needdestroy = 0; 03492 struct ast_channel *oldowner = ast; 03493 03494 if (!p) { 03495 if (option_debug) 03496 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03497 return 0; 03498 } 03499 03500 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03501 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03502 if (option_debug && sipdebug) 03503 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03504 update_call_counter(p, DEC_CALL_LIMIT); 03505 } 03506 if (option_debug >3) 03507 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03508 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03509 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03510 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03511 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03512 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03513 p->owner->tech_pvt = NULL; 03514 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03515 return 0; 03516 } 03517 if (option_debug) { 03518 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03519 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03520 else { 03521 if (option_debug) 03522 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03523 } 03524 } 03525 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03526 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03527 03528 ast_mutex_lock(&p->lock); 03529 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03530 if (option_debug && sipdebug) 03531 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03532 update_call_counter(p, DEC_CALL_LIMIT); 03533 } 03534 03535 /* Determine how to disconnect */ 03536 if (p->owner != ast) { 03537 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03538 ast_mutex_unlock(&p->lock); 03539 return 0; 03540 } 03541 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03542 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03543 needcancel = TRUE; 03544 if (option_debug > 3) 03545 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03546 } 03547 03548 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03549 03550 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03551 03552 /* Disconnect */ 03553 if (p->vad) 03554 ast_dsp_free(p->vad); 03555 03556 p->owner = NULL; 03557 ast->tech_pvt = NULL; 03558 03559 ast_module_unref(ast_module_info->self); 03560 03561 /* Do not destroy this pvt until we have timeout or 03562 get an answer to the BYE or INVITE/CANCEL 03563 If we get no answer during retransmit period, drop the call anyway. 03564 (Sorry, mother-in-law, you can't deny a hangup by sending 03565 603 declined to BYE...) 03566 */ 03567 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03568 needdestroy = 1; /* Set destroy flag at end of this function */ 03569 else if (p->invitestate != INV_CALLING) 03570 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03571 03572 /* Start the process if it's not already started */ 03573 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03574 if (needcancel) { /* Outgoing call, not up */ 03575 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03576 /* stop retransmitting an INVITE that has not received a response */ 03577 __sip_pretend_ack(p); 03578 p->invitestate = INV_CANCELLED; 03579 03580 /* if we can't send right now, mark it pending */ 03581 if (p->invitestate == INV_CALLING) { 03582 /* We can't send anything in CALLING state */ 03583 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03584 /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */ 03585 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03586 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03587 } else { 03588 /* Send a new request: CANCEL */ 03589 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03590 /* Actually don't destroy us yet, wait for the 487 on our original 03591 INVITE, but do set an autodestruct just in case we never get it. */ 03592 needdestroy = 0; 03593 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03594 } 03595 if ( p->initid != -1 ) { 03596 /* channel still up - reverse dec of inUse counter 03597 only if the channel is not auto-congested */ 03598 update_call_counter(p, INC_CALL_LIMIT); 03599 } 03600 } else { /* Incoming call, not up */ 03601 const char *res; 03602 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03603 transmit_response_reliable(p, res, &p->initreq); 03604 else 03605 transmit_response_reliable(p, "603 Declined", &p->initreq); 03606 p->invitestate = INV_TERMINATED; 03607 } 03608 } else { /* Call is in UP state, send BYE */ 03609 if (!p->pendinginvite) { 03610 char *audioqos = ""; 03611 char *videoqos = ""; 03612 if (p->rtp) 03613 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03614 if (p->vrtp) 03615 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03616 /* Send a hangup */ 03617 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03618 03619 /* Get RTCP quality before end of call */ 03620 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03621 if (p->rtp) 03622 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03623 if (p->vrtp) 03624 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03625 } 03626 if (p->rtp && oldowner) 03627 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03628 if (p->vrtp && oldowner) 03629 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03630 } else { 03631 /* Note we will need a BYE when this all settles out 03632 but we can't send one while we have "INVITE" outstanding. */ 03633 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03634 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03635 AST_SCHED_DEL(sched, p->waitid); 03636 if (sip_cancel_destroy(p)) 03637 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03638 } 03639 } 03640 } 03641 if (needdestroy) 03642 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03643 ast_mutex_unlock(&p->lock); 03644 return 0; 03645 }
static int sip_indicate | ( | struct ast_channel * | ast, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
Definition at line 3892 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_change_source(), ast_rtp_update_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03893 { 03894 struct sip_pvt *p = ast->tech_pvt; 03895 int res = 0; 03896 03897 ast_mutex_lock(&p->lock); 03898 switch(condition) { 03899 case AST_CONTROL_RINGING: 03900 if (ast->_state == AST_STATE_RING) { 03901 p->invitestate = INV_EARLY_MEDIA; 03902 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03903 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03904 /* Send 180 ringing if out-of-band seems reasonable */ 03905 transmit_response(p, "180 Ringing", &p->initreq); 03906 ast_set_flag(&p->flags[0], SIP_RINGING); 03907 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03908 break; 03909 } else { 03910 /* Well, if it's not reasonable, just send in-band */ 03911 } 03912 } 03913 res = -1; 03914 break; 03915 case AST_CONTROL_BUSY: 03916 if (ast->_state != AST_STATE_UP) { 03917 transmit_response(p, "486 Busy Here", &p->initreq); 03918 p->invitestate = INV_COMPLETED; 03919 sip_alreadygone(p); 03920 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03921 break; 03922 } 03923 res = -1; 03924 break; 03925 case AST_CONTROL_CONGESTION: 03926 if (ast->_state != AST_STATE_UP) { 03927 transmit_response(p, "503 Service Unavailable", &p->initreq); 03928 p->invitestate = INV_COMPLETED; 03929 sip_alreadygone(p); 03930 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03931 break; 03932 } 03933 res = -1; 03934 break; 03935 case AST_CONTROL_PROCEEDING: 03936 if ((ast->_state != AST_STATE_UP) && 03937 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03938 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03939 transmit_response(p, "100 Trying", &p->initreq); 03940 p->invitestate = INV_PROCEEDING; 03941 break; 03942 } 03943 res = -1; 03944 break; 03945 case AST_CONTROL_PROGRESS: 03946 if ((ast->_state != AST_STATE_UP) && 03947 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03948 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03949 p->invitestate = INV_EARLY_MEDIA; 03950 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03951 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03952 break; 03953 } 03954 res = -1; 03955 break; 03956 case AST_CONTROL_HOLD: 03957 ast_rtp_update_source(p->rtp); 03958 ast_moh_start(ast, data, p->mohinterpret); 03959 break; 03960 case AST_CONTROL_UNHOLD: 03961 ast_rtp_update_source(p->rtp); 03962 ast_moh_stop(ast); 03963 break; 03964 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03965 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03966 transmit_info_with_vidupdate(p); 03967 /* ast_rtcp_send_h261fur(p->vrtp); */ 03968 } else 03969 res = -1; 03970 break; 03971 case AST_CONTROL_SRCUPDATE: 03972 ast_rtp_update_source(p->rtp); 03973 break; 03974 case AST_CONTROL_SRCCHANGE: 03975 ast_rtp_change_source(p->rtp); 03976 break; 03977 case -1: 03978 res = -1; 03979 break; 03980 default: 03981 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03982 res = -1; 03983 break; 03984 } 03985 ast_mutex_unlock(&p->lock); 03986 return res; 03987 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1756 of file chan_sip.c.
References ast_test_flag, sip_pvt::flags, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by check_via(), retrans_pkt(), and send_response().
01757 { 01758 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01759 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static, read] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 3995 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
03996 { 03997 struct ast_channel *tmp; 03998 struct ast_variable *v = NULL; 03999 int fmt; 04000 int what; 04001 int needvideo = 0, video = 0; 04002 char *decoded_exten; 04003 { 04004 const char *my_name; /* pick a good name */ 04005 04006 if (title) 04007 my_name = title; 04008 else if ( (my_name = strchr(i->fromdomain,':')) ) 04009 my_name++; /* skip ':' */ 04010 else 04011 my_name = i->fromdomain; 04012 04013 ast_mutex_unlock(&i->lock); 04014 /* Don't hold a sip pvt lock while we allocate a channel */ 04015 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i); 04016 04017 } 04018 if (!tmp) { 04019 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04020 ast_mutex_lock(&i->lock); 04021 return NULL; 04022 } 04023 ast_mutex_lock(&i->lock); 04024 04025 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04026 tmp->tech = &sip_tech_info; 04027 else 04028 tmp->tech = &sip_tech; 04029 04030 /* Select our native format based on codec preference until we receive 04031 something from another device to the contrary. */ 04032 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04033 what = i->jointcapability; 04034 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04035 } else if (i->capability) { /* Our configured capability for this peer */ 04036 what = i->capability; 04037 video = i->capability & AST_FORMAT_VIDEO_MASK; 04038 } else { 04039 what = global_capability; /* Global codec support */ 04040 video = global_capability & AST_FORMAT_VIDEO_MASK; 04041 } 04042 04043 /* Set the native formats for audio and merge in video */ 04044 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04045 if (option_debug > 2) { 04046 char buf[SIPBUFSIZE]; 04047 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04048 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04049 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04050 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04051 if (i->prefcodec) 04052 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04053 } 04054 04055 /* XXX Why are we choosing a codec from the native formats?? */ 04056 fmt = ast_best_codec(tmp->nativeformats); 04057 04058 /* If we have a prefcodec setting, we have an inbound channel that set a 04059 preferred format for this call. Otherwise, we check the jointcapability 04060 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04061 */ 04062 if (i->vrtp) { 04063 if (i->prefcodec) 04064 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04065 else 04066 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04067 } 04068 04069 if (option_debug > 2) { 04070 if (needvideo) 04071 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04072 else 04073 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04074 } 04075 04076 04077 04078 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04079 i->vad = ast_dsp_new(); 04080 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04081 if (global_relaxdtmf) 04082 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04083 } 04084 if (i->rtp) { 04085 tmp->fds[0] = ast_rtp_fd(i->rtp); 04086 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04087 } 04088 if (needvideo && i->vrtp) { 04089 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04090 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04091 } 04092 if (i->udptl) { 04093 tmp->fds[5] = ast_udptl_fd(i->udptl); 04094 } 04095 if (state == AST_STATE_RING) 04096 tmp->rings = 1; 04097 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04098 tmp->writeformat = fmt; 04099 tmp->rawwriteformat = fmt; 04100 tmp->readformat = fmt; 04101 tmp->rawreadformat = fmt; 04102 tmp->tech_pvt = i; 04103 04104 tmp->callgroup = i->callgroup; 04105 tmp->pickupgroup = i->pickupgroup; 04106 tmp->cid.cid_pres = i->callingpres; 04107 if (!ast_strlen_zero(i->accountcode)) 04108 ast_string_field_set(tmp, accountcode, i->accountcode); 04109 if (i->amaflags) 04110 tmp->amaflags = i->amaflags; 04111 if (!ast_strlen_zero(i->language)) 04112 ast_string_field_set(tmp, language, i->language); 04113 i->owner = tmp; 04114 ast_module_ref(ast_module_info->self); 04115 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04116 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04117 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04118 * structure so that there aren't issues when forming URI's 04119 */ 04120 decoded_exten = ast_strdupa(i->exten); 04121 ast_uri_decode(decoded_exten); 04122 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04123 04124 /* Don't use ast_set_callerid() here because it will 04125 * generate an unnecessary NewCallerID event */ 04126 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04127 if (!ast_strlen_zero(i->rdnis)) 04128 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04129 04130 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04131 tmp->cid.cid_dnid = ast_strdup(i->exten); 04132 04133 tmp->priority = 1; 04134 if (!ast_strlen_zero(i->uri)) 04135 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04136 if (!ast_strlen_zero(i->domain)) 04137 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04138 if (!ast_strlen_zero(i->useragent)) 04139 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04140 if (!ast_strlen_zero(i->callid)) 04141 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04142 if (i->rtp) 04143 ast_jb_configure(tmp, &global_jbconf); 04144 04145 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04146 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04147 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04148 04149 /* Set channel variables for this call from configuration */ 04150 for (v = i->chanvars ; v ; v = v->next) 04151 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04152 04153 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04154 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04155 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04156 ast_hangup(tmp); 04157 tmp = NULL; 04158 } 04159 04160 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04161 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04162 04163 return tmp; 04164 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11444 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11445 { 11446 if (argc != 4) 11447 return RESULT_SHOWUSAGE; 11448 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11449 ast_cli(fd, "SIP Debugging Disabled\n"); 11450 return RESULT_SUCCESS; 11451 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11453 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11454 { 11455 if (argc != 3) 11456 return RESULT_SHOWUSAGE; 11457 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11458 ast_cli(fd, "SIP Debugging Disabled\n"); 11459 return RESULT_SUCCESS; 11460 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11474 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11475 { 11476 if (argc != 3) { 11477 return RESULT_SHOWUSAGE; 11478 } 11479 recordhistory = FALSE; 11480 ast_cli(fd, "SIP History Recording Disabled\n"); 11481 return RESULT_SUCCESS; 11482 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11388 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.
11389 { 11390 struct ast_variable *varlist; 11391 int i; 11392 11393 if (argc < 4) 11394 return RESULT_SHOWUSAGE; 11395 11396 if (!notify_types) { 11397 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11398 return RESULT_FAILURE; 11399 } 11400 11401 varlist = ast_variable_browse(notify_types, argv[2]); 11402 11403 if (!varlist) { 11404 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11405 return RESULT_FAILURE; 11406 } 11407 11408 for (i = 3; i < argc; i++) { 11409 struct sip_pvt *p; 11410 struct sip_request req; 11411 struct ast_variable *var; 11412 11413 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11414 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11415 return RESULT_FAILURE; 11416 } 11417 11418 if (create_addr(p, argv[i])) { 11419 /* Maybe they're not registered, etc. */ 11420 sip_destroy(p); 11421 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11422 continue; 11423 } 11424 11425 initreqprep(&req, p, SIP_NOTIFY); 11426 11427 for (var = varlist; var; var = var->next) 11428 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11429 11430 /* Recalculate our side, and recalculate Call ID */ 11431 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11432 p->ourip = __ourip; 11433 build_via(p); 11434 build_callid_pvt(p); 11435 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11436 transmit_sip_request(p, &req); 11437 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11438 } 11439 11440 return RESULT_SUCCESS; 11441 }
static int sip_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Park a call using the subsystem in res_features.c This is executed in a separate thread.
Definition at line 13204 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
13205 { 13206 struct sip_dual *d; 13207 struct ast_channel *transferee, *transferer; 13208 /* Chan2m: The transferer, chan1m: The transferee */ 13209 pthread_t th; 13210 13211 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13212 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13213 if ((!transferer) || (!transferee)) { 13214 if (transferee) { 13215 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13216 ast_hangup(transferee); 13217 } 13218 if (transferer) { 13219 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13220 ast_hangup(transferer); 13221 } 13222 return -1; 13223 } 13224 13225 /* Make formats okay */ 13226 transferee->readformat = chan1->readformat; 13227 transferee->writeformat = chan1->writeformat; 13228 13229 /* Prepare for taking over the channel */ 13230 ast_channel_masquerade(transferee, chan1); 13231 13232 /* Setup the extensions and such */ 13233 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13234 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13235 transferee->priority = chan1->priority; 13236 13237 /* We make a clone of the peer channel too, so we can play 13238 back the announcement */ 13239 13240 /* Make formats okay */ 13241 transferer->readformat = chan2->readformat; 13242 transferer->writeformat = chan2->writeformat; 13243 13244 /* Prepare for taking over the channel. Go ahead and grab this channel 13245 * lock here to avoid a deadlock with callbacks into the channel driver 13246 * that hold the channel lock and want the pvt lock. */ 13247 while (ast_channel_trylock(chan2)) { 13248 struct sip_pvt *pvt = chan2->tech_pvt; 13249 DEADLOCK_AVOIDANCE(&pvt->lock); 13250 } 13251 ast_channel_masquerade(transferer, chan2); 13252 ast_channel_unlock(chan2); 13253 13254 /* Setup the extensions and such */ 13255 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13256 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13257 transferer->priority = chan2->priority; 13258 13259 ast_channel_lock(transferer); 13260 if (ast_do_masquerade(transferer)) { 13261 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13262 ast_channel_unlock(transferer); 13263 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13264 ast_hangup(transferer); 13265 return -1; 13266 } 13267 ast_channel_unlock(transferer); 13268 if (!transferer || !transferee) { 13269 if (!transferer) { 13270 if (option_debug) 13271 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13272 } 13273 if (!transferee) { 13274 if (option_debug) 13275 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13276 } 13277 return -1; 13278 } 13279 if ((d = ast_calloc(1, sizeof(*d)))) { 13280 pthread_attr_t attr; 13281 13282 pthread_attr_init(&attr); 13283 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13284 13285 /* Save original request for followup */ 13286 copy_request(&d->req, req); 13287 d->chan1 = transferee; /* Transferee */ 13288 d->chan2 = transferer; /* Transferer */ 13289 d->seqno = seqno; 13290 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13291 /* Could not start thread */ 13292 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13293 by sip_park_thread() */ 13294 pthread_attr_destroy(&attr); 13295 return 0; 13296 } 13297 pthread_attr_destroy(&attr); 13298 } 13299 return -1; 13300 }
static void * sip_park_thread | ( | void * | stuff | ) | [static] |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
Definition at line 13137 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
13138 { 13139 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13140 struct sip_dual *d; 13141 struct sip_request req; 13142 int ext; 13143 int res; 13144 13145 d = stuff; 13146 transferee = d->chan1; 13147 transferer = d->chan2; 13148 copy_request(&req, &d->req); 13149 free(d); 13150 13151 if (!transferee || !transferer) { 13152 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13153 return NULL; 13154 } 13155 if (option_debug > 3) 13156 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13157 13158 ast_channel_lock(transferee); 13159 if (ast_do_masquerade(transferee)) { 13160 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13161 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13162 ast_channel_unlock(transferee); 13163 return NULL; 13164 } 13165 ast_channel_unlock(transferee); 13166 13167 res = ast_park_call(transferee, transferer, 0, &ext); 13168 13169 13170 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13171 if (!res) { 13172 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13173 } else { 13174 /* Then tell the transferer what happened */ 13175 sprintf(buf, "Call parked on extension '%d'", ext); 13176 transmit_message_with_text(transferer->tech_pvt, buf); 13177 } 13178 #endif 13179 13180 /* Any way back to the current call??? */ 13181 /* Transmit response to the REFER request */ 13182 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13183 if (!res) { 13184 /* Transfer succeeded */ 13185 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13186 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13187 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13188 ast_hangup(transferer); /* This will cause a BYE */ 13189 if (option_debug) 13190 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13191 } else { 13192 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13193 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13194 if (option_debug) 13195 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13196 /* Do not hangup call */ 13197 } 13198 return NULL; 13199 }
static void sip_peer_hold | ( | struct sip_pvt * | p, | |
int | hold | |||
) | [static] |
Change onhold state of a peer using a pvt structure.
Definition at line 8583 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), and sip_peer::onHold.
Referenced by change_hold_state(), and update_call_counter().
08584 { 08585 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08586 08587 if (!peer) 08588 return; 08589 08590 /* If they put someone on hold, increment the value... otherwise decrement it */ 08591 if (hold) 08592 peer->onHold++; 08593 else 08594 peer->onHold--; 08595 08596 /* Request device state update */ 08597 ast_device_state_changed("SIP/%s", peer->name); 08598 08599 return; 08600 }
static void sip_poke_all_peers | ( | void | ) | [static] |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
Definition at line 17938 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
17939 { 17940 int ms = 0; 17941 17942 if (!speerobjs) /* No peers, just give up */ 17943 return; 17944 17945 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17946 ASTOBJ_WRLOCK(iterator); 17947 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 17948 struct sip_peer *peer_ptr = iterator; 17949 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17950 } 17951 ms += 100; 17952 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 17953 if (iterator->pokeexpire == -1) { 17954 struct sip_peer *peer_ptr = iterator; 17955 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17956 } 17957 ASTOBJ_UNLOCK(iterator); 17958 } while (0) 17959 ); 17960 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15849 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15850 { 15851 struct sip_peer *peer = (struct sip_peer *)data; 15852 15853 peer->pokeexpire = -1; 15854 if (peer->lastms > -1) { 15855 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15856 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15857 } 15858 if (peer->call) 15859 sip_destroy(peer->call); 15860 peer->call = NULL; 15861 peer->lastms = -1; 15862 ast_device_state_changed("SIP/%s", peer->name); 15863 15864 /* This function gets called one place outside of the scheduler ... */ 15865 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15866 struct sip_peer *peer_ptr = peer; 15867 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15868 } 15869 15870 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 15871 * inherit the reference that the current callback already has. */ 15872 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15873 if (peer->pokeexpire == -1) { 15874 ASTOBJ_UNREF(peer, sip_destroy_peer); 15875 } 15876 15877 return 0; 15878 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15883 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_callid_pvt(), build_via(), sip_peer::call, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sip_alloc(), sip_destroy(), sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15884 { 15885 struct sip_pvt *p; 15886 int xmitres = 0; 15887 15888 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15889 /* IF we have no IP, or this isn't to be monitored, return 15890 imeediately after clearing things out */ 15891 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15892 struct sip_peer *peer_ptr = peer; 15893 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15894 } 15895 peer->lastms = 0; 15896 peer->call = NULL; 15897 return 0; 15898 } 15899 if (peer->call) { 15900 if (sipdebug) 15901 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15902 sip_destroy(peer->call); 15903 } 15904 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15905 return -1; 15906 15907 p->sa = peer->addr; 15908 p->recv = peer->addr; 15909 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15910 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15911 15912 /* Send OPTIONs to peer's fullcontact */ 15913 if (!ast_strlen_zero(peer->fullcontact)) 15914 ast_string_field_set(p, fullcontact, peer->fullcontact); 15915 15916 if (!ast_strlen_zero(peer->tohost)) 15917 ast_string_field_set(p, tohost, peer->tohost); 15918 else 15919 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15920 15921 /* Recalculate our side, and recalculate Call ID */ 15922 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15923 p->ourip = __ourip; 15924 build_via(p); 15925 build_callid_pvt(p); 15926 15927 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15928 struct sip_peer *peer_ptr = peer; 15929 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15930 } 15931 15932 p->relatedpeer = ASTOBJ_REF(peer); 15933 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15934 #ifdef VOCAL_DATA_HACK 15935 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15936 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15937 #else 15938 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15939 #endif 15940 gettimeofday(&peer->ps, NULL); 15941 if (xmitres == XMIT_ERROR) { 15942 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 15943 } else { 15944 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15945 struct sip_peer *peer_ptr = peer; 15946 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15947 } 15948 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 15949 if (peer->pokeexpire == -1) { 15950 struct sip_peer *peer_ptr = peer; 15951 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15952 } 15953 } 15954 15955 return 0; 15956 }
static int sip_poke_peer_s | ( | const void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 7948 of file chan_sip.c.
References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
07949 { 07950 struct sip_peer *peer = (struct sip_peer *) data; 07951 07952 peer->pokeexpire = -1; 07953 07954 sip_poke_peer(peer); 07955 07956 ASTOBJ_UNREF(peer, sip_destroy_peer); 07957 07958 return 0; 07959 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10177 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.
10178 { 10179 struct sip_peer *peer; 10180 struct sip_user *user; 10181 int pruneuser = FALSE; 10182 int prunepeer = FALSE; 10183 int multi = FALSE; 10184 char *name = NULL; 10185 regex_t regexbuf; 10186 10187 switch (argc) { 10188 case 4: 10189 if (!strcasecmp(argv[3], "user")) 10190 return RESULT_SHOWUSAGE; 10191 if (!strcasecmp(argv[3], "peer")) 10192 return RESULT_SHOWUSAGE; 10193 if (!strcasecmp(argv[3], "like")) 10194 return RESULT_SHOWUSAGE; 10195 if (!strcasecmp(argv[3], "all")) { 10196 multi = TRUE; 10197 pruneuser = prunepeer = TRUE; 10198 } else { 10199 pruneuser = prunepeer = TRUE; 10200 name = argv[3]; 10201 } 10202 break; 10203 case 5: 10204 if (!strcasecmp(argv[4], "like")) 10205 return RESULT_SHOWUSAGE; 10206 if (!strcasecmp(argv[3], "all")) 10207 return RESULT_SHOWUSAGE; 10208 if (!strcasecmp(argv[3], "like")) { 10209 multi = TRUE; 10210 name = argv[4]; 10211 pruneuser = prunepeer = TRUE; 10212 } else if (!strcasecmp(argv[3], "user")) { 10213 pruneuser = TRUE; 10214 if (!strcasecmp(argv[4], "all")) 10215 multi = TRUE; 10216 else 10217 name = argv[4]; 10218 } else if (!strcasecmp(argv[3], "peer")) { 10219 prunepeer = TRUE; 10220 if (!strcasecmp(argv[4], "all")) 10221 multi = TRUE; 10222 else 10223 name = argv[4]; 10224 } else 10225 return RESULT_SHOWUSAGE; 10226 break; 10227 case 6: 10228 if (strcasecmp(argv[4], "like")) 10229 return RESULT_SHOWUSAGE; 10230 if (!strcasecmp(argv[3], "user")) { 10231 pruneuser = TRUE; 10232 name = argv[5]; 10233 } else if (!strcasecmp(argv[3], "peer")) { 10234 prunepeer = TRUE; 10235 name = argv[5]; 10236 } else 10237 return RESULT_SHOWUSAGE; 10238 break; 10239 default: 10240 return RESULT_SHOWUSAGE; 10241 } 10242 10243 if (multi && name) { 10244 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10245 return RESULT_SHOWUSAGE; 10246 } 10247 10248 if (multi) { 10249 if (prunepeer) { 10250 int pruned = 0; 10251 10252 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10253 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10254 ASTOBJ_RDLOCK(iterator); 10255 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10256 ASTOBJ_UNLOCK(iterator); 10257 continue; 10258 }; 10259 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10260 ASTOBJ_MARK(iterator); 10261 pruned++; 10262 } 10263 ASTOBJ_UNLOCK(iterator); 10264 } while (0) ); 10265 if (pruned) { 10266 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10267 ast_cli(fd, "%d peers pruned.\n", pruned); 10268 } else 10269 ast_cli(fd, "No peers found to prune.\n"); 10270 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10271 } 10272 if (pruneuser) { 10273 int pruned = 0; 10274 10275 ASTOBJ_CONTAINER_WRLOCK(&userl); 10276 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10277 ASTOBJ_RDLOCK(iterator); 10278 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10279 ASTOBJ_UNLOCK(iterator); 10280 continue; 10281 }; 10282 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10283 ASTOBJ_MARK(iterator); 10284 pruned++; 10285 } 10286 ASTOBJ_UNLOCK(iterator); 10287 } while (0) ); 10288 if (pruned) { 10289 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10290 ast_cli(fd, "%d users pruned.\n", pruned); 10291 } else 10292 ast_cli(fd, "No users found to prune.\n"); 10293 ASTOBJ_CONTAINER_UNLOCK(&userl); 10294 } 10295 } else { 10296 if (prunepeer) { 10297 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10298 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10299 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10300 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10301 } else 10302 ast_cli(fd, "Peer '%s' pruned.\n", name); 10303 ASTOBJ_UNREF(peer, sip_destroy_peer); 10304 } else 10305 ast_cli(fd, "Peer '%s' not found.\n", name); 10306 } 10307 if (pruneuser) { 10308 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10309 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10310 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10311 ASTOBJ_CONTAINER_LINK(&userl, user); 10312 } else 10313 ast_cli(fd, "User '%s' pruned.\n", name); 10314 ASTOBJ_UNREF(user, sip_destroy_user); 10315 } else 10316 ast_cli(fd, "User '%s' not found.\n", name); 10317 } 10318 } 10319 10320 return RESULT_SUCCESS; 10321 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4367 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().
04368 { 04369 struct ast_frame *fr; 04370 struct sip_pvt *p = ast->tech_pvt; 04371 int faxdetected = FALSE; 04372 04373 ast_mutex_lock(&p->lock); 04374 fr = sip_rtp_read(ast, p, &faxdetected); 04375 p->lastrtprx = time(NULL); 04376 04377 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04378 /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */ 04379 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04380 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04381 if (!p->pendinginvite) { 04382 if (option_debug > 2) 04383 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04384 p->t38.state = T38_LOCAL_REINVITE; 04385 transmit_reinvite_with_t38_sdp(p); 04386 if (option_debug > 1) 04387 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04388 } 04389 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04390 if (option_debug > 2) 04391 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04392 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04393 } 04394 } 04395 04396 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04397 if (fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04398 fr = &ast_null_frame; 04399 } 04400 04401 ast_mutex_unlock(&p->lock); 04402 return fr; 04403 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 1750 of file chan_sip.c.
References ast_test_flag, sip_pvt::flags, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.
Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), and sip_debug_test_pvt().
01751 { 01752 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01753 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7753 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
07754 { 07755 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07756 return p->refer ? 1 : 0; 07757 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7508 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_pvt::lock, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, and transmit_register().
Referenced by transmit_register().
07509 { 07510 07511 /* if we are here, our registration timed out, so we'll just do it over */ 07512 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07513 struct sip_pvt *p; 07514 int res; 07515 07516 /* if we couldn't get a reference to the registry object, punt */ 07517 if (!r) 07518 return 0; 07519 07520 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07521 if (r->call) { 07522 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07523 in the single SIP manager thread. */ 07524 p = r->call; 07525 ast_mutex_lock(&p->lock); 07526 if (p->registry) 07527 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07528 r->call = NULL; 07529 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07530 /* Pretend to ACK anything just in case */ 07531 __sip_pretend_ack(p); 07532 ast_mutex_unlock(&p->lock); 07533 } 07534 /* If we have a limit, stop registration and give up */ 07535 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07536 /* Ok, enough is enough. Don't try any more */ 07537 /* We could add an external notification here... 07538 steal it from app_voicemail :-) */ 07539 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07540 r->regstate = REG_STATE_FAILED; 07541 } else { 07542 r->regstate = REG_STATE_UNREGISTERED; 07543 r->timeout = -1; 07544 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07545 } 07546 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate)); 07547 ASTOBJ_UNREF(r, sip_registry_destroy); 07548 return 0; 07549 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4694 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::callid_valid, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, and username.
Referenced by reload_config().
04695 { 04696 struct sip_registry *reg; 04697 int portnum = 0; 04698 char username[256] = ""; 04699 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04700 char *porta=NULL; 04701 char *contact=NULL; 04702 04703 if (!value) 04704 return -1; 04705 ast_copy_string(username, value, sizeof(username)); 04706 /* First split around the last '@' then parse the two components. */ 04707 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04708 if (hostname) 04709 *hostname++ = '\0'; 04710 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04711 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04712 return -1; 04713 } 04714 /* split user[:secret[:authuser]] */ 04715 secret = strchr(username, ':'); 04716 if (secret) { 04717 *secret++ = '\0'; 04718 authuser = strchr(secret, ':'); 04719 if (authuser) 04720 *authuser++ = '\0'; 04721 } 04722 /* split host[:port][/contact] */ 04723 contact = strchr(hostname, '/'); 04724 if (contact) 04725 *contact++ = '\0'; 04726 if (ast_strlen_zero(contact)) 04727 contact = "s"; 04728 porta = strchr(hostname, ':'); 04729 if (porta) { 04730 *porta++ = '\0'; 04731 portnum = atoi(porta); 04732 if (portnum == 0) { 04733 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04734 return -1; 04735 } 04736 } 04737 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04738 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04739 return -1; 04740 } 04741 04742 if (ast_string_field_init(reg, 256)) { 04743 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04744 free(reg); 04745 return -1; 04746 } 04747 04748 regobjs++; 04749 ASTOBJ_INIT(reg); 04750 ast_string_field_set(reg, contact, contact); 04751 if (!ast_strlen_zero(username)) 04752 ast_string_field_set(reg, username, username); 04753 if (hostname) 04754 ast_string_field_set(reg, hostname, hostname); 04755 if (authuser) 04756 ast_string_field_set(reg, authuser, authuser); 04757 if (secret) 04758 ast_string_field_set(reg, secret, secret); 04759 reg->expire = -1; 04760 reg->timeout = -1; 04761 reg->refresh = default_expiry; 04762 reg->portno = portnum; 04763 reg->callid_valid = FALSE; 04764 reg->ocseq = INITIAL_CSEQ; 04765 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04766 ASTOBJ_UNREF(reg,sip_registry_destroy); 04767 return 0; 04768 }
static void sip_registry_destroy | ( | struct sip_registry * | reg | ) | [static] |
Destroy registry object Objects created with the register= statement in static configuration.
Definition at line 3046 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03047 { 03048 /* Really delete */ 03049 if (option_debug > 2) 03050 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03051 03052 if (reg->call) { 03053 /* Clear registry before destroying to ensure 03054 we don't get reentered trying to grab the registry lock */ 03055 reg->call->registry = NULL; 03056 if (option_debug > 2) 03057 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03058 sip_destroy(reg->call); 03059 } 03060 AST_SCHED_DEL(sched, reg->expire); 03061 AST_SCHED_DEL(sched, reg->timeout); 03062 ast_string_field_free_memory(reg); 03063 regobjs--; 03064 free(reg); 03065 03066 }
static int sip_reinvite_retry | ( | const void * | data | ) | [static] |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
Definition at line 12111 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12112 { 12113 struct sip_pvt *p = (struct sip_pvt *) data; 12114 12115 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12116 p->waitid = -1; 12117 return 0; 12118 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18006 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), and TRUE.
Referenced by reload().
18007 { 18008 ast_mutex_lock(&sip_reload_lock); 18009 if (sip_reloading) 18010 ast_verbose("Previous SIP reload not yet done\n"); 18011 else { 18012 sip_reloading = TRUE; 18013 if (fd) 18014 sip_reloadreason = CHANNEL_CLI_RELOAD; 18015 else 18016 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18017 } 18018 ast_mutex_unlock(&sip_reload_lock); 18019 restart_monitor(); 18020 18021 return 0; 18022 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 16061 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
16062 { 16063 int oldformat; 16064 struct sip_pvt *p; 16065 struct ast_channel *tmpc = NULL; 16066 char *ext, *host; 16067 char tmp[256]; 16068 char *dest = data; 16069 16070 oldformat = format; 16071 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16072 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability)); 16073 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16074 return NULL; 16075 } 16076 if (option_debug) 16077 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16078 16079 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16080 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16081 *cause = AST_CAUSE_SWITCH_CONGESTION; 16082 return NULL; 16083 } 16084 16085 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16086 16087 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16088 sip_destroy(p); 16089 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16090 *cause = AST_CAUSE_SWITCH_CONGESTION; 16091 return NULL; 16092 } 16093 16094 ast_copy_string(tmp, dest, sizeof(tmp)); 16095 host = strchr(tmp, '@'); 16096 if (host) { 16097 *host++ = '\0'; 16098 ext = tmp; 16099 } else { 16100 ext = strchr(tmp, '/'); 16101 if (ext) 16102 *ext++ = '\0'; 16103 host = tmp; 16104 } 16105 16106 if (create_addr(p, host)) { 16107 *cause = AST_CAUSE_UNREGISTERED; 16108 if (option_debug > 2) 16109 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16110 sip_destroy(p); 16111 return NULL; 16112 } 16113 if (ast_strlen_zero(p->peername) && ext) 16114 ast_string_field_set(p, peername, ext); 16115 /* Recalculate our side, and recalculate Call ID */ 16116 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16117 p->ourip = __ourip; 16118 build_via(p); 16119 build_callid_pvt(p); 16120 16121 /* We have an extension to call, don't use the full contact here */ 16122 /* This to enable dialing registered peers with extension dialling, 16123 like SIP/peername/extension 16124 SIP/peername will still use the full contact */ 16125 if (ext) { 16126 ast_string_field_set(p, username, ext); 16127 ast_string_field_free(p, fullcontact); 16128 } 16129 #if 0 16130 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16131 #endif 16132 p->prefcodec = oldformat; /* Format for this call */ 16133 ast_mutex_lock(&p->lock); 16134 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16135 ast_mutex_unlock(&p->lock); 16136 if (!tmpc) 16137 sip_destroy(p); 16138 ast_update_use_count(); 16139 restart_monitor(); 16140 return tmpc; 16141 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7476 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), and sipdebug.
Referenced by handle_response_register(), and sip_send_all_registers().
07477 { 07478 /* if we are here, we know that we need to reregister. */ 07479 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07480 07481 /* if we couldn't get a reference to the registry object, punt */ 07482 if (!r) 07483 return 0; 07484 07485 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07486 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07487 /* Since registry's are only added/removed by the the monitor thread, this 07488 may be overkill to reference/dereference at all here */ 07489 if (sipdebug) 07490 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07491 07492 r->expire = -1; 07493 __sip_do_register(r); 07494 ASTOBJ_UNREF(r, sip_registry_destroy); 07495 return 0; 07496 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static, read] |
Read RTP from network.
Definition at line 4297 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04298 { 04299 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04300 struct ast_frame *f; 04301 04302 if (!p->rtp) { 04303 /* We have no RTP allocated for this channel */ 04304 return &ast_null_frame; 04305 } 04306 04307 switch(ast->fdno) { 04308 case 0: 04309 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04310 break; 04311 case 1: 04312 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04313 break; 04314 case 2: 04315 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04316 break; 04317 case 3: 04318 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04319 break; 04320 case 5: 04321 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04322 break; 04323 default: 04324 f = &ast_null_frame; 04325 } 04326 /* Don't forward RFC2833 if we're not supposed to */ 04327 if (f && (f->frametype == AST_FRAME_DTMF) && 04328 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04329 return &ast_null_frame; 04330 04331 /* We already hold the channel lock */ 04332 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04333 return f; 04334 04335 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04336 if (!(f->subclass & p->jointcapability)) { 04337 if (option_debug) { 04338 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04339 ast_getformatname(f->subclass), p->owner->name); 04340 } 04341 return &ast_null_frame; 04342 } 04343 if (option_debug) 04344 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04345 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04346 ast_set_read_format(p->owner, p->owner->readformat); 04347 ast_set_write_format(p->owner, p->owner->writeformat); 04348 } 04349 04350 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04351 f = ast_dsp_process(p->owner, p->vad, f); 04352 if (f && f->frametype == AST_FRAME_DTMF) { 04353 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04354 if (option_debug) 04355 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04356 *faxdetect = 1; 04357 } else if (option_debug) { 04358 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04359 } 04360 } 04361 } 04362 04363 return f; 04364 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2112 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::autokillid, sip_pvt::flags, sip_pvt::method, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02113 { 02114 if (ms < 0) { 02115 if (p->timer_t1 == 0) 02116 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02117 ms = p->timer_t1 * 64; 02118 } 02119 if (sip_debug_test_pvt(p)) 02120 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02121 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02122 append_history(p, "SchedDestroy", "%d ms", ms); 02123 02124 AST_SCHED_DEL(sched, p->autokillid); 02125 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02126 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17963 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
17964 { 17965 int ms; 17966 int regspacing; 17967 if (!regobjs) 17968 return; 17969 regspacing = default_expiry * 1000/regobjs; 17970 if (regspacing > 100) 17971 regspacing = 100; 17972 ms = regspacing; 17973 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17974 ASTOBJ_WRLOCK(iterator); 17975 AST_SCHED_DEL(sched, iterator->expire); 17976 ms += regspacing; 17977 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17978 ASTOBJ_UNLOCK(iterator); 17979 } while (0) 17980 ); 17981 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer | ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 15583 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by do_monitor(), and handle_request_subscribe().
15584 { 15585 /* Called with peerl lock, but releases it */ 15586 struct sip_pvt *p; 15587 int newmsgs, oldmsgs; 15588 15589 /* Do we have an IP address? If not, skip this peer */ 15590 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15591 return 0; 15592 15593 /* Check for messages */ 15594 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15595 15596 peer->lastmsgcheck = time(NULL); 15597 15598 /* Return now if it's the same thing we told them last time */ 15599 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15600 return 0; 15601 } 15602 15603 15604 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15605 15606 if (peer->mwipvt) { 15607 /* Base message on subscription */ 15608 p = peer->mwipvt; 15609 } else { 15610 /* Build temporary dialog for this message */ 15611 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15612 return -1; 15613 if (create_addr_from_peer(p, peer)) { 15614 /* Maybe they're not registered, etc. */ 15615 sip_destroy(p); 15616 return 0; 15617 } 15618 /* Recalculate our side, and recalculate Call ID */ 15619 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15620 p->ourip = __ourip; 15621 build_via(p); 15622 build_callid_pvt(p); 15623 /* Destroy this session after 32 secs */ 15624 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15625 } 15626 /* Send MWI */ 15627 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15628 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15629 return 0; 15630 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3823 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, and ast_channel::tech_pvt.
03824 { 03825 struct sip_pvt *p = ast->tech_pvt; 03826 int res = 0; 03827 03828 ast_mutex_lock(&p->lock); 03829 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03830 case SIP_DTMF_INBAND: 03831 res = -1; /* Tell Asterisk to generate inband indications */ 03832 break; 03833 case SIP_DTMF_RFC2833: 03834 if (p->rtp) 03835 ast_rtp_senddigit_begin(p->rtp, digit); 03836 break; 03837 default: 03838 break; 03839 } 03840 ast_mutex_unlock(&p->lock); 03841 03842 return res; 03843 }
static int sip_senddigit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
Definition at line 3847 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
03848 { 03849 struct sip_pvt *p = ast->tech_pvt; 03850 int res = 0; 03851 03852 ast_mutex_lock(&p->lock); 03853 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03854 case SIP_DTMF_INFO: 03855 transmit_info_with_digit(p, digit, duration); 03856 break; 03857 case SIP_DTMF_RFC2833: 03858 if (p->rtp) 03859 ast_rtp_senddigit_end(p->rtp, digit); 03860 break; 03861 case SIP_DTMF_INBAND: 03862 res = -1; /* Tell Asterisk to stop inband indications */ 03863 break; 03864 } 03865 ast_mutex_unlock(&p->lock); 03866 03867 return res; 03868 }
static int sip_sendtext | ( | struct ast_channel * | ast, | |
const char * | text | |||
) | [static] |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
Definition at line 2372 of file chan_sip.c.
References ast_strlen_zero(), ast_verbose(), debug, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02373 { 02374 struct sip_pvt *p = ast->tech_pvt; 02375 int debug = sip_debug_test_pvt(p); 02376 02377 if (debug) 02378 ast_verbose("Sending text %s on %s\n", text, ast->name); 02379 if (!p) 02380 return -1; 02381 if (ast_strlen_zero(text)) 02382 return 0; 02383 if (debug) 02384 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02385 transmit_message_with_text(p, text); 02386 return 0; 02387 }
static int sip_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Set the RTP peer for this call.
Definition at line 17690 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.
Referenced by sip_fixup().
17691 { 17692 struct sip_pvt *p; 17693 int changed = 0; 17694 17695 p = chan->tech_pvt; 17696 if (!p) 17697 return -1; 17698 17699 /* Disable early RTP bridge */ 17700 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17701 return 0; 17702 17703 ast_mutex_lock(&p->lock); 17704 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17705 /* If we're destroyed, don't bother */ 17706 ast_mutex_unlock(&p->lock); 17707 return 0; 17708 } 17709 17710 /* if this peer cannot handle reinvites of the media stream to devices 17711 that are known to be behind a NAT, then stop the process now 17712 */ 17713 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17714 ast_mutex_unlock(&p->lock); 17715 return 0; 17716 } 17717 17718 if (rtp) { 17719 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17720 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17721 memset(&p->redirip, 0, sizeof(p->redirip)); 17722 changed = 1; 17723 } 17724 if (vrtp) { 17725 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17726 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17727 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17728 changed = 1; 17729 } 17730 if (codecs) { 17731 if ((p->redircodecs != codecs)) { 17732 p->redircodecs = codecs; 17733 changed = 1; 17734 } 17735 if ((p->capability & codecs) != p->capability) { 17736 p->jointcapability &= codecs; 17737 p->capability &= codecs; 17738 changed = 1; 17739 } 17740 } 17741 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17742 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17743 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17744 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17745 if (option_debug) 17746 ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip)); 17747 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17748 if (option_debug > 2) { 17749 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip)); 17750 } 17751 transmit_reinvite_with_sdp(p); 17752 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17753 if (option_debug > 2) { 17754 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip)); 17755 } 17756 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17757 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17758 } 17759 } 17760 /* Reset lastrtprx timer */ 17761 p->lastrtprx = p->lastrtptx = time(NULL); 17762 ast_mutex_unlock(&p->lock); 17763 return 0; 17764 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17517 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.
17518 { 17519 struct sip_pvt *p; 17520 17521 p = chan->tech_pvt; 17522 if (!p) 17523 return -1; 17524 ast_mutex_lock(&p->lock); 17525 if (udptl) 17526 ast_udptl_get_peer(udptl, &p->udptlredirip); 17527 else 17528 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17529 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17530 if (!p->pendinginvite) { 17531 if (option_debug > 2) { 17532 ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 17533 } 17534 transmit_reinvite_with_t38_sdp(p); 17535 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17536 if (option_debug > 2) { 17537 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0); 17538 } 17539 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17540 } 17541 } 17542 /* Reset lastrtprx timer */ 17543 p->lastrtprx = p->lastrtptx = time(NULL); 17544 ast_mutex_unlock(&p->lock); 17545 return 0; 17546 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11050 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
11051 { 11052 struct sip_pvt *cur; 11053 size_t len; 11054 int found = 0; 11055 11056 if (argc != 4) 11057 return RESULT_SHOWUSAGE; 11058 len = strlen(argv[3]); 11059 ast_mutex_lock(&iflock); 11060 for (cur = iflist; cur; cur = cur->next) { 11061 if (!strncasecmp(cur->callid, argv[3], len)) { 11062 char formatbuf[SIPBUFSIZE/2]; 11063 ast_cli(fd,"\n"); 11064 if (cur->subscribed != NONE) 11065 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11066 else 11067 ast_cli(fd, " * SIP Call\n"); 11068 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11069 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11070 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11071 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11072 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11073 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11074 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11075 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11076 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11077 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11078 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11079 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11080 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11081 ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); 11082 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11083 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11084 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11085 if (!ast_strlen_zero(cur->username)) 11086 ast_cli(fd, " Username: %s\n", cur->username); 11087 if (!ast_strlen_zero(cur->peername)) 11088 ast_cli(fd, " Peername: %s\n", cur->peername); 11089 if (!ast_strlen_zero(cur->uri)) 11090 ast_cli(fd, " Original uri: %s\n", cur->uri); 11091 if (!ast_strlen_zero(cur->cid_num)) 11092 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11093 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11094 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11095 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11096 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11097 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11098 ast_cli(fd, " SIP Options: "); 11099 if (cur->sipoptions) { 11100 int x; 11101 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11102 if (cur->sipoptions & sip_options[x].id) 11103 ast_cli(fd, "%s ", sip_options[x].text); 11104 } 11105 } else 11106 ast_cli(fd, "(none)\n"); 11107 ast_cli(fd, "\n\n"); 11108 found++; 11109 } 11110 } 11111 ast_mutex_unlock(&iflock); 11112 if (!found) 11113 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11114 return RESULT_SUCCESS; 11115 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10843 of file chan_sip.c.
References __sip_show_channels().
10844 { 10845 return __sip_show_channels(fd, argc, argv, 0); 10846 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10355 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), FORMAT, domain::mode, RESULT_SUCCESS, and S_OR.
10356 { 10357 struct domain *d; 10358 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10359 10360 if (AST_LIST_EMPTY(&domain_list)) { 10361 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10362 return RESULT_SUCCESS; 10363 } else { 10364 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10365 AST_LIST_LOCK(&domain_list); 10366 AST_LIST_TRAVERSE(&domain_list, d, list) 10367 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10368 domain_mode_to_text(d->mode)); 10369 AST_LIST_UNLOCK(&domain_list); 10370 ast_cli(fd, "\n"); 10371 return RESULT_SUCCESS; 10372 } 10373 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11118 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.
11119 { 11120 struct sip_pvt *cur; 11121 size_t len; 11122 int found = 0; 11123 11124 if (argc != 4) 11125 return RESULT_SHOWUSAGE; 11126 if (!recordhistory) 11127 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11128 len = strlen(argv[3]); 11129 ast_mutex_lock(&iflock); 11130 for (cur = iflist; cur; cur = cur->next) { 11131 if (!strncasecmp(cur->callid, argv[3], len)) { 11132 struct sip_history *hist; 11133 int x = 0; 11134 11135 ast_cli(fd,"\n"); 11136 if (cur->subscribed != NONE) 11137 ast_cli(fd, " * Subscription\n"); 11138 else 11139 ast_cli(fd, " * SIP Call\n"); 11140 if (cur->history) 11141 AST_LIST_TRAVERSE(cur->history, hist, list) 11142 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11143 if (x == 0) 11144 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11145 found++; 11146 } 11147 } 11148 ast_mutex_unlock(&iflock); 11149 if (!found) 11150 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11151 return RESULT_SUCCESS; 11152 }
static int sip_show_inuse | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command to show calls within limits set by call_limit.
Definition at line 9780 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
09781 { 09782 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09783 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09784 char ilimits[40]; 09785 char iused[40]; 09786 int showall = FALSE; 09787 09788 if (argc < 3) 09789 return RESULT_SHOWUSAGE; 09790 09791 if (argc == 4 && !strcmp(argv[3],"all")) 09792 showall = TRUE; 09793 09794 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09795 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09796 ASTOBJ_RDLOCK(iterator); 09797 if (iterator->call_limit) 09798 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09799 else 09800 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09801 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09802 if (showall || iterator->call_limit) 09803 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09804 ASTOBJ_UNLOCK(iterator); 09805 } while (0) ); 09806 09807 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09808 09809 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09810 ASTOBJ_RDLOCK(iterator); 09811 if (iterator->call_limit) 09812 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09813 else 09814 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09815 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09816 if (showall || iterator->call_limit) 09817 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09818 ASTOBJ_UNLOCK(iterator); 09819 } while (0) ); 09820 09821 return RESULT_SUCCESS; 09822 #undef FORMAT 09823 #undef FORMAT2 09824 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10101 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10102 { 10103 char tmp[256]; 10104 if (argc != 3) 10105 return RESULT_SHOWUSAGE; 10106 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10107 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10108 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10109 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10110 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10111 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10112 return RESULT_SUCCESS; 10113 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10407 of file chan_sip.c.
References _sip_show_peer().
10408 { 10409 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10410 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9957 of file chan_sip.c.
References _sip_show_peers().
09958 { 09959 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09960 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10680 of file chan_sip.c.
References ast_cli(), ast_localtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FORMAT, FORMAT2, regl, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and STANDARD_SIP_PORT.
10681 { 10682 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10683 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10684 char host[80]; 10685 char tmpdat[256]; 10686 struct tm tm; 10687 10688 10689 if (argc != 3) 10690 return RESULT_SHOWUSAGE; 10691 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10692 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10693 ASTOBJ_RDLOCK(iterator); 10694 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10695 if (iterator->regtime) { 10696 ast_localtime(&iterator->regtime, &tm, NULL); 10697 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10698 } else { 10699 tmpdat[0] = 0; 10700 } 10701 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10702 ASTOBJ_UNLOCK(iterator); 10703 } while(0)); 10704 return RESULT_SUCCESS; 10705 #undef FORMAT 10706 #undef FORMAT2 10707 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10710 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().
10711 { 10712 int realtimepeers; 10713 int realtimeusers; 10714 char codec_buf[SIPBUFSIZE]; 10715 10716 realtimepeers = ast_check_realtime("sippeers"); 10717 realtimeusers = ast_check_realtime("sipusers"); 10718 10719 if (argc != 3) 10720 return RESULT_SHOWUSAGE; 10721 ast_cli(fd, "\n\nGlobal Settings:\n"); 10722 ast_cli(fd, "----------------\n"); 10723 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10724 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10725 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10726 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10727 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10728 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10729 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10730 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10731 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10732 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10733 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10734 ast_cli(fd, " Our auth realm %s\n", global_realm); 10735 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10736 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10737 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10738 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10739 ast_cli(fd, " User Agent: %s\n", global_useragent); 10740 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10741 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10742 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10743 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10744 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10745 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10746 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10747 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10748 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10749 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10750 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10751 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10752 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10753 #endif 10754 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10755 if (!realtimepeers && !realtimeusers) 10756 ast_cli(fd, " SIP realtime: Disabled\n" ); 10757 else 10758 ast_cli(fd, " SIP realtime: Enabled\n" ); 10759 10760 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10761 ast_cli(fd, "---------------------------\n"); 10762 ast_cli(fd, " Codecs: "); 10763 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10764 ast_cli(fd, "%s\n", codec_buf); 10765 ast_cli(fd, " Codec Order: "); 10766 print_codec_to_cli(fd, &default_prefs); 10767 ast_cli(fd, "\n"); 10768 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10769 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10770 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10771 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10772 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10773 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10774 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10775 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10776 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10777 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10778 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10779 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10780 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10781 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10782 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10783 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10784 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10785 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10786 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10787 ast_cli(fd, "\nDefault Settings:\n"); 10788 ast_cli(fd, "-----------------\n"); 10789 ast_cli(fd, " Context: %s\n", default_context); 10790 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10791 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10792 ast_cli(fd, " Qualify: %d\n", default_qualify); 10793 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10794 ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); 10795 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10796 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10797 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10798 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10799 10800 10801 if (realtimepeers || realtimeusers) { 10802 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10803 ast_cli(fd, "----------------------\n"); 10804 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10805 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10806 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10807 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10808 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10809 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10810 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10811 } 10812 ast_cli(fd, "\n----\n"); 10813 return RESULT_SUCCESS; 10814 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10849 of file chan_sip.c.
References __sip_show_channels().
10850 { 10851 return __sip_show_channels(fd, argc, argv, 1); 10852 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10625 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.
10626 { 10627 char cbuf[256]; 10628 struct sip_user *user; 10629 struct ast_variable *v; 10630 int load_realtime; 10631 10632 if (argc < 4) 10633 return RESULT_SHOWUSAGE; 10634 10635 /* Load from realtime storage? */ 10636 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10637 10638 user = find_user(argv[3], load_realtime); 10639 if (user) { 10640 ast_cli(fd,"\n\n"); 10641 ast_cli(fd, " * Name : %s\n", user->name); 10642 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10643 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10644 ast_cli(fd, " Context : %s\n", user->context); 10645 ast_cli(fd, " Language : %s\n", user->language); 10646 if (!ast_strlen_zero(user->accountcode)) 10647 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10648 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10649 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10650 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10651 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10652 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10653 ast_cli(fd, " Callgroup : "); 10654 print_group(fd, user->callgroup, 0); 10655 ast_cli(fd, " Pickupgroup : "); 10656 print_group(fd, user->pickupgroup, 0); 10657 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10658 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10659 ast_cli(fd, " Codec Order : ("); 10660 print_codec_to_cli(fd, &user->prefs); 10661 ast_cli(fd, ")\n"); 10662 10663 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10664 if (user->chanvars) { 10665 ast_cli(fd, " Variables :\n"); 10666 for (v = user->chanvars ; v ; v = v->next) 10667 ast_cli(fd, " %s = %s\n", v->name, v->value); 10668 } 10669 ast_cli(fd,"\n"); 10670 ASTOBJ_UNREF(user,sip_destroy_user); 10671 } else { 10672 ast_cli(fd,"User %s not found.\n", argv[3]); 10673 ast_cli(fd,"\n"); 10674 } 10675 10676 return RESULT_SUCCESS; 10677 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9880 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, TRUE, and userl.
09881 { 09882 regex_t regexbuf; 09883 int havepattern = FALSE; 09884 09885 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09886 09887 switch (argc) { 09888 case 5: 09889 if (!strcasecmp(argv[3], "like")) { 09890 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09891 return RESULT_SHOWUSAGE; 09892 havepattern = TRUE; 09893 } else 09894 return RESULT_SHOWUSAGE; 09895 case 3: 09896 break; 09897 default: 09898 return RESULT_SHOWUSAGE; 09899 } 09900 09901 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09902 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09903 ASTOBJ_RDLOCK(iterator); 09904 09905 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09906 ASTOBJ_UNLOCK(iterator); 09907 continue; 09908 } 09909 09910 ast_cli(fd, FORMAT, iterator->name, 09911 iterator->secret, 09912 iterator->accountcode, 09913 iterator->context, 09914 iterator->ha ? "Yes" : "No", 09915 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09916 ASTOBJ_UNLOCK(iterator); 09917 } while (0) 09918 ); 09919 09920 if (havepattern) 09921 regfree(®exbuf); 09922 09923 return RESULT_SUCCESS; 09924 #undef FORMAT 09925 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17877 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
17878 { 17879 char *cdest; 17880 char *extension, *host, *port; 17881 char tmp[80]; 17882 17883 cdest = ast_strdupa(dest); 17884 17885 extension = strsep(&cdest, "@"); 17886 host = strsep(&cdest, ":"); 17887 port = strsep(&cdest, ":"); 17888 if (ast_strlen_zero(extension)) { 17889 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17890 return 0; 17891 } 17892 17893 /* we'll issue the redirect message here */ 17894 if (!host) { 17895 char *localtmp; 17896 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17897 if (ast_strlen_zero(tmp)) { 17898 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17899 return 0; 17900 } 17901 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17902 char lhost[80], lport[80]; 17903 memset(lhost, 0, sizeof(lhost)); 17904 memset(lport, 0, sizeof(lport)); 17905 localtmp++; 17906 /* This is okey because lhost and lport are as big as tmp */ 17907 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17908 if (ast_strlen_zero(lhost)) { 17909 ast_log(LOG_ERROR, "Can't find the host address\n"); 17910 return 0; 17911 } 17912 host = ast_strdupa(lhost); 17913 if (!ast_strlen_zero(lport)) { 17914 port = ast_strdupa(lport); 17915 } 17916 } 17917 } 17918 17919 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17920 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17921 17922 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17923 sip_alreadygone(p); 17924 return 0; 17925 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3871 of file chan_sip.c.
References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RING, sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
03872 { 03873 struct sip_pvt *p = ast->tech_pvt; 03874 int res; 03875 03876 if (dest == NULL) /* functions below do not take a NULL */ 03877 dest = ""; 03878 ast_mutex_lock(&p->lock); 03879 if (ast->_state == AST_STATE_RING) 03880 res = sip_sipredirect(p, dest); 03881 else 03882 res = transmit_refer(p, dest); 03883 ast_mutex_unlock(&p->lock); 03884 return res; 03885 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3698 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_update_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03699 { 03700 struct sip_pvt *p = ast->tech_pvt; 03701 int res = 0; 03702 03703 switch (frame->frametype) { 03704 case AST_FRAME_VOICE: 03705 if (!(frame->subclass & ast->nativeformats)) { 03706 char s1[512], s2[512], s3[512]; 03707 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03708 frame->subclass, 03709 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03710 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03711 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03712 ast->readformat, 03713 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03714 ast->writeformat); 03715 return 0; 03716 } 03717 if (p) { 03718 ast_mutex_lock(&p->lock); 03719 if (p->rtp) { 03720 /* If channel is not up, activate early media session */ 03721 if ((ast->_state != AST_STATE_UP) && 03722 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03723 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03724 ast_rtp_update_source(p->rtp); 03725 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03726 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03727 } 03728 p->lastrtptx = time(NULL); 03729 res = ast_rtp_write(p->rtp, frame); 03730 } 03731 ast_mutex_unlock(&p->lock); 03732 } 03733 break; 03734 case AST_FRAME_VIDEO: 03735 if (p) { 03736 ast_mutex_lock(&p->lock); 03737 if (p->vrtp) { 03738 /* Activate video early media */ 03739 if ((ast->_state != AST_STATE_UP) && 03740 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03741 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03742 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03743 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03744 } 03745 p->lastrtptx = time(NULL); 03746 res = ast_rtp_write(p->vrtp, frame); 03747 } 03748 ast_mutex_unlock(&p->lock); 03749 } 03750 break; 03751 case AST_FRAME_IMAGE: 03752 return 0; 03753 break; 03754 case AST_FRAME_MODEM: 03755 if (p) { 03756 ast_mutex_lock(&p->lock); 03757 /* UDPTL requires two-way communication, so early media is not needed here. 03758 we simply forget the frames if we get modem frames before the bridge is up. 03759 Fax will re-transmit. 03760 */ 03761 if (p->udptl && ast->_state == AST_STATE_UP) 03762 res = ast_udptl_write(p->udptl, frame); 03763 ast_mutex_unlock(&p->lock); 03764 } 03765 break; 03766 default: 03767 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03768 return 0; 03769 } 03770 03771 return res; 03772 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15481 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_request::data, errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_request::rlPart1, sip_request::rlPart2, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15482 { 15483 struct sip_request req; 15484 struct sockaddr_in sin = { 0, }; 15485 struct sip_pvt *p; 15486 int res; 15487 socklen_t len = sizeof(sin); 15488 int nounlock; 15489 int recount = 0; 15490 int lockretry; 15491 15492 memset(&req, 0, sizeof(req)); 15493 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15494 if (res < 0) { 15495 #if !defined(__FreeBSD__) 15496 if (errno == EAGAIN) 15497 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15498 else 15499 #endif 15500 if (errno != ECONNREFUSED) 15501 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15502 return 1; 15503 } 15504 if (option_debug && res == sizeof(req.data) - 1) 15505 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15506 15507 req.data[res] = '\0'; 15508 req.len = res; 15509 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15510 ast_set_flag(&req, SIP_PKT_DEBUG); 15511 if (pedanticsipchecking) 15512 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15513 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15514 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15515 15516 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 15517 return 1; 15518 15519 req.method = find_sip_method(req.rlPart1); 15520 15521 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15522 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15523 15524 if (req.headers < 2) /* Must have at least two headers */ 15525 return 1; 15526 15527 /* Process request, with netlock held, and with usual deadlock avoidance */ 15528 for (lockretry = 100; lockretry > 0; lockretry--) { 15529 ast_mutex_lock(&netlock); 15530 15531 /* Find the active SIP dialog or create a new one */ 15532 p = find_call(&req, &sin, req.method); /* returns p locked */ 15533 if (p == NULL) { 15534 if (option_debug) 15535 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15536 ast_mutex_unlock(&netlock); 15537 return 1; 15538 } 15539 /* Go ahead and lock the owner if it has one -- we may need it */ 15540 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15541 if (!p->owner || !ast_channel_trylock(p->owner)) 15542 break; /* locking succeeded */ 15543 if (option_debug) 15544 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15545 ast_mutex_unlock(&p->lock); 15546 ast_mutex_unlock(&netlock); 15547 /* Sleep for a very short amount of time */ 15548 usleep(1); 15549 } 15550 p->recv = sin; 15551 15552 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15553 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15554 15555 if (!lockretry) { 15556 if (p->owner) 15557 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15558 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15559 if (req.method != SIP_ACK) 15560 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15561 /* XXX We could add retry-after to make sure they come back */ 15562 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15563 return 1; 15564 } 15565 nounlock = 0; 15566 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15567 /* Request failed */ 15568 if (option_debug) 15569 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15570 } 15571 15572 if (p->owner && !nounlock) 15573 ast_channel_unlock(p->owner); 15574 ast_mutex_unlock(&p->lock); 15575 ast_mutex_unlock(&netlock); 15576 if (recount) 15577 ast_update_use_count(); 15578 15579 return 1; 15580 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12698 of file chan_sip.c.
References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
12699 { 12700 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12701 if (p->rtp) 12702 ast_rtp_stop(p->rtp); 12703 if (p->vrtp) 12704 ast_rtp_stop(p->vrtp); 12705 if (p->udptl) 12706 ast_udptl_stop(p->udptl); 12707 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10817 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
10818 { 10819 int i; 10820 10821 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10822 if (subscription_types[i].type == subtype) { 10823 return subscription_types[i].text; 10824 } 10825 } 10826 return subscription_types[0].text; 10827 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6286 of file chan_sip.c.
References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.
Referenced by add_t38_sdp().
06287 { 06288 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06289 06290 if (maxrate & T38FAX_RATE_14400) { 06291 if (option_debug > 1) 06292 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06293 return 14400; 06294 } else if (maxrate & T38FAX_RATE_12000) { 06295 if (option_debug > 1) 06296 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06297 return 12000; 06298 } else if (maxrate & T38FAX_RATE_9600) { 06299 if (option_debug > 1) 06300 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06301 return 9600; 06302 } else if (maxrate & T38FAX_RATE_7200) { 06303 if (option_debug > 1) 06304 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06305 return 7200; 06306 } else if (maxrate & T38FAX_RATE_4800) { 06307 if (option_debug > 1) 06308 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06309 return 4800; 06310 } else if (maxrate & T38FAX_RATE_2400) { 06311 if (option_debug > 1) 06312 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06313 return 2400; 06314 } else { 06315 if (option_debug > 1) 06316 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06317 return 0; 06318 } 06319 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16622 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
16623 { 16624 struct sip_peer *peer; 16625 16626 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16627 return NULL; 16628 16629 apeerobjs++; 16630 ASTOBJ_INIT(peer); 16631 set_peer_defaults(peer); 16632 16633 ast_copy_string(peer->name, name, sizeof(peer->name)); 16634 16635 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16636 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16637 peer->prefs = default_prefs; 16638 reg_source_db(peer); 16639 16640 return peer; 16641 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 6061 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06062 { 06063 struct sip_pvt *p = data; 06064 06065 ast_string_field_free_memory(p); 06066 06067 free(data); 06068 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 9827 of file chan_sip.c.
References TRANSFER_CLOSED, and TRANSFER_OPENFORALL.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().
09828 { 09829 if (mode == TRANSFER_OPENFORALL) 09830 return "open"; 09831 else if (mode == TRANSFER_CLOSED) 09832 return "closed"; 09833 return "strict"; 09834 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8648 of file chan_sip.c.
References ast_random(), ast_string_field_build, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08649 { 08650 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08651 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08652 }
static int transmit_info_with_digit | ( | struct sip_pvt * | p, | |
const char | digit, | |||
unsigned int | duration | |||
) | [static] |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
Definition at line 7834 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07835 { 07836 struct sip_request req; 07837 07838 reqprep(&req, p, SIP_INFO, 0, 1); 07839 add_digit(&req, digit, duration); 07840 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07841 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7844 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07845 { 07846 struct sip_request req; 07847 07848 reqprep(&req, p, SIP_INFO, 0, 1); 07849 add_vidupdate(&req); 07850 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07851 }
static int transmit_invite | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | sdp, | |||
int | init | |||
) | [static] |
Build REFER/INVITE/OPTIONS message and transmit it.
Definition at line 7093 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07094 { 07095 struct sip_request req; 07096 07097 req.method = sipmethod; 07098 if (init) { /* Seems like init always is 2 */ 07099 /* Bump branch even on initial requests */ 07100 p->branch ^= ast_random(); 07101 build_via(p); 07102 if (init > 1) 07103 initreqprep(&req, p, sipmethod); 07104 else 07105 reqprep(&req, p, sipmethod, 0, 1); 07106 } else 07107 reqprep(&req, p, sipmethod, 0, 1); 07108 07109 if (p->options && p->options->auth) 07110 add_header(&req, p->options->authheader, p->options->auth); 07111 append_date(&req); 07112 if (sipmethod == SIP_REFER) { /* Call transfer */ 07113 if (p->refer) { 07114 char buf[SIPBUFSIZE]; 07115 if (!ast_strlen_zero(p->refer->refer_to)) 07116 add_header(&req, "Refer-To", p->refer->refer_to); 07117 if (!ast_strlen_zero(p->refer->referred_by)) { 07118 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07119 add_header(&req, "Referred-By", buf); 07120 } 07121 } 07122 } 07123 /* This new INVITE is part of an attended transfer. Make sure that the 07124 other end knows and replace the current call with this new call */ 07125 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07126 add_header(&req, "Replaces", p->options->replaces); 07127 add_header(&req, "Require", "replaces"); 07128 } 07129 07130 add_header(&req, "Allow", ALLOWED_METHODS); 07131 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07132 if (p->options && p->options->addsipheaders && p->owner) { 07133 struct ast_channel *chan = p->owner; /* The owner channel */ 07134 struct varshead *headp; 07135 07136 ast_channel_lock(chan); 07137 07138 headp = &chan->varshead; 07139 07140 if (!headp) 07141 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07142 else { 07143 const struct ast_var_t *current; 07144 AST_LIST_TRAVERSE(headp, current, entries) { 07145 /* SIPADDHEADER: Add SIP header to outgoing call */ 07146 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07147 char *content, *end; 07148 const char *header = ast_var_value(current); 07149 char *headdup = ast_strdupa(header); 07150 07151 /* Strip of the starting " (if it's there) */ 07152 if (*headdup == '"') 07153 headdup++; 07154 if ((content = strchr(headdup, ':'))) { 07155 *content++ = '\0'; 07156 content = ast_skip_blanks(content); /* Skip white space */ 07157 /* Strip the ending " (if it's there) */ 07158 end = content + strlen(content) -1; 07159 if (*end == '"') 07160 *end = '\0'; 07161 07162 add_header(&req, headdup, content); 07163 if (sipdebug) 07164 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07165 } 07166 } 07167 } 07168 } 07169 07170 ast_channel_unlock(chan); 07171 } 07172 if (sdp) { 07173 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07174 ast_udptl_offered_from_local(p->udptl, 1); 07175 if (option_debug) 07176 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07177 add_t38_sdp(&req, p); 07178 } else if (p->rtp) 07179 add_sdp(&req, p); 07180 } else { 07181 add_header_contentLength(&req, 0); 07182 } 07183 07184 if (!p->initreq.headers) 07185 initialize_initreq(p, &req); 07186 p->lastinvite = p->ocseq; 07187 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07188 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7743 of file chan_sip.c.
References add_text(), sip_pvt::ocseq, reqprep(), send_request(), SIP_MESSAGE, and XMIT_RELIABLE.
Referenced by sip_park_thread(), and sip_sendtext().
07744 { 07745 struct sip_request req; 07746 07747 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07748 add_text(&req, text); 07749 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07750 }
static int transmit_notify_with_mwi | ( | struct sip_pvt * | p, | |
int | newmsgs, | |||
int | oldmsgs, | |||
char * | vmexten | |||
) | [static] |
Notify user of messages waiting in voicemail.
Definition at line 7379 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07380 { 07381 struct sip_request req; 07382 char tmp[500]; 07383 char *t = tmp; 07384 size_t maxbytes = sizeof(tmp); 07385 07386 initreqprep(&req, p, SIP_NOTIFY); 07387 add_header(&req, "Event", "message-summary"); 07388 add_header(&req, "Content-Type", default_notifymime); 07389 07390 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07391 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07392 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07393 /* Cisco has a bug in the SIP stack where it can't accept the 07394 (0/0) notification. This can temporarily be disabled in 07395 sip.conf with the "buggymwi" option */ 07396 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d%s\r\n", newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); 07397 07398 if (p->subscribed) { 07399 if (p->expiry) 07400 add_header(&req, "Subscription-State", "active"); 07401 else /* Expired */ 07402 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07403 } 07404 07405 if (t > tmp + sizeof(tmp)) 07406 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07407 07408 add_header_contentLength(&req, strlen(tmp)); 07409 add_line(&req, tmp); 07410 07411 if (!p->initreq.headers) 07412 initialize_initreq(p, &req); 07413 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07414 }
static int transmit_notify_with_sipfrag | ( | struct sip_pvt * | p, | |
int | cseq, | |||
char * | message, | |||
int | terminate | |||
) | [static] |
Notify a transferring party of the status of transfer.
Definition at line 7425 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07426 { 07427 struct sip_request req; 07428 char tmp[SIPBUFSIZE/2]; 07429 07430 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07431 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07432 add_header(&req, "Event", tmp); 07433 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07434 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07435 add_header(&req, "Allow", ALLOWED_METHODS); 07436 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07437 07438 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07439 add_header_contentLength(&req, strlen(tmp)); 07440 add_line(&req, tmp); 07441 07442 if (!p->initreq.headers) 07443 initialize_initreq(p, &req); 07444 07445 p->lastnoninvite = p->ocseq; 07446 07447 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07448 }
static int transmit_refer | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 7764 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.
Referenced by sip_transfer().
07765 { 07766 struct sip_request req = { 07767 .headers = 0, 07768 }; 07769 char from[256]; 07770 const char *of; 07771 char *c; 07772 char referto[256]; 07773 char *ttag, *ftag; 07774 char *theirtag = ast_strdupa(p->theirtag); 07775 07776 if (option_debug || sipdebug) 07777 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07778 07779 /* Are we transfering an inbound or outbound call ? */ 07780 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07781 of = get_header(&p->initreq, "To"); 07782 ttag = theirtag; 07783 ftag = p->tag; 07784 } else { 07785 of = get_header(&p->initreq, "From"); 07786 ftag = theirtag; 07787 ttag = p->tag; 07788 } 07789 07790 ast_copy_string(from, of, sizeof(from)); 07791 of = get_in_brackets(from); 07792 ast_string_field_set(p, from, of); 07793 if (strncasecmp(of, "sip:", 4)) 07794 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07795 else 07796 of += 4; 07797 /* Get just the username part */ 07798 if ((c = strchr(dest, '@'))) 07799 c = NULL; 07800 else if ((c = strchr(of, '@'))) 07801 *c++ = '\0'; 07802 if (c) 07803 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07804 else 07805 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07806 07807 /* save in case we get 407 challenge */ 07808 sip_refer_allocate(p); 07809 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07810 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07811 p->refer->status = REFER_SENT; /* Set refer status */ 07812 07813 reqprep(&req, p, SIP_REFER, 0, 1); 07814 07815 add_header(&req, "Refer-To", referto); 07816 add_header(&req, "Allow", ALLOWED_METHODS); 07817 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07818 if (!ast_strlen_zero(p->our_contact)) 07819 add_header(&req, "Referred-By", p->our_contact); 07820 07821 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07822 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07823 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07824 07825 /*! \todo In theory, we should hang around and wait for a reply, before 07826 returning to the dial plan here. Don't know really how that would 07827 affect the transfer() app or the pbx, but, well, to make this 07828 useful we should have a STATUS code on transfer(). 07829 */ 07830 }
static int transmit_register | ( | struct sip_registry * | r, | |
int | sipmethod, | |||
const char * | auth, | |||
const char * | authheader | |||
) | [static] |
Transmit register to SIP proxy or UA.
Definition at line 7552 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_pvt::ourip, sip_registry::portno, sip_pvt::recv, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07553 { 07554 struct sip_request req; 07555 char from[256]; 07556 char to[256]; 07557 char tmp[80]; 07558 char addr[80]; 07559 struct sip_pvt *p; 07560 07561 /* exit if we are already in process with this registrar ?*/ 07562 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07563 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07564 return 0; 07565 } 07566 07567 if (r->call) { /* We have a registration */ 07568 if (!auth) { 07569 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07570 return 0; 07571 } else { 07572 p = r->call; 07573 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07574 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07575 } 07576 } else { 07577 /* Build callid for registration if we haven't registered before */ 07578 if (!r->callid_valid) { 07579 build_callid_registry(r, __ourip, default_fromdomain); 07580 r->callid_valid = TRUE; 07581 } 07582 /* Allocate SIP packet for registration */ 07583 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07584 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07585 return 0; 07586 } 07587 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07588 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07589 /* Find address to hostname */ 07590 if (create_addr(p, r->hostname)) { 07591 /* we have what we hope is a temporary network error, 07592 * probably DNS. We need to reschedule a registration try */ 07593 sip_destroy(p); 07594 07595 if (r->timeout > -1) 07596 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07597 else 07598 ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); 07599 07600 AST_SCHED_DEL(sched, r->timeout); 07601 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07602 r->regattempts++; 07603 return 0; 07604 } 07605 /* Copy back Call-ID in case create_addr changed it */ 07606 ast_string_field_set(r, callid, p->callid); 07607 if (r->portno) { 07608 p->sa.sin_port = htons(r->portno); 07609 p->recv.sin_port = htons(r->portno); 07610 } else /* Set registry port to the port set from the peer definition/srv or default */ 07611 r->portno = ntohs(p->sa.sin_port); 07612 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07613 r->call=p; /* Save pointer to SIP packet */ 07614 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07615 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07616 ast_string_field_set(p, peersecret, r->secret); 07617 if (!ast_strlen_zero(r->md5secret)) 07618 ast_string_field_set(p, peermd5secret, r->md5secret); 07619 /* User name in this realm 07620 - if authuser is set, use that, otherwise use username */ 07621 if (!ast_strlen_zero(r->authuser)) { 07622 ast_string_field_set(p, peername, r->authuser); 07623 ast_string_field_set(p, authname, r->authuser); 07624 } else if (!ast_strlen_zero(r->username)) { 07625 ast_string_field_set(p, peername, r->username); 07626 ast_string_field_set(p, authname, r->username); 07627 ast_string_field_set(p, fromuser, r->username); 07628 } 07629 if (!ast_strlen_zero(r->username)) 07630 ast_string_field_set(p, username, r->username); 07631 /* Save extension in packet */ 07632 ast_string_field_set(p, exten, r->contact); 07633 07634 /* 07635 check which address we should use in our contact header 07636 based on whether the remote host is on the external or 07637 internal network so we can register through nat 07638 */ 07639 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07640 p->ourip = bindaddr.sin_addr; 07641 build_contact(p); 07642 } 07643 07644 /* set up a timeout */ 07645 if (auth == NULL) { 07646 if (r->timeout > -1) 07647 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07648 AST_SCHED_DEL(sched, r->timeout); 07649 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07650 if (option_debug) 07651 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07652 } 07653 07654 if (strchr(r->username, '@')) { 07655 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07656 if (!ast_strlen_zero(p->theirtag)) 07657 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07658 else 07659 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07660 } else { 07661 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07662 if (!ast_strlen_zero(p->theirtag)) 07663 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07664 else 07665 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07666 } 07667 07668 /* Fromdomain is what we are registering to, regardless of actual 07669 host name from SRV */ 07670 if (!ast_strlen_zero(p->fromdomain)) { 07671 if (r->portno && r->portno != STANDARD_SIP_PORT) 07672 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07673 else 07674 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07675 } else { 07676 if (r->portno && r->portno != STANDARD_SIP_PORT) 07677 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07678 else 07679 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07680 } 07681 ast_string_field_set(p, uri, addr); 07682 07683 p->branch ^= ast_random(); 07684 07685 init_req(&req, sipmethod, addr); 07686 07687 /* Add to CSEQ */ 07688 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07689 p->ocseq = r->ocseq; 07690 07691 build_via(p); 07692 add_header(&req, "Via", p->via); 07693 add_header(&req, "From", from); 07694 add_header(&req, "To", to); 07695 add_header(&req, "Call-ID", p->callid); 07696 add_header(&req, "CSeq", tmp); 07697 if (!ast_strlen_zero(global_useragent)) 07698 add_header(&req, "User-Agent", global_useragent); 07699 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07700 07701 07702 if (auth) /* Add auth header */ 07703 add_header(&req, authheader, auth); 07704 else if (!ast_strlen_zero(r->nonce)) { 07705 char digest[1024]; 07706 07707 /* We have auth data to reuse, build a digest header! */ 07708 if (sipdebug) 07709 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07710 ast_string_field_set(p, realm, r->realm); 07711 ast_string_field_set(p, nonce, r->nonce); 07712 ast_string_field_set(p, domain, r->domain); 07713 ast_string_field_set(p, opaque, r->opaque); 07714 ast_string_field_set(p, qop, r->qop); 07715 r->noncecount++; 07716 p->noncecount = r->noncecount; 07717 07718 memset(digest,0,sizeof(digest)); 07719 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07720 add_header(&req, "Authorization", digest); 07721 else 07722 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07723 07724 } 07725 07726 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07727 add_header(&req, "Expires", tmp); 07728 add_header(&req, "Contact", p->our_contact); 07729 add_header(&req, "Event", "registration"); 07730 add_header_contentLength(&req, 0); 07731 07732 initialize_initreq(p, &req); 07733 if (sip_debug_test_pvt(p)) 07734 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07735 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07736 r->regattempts++; /* Another attempt */ 07737 if (option_debug > 3) 07738 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07739 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07740 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6813 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
06814 { 06815 struct sip_request req; 06816 06817 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06818 06819 add_header(&req, "Allow", ALLOWED_METHODS); 06820 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06821 if (sipdebug) 06822 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06823 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06824 append_history(p, "ReInv", "Re-invite sent"); 06825 add_sdp(&req, p); 06826 /* Use this as the basis */ 06827 initialize_initreq(p, &req); 06828 p->lastinvite = p->ocseq; 06829 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06830 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06831 }
static int transmit_reinvite_with_t38_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path.
Definition at line 6837 of file chan_sip.c.
References add_header(), add_t38_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, ast_udptl_offered_from_local(), sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, sip_pvt::udptl, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), and sip_set_udptl_peer().
06838 { 06839 struct sip_request req; 06840 06841 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06842 06843 add_header(&req, "Allow", ALLOWED_METHODS); 06844 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06845 if (sipdebug) 06846 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06847 ast_udptl_offered_from_local(p->udptl, 1); 06848 add_t38_sdp(&req, p); 06849 /* Use this as the basis */ 06850 initialize_initreq(p, &req); 06851 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06852 p->lastinvite = p->ocseq; 06853 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06854 }
static int transmit_request | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | inc, | |||
enum xmittype | reliable, | |||
int | newbranch | |||
) | [static] |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
Definition at line 7856 of file chan_sip.c.
References add_header_contentLength(), INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), and SIP_ACK.
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
07857 { 07858 struct sip_request resp; 07859 07860 if (sipmethod == SIP_ACK) 07861 p->invitestate = INV_CONFIRMED; 07862 07863 reqprep(&resp, p, sipmethod, seqno, newbranch); 07864 add_header_contentLength(&resp, 0); 07865 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07866 }
static int transmit_request_with_auth | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | seqno, | |||
enum xmittype | reliable, | |||
int | newbranch | |||
) | [static] |
Transmit SIP request, auth added.
Definition at line 7869 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
07870 { 07871 struct sip_request resp; 07872 07873 reqprep(&resp, p, sipmethod, seqno, newbranch); 07874 if (!ast_strlen_zero(p->realm)) { 07875 char digest[1024]; 07876 07877 memset(digest, 0, sizeof(digest)); 07878 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07879 if (p->options && p->options->auth_type == PROXY_AUTH) 07880 add_header(&resp, "Proxy-Authorization", digest); 07881 else if (p->options && p->options->auth_type == WWW_AUTH) 07882 add_header(&resp, "Authorization", digest); 07883 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07884 add_header(&resp, "Proxy-Authorization", digest); 07885 } else 07886 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07887 } 07888 /* If we are hanging up and know a cause for that, send it in clear text to make 07889 debugging easier. */ 07890 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07891 char buf[10]; 07892 07893 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07894 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07895 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07896 } 07897 07898 add_header_contentLength(&resp, 0); 07899 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07900 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6122 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06123 { 06124 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06125 }
static int transmit_response_reliable | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
Definition at line 6141 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect().
06142 { 06143 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06144 }
static int transmit_response_using_temp | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method, | |||
const struct sip_request * | req, | |||
const char * | msg | |||
) | [static] |
Transmit response, no retransmits, using a temporary pvt structure.
Definition at line 6071 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, sip_pvt::branch, build_via(), check_via(), do_setnat(), sip_pvt::flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, and XMIT_UNRELIABLE.
Referenced by find_call().
06072 { 06073 struct sip_pvt *p = NULL; 06074 06075 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06076 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06077 return -1; 06078 } 06079 06080 /* if the structure was just allocated, initialize it */ 06081 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06082 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06083 if (ast_string_field_init(p, 512)) 06084 return -1; 06085 } 06086 06087 /* Initialize the bare minimum */ 06088 p->method = intended_method; 06089 06090 if (sin) { 06091 p->sa = *sin; 06092 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06093 p->ourip = __ourip; 06094 } else 06095 p->ourip = __ourip; 06096 06097 p->branch = ast_random(); 06098 make_our_tag(p->tag, sizeof(p->tag)); 06099 p->ocseq = INITIAL_CSEQ; 06100 06101 if (useglobal_nat && sin) { 06102 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06103 p->recv = *sin; 06104 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06105 } 06106 check_via(p, req); 06107 06108 ast_string_field_set(p, fromdomain, default_fromdomain); 06109 build_via(p); 06110 ast_string_field_set(p, callid, callid); 06111 06112 /* Use this temporary pvt structure to send the message */ 06113 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06114 06115 /* Free the string fields, but not the pool space */ 06116 ast_string_field_reset_all(p); 06117 06118 return 0; 06119 }
static int transmit_response_with_allow | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Append Accept header, content length before transmitting response.
Definition at line 6169 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06170 { 06171 struct sip_request resp; 06172 respprep(&resp, p, msg, req); 06173 add_header(&resp, "Accept", "application/sdp"); 06174 add_header_contentLength(&resp, 0); 06175 return send_response(p, &resp, reliable, 0); 06176 }
static int transmit_response_with_auth | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
const char * | rand, | |||
enum xmittype | reliable, | |||
const char * | header, | |||
int | stale | |||
) | [static] |
Respond with authorization request.
Definition at line 6179 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
06180 { 06181 struct sip_request resp; 06182 char tmp[512]; 06183 int seqno = 0; 06184 06185 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06186 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06187 return -1; 06188 } 06189 /* Stale means that they sent us correct authentication, but 06190 based it on an old challenge (nonce) */ 06191 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06192 respprep(&resp, p, msg, req); 06193 add_header(&resp, header, tmp); 06194 add_header_contentLength(&resp, 0); 06195 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06196 return send_response(p, &resp, reliable, seqno); 06197 }
static int transmit_response_with_date | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Append date and content length before transmitting response.
Definition at line 6159 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06160 { 06161 struct sip_request resp; 06162 respprep(&resp, p, msg, req); 06163 append_date(&resp); 06164 add_header_contentLength(&resp, 0); 06165 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06166 }
static int transmit_response_with_sdp | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Used for 200 OK and 183 early media.
Definition at line 6742 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06743 { 06744 struct sip_request resp; 06745 int seqno; 06746 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06747 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06748 return -1; 06749 } 06750 respprep(&resp, p, msg, req); 06751 if (p->rtp) { 06752 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06753 if (option_debug) 06754 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06755 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06756 } 06757 try_suggested_sip_codec(p); 06758 add_sdp(&resp, p); 06759 } else 06760 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06761 if (reliable && !p->pendinginvite) 06762 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06763 return send_response(p, &resp, reliable, seqno); 06764 }
static int transmit_response_with_t38_sdp | ( | struct sip_pvt * | p, | |
char * | msg, | |||
struct sip_request * | req, | |||
int | retrans | |||
) | [static] |
Used for 200 OK and 183 early media.
Definition at line 6702 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06703 { 06704 struct sip_request resp; 06705 int seqno; 06706 06707 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06708 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06709 return -1; 06710 } 06711 respprep(&resp, p, msg, req); 06712 if (p->udptl) { 06713 ast_udptl_offered_from_local(p->udptl, 0); 06714 add_t38_sdp(&resp, p); 06715 } else 06716 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06717 if (retrans && !p->pendinginvite) 06718 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06719 return send_response(p, &resp, retrans, seqno); 06720 }
static int transmit_response_with_unsupported | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
const char * | unsupported | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6128 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06129 { 06130 struct sip_request resp; 06131 respprep(&resp, p, msg, req); 06132 append_date(&resp); 06133 add_header(&resp, "Unsupported", unsupported); 06134 add_header_contentLength(&resp, 0); 06135 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06136 }
static int transmit_sip_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Transmit SIP request unreliably (only used in sip_notify subsystem).
Definition at line 7417 of file chan_sip.c.
References sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, send_request(), and XMIT_UNRELIABLE.
Referenced by sip_notify().
07418 { 07419 if (!p->initreq.headers) /* Initialize first request before sending */ 07420 initialize_initreq(p, req); 07421 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07422 }
static int transmit_state_notify | ( | struct sip_pvt * | p, | |
int | state, | |||
int | full, | |||
int | timeout | |||
) | [static] |
Used in the SUBSCRIBE notification subsystem.
Definition at line 7191 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
07192 { 07193 char tmp[4000], from[256], to[256]; 07194 char *t = tmp, *c, *mfrom, *mto; 07195 size_t maxbytes = sizeof(tmp); 07196 struct sip_request req; 07197 char hint[AST_MAX_EXTENSION]; 07198 char *statestring = "terminated"; 07199 const struct cfsubscription_types *subscriptiontype; 07200 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07201 char *pidfstate = "--"; 07202 char *pidfnote= "Ready"; 07203 07204 memset(from, 0, sizeof(from)); 07205 memset(to, 0, sizeof(to)); 07206 memset(tmp, 0, sizeof(tmp)); 07207 07208 switch (state) { 07209 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07210 statestring = (global_notifyringing) ? "early" : "confirmed"; 07211 local_state = NOTIFY_INUSE; 07212 pidfstate = "busy"; 07213 pidfnote = "Ringing"; 07214 break; 07215 case AST_EXTENSION_RINGING: 07216 statestring = "early"; 07217 local_state = NOTIFY_INUSE; 07218 pidfstate = "busy"; 07219 pidfnote = "Ringing"; 07220 break; 07221 case AST_EXTENSION_INUSE: 07222 statestring = "confirmed"; 07223 local_state = NOTIFY_INUSE; 07224 pidfstate = "busy"; 07225 pidfnote = "On the phone"; 07226 break; 07227 case AST_EXTENSION_BUSY: 07228 statestring = "confirmed"; 07229 local_state = NOTIFY_CLOSED; 07230 pidfstate = "busy"; 07231 pidfnote = "On the phone"; 07232 break; 07233 case AST_EXTENSION_UNAVAILABLE: 07234 statestring = "terminated"; 07235 local_state = NOTIFY_CLOSED; 07236 pidfstate = "away"; 07237 pidfnote = "Unavailable"; 07238 break; 07239 case AST_EXTENSION_ONHOLD: 07240 statestring = "confirmed"; 07241 local_state = NOTIFY_CLOSED; 07242 pidfstate = "busy"; 07243 pidfnote = "On Hold"; 07244 break; 07245 case AST_EXTENSION_NOT_INUSE: 07246 default: 07247 /* Default setting */ 07248 break; 07249 } 07250 07251 subscriptiontype = find_subscription_type(p->subscribed); 07252 07253 /* Check which device/devices we are watching and if they are registered */ 07254 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07255 char *hint2 = hint, *individual_hint = NULL; 07256 int hint_count = 0, unavailable_count = 0; 07257 07258 while ((individual_hint = strsep(&hint2, "&"))) { 07259 hint_count++; 07260 07261 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07262 unavailable_count++; 07263 } 07264 07265 /* If none of the hinted devices are registered, we will 07266 * override notification and show no availability. 07267 */ 07268 if (hint_count > 0 && hint_count == unavailable_count) { 07269 local_state = NOTIFY_CLOSED; 07270 pidfstate = "away"; 07271 pidfnote = "Not online"; 07272 } 07273 } 07274 07275 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07276 c = get_in_brackets(from); 07277 if (strncasecmp(c, "sip:", 4)) { 07278 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07279 return -1; 07280 } 07281 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07282 07283 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07284 c = get_in_brackets(to); 07285 if (strncasecmp(c, "sip:", 4)) { 07286 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07287 return -1; 07288 } 07289 mto = strsep(&c, ";"); /* trim ; and beyond */ 07290 07291 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07292 07293 07294 add_header(&req, "Event", subscriptiontype->event); 07295 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07296 switch(state) { 07297 case AST_EXTENSION_DEACTIVATED: 07298 if (timeout) 07299 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07300 else { 07301 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07302 add_header(&req, "Retry-After", "60"); 07303 } 07304 break; 07305 case AST_EXTENSION_REMOVED: 07306 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07307 break; 07308 default: 07309 if (p->expiry) 07310 add_header(&req, "Subscription-State", "active"); 07311 else /* Expired */ 07312 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07313 } 07314 switch (p->subscribed) { 07315 case XPIDF_XML: 07316 case CPIM_PIDF_XML: 07317 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07318 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07319 ast_build_string(&t, &maxbytes, "<presence>\n"); 07320 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07321 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07322 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07323 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07324 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07325 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07326 break; 07327 case PIDF_XML: /* Eyebeam supports this format */ 07328 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07329 ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom); 07330 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07331 if (pidfstate[0] != '-') 07332 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07333 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07334 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07335 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07336 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07337 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07338 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07339 else 07340 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07341 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07342 break; 07343 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07344 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07345 ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto); 07346 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07347 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07348 else 07349 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07350 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07351 if (state == AST_EXTENSION_ONHOLD) { 07352 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07353 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07354 "</target>\n</local>\n", mto); 07355 } 07356 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07357 break; 07358 case NONE: 07359 default: 07360 break; 07361 } 07362 07363 if (t > tmp + sizeof(tmp)) 07364 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07365 07366 add_header_contentLength(&req, strlen(tmp)); 07367 add_line(&req, tmp); 07368 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07369 07370 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07371 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3648 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03649 { 03650 int fmt; 03651 const char *codec; 03652 03653 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03654 if (!codec) 03655 return; 03656 03657 fmt = ast_getformatbyname(codec); 03658 if (fmt) { 03659 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03660 if (p->jointcapability & fmt) { 03661 p->jointcapability &= fmt; 03662 p->capability &= fmt; 03663 } else 03664 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03665 } else 03666 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03667 return; 03668 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18204 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, clear_realm_authentication(), clear_sip_domains(), iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipsock, TRUE, and userl.
18205 { 18206 struct sip_pvt *p, *pl; 18207 18208 /* First, take us out of the channel type list */ 18209 ast_channel_unregister(&sip_tech); 18210 18211 /* Unregister dial plan functions */ 18212 ast_custom_function_unregister(&sipchaninfo_function); 18213 ast_custom_function_unregister(&sippeer_function); 18214 ast_custom_function_unregister(&sip_header_function); 18215 ast_custom_function_unregister(&checksipdomain_function); 18216 18217 /* Unregister dial plan applications */ 18218 ast_unregister_application(app_dtmfmode); 18219 ast_unregister_application(app_sipaddheader); 18220 18221 /* Unregister CLI commands */ 18222 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18223 18224 /* Disconnect from the RTP subsystem */ 18225 ast_rtp_proto_unregister(&sip_rtp); 18226 18227 /* Disconnect from UDPTL */ 18228 ast_udptl_proto_unregister(&sip_udptl); 18229 18230 /* Unregister AMI actions */ 18231 ast_manager_unregister("SIPpeers"); 18232 ast_manager_unregister("SIPshowpeer"); 18233 18234 ast_mutex_lock(&iflock); 18235 /* Hangup all interfaces if they have an owner */ 18236 for (p = iflist; p ; p = p->next) { 18237 if (p->owner) 18238 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18239 } 18240 ast_mutex_unlock(&iflock); 18241 18242 ast_mutex_lock(&monlock); 18243 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18244 pthread_cancel(monitor_thread); 18245 pthread_kill(monitor_thread, SIGURG); 18246 pthread_join(monitor_thread, NULL); 18247 } 18248 monitor_thread = AST_PTHREADT_STOP; 18249 ast_mutex_unlock(&monlock); 18250 18251 restartdestroy: 18252 ast_mutex_lock(&iflock); 18253 /* Destroy all the interfaces and free their memory */ 18254 p = iflist; 18255 while (p) { 18256 pl = p; 18257 p = p->next; 18258 if (__sip_destroy(pl, TRUE) < 0) { 18259 /* Something is still bridged, let it react to getting a hangup */ 18260 iflist = p; 18261 ast_mutex_unlock(&iflock); 18262 usleep(1); 18263 goto restartdestroy; 18264 } 18265 } 18266 iflist = NULL; 18267 ast_mutex_unlock(&iflock); 18268 18269 /* Free memory for local network address mask */ 18270 ast_free_ha(localaddr); 18271 18272 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18273 ASTOBJ_CONTAINER_DESTROY(&userl); 18274 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18275 ASTOBJ_CONTAINER_DESTROY(&peerl); 18276 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18277 ASTOBJ_CONTAINER_DESTROY(®l); 18278 18279 clear_realm_authentication(authl); 18280 clear_sip_domains(); 18281 close(sipsock); 18282 sched_context_destroy(sched); 18283 18284 return 0; 18285 }
static int update_call_counter | ( | struct sip_pvt * | fup, | |
int | event | |||
) | [static] |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted.
Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.
Thought: For realtime, we should propably update storage with inuse counter...
Definition at line 3201 of file chan_sip.c.
References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_peer::flags, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03202 { 03203 char name[256]; 03204 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03205 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03206 struct sip_user *u = NULL; 03207 struct sip_peer *p = NULL; 03208 03209 if (option_debug > 2) 03210 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03211 03212 /* Test if we need to check call limits, in order to avoid 03213 realtime lookups if we do not need it */ 03214 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03215 return 0; 03216 03217 ast_copy_string(name, fup->username, sizeof(name)); 03218 03219 /* Check the list of users only for incoming calls */ 03220 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03221 inuse = &u->inUse; 03222 call_limit = &u->call_limit; 03223 inringing = NULL; 03224 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03225 inuse = &p->inUse; 03226 call_limit = &p->call_limit; 03227 inringing = &p->inRinging; 03228 ast_copy_string(name, fup->peername, sizeof(name)); 03229 } 03230 if (!p && !u) { 03231 if (option_debug > 1) 03232 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03233 return 0; 03234 } 03235 03236 switch(event) { 03237 /* incoming and outgoing affects the inUse counter */ 03238 case DEC_CALL_LIMIT: 03239 if ( *inuse > 0 ) { 03240 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03241 (*inuse)--; 03242 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03243 } 03244 } else { 03245 *inuse = 0; 03246 } 03247 if (inringing) { 03248 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03249 if (*inringing > 0) 03250 (*inringing)--; 03251 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03252 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03253 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03254 } 03255 } 03256 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03257 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03258 sip_peer_hold(fup, 0); 03259 } 03260 if (option_debug > 1 || sipdebug) { 03261 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03262 } 03263 break; 03264 03265 case INC_CALL_RINGING: 03266 case INC_CALL_LIMIT: 03267 if (*call_limit > 0 ) { 03268 if (*inuse >= *call_limit) { 03269 ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03270 if (u) 03271 ASTOBJ_UNREF(u, sip_destroy_user); 03272 else 03273 ASTOBJ_UNREF(p, sip_destroy_peer); 03274 return -1; 03275 } 03276 } 03277 if (inringing && (event == INC_CALL_RINGING)) { 03278 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03279 (*inringing)++; 03280 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03281 } 03282 } 03283 /* Continue */ 03284 (*inuse)++; 03285 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03286 if (option_debug > 1 || sipdebug) { 03287 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03288 } 03289 break; 03290 03291 case DEC_CALL_RINGING: 03292 if (inringing) { 03293 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03294 if (*inringing > 0) 03295 (*inringing)--; 03296 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03297 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03298 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03299 } 03300 } 03301 break; 03302 03303 default: 03304 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03305 } 03306 if (p) { 03307 ast_device_state_changed("SIP/%s", p->name); 03308 ASTOBJ_UNREF(p, sip_destroy_peer); 03309 } else /* u must be set */ 03310 ASTOBJ_UNREF(u, sip_destroy_user); 03311 return 0; 03312 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2490 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02491 { 02492 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02493 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02494 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02495 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02496 } 02497 }
struct in_addr __ourip [static] |
Definition at line 1209 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 566 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 582 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17768 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17770 of file chan_sip.c.
Authentication list for realm authentication
Definition at line 1198 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 546 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1203 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
Definition at line 11852 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
Definition at line 18040 of file chan_sip.c.
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 18030 of file chan_sip.c.
struct ast_cli_entry cli_sip_no_debug_deprecated [static] |
Initial value:
{ { "sip", "no", "debug", NULL }, sip_no_debug_deprecated, "Disable SIP debugging", debug_usage }
Definition at line 18035 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 560 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 232 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11736 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1212 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 223 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 525 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 534 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 531 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 532 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 528 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 535 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 529 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 524 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 530 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17767 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17773 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 562 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1206 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1205 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1204 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1207 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 553 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 554 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 570 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 543 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 569 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 567 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 538 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 585 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 230 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 539 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 572 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 556 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 542 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 541 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 563 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 551 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 552 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 564 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 547 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 540 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 549 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 550 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 548 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 568 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 558 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 559 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 565 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11753 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
struct io_context* io [static] |
The IO context
Definition at line 606 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1208 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 10376 of file chan_sip.c.
Referenced by load_module().
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 9927 of file chan_sip.c.
Referenced by load_module().
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 192 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 191 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 600 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 11745 of file chan_sip.c.
char no_history_usage[] [static] |
Initial value:
"Usage: sip history off\n" " Disables recording of SIP dialog history for debugging purposes\n"
Definition at line 11749 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 233 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1214 of file chan_sip.c.
Referenced by complete_sipnotify(), reload_config(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 11685 of file chan_sip.c.
int ourport [static] |
Definition at line 1211 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 545 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 11727 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 561 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 583 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 581 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 579 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 605 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 11709 of file chan_sip.c.
char show_channels_usage[] [static] |
Initial value:
"Usage: sip show channels\n" " Lists all currently active SIP channels.\n"
Definition at line 11705 of file chan_sip.c.
char show_domains_usage[] [static] |
Initial value:
"Usage: sip show domains\n" " Lists all configured SIP local domains.\n" " Asterisk only responds to SIP messages to local domains.\n"
Definition at line 11680 of file chan_sip.c.
char show_history_usage[] [static] |
Initial value:
"Usage: sip show history <channel>\n" " Provides detailed dialog history on a given SIP channel.\n"
Definition at line 11713 of file chan_sip.c.
char show_inuse_usage[] [static] |
Initial value:
"Usage: sip show inuse [all]\n" " List all SIP users and peers usage counters and limits.\n" " Add option \"all\" to show all devices, not only those with a limit.\n"
Definition at line 11700 of file chan_sip.c.
char show_objects_usage[] [static] |
Initial value:
"Usage: sip show objects\n" " Lists status of known SIP objects\n"
Definition at line 11766 of file chan_sip.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: sip show peer <name> [load]\n" " Shows all details on one SIP peer and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n"
Definition at line 11722 of file chan_sip.c.
char show_peers_usage[] [static] |
Initial value:
"Usage: sip show peers [like <pattern>]\n" " Lists all known SIP peers.\n" " Optional regular expression pattern is used to filter the peer list.\n"
Definition at line 11717 of file chan_sip.c.
char show_reg_usage[] [static] |
Initial value:
"Usage: sip show registry\n" " Lists all registration requests and status.\n"
Definition at line 11732 of file chan_sip.c.
char show_settings_usage[] [static] |
Initial value:
"Usage: sip show settings\n" " Provides detailed list of the configuration of the SIP channel.\n"
Definition at line 11770 of file chan_sip.c.
char show_subscriptions_usage[] [static] |
Initial value:
"Usage: sip show subscriptions\n" " Lists active SIP subscriptions for extension states\n"
Definition at line 11762 of file chan_sip.c.
char show_user_usage[] [static] |
Initial value:
"Usage: sip show user <name> [load]\n" " Shows all details on one SIP user and the current status.\n" " Option \"load\" forces lookup of peer in realtime storage.\n"
Definition at line 11695 of file chan_sip.c.
char show_users_usage[] [static] |
Initial value:
"Usage: sip show users [like <pattern>]\n" " Lists all known SIP users.\n" " Optional regular expression pattern is used to filter the user list.\n"
Definition at line 11690 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 11828 of file chan_sip.c.
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 11758 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 602 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 603 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 1611 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_channel_tech sip_tech [static] |
Definition of this channel for PBX channel registration.
Definition at line 1553 of file chan_sip.c.
Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), load_module(), sip_dtmfmode(), sip_new(), and unload_module().
struct ast_channel_tech sip_tech_info [static] |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames.
Definition at line 1579 of file chan_sip.c.
Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_invite(), handle_response_invite(), sip_dtmfmode(), and sip_new().
struct ast_udptl_protocol sip_udptl [static] |
Initial value:
{ type: "SIP", get_udptl_info: sip_get_udptl_peer, set_udptl_peer: sip_set_udptl_peer, }
Definition at line 1620 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1202 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 607 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 580 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 544 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 578 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17766 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17771 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.