#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 | display_nat_warning (const char *cat, int reason, struct ast_flags *flags) |
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_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
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, int sipmethod, struct sip_request *req, enum xmittype 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 |
Definition at line 8398 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#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(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().
#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 6439 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(), display_nat_warning(), 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(), nat2str(), and reload_config().
#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(), register_verify(), and transmit_fake_auth_response().
#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 4251 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04252 { 04253 int pass; 04254 04255 /* 04256 * Technically you can place arbitrary whitespace both before and after the ':' in 04257 * a header, although RFC3261 clearly says you shouldn't before, and place just 04258 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04259 * a good idea to say you can do it, and if you can do it, why in the hell would. 04260 * you say you shouldn't. 04261 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04262 * and we always allow spaces after that for compatibility. 04263 */ 04264 for (pass = 0; name && pass < 2;pass++) { 04265 int x, len = strlen(name); 04266 for (x=*start; x<req->headers; x++) { 04267 if (!strncasecmp(req->header[x], name, len)) { 04268 char *r = req->header[x] + len; /* skip name */ 04269 if (pedanticsipchecking) 04270 r = ast_skip_blanks(r); 04271 04272 if (*r == ':') { 04273 *start = x+1; 04274 return ast_skip_blanks(r+1); 04275 } 04276 } 04277 } 04278 if (pass == 0) /* Try aliases */ 04279 name = find_alias(name, NULL); 04280 } 04281 04282 /* Don't return NULL, so get_header is always a valid pointer */ 04283 return ""; 04284 }
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 7494 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07495 { 07496 int res; 07497 07498 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07499 return res; 07500 }
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 10942 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().
10943 { 10944 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10945 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10946 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10947 struct sip_pvt *cur; 10948 int numchans = 0; 10949 char *referstatus = NULL; 10950 10951 if (argc != 3) 10952 return RESULT_SHOWUSAGE; 10953 ast_mutex_lock(&iflock); 10954 cur = iflist; 10955 if (!subscriptions) 10956 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10957 else 10958 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10959 for (; cur; cur = cur->next) { 10960 referstatus = ""; 10961 if (cur->refer) { /* SIP transfer in progress */ 10962 referstatus = referstatus2str(cur->refer->status); 10963 } 10964 if (cur->subscribed == NONE && !subscriptions) { 10965 char formatbuf[SIPBUFSIZE/2]; 10966 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10967 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10968 cur->callid, 10969 cur->ocseq, cur->icseq, 10970 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10971 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10972 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10973 cur->lastmsg , 10974 referstatus 10975 ); 10976 numchans++; 10977 } 10978 if (cur->subscribed != NONE && subscriptions) { 10979 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10980 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10981 cur->callid, 10982 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10983 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10984 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10985 subscription_type2str(cur->subscribed), 10986 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10987 ); 10988 numchans++; 10989 } 10990 } 10991 ast_mutex_unlock(&iflock); 10992 if (!subscriptions) 10993 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10994 else 10995 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10996 return RESULT_SUCCESS; 10997 #undef FORMAT 10998 #undef FORMAT2 10999 #undef FORMAT3 11000 }
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 6033 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().
06034 { 06035 struct sip_request resp; 06036 int seqno = 0; 06037 06038 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06039 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06040 return -1; 06041 } 06042 respprep(&resp, p, msg, req); 06043 add_header_contentLength(&resp, 0); 06044 /* If we are cancelling an incoming invite for some reason, add information 06045 about the reason why we are doing this in clear text */ 06046 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06047 char buf[10]; 06048 06049 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06050 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06051 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06052 } 06053 return send_response(p, &resp, reliable, seqno); 06054 }
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 10500 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().
10501 { 10502 char status[30] = ""; 10503 char cbuf[256]; 10504 struct sip_peer *peer; 10505 char codec_buf[512]; 10506 struct ast_codec_pref *pref; 10507 struct ast_variable *v; 10508 struct sip_auth *auth; 10509 int x = 0, codec = 0, load_realtime; 10510 int realtimepeers; 10511 10512 realtimepeers = ast_check_realtime("sippeers"); 10513 10514 if (argc < 4) 10515 return RESULT_SHOWUSAGE; 10516 10517 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10518 peer = find_peer(argv[3], NULL, load_realtime); 10519 if (s) { /* Manager */ 10520 if (peer) { 10521 const char *id = astman_get_header(m,"ActionID"); 10522 10523 astman_append(s, "Response: Success\r\n"); 10524 if (!ast_strlen_zero(id)) 10525 astman_append(s, "ActionID: %s\r\n",id); 10526 } else { 10527 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10528 astman_send_error(s, m, cbuf); 10529 return 0; 10530 } 10531 } 10532 if (peer && type==0 ) { /* Normal listing */ 10533 ast_cli(fd,"\n\n"); 10534 ast_cli(fd, " * Name : %s\n", peer->name); 10535 if (realtimepeers) { /* Realtime is enabled */ 10536 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10537 } 10538 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10539 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10540 for (auth = peer->auth; auth; auth = auth->next) { 10541 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10542 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10543 } 10544 ast_cli(fd, " Context : %s\n", peer->context); 10545 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10546 ast_cli(fd, " Language : %s\n", peer->language); 10547 if (!ast_strlen_zero(peer->accountcode)) 10548 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10549 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10550 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10551 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10552 if (!ast_strlen_zero(peer->fromuser)) 10553 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10554 if (!ast_strlen_zero(peer->fromdomain)) 10555 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10556 ast_cli(fd, " Callgroup : "); 10557 print_group(fd, peer->callgroup, 0); 10558 ast_cli(fd, " Pickupgroup : "); 10559 print_group(fd, peer->pickupgroup, 0); 10560 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10561 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10562 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10563 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10564 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10565 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10566 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10567 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10568 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))); 10569 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10570 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10571 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10572 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10573 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10574 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10575 #endif 10576 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10577 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10578 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10579 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10580 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10581 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10582 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10583 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10584 10585 /* - is enumerated */ 10586 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10587 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10588 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10589 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)); 10590 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10591 if (!ast_strlen_zero(global_regcontext)) 10592 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10593 ast_cli(fd, " Def. Username: %s\n", peer->username); 10594 ast_cli(fd, " SIP Options : "); 10595 if (peer->sipoptions) { 10596 int lastoption = -1; 10597 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10598 if (sip_options[x].id != lastoption) { 10599 if (peer->sipoptions & sip_options[x].id) 10600 ast_cli(fd, "%s ", sip_options[x].text); 10601 lastoption = x; 10602 } 10603 } 10604 } else 10605 ast_cli(fd, "(none)"); 10606 10607 ast_cli(fd, "\n"); 10608 ast_cli(fd, " Codecs : "); 10609 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10610 ast_cli(fd, "%s\n", codec_buf); 10611 ast_cli(fd, " Codec Order : ("); 10612 print_codec_to_cli(fd, &peer->prefs); 10613 ast_cli(fd, ")\n"); 10614 10615 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10616 ast_cli(fd, " Status : "); 10617 peer_status(peer, status, sizeof(status)); 10618 ast_cli(fd, "%s\n",status); 10619 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10620 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10621 if (peer->chanvars) { 10622 ast_cli(fd, " Variables :\n"); 10623 for (v = peer->chanvars ; v ; v = v->next) 10624 ast_cli(fd, " %s = %s\n", v->name, v->value); 10625 } 10626 ast_cli(fd,"\n"); 10627 ASTOBJ_UNREF(peer,sip_destroy_peer); 10628 } else if (peer && type == 1) { /* manager listing */ 10629 char buf[256]; 10630 astman_append(s, "Channeltype: SIP\r\n"); 10631 astman_append(s, "ObjectName: %s\r\n", peer->name); 10632 astman_append(s, "ChanObjectType: peer\r\n"); 10633 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10634 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10635 astman_append(s, "Context: %s\r\n", peer->context); 10636 astman_append(s, "Language: %s\r\n", peer->language); 10637 if (!ast_strlen_zero(peer->accountcode)) 10638 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10639 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10640 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10641 if (!ast_strlen_zero(peer->fromuser)) 10642 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10643 if (!ast_strlen_zero(peer->fromdomain)) 10644 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10645 astman_append(s, "Callgroup: "); 10646 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10647 astman_append(s, "Pickupgroup: "); 10648 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10649 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10650 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10651 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10652 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10653 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10654 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10655 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10656 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10657 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))); 10658 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10659 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10660 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10661 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10662 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10663 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10664 10665 /* - is enumerated */ 10666 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10667 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10668 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10669 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)); 10670 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)); 10671 astman_append(s, "Default-Username: %s\r\n", peer->username); 10672 if (!ast_strlen_zero(global_regcontext)) 10673 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10674 astman_append(s, "Codecs: "); 10675 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10676 astman_append(s, "%s\r\n", codec_buf); 10677 astman_append(s, "CodecOrder: "); 10678 pref = &peer->prefs; 10679 for(x = 0; x < 32 ; x++) { 10680 codec = ast_codec_pref_index(pref,x); 10681 if (!codec) 10682 break; 10683 astman_append(s, "%s", ast_getformatname(codec)); 10684 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10685 astman_append(s, ","); 10686 } 10687 10688 astman_append(s, "\r\n"); 10689 astman_append(s, "Status: "); 10690 peer_status(peer, status, sizeof(status)); 10691 astman_append(s, "%s\r\n", status); 10692 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10693 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10694 if (peer->chanvars) { 10695 for (v = peer->chanvars ; v ; v = v->next) { 10696 astman_append(s, "ChanVariable:\n"); 10697 astman_append(s, " %s,%s\r\n", v->name, v->value); 10698 } 10699 } 10700 10701 ASTOBJ_UNREF(peer,sip_destroy_peer); 10702 10703 } else { 10704 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10705 ast_cli(fd,"\n"); 10706 } 10707 10708 return RESULT_SUCCESS; 10709 }
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 10050 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().
10051 { 10052 regex_t regexbuf; 10053 int havepattern = FALSE; 10054 10055 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10056 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10057 10058 char name[256]; 10059 int total_peers = 0; 10060 int peers_mon_online = 0; 10061 int peers_mon_offline = 0; 10062 int peers_unmon_offline = 0; 10063 int peers_unmon_online = 0; 10064 const char *id; 10065 char idtext[256] = ""; 10066 int realtimepeers; 10067 10068 realtimepeers = ast_check_realtime("sippeers"); 10069 10070 if (s) { /* Manager - get ActionID */ 10071 id = astman_get_header(m,"ActionID"); 10072 if (!ast_strlen_zero(id)) 10073 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10074 } 10075 10076 switch (argc) { 10077 case 5: 10078 if (!strcasecmp(argv[3], "like")) { 10079 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10080 return RESULT_SHOWUSAGE; 10081 havepattern = TRUE; 10082 } else 10083 return RESULT_SHOWUSAGE; 10084 case 3: 10085 break; 10086 default: 10087 return RESULT_SHOWUSAGE; 10088 } 10089 10090 if (!s) /* Normal list */ 10091 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10092 10093 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10094 char status[20] = ""; 10095 char srch[2000]; 10096 char pstatus; 10097 10098 ASTOBJ_RDLOCK(iterator); 10099 10100 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10101 ASTOBJ_UNLOCK(iterator); 10102 continue; 10103 } 10104 10105 if (!ast_strlen_zero(iterator->username) && !s) 10106 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10107 else 10108 ast_copy_string(name, iterator->name, sizeof(name)); 10109 10110 pstatus = peer_status(iterator, status, sizeof(status)); 10111 if (pstatus == 1) 10112 peers_mon_online++; 10113 else if (pstatus == 0) 10114 peers_mon_offline++; 10115 else { 10116 if (iterator->addr.sin_port == 0) 10117 peers_unmon_offline++; 10118 else 10119 peers_unmon_online++; 10120 } 10121 10122 snprintf(srch, sizeof(srch), FORMAT, name, 10123 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10124 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10125 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10126 iterator->ha ? " A " : " ", /* permit/deny */ 10127 ntohs(iterator->addr.sin_port), status, 10128 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10129 10130 if (!s) {/* Normal CLI list */ 10131 ast_cli(fd, FORMAT, name, 10132 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10133 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10134 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10135 iterator->ha ? " A " : " ", /* permit/deny */ 10136 10137 ntohs(iterator->addr.sin_port), status, 10138 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10139 } else { /* Manager format */ 10140 /* The names here need to be the same as other channels */ 10141 astman_append(s, 10142 "Event: PeerEntry\r\n%s" 10143 "Channeltype: SIP\r\n" 10144 "ObjectName: %s\r\n" 10145 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10146 "IPaddress: %s\r\n" 10147 "IPport: %d\r\n" 10148 "Dynamic: %s\r\n" 10149 "Natsupport: %s\r\n" 10150 "VideoSupport: %s\r\n" 10151 "ACL: %s\r\n" 10152 "Status: %s\r\n" 10153 "RealtimeDevice: %s\r\n\r\n", 10154 idtext, 10155 iterator->name, 10156 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10157 ntohs(iterator->addr.sin_port), 10158 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10159 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10160 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10161 iterator->ha ? "yes" : "no", /* permit/deny */ 10162 status, 10163 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10164 } 10165 10166 ASTOBJ_UNLOCK(iterator); 10167 10168 total_peers++; 10169 } while(0) ); 10170 10171 if (!s) 10172 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10173 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10174 10175 if (havepattern) 10176 regfree(®exbuf); 10177 10178 if (total) 10179 *total = total_peers; 10180 10181 10182 return RESULT_SUCCESS; 10183 #undef FORMAT 10184 #undef FORMAT2 10185 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15161 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.
15162 { 15163 struct ast_rtp_quality qos; 15164 struct sip_pvt *p = chan->tech_pvt; 15165 char *all = "", *parse = ast_strdupa(preparse); 15166 AST_DECLARE_APP_ARGS(args, 15167 AST_APP_ARG(param); 15168 AST_APP_ARG(type); 15169 AST_APP_ARG(field); 15170 ); 15171 AST_STANDARD_APP_ARGS(args, parse); 15172 15173 /* Sanity check */ 15174 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15175 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15176 return 0; 15177 } 15178 15179 if (strcasecmp(args.param, "rtpqos")) 15180 return 0; 15181 15182 /* Default arguments of audio,all */ 15183 if (ast_strlen_zero(args.type)) 15184 args.type = "audio"; 15185 if (ast_strlen_zero(args.field)) 15186 args.field = "all"; 15187 15188 memset(buf, 0, buflen); 15189 memset(&qos, 0, sizeof(qos)); 15190 15191 if (strcasecmp(args.type, "AUDIO") == 0) { 15192 all = ast_rtp_get_quality(p->rtp, &qos); 15193 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15194 all = ast_rtp_get_quality(p->vrtp, &qos); 15195 } 15196 15197 if (strcasecmp(args.field, "local_ssrc") == 0) 15198 snprintf(buf, buflen, "%u", qos.local_ssrc); 15199 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15200 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15201 else if (strcasecmp(args.field, "local_jitter") == 0) 15202 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15203 else if (strcasecmp(args.field, "local_count") == 0) 15204 snprintf(buf, buflen, "%u", qos.local_count); 15205 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15206 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15207 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15208 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15209 else if (strcasecmp(args.field, "remote_jitter") == 0) 15210 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15211 else if (strcasecmp(args.field, "remote_count") == 0) 15212 snprintf(buf, buflen, "%u", qos.remote_count); 15213 else if (strcasecmp(args.field, "rtt") == 0) 15214 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15215 else if (strcasecmp(args.field, "all") == 0) 15216 ast_copy_string(buf, all, buflen); 15217 else { 15218 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15219 return -1; 15220 } 15221 return 0; 15222 }
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 6238 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().
06241 { 06242 int rtp_code; 06243 struct ast_format_list fmt; 06244 06245 06246 if (debug) 06247 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06248 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06249 return; 06250 06251 if (p->rtp) { 06252 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06253 fmt = ast_codec_pref_getsize(pref, codec); 06254 } 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 */ 06255 return; 06256 ast_build_string(m_buf, m_size, " %d", rtp_code); 06257 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06258 ast_rtp_lookup_mime_subtype(1, codec, 06259 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06260 sample_rate); 06261 if (codec == AST_FORMAT_G729A) { 06262 /* Indicate that we don't support VAD (G.729 annex B) */ 06263 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06264 } else if (codec == AST_FORMAT_G723_1) { 06265 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06266 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06267 } else if (codec == AST_FORMAT_ILBC) { 06268 /* Add information about us using only 20/30 ms packetization */ 06269 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06270 } 06271 06272 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06273 *min_packet_size = fmt.cur_ms; 06274 06275 /* Our first codec packetization processed cannot be less than zero */ 06276 if ((*min_packet_size) == 0 && fmt.cur_ms) 06277 *min_packet_size = fmt.cur_ms; 06278 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6206 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06207 { 06208 char tmp[256]; 06209 06210 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06211 add_header(req, "Content-Type", "application/dtmf-relay"); 06212 add_header_contentLength(req, strlen(tmp)); 06213 add_line(req, tmp); 06214 return 0; 06215 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5600 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.
05601 { 05602 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05603 05604 if (req->headers == SIP_MAX_HEADERS) { 05605 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05606 return -1; 05607 } 05608 05609 if (req->lines) { 05610 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05611 return -1; 05612 } 05613 05614 if (maxlen <= 0) { 05615 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05616 return -1; 05617 } 05618 05619 req->header[req->headers] = req->data + req->len; 05620 05621 if (compactheaders) 05622 var = find_alias(var, var); 05623 05624 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05625 req->len += strlen(req->header[req->headers]); 05626 req->headers++; 05627 05628 return 0; 05629 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5632 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().
05633 { 05634 char clen[10]; 05635 05636 snprintf(clen, sizeof(clen), "%d", len); 05637 return add_header(req, "Content-Length", clen); 05638 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5641 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.
05642 { 05643 if (req->lines == SIP_MAX_LINES) { 05644 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05645 return -1; 05646 } 05647 if (!req->lines) { 05648 /* Add extra empty return */ 05649 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05650 req->len += strlen(req->data + req->len); 05651 } 05652 if (req->len >= sizeof(req->data) - 4) { 05653 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05654 return -1; 05655 } 05656 req->line[req->lines] = req->data + req->len; 05657 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05658 req->len += strlen(req->line[req->lines]); 05659 req->lines++; 05660 return 0; 05661 }
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 6414 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().
06417 { 06418 int rtp_code; 06419 06420 if (debug) 06421 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06422 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06423 return; 06424 06425 ast_build_string(m_buf, m_size, " %d", rtp_code); 06426 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06427 ast_rtp_lookup_mime_subtype(0, format, 0), 06428 sample_rate); 06429 if (format == AST_RTP_DTMF) 06430 /* Indicate we support DTMF and FLASH... */ 06431 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06432 }
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 16779 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().
16780 { 16781 char authcopy[256]; 16782 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16783 char *stringp; 16784 struct sip_auth *a, *b, *auth; 16785 16786 if (ast_strlen_zero(configuration)) 16787 return authlist; 16788 16789 if (option_debug) 16790 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16791 16792 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16793 stringp = authcopy; 16794 16795 username = stringp; 16796 realm = strrchr(stringp, '@'); 16797 if (realm) 16798 *realm++ = '\0'; 16799 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16800 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16801 return authlist; 16802 } 16803 stringp = username; 16804 username = strsep(&stringp, ":"); 16805 if (username) { 16806 secret = strsep(&stringp, ":"); 16807 if (!secret) { 16808 stringp = username; 16809 md5secret = strsep(&stringp,"#"); 16810 } 16811 } 16812 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16813 return authlist; 16814 16815 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16816 ast_copy_string(auth->username, username, sizeof(auth->username)); 16817 if (secret) 16818 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16819 if (md5secret) 16820 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16821 16822 /* find the end of the list */ 16823 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16824 ; 16825 if (b) 16826 b->next = auth; /* Add structure add end of list */ 16827 else 16828 authlist = auth; 16829 16830 if (option_verbose > 2) 16831 ast_verbose("Added authentication for realm %s\n", realm); 16832 16833 return authlist; 16834 16835 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5762 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05763 { 05764 char r[SIPBUFSIZE*2], *p; 05765 int n, rem = sizeof(r); 05766 05767 if (!route) 05768 return; 05769 05770 p = r; 05771 for (;route ; route = route->next) { 05772 n = strlen(route->hop); 05773 if (rem < n+3) /* we need room for ",<route>" */ 05774 break; 05775 if (p != r) { /* add a separator after fist route */ 05776 *p++ = ','; 05777 --rem; 05778 } 05779 *p++ = '<'; 05780 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05781 p += n; 05782 *p++ = '>'; 05783 rem -= (n+2); 05784 } 05785 *p = '\0'; 05786 add_header(req, "Route", r); 05787 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6442 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.
06443 { 06444 int len = 0; 06445 int alreadysent = 0; 06446 06447 struct sockaddr_in sin; 06448 struct sockaddr_in vsin; 06449 struct sockaddr_in dest; 06450 struct sockaddr_in vdest = { 0, }; 06451 06452 /* SDP fields */ 06453 char *version = "v=0\r\n"; /* Protocol version */ 06454 char *subject = "s=session\r\n"; /* Subject of the session */ 06455 char owner[256]; /* Session owner/creator */ 06456 char connection[256]; /* Connection data */ 06457 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06458 char bandwidth[256] = ""; /* Max bitrate */ 06459 char *hold; 06460 char m_audio[256]; /* Media declaration line for audio */ 06461 char m_video[256]; /* Media declaration line for video */ 06462 char a_audio[1024]; /* Attributes for audio */ 06463 char a_video[1024]; /* Attributes for video */ 06464 char *m_audio_next = m_audio; 06465 char *m_video_next = m_video; 06466 size_t m_audio_left = sizeof(m_audio); 06467 size_t m_video_left = sizeof(m_video); 06468 char *a_audio_next = a_audio; 06469 char *a_video_next = a_video; 06470 size_t a_audio_left = sizeof(a_audio); 06471 size_t a_video_left = sizeof(a_video); 06472 06473 int x; 06474 int capability; 06475 int needvideo = FALSE; 06476 int debug = sip_debug_test_pvt(p); 06477 int min_audio_packet_size = 0; 06478 int min_video_packet_size = 0; 06479 06480 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06481 06482 if (!p->rtp) { 06483 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06484 return AST_FAILURE; 06485 } 06486 06487 /* Set RTP Session ID and version */ 06488 if (!p->sessionid) { 06489 p->sessionid = getpid(); 06490 p->sessionversion = p->sessionid; 06491 } else 06492 p->sessionversion++; 06493 06494 /* Get our addresses */ 06495 ast_rtp_get_us(p->rtp, &sin); 06496 if (p->vrtp) 06497 ast_rtp_get_us(p->vrtp, &vsin); 06498 06499 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06500 if (p->redirip.sin_addr.s_addr) { 06501 dest.sin_port = p->redirip.sin_port; 06502 dest.sin_addr = p->redirip.sin_addr; 06503 } else { 06504 dest.sin_addr = p->ourip; 06505 dest.sin_port = sin.sin_port; 06506 } 06507 06508 capability = p->jointcapability; 06509 06510 06511 if (option_debug > 1) { 06512 char codecbuf[SIPBUFSIZE]; 06513 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"); 06514 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06515 } 06516 06517 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06518 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06519 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06520 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06521 } 06522 #endif 06523 06524 /* Check if we need video in this call */ 06525 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06526 if (p->vrtp) { 06527 needvideo = TRUE; 06528 if (option_debug > 1) 06529 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06530 } else if (option_debug > 1) 06531 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06532 } 06533 06534 06535 /* Ok, we need video. Let's add what we need for video and set codecs. 06536 Video is handled differently than audio since we can not transcode. */ 06537 if (needvideo) { 06538 /* Determine video destination */ 06539 if (p->vredirip.sin_addr.s_addr) { 06540 vdest.sin_addr = p->vredirip.sin_addr; 06541 vdest.sin_port = p->vredirip.sin_port; 06542 } else { 06543 vdest.sin_addr = p->ourip; 06544 vdest.sin_port = vsin.sin_port; 06545 } 06546 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06547 06548 /* Build max bitrate string */ 06549 if (p->maxcallbitrate) 06550 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06551 if (debug) 06552 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06553 } 06554 06555 if (debug) 06556 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06557 06558 /* Start building generic SDP headers */ 06559 06560 /* We break with the "recommendation" and send our IP, in order that our 06561 peer doesn't have to ast_gethostbyname() us */ 06562 06563 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06564 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06565 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06566 06567 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06568 hold = "a=recvonly\r\n"; 06569 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06570 hold = "a=inactive\r\n"; 06571 else 06572 hold = "a=sendrecv\r\n"; 06573 06574 /* Now, start adding audio codecs. These are added in this order: 06575 - First what was requested by the calling channel 06576 - Then preferences in order from sip.conf device config for this peer/user 06577 - Then other codecs in capabilities, including video 06578 */ 06579 06580 /* Prefer the audio codec we were requested to use, first, no matter what 06581 Note that p->prefcodec can include video codecs, so mask them out 06582 */ 06583 if (capability & p->prefcodec) { 06584 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06585 06586 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06587 &m_audio_next, &m_audio_left, 06588 &a_audio_next, &a_audio_left, 06589 debug, &min_audio_packet_size); 06590 alreadysent |= codec; 06591 } 06592 06593 /* Start by sending our preferred audio codecs */ 06594 for (x = 0; x < 32; x++) { 06595 int codec; 06596 06597 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06598 break; 06599 06600 if (!(capability & codec)) 06601 continue; 06602 06603 if (alreadysent & codec) 06604 continue; 06605 06606 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06607 &m_audio_next, &m_audio_left, 06608 &a_audio_next, &a_audio_left, 06609 debug, &min_audio_packet_size); 06610 alreadysent |= codec; 06611 } 06612 06613 /* Now send any other common audio and video codecs, and non-codec formats: */ 06614 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06615 if (!(capability & x)) /* Codec not requested */ 06616 continue; 06617 06618 if (alreadysent & x) /* Already added to SDP */ 06619 continue; 06620 06621 if (x <= AST_FORMAT_MAX_AUDIO) 06622 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06623 &m_audio_next, &m_audio_left, 06624 &a_audio_next, &a_audio_left, 06625 debug, &min_audio_packet_size); 06626 else 06627 add_codec_to_sdp(p, x, 90000, 06628 &m_video_next, &m_video_left, 06629 &a_video_next, &a_video_left, 06630 debug, &min_video_packet_size); 06631 } 06632 06633 /* Now add DTMF RFC2833 telephony-event as a codec */ 06634 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06635 if (!(p->jointnoncodeccapability & x)) 06636 continue; 06637 06638 add_noncodec_to_sdp(p, x, 8000, 06639 &m_audio_next, &m_audio_left, 06640 &a_audio_next, &a_audio_left, 06641 debug); 06642 } 06643 06644 if (option_debug > 2) 06645 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06646 06647 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06648 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06649 06650 if (min_audio_packet_size) 06651 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06652 06653 if (min_video_packet_size) 06654 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06655 06656 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06657 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06658 06659 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06660 if (needvideo) 06661 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06662 06663 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06664 if (needvideo) /* only if video response is appropriate */ 06665 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06666 06667 add_header(resp, "Content-Type", "application/sdp"); 06668 add_header_contentLength(resp, len); 06669 add_line(resp, version); 06670 add_line(resp, owner); 06671 add_line(resp, subject); 06672 add_line(resp, connection); 06673 if (needvideo) /* only if video response is appropriate */ 06674 add_line(resp, bandwidth); 06675 add_line(resp, stime); 06676 add_line(resp, m_audio); 06677 add_line(resp, a_audio); 06678 add_line(resp, hold); 06679 if (needvideo) { /* only if video response is appropriate */ 06680 add_line(resp, m_video); 06681 add_line(resp, a_video); 06682 add_line(resp, hold); /* Repeat hold for the video stream */ 06683 } 06684 06685 /* Update lastrtprx when we send our SDP */ 06686 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06687 06688 if (option_debug > 2) { 06689 char buf[SIPBUFSIZE]; 06690 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06691 } 06692 06693 return AST_SUCCESS; 06694 }
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 16715 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().
16716 { 16717 struct domain *d; 16718 16719 if (ast_strlen_zero(domain)) { 16720 ast_log(LOG_WARNING, "Zero length domain.\n"); 16721 return 1; 16722 } 16723 16724 if (!(d = ast_calloc(1, sizeof(*d)))) 16725 return 0; 16726 16727 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16728 16729 if (!ast_strlen_zero(context)) 16730 ast_copy_string(d->context, context, sizeof(d->context)); 16731 16732 d->mode = mode; 16733 16734 AST_LIST_LOCK(&domain_list); 16735 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16736 AST_LIST_UNLOCK(&domain_list); 16737 16738 if (sipdebug) 16739 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16740 16741 return 1; 16742 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6317 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().
06318 { 06319 int len = 0; 06320 int x = 0; 06321 struct sockaddr_in udptlsin; 06322 char v[256] = ""; 06323 char s[256] = ""; 06324 char o[256] = ""; 06325 char c[256] = ""; 06326 char t[256] = ""; 06327 char m_modem[256]; 06328 char a_modem[1024]; 06329 char *m_modem_next = m_modem; 06330 size_t m_modem_left = sizeof(m_modem); 06331 char *a_modem_next = a_modem; 06332 size_t a_modem_left = sizeof(a_modem); 06333 struct sockaddr_in udptldest = { 0, }; 06334 int debug; 06335 06336 debug = sip_debug_test_pvt(p); 06337 len = 0; 06338 if (!p->udptl) { 06339 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06340 return -1; 06341 } 06342 06343 if (!p->sessionid) { 06344 p->sessionid = getpid(); 06345 p->sessionversion = p->sessionid; 06346 } else 06347 p->sessionversion++; 06348 06349 /* Our T.38 end is */ 06350 ast_udptl_get_us(p->udptl, &udptlsin); 06351 06352 /* Determine T.38 UDPTL destination */ 06353 if (p->udptlredirip.sin_addr.s_addr) { 06354 udptldest.sin_port = p->udptlredirip.sin_port; 06355 udptldest.sin_addr = p->udptlredirip.sin_addr; 06356 } else { 06357 udptldest.sin_addr = p->ourip; 06358 udptldest.sin_port = udptlsin.sin_port; 06359 } 06360 06361 if (debug) 06362 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06363 06364 /* We break with the "recommendation" and send our IP, in order that our 06365 peer doesn't have to ast_gethostbyname() us */ 06366 06367 if (debug) { 06368 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06369 p->t38.capability, 06370 p->t38.peercapability, 06371 p->t38.jointcapability); 06372 } 06373 snprintf(v, sizeof(v), "v=0\r\n"); 06374 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06375 snprintf(s, sizeof(s), "s=session\r\n"); 06376 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06377 snprintf(t, sizeof(t), "t=0 0\r\n"); 06378 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06379 06380 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06381 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06382 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06383 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06384 if ((x = t38_get_rate(p->t38.jointcapability))) 06385 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06386 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06387 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06388 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06389 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06390 x = ast_udptl_get_local_max_datagram(p->udptl); 06391 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06392 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06393 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06394 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06395 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06396 add_header(resp, "Content-Type", "application/sdp"); 06397 add_header_contentLength(resp, len); 06398 add_line(resp, v); 06399 add_line(resp, o); 06400 add_line(resp, s); 06401 add_line(resp, c); 06402 add_line(resp, t); 06403 add_line(resp, m_modem); 06404 add_line(resp, a_modem); 06405 06406 /* Update lastrtprx when we send our SDP */ 06407 p->lastrtprx = p->lastrtptx = time(NULL); 06408 06409 return 0; 06410 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6195 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06196 { 06197 /* XXX Convert \n's to \r\n's XXX */ 06198 add_header(req, "Content-Type", "text/plain"); 06199 add_header_contentLength(req, strlen(text)); 06200 add_line(req, text); 06201 return 0; 06202 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6219 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06220 { 06221 const char *xml_is_a_huge_waste_of_space = 06222 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06223 " <media_control>\r\n" 06224 " <vc_primitive>\r\n" 06225 " <to_encoder>\r\n" 06226 " <picture_fast_update>\r\n" 06227 " </picture_fast_update>\r\n" 06228 " </to_encoder>\r\n" 06229 " </vc_primitive>\r\n" 06230 " </media_control>\r\n"; 06231 add_header(req, "Content-Type", "application/media_control+xml"); 06232 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06233 add_line(req, xml_is_a_huge_waste_of_space); 06234 return 0; 06235 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6142 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().
06143 { 06144 char tmpdat[256]; 06145 struct tm tm; 06146 time_t t = time(NULL); 06147 06148 gmtime_r(&t, &tm); 06149 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06150 add_header(req, "Date", tmpdat); 06151 }
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 13392 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().
13393 { 13394 if (chan && chan->_state == AST_STATE_UP) { 13395 if (ast_test_flag(chan, AST_FLAG_MOH)) 13396 ast_moh_stop(chan); 13397 else if (chan->generatordata) 13398 ast_deactivate_generator(chan); 13399 } 13400 }
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 13404 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.
13405 { 13406 int res = 0; 13407 struct ast_channel *peera = NULL, 13408 *peerb = NULL, 13409 *peerc = NULL, 13410 *peerd = NULL; 13411 13412 13413 /* We will try to connect the transferee with the target and hangup 13414 all channels to the transferer */ 13415 if (option_debug > 3) { 13416 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13417 if (transferer->chan1) 13418 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13419 else 13420 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13421 if (target->chan1) 13422 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13423 else 13424 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13425 if (transferer->chan2) 13426 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13427 else 13428 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13429 if (target->chan2) 13430 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)"); 13431 else 13432 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13433 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13434 } 13435 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13436 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13437 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13438 peerc = transferer->chan2; /* Asterisk to Transferee */ 13439 peerd = target->chan2; /* Asterisk to Target */ 13440 if (option_debug > 2) 13441 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13442 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13443 peera = target->chan1; /* Transferer to PBX -> target channel */ 13444 peerb = transferer->chan1; /* Transferer to IVR*/ 13445 peerc = target->chan2; /* Asterisk to Target */ 13446 peerd = transferer->chan2; /* Nothing */ 13447 if (option_debug > 2) 13448 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13449 } 13450 13451 if (peera && peerb && peerc && (peerb != peerc)) { 13452 ast_quiet_chan(peera); /* Stop generators */ 13453 ast_quiet_chan(peerb); 13454 ast_quiet_chan(peerc); 13455 if (peerd) 13456 ast_quiet_chan(peerd); 13457 13458 /* Fix CDRs so they're attached to the remaining channel */ 13459 if (peera->cdr && peerb->cdr) 13460 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13461 else if (peera->cdr) 13462 peerb->cdr = peera->cdr; 13463 peera->cdr = NULL; 13464 13465 if (peerb->cdr && peerc->cdr) 13466 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13467 else if (peerc->cdr) 13468 peerb->cdr = peerc->cdr; 13469 peerc->cdr = NULL; 13470 13471 if (option_debug > 3) 13472 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13473 if (ast_channel_masquerade(peerb, peerc)) { 13474 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13475 res = -1; 13476 } else 13477 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13478 return res; 13479 } else { 13480 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13481 if (transferer->chan1) 13482 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13483 if (target->chan1) 13484 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13485 return -2; 13486 } 13487 return 0; 13488 }
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 4417 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().
04418 { 04419 char buf[33]; 04420 04421 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04422 04423 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04424 04425 }
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 4428 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04429 { 04430 char buf[33]; 04431 04432 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04433 04434 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04435 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6865 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().
06866 { 06867 /* Construct Contact: header */ 06868 if (ourport != STANDARD_SIP_PORT) 06869 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); 06870 else 06871 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06872 }
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 17046 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.
17047 { 17048 struct sip_peer *peer = NULL; 17049 struct ast_ha *oldha = NULL; 17050 int obproxyfound=0; 17051 int found=0; 17052 int firstpass=1; 17053 int format=0; /* Ama flags */ 17054 time_t regseconds = 0; 17055 char *varname = NULL, *varval = NULL; 17056 struct ast_variable *tmpvar = NULL; 17057 struct ast_flags peerflags[2] = {{(0)}}; 17058 struct ast_flags mask[2] = {{(0)}}; 17059 char fullcontact[sizeof(peer->fullcontact)] = ""; 17060 17061 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17062 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17063 /* We also use a case-sensitive comparison (unlike find_peer) so 17064 that case changes made to the peer name will be properly handled 17065 during reload 17066 */ 17067 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17068 17069 if (peer) { 17070 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17071 found = 1; 17072 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17073 firstpass = 0; 17074 } else { 17075 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17076 return NULL; 17077 17078 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17079 rpeerobjs++; 17080 else 17081 speerobjs++; 17082 ASTOBJ_INIT(peer); 17083 } 17084 /* Note that our peer HAS had its reference count incrased */ 17085 if (firstpass) { 17086 peer->lastmsgssent = -1; 17087 oldha = peer->ha; 17088 peer->ha = NULL; 17089 set_peer_defaults(peer); /* Set peer defaults */ 17090 } 17091 if (!found && name) 17092 ast_copy_string(peer->name, name, sizeof(peer->name)); 17093 17094 /* If we have channel variables, remove them (reload) */ 17095 if (peer->chanvars) { 17096 ast_variables_destroy(peer->chanvars); 17097 peer->chanvars = NULL; 17098 /* XXX should unregister ? */ 17099 } 17100 17101 /* If we have realm authentication information, remove them (reload) */ 17102 clear_realm_authentication(peer->auth); 17103 peer->auth = NULL; 17104 17105 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17106 if (handle_common_options(&peerflags[0], &mask[0], v)) 17107 continue; 17108 if (realtime && !strcasecmp(v->name, "regseconds")) { 17109 ast_get_time_t(v->value, ®seconds, 0, NULL); 17110 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17111 inet_aton(v->value, &(peer->addr.sin_addr)); 17112 } else if (realtime && !strcasecmp(v->name, "name")) 17113 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17114 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17115 /* Reconstruct field, because realtime separates our value at the ';' */ 17116 if (!ast_strlen_zero(fullcontact)) { 17117 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17118 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17119 } else { 17120 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17121 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17122 } 17123 } else if (!strcasecmp(v->name, "secret")) 17124 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17125 else if (!strcasecmp(v->name, "md5secret")) 17126 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17127 else if (!strcasecmp(v->name, "auth")) 17128 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17129 else if (!strcasecmp(v->name, "callerid")) { 17130 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17131 } else if (!strcasecmp(v->name, "fullname")) { 17132 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17133 } else if (!strcasecmp(v->name, "cid_number")) { 17134 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17135 } else if (!strcasecmp(v->name, "context")) { 17136 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17137 } else if (!strcasecmp(v->name, "subscribecontext")) { 17138 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17139 } else if (!strcasecmp(v->name, "fromdomain")) { 17140 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17141 } else if (!strcasecmp(v->name, "usereqphone")) { 17142 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17143 } else if (!strcasecmp(v->name, "fromuser")) { 17144 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17145 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17146 if (!strcasecmp(v->value, "dynamic")) { 17147 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17148 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17149 } else { 17150 /* They'll register with us */ 17151 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17152 /* Initialize stuff if this is a new peer, or if it used to be 17153 * non-dynamic before the reload. */ 17154 memset(&peer->addr.sin_addr, 0, 4); 17155 if (peer->addr.sin_port) { 17156 /* If we've already got a port, make it the default rather than absolute */ 17157 peer->defaddr.sin_port = peer->addr.sin_port; 17158 peer->addr.sin_port = 0; 17159 } 17160 } 17161 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17162 } 17163 } else { 17164 /* Non-dynamic. Make sure we become that way if we're not */ 17165 if (!AST_SCHED_DEL(sched, peer->expire)) { 17166 struct sip_peer *peer_ptr = peer; 17167 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17168 } 17169 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17170 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17171 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17172 ASTOBJ_UNREF(peer, sip_destroy_peer); 17173 return NULL; 17174 } 17175 } 17176 if (!strcasecmp(v->name, "outboundproxy")) 17177 obproxyfound=1; 17178 else { 17179 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17180 if (!peer->addr.sin_port) 17181 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17182 } 17183 } 17184 } else if (!strcasecmp(v->name, "defaultip")) { 17185 if (ast_get_ip(&peer->defaddr, v->value)) { 17186 ASTOBJ_UNREF(peer, sip_destroy_peer); 17187 return NULL; 17188 } 17189 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17190 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17191 } else if (!strcasecmp(v->name, "port")) { 17192 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17193 peer->defaddr.sin_port = htons(atoi(v->value)); 17194 else 17195 peer->addr.sin_port = htons(atoi(v->value)); 17196 } else if (!strcasecmp(v->name, "callingpres")) { 17197 peer->callingpres = ast_parse_caller_presentation(v->value); 17198 if (peer->callingpres == -1) 17199 peer->callingpres = atoi(v->value); 17200 } else if (!strcasecmp(v->name, "username")) { 17201 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17202 } else if (!strcasecmp(v->name, "language")) { 17203 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17204 } else if (!strcasecmp(v->name, "regexten")) { 17205 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17206 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17207 peer->call_limit = atoi(v->value); 17208 if (peer->call_limit < 0) 17209 peer->call_limit = 0; 17210 } else if (!strcasecmp(v->name, "amaflags")) { 17211 format = ast_cdr_amaflags2int(v->value); 17212 if (format < 0) { 17213 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17214 } else { 17215 peer->amaflags = format; 17216 } 17217 } else if (!strcasecmp(v->name, "accountcode")) { 17218 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17219 } else if (!strcasecmp(v->name, "mohinterpret") 17220 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17221 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17222 } else if (!strcasecmp(v->name, "mohsuggest")) { 17223 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17224 } else if (!strcasecmp(v->name, "mailbox")) { 17225 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17226 } else if (!strcasecmp(v->name, "subscribemwi")) { 17227 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17228 } else if (!strcasecmp(v->name, "vmexten")) { 17229 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17230 } else if (!strcasecmp(v->name, "callgroup")) { 17231 peer->callgroup = ast_get_group(v->value); 17232 } else if (!strcasecmp(v->name, "allowtransfer")) { 17233 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17234 } else if (!strcasecmp(v->name, "pickupgroup")) { 17235 peer->pickupgroup = ast_get_group(v->value); 17236 } else if (!strcasecmp(v->name, "allow")) { 17237 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17238 } else if (!strcasecmp(v->name, "disallow")) { 17239 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17240 } else if (!strcasecmp(v->name, "autoframing")) { 17241 peer->autoframing = ast_true(v->value); 17242 } else if (!strcasecmp(v->name, "rtptimeout")) { 17243 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17244 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17245 peer->rtptimeout = global_rtptimeout; 17246 } 17247 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17248 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17249 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17250 peer->rtpholdtimeout = global_rtpholdtimeout; 17251 } 17252 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17253 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17254 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17255 peer->rtpkeepalive = global_rtpkeepalive; 17256 } 17257 } else if (!strcasecmp(v->name, "setvar")) { 17258 /* Set peer channel variable */ 17259 varname = ast_strdupa(v->value); 17260 if ((varval = strchr(varname, '='))) { 17261 *varval++ = '\0'; 17262 if ((tmpvar = ast_variable_new(varname, varval))) { 17263 tmpvar->next = peer->chanvars; 17264 peer->chanvars = tmpvar; 17265 } 17266 } 17267 } else if (!strcasecmp(v->name, "qualify")) { 17268 if (!strcasecmp(v->value, "no")) { 17269 peer->maxms = 0; 17270 } else if (!strcasecmp(v->value, "yes")) { 17271 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17272 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 17273 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); 17274 peer->maxms = 0; 17275 } 17276 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17277 peer->maxcallbitrate = atoi(v->value); 17278 if (peer->maxcallbitrate < 0) 17279 peer->maxcallbitrate = default_maxcallbitrate; 17280 } 17281 } 17282 if (!ast_strlen_zero(fullcontact)) { 17283 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17284 } 17285 17286 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17287 time_t nowtime = time(NULL); 17288 17289 if ((nowtime - regseconds) > 0) { 17290 destroy_association(peer); 17291 memset(&peer->addr, 0, sizeof(peer->addr)); 17292 if (option_debug) 17293 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17294 } 17295 } 17296 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17297 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17298 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17299 global_allowsubscribe = TRUE; /* No global ban any more */ 17300 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17301 reg_source_db(peer); 17302 ASTOBJ_UNMARK(peer); 17303 ast_free_ha(oldha); 17304 return peer; 17305 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11692 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().
11693 { 11694 char a1[256]; 11695 char a2[256]; 11696 char a1_hash[256]; 11697 char a2_hash[256]; 11698 char resp[256]; 11699 char resp_hash[256]; 11700 char uri[256]; 11701 char opaque[256] = ""; 11702 char cnonce[80]; 11703 const char *username; 11704 const char *secret; 11705 const char *md5secret; 11706 struct sip_auth *auth = NULL; /* Realm authentication */ 11707 11708 if (!ast_strlen_zero(p->domain)) 11709 ast_copy_string(uri, p->domain, sizeof(uri)); 11710 else if (!ast_strlen_zero(p->uri)) 11711 ast_copy_string(uri, p->uri, sizeof(uri)); 11712 else 11713 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11714 11715 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11716 11717 /* Check if we have separate auth credentials */ 11718 if ((auth = find_realm_authentication(authl, p->realm))) { 11719 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11720 auth->username, p->peername, p->username); 11721 username = auth->username; 11722 secret = auth->secret; 11723 md5secret = auth->md5secret; 11724 if (sipdebug) 11725 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11726 } else { 11727 /* No authentication, use peer or register= config */ 11728 username = p->authname; 11729 secret = p->peersecret; 11730 md5secret = p->peermd5secret; 11731 } 11732 if (ast_strlen_zero(username)) /* We have no authentication */ 11733 return -1; 11734 11735 /* Calculate SIP digest response */ 11736 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11737 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11738 if (!ast_strlen_zero(md5secret)) 11739 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11740 else 11741 ast_md5_hash(a1_hash,a1); 11742 ast_md5_hash(a2_hash,a2); 11743 11744 p->noncecount++; 11745 if (!ast_strlen_zero(p->qop)) 11746 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11747 else 11748 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11749 ast_md5_hash(resp_hash, resp); 11750 11751 /* only include the opaque string if it's set */ 11752 if (!ast_strlen_zero(p->opaque)) { 11753 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11754 } 11755 11756 /* XXX We hard code our qop to "auth" for now. XXX */ 11757 if (!ast_strlen_zero(p->qop)) 11758 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); 11759 else 11760 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); 11761 11762 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11763 11764 return 0; 11765 }
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 8292 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().
08293 { 08294 struct sip_route *thishop, *head, *tail; 08295 int start = 0; 08296 int len; 08297 const char *rr, *contact, *c; 08298 08299 /* Once a persistant route is set, don't fool with it */ 08300 if (p->route && p->route_persistant) { 08301 if (option_debug) 08302 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08303 return; 08304 } 08305 08306 if (p->route) { 08307 free_old_route(p->route); 08308 p->route = NULL; 08309 } 08310 08311 /* We only want to create the route set the first time this is called */ 08312 p->route_persistant = 1; 08313 08314 /* Build a tailq, then assign it to p->route when done. 08315 * If backwards, we add entries from the head so they end up 08316 * in reverse order. However, we do need to maintain a correct 08317 * tail pointer because the contact is always at the end. 08318 */ 08319 head = NULL; 08320 tail = head; 08321 /* 1st we pass through all the hops in any Record-Route headers */ 08322 for (;;) { 08323 /* Each Record-Route header */ 08324 rr = __get_header(req, "Record-Route", &start); 08325 if (*rr == '\0') 08326 break; 08327 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08328 ++rr; 08329 len = strcspn(rr, ">") + 1; 08330 /* Make a struct route */ 08331 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08332 /* ast_calloc is not needed because all fields are initialized in this block */ 08333 ast_copy_string(thishop->hop, rr, len); 08334 if (option_debug > 1) 08335 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08336 /* Link in */ 08337 if (backwards) { 08338 /* Link in at head so they end up in reverse order */ 08339 thishop->next = head; 08340 head = thishop; 08341 /* If this was the first then it'll be the tail */ 08342 if (!tail) 08343 tail = thishop; 08344 } else { 08345 thishop->next = NULL; 08346 /* Link in at the end */ 08347 if (tail) 08348 tail->next = thishop; 08349 else 08350 head = thishop; 08351 tail = thishop; 08352 } 08353 } 08354 } 08355 } 08356 08357 /* Only append the contact if we are dealing with a strict router */ 08358 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08359 /* 2nd append the Contact: if there is one */ 08360 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08361 contact = get_header(req, "Contact"); 08362 if (!ast_strlen_zero(contact)) { 08363 if (option_debug > 1) 08364 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08365 /* Look for <: delimited address */ 08366 c = strchr(contact, '<'); 08367 if (c) { 08368 /* Take to > */ 08369 ++c; 08370 len = strcspn(c, ">") + 1; 08371 } else { 08372 /* No <> - just take the lot */ 08373 c = contact; 08374 len = strlen(contact) + 1; 08375 } 08376 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08377 /* ast_calloc is not needed because all fields are initialized in this block */ 08378 ast_copy_string(thishop->hop, c, len); 08379 thishop->next = NULL; 08380 /* Goes at the end */ 08381 if (tail) 08382 tail->next = thishop; 08383 else 08384 head = thishop; 08385 } 08386 } 08387 } 08388 08389 /* Store as new route */ 08390 p->route = head; 08391 08392 /* For debugging dump what we ended up with */ 08393 if (sip_debug_test_pvt(p)) 08394 list_route(p->route); 08395 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6875 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().
06876 { 06877 int send_pres_tags = TRUE; 06878 const char *privacy=NULL; 06879 const char *screen=NULL; 06880 char buf[256]; 06881 const char *clid = default_callerid; 06882 const char *clin = NULL; 06883 const char *fromdomain; 06884 06885 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06886 return; 06887 06888 if (p->owner && p->owner->cid.cid_num) 06889 clid = p->owner->cid.cid_num; 06890 if (p->owner && p->owner->cid.cid_name) 06891 clin = p->owner->cid.cid_name; 06892 if (ast_strlen_zero(clin)) 06893 clin = clid; 06894 06895 switch (p->callingpres) { 06896 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06897 privacy = "off"; 06898 screen = "no"; 06899 break; 06900 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06901 privacy = "off"; 06902 screen = "yes"; 06903 break; 06904 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06905 privacy = "off"; 06906 screen = "no"; 06907 break; 06908 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06909 privacy = "off"; 06910 screen = "yes"; 06911 break; 06912 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06913 privacy = "full"; 06914 screen = "no"; 06915 break; 06916 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06917 privacy = "full"; 06918 screen = "yes"; 06919 break; 06920 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06921 privacy = "full"; 06922 screen = "no"; 06923 break; 06924 case AST_PRES_PROHIB_NETWORK_NUMBER: 06925 privacy = "full"; 06926 screen = "yes"; 06927 break; 06928 case AST_PRES_NUMBER_NOT_AVAILABLE: 06929 send_pres_tags = FALSE; 06930 break; 06931 default: 06932 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06933 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06934 privacy = "full"; 06935 else 06936 privacy = "off"; 06937 screen = "no"; 06938 break; 06939 } 06940 06941 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06942 06943 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06944 if (send_pres_tags) 06945 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06946 ast_string_field_set(p, rpid, buf); 06947 06948 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06949 S_OR(p->fromuser, clid), 06950 fromdomain, p->tag); 06951 }
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 16866 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.
16867 { 16868 struct sip_user *user; 16869 int format; 16870 struct ast_ha *oldha = NULL; 16871 char *varname = NULL, *varval = NULL; 16872 struct ast_variable *tmpvar = NULL; 16873 struct ast_flags userflags[2] = {{(0)}}; 16874 struct ast_flags mask[2] = {{(0)}}; 16875 16876 16877 if (!(user = ast_calloc(1, sizeof(*user)))) 16878 return NULL; 16879 16880 suserobjs++; 16881 ASTOBJ_INIT(user); 16882 ast_copy_string(user->name, name, sizeof(user->name)); 16883 oldha = user->ha; 16884 user->ha = NULL; 16885 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16886 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16887 user->capability = global_capability; 16888 user->allowtransfer = global_allowtransfer; 16889 user->maxcallbitrate = default_maxcallbitrate; 16890 user->autoframing = global_autoframing; 16891 user->prefs = default_prefs; 16892 /* set default context */ 16893 strcpy(user->context, default_context); 16894 strcpy(user->language, default_language); 16895 strcpy(user->mohinterpret, default_mohinterpret); 16896 strcpy(user->mohsuggest, default_mohsuggest); 16897 /* First we walk through the v parameters list and then the alt parameters list */ 16898 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16899 if (handle_common_options(&userflags[0], &mask[0], v)) 16900 continue; 16901 16902 if (!strcasecmp(v->name, "context")) { 16903 ast_copy_string(user->context, v->value, sizeof(user->context)); 16904 } else if (!strcasecmp(v->name, "subscribecontext")) { 16905 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16906 } else if (!strcasecmp(v->name, "setvar")) { 16907 varname = ast_strdupa(v->value); 16908 if ((varval = strchr(varname,'='))) { 16909 *varval++ = '\0'; 16910 if ((tmpvar = ast_variable_new(varname, varval))) { 16911 tmpvar->next = user->chanvars; 16912 user->chanvars = tmpvar; 16913 } 16914 } 16915 } else if (!strcasecmp(v->name, "permit") || 16916 !strcasecmp(v->name, "deny")) { 16917 user->ha = ast_append_ha(v->name, v->value, user->ha); 16918 } else if (!strcasecmp(v->name, "allowtransfer")) { 16919 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16920 } else if (!strcasecmp(v->name, "secret")) { 16921 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16922 } else if (!strcasecmp(v->name, "md5secret")) { 16923 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16924 } else if (!strcasecmp(v->name, "callerid")) { 16925 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16926 } else if (!strcasecmp(v->name, "fullname")) { 16927 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16928 } else if (!strcasecmp(v->name, "cid_number")) { 16929 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16930 } else if (!strcasecmp(v->name, "callgroup")) { 16931 user->callgroup = ast_get_group(v->value); 16932 } else if (!strcasecmp(v->name, "pickupgroup")) { 16933 user->pickupgroup = ast_get_group(v->value); 16934 } else if (!strcasecmp(v->name, "language")) { 16935 ast_copy_string(user->language, v->value, sizeof(user->language)); 16936 } else if (!strcasecmp(v->name, "mohinterpret") 16937 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16938 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16939 } else if (!strcasecmp(v->name, "mohsuggest")) { 16940 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16941 } else if (!strcasecmp(v->name, "accountcode")) { 16942 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16943 } else if (!strcasecmp(v->name, "call-limit")) { 16944 user->call_limit = atoi(v->value); 16945 if (user->call_limit < 0) 16946 user->call_limit = 0; 16947 } else if (!strcasecmp(v->name, "amaflags")) { 16948 format = ast_cdr_amaflags2int(v->value); 16949 if (format < 0) { 16950 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16951 } else { 16952 user->amaflags = format; 16953 } 16954 } else if (!strcasecmp(v->name, "allow")) { 16955 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16956 } else if (!strcasecmp(v->name, "disallow")) { 16957 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16958 } else if (!strcasecmp(v->name, "autoframing")) { 16959 user->autoframing = ast_true(v->value); 16960 } else if (!strcasecmp(v->name, "callingpres")) { 16961 user->callingpres = ast_parse_caller_presentation(v->value); 16962 if (user->callingpres == -1) 16963 user->callingpres = atoi(v->value); 16964 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16965 user->maxcallbitrate = atoi(v->value); 16966 if (user->maxcallbitrate < 0) 16967 user->maxcallbitrate = default_maxcallbitrate; 16968 } 16969 /* We can't just report unknown options here because this may be a 16970 * type=friend entry. All user options are valid for a peer, but not 16971 * the other way around. */ 16972 } 16973 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16974 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16975 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16976 global_allowsubscribe = TRUE; /* No global ban any more */ 16977 ast_free_ha(oldha); 16978 return user; 16979 }
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 8600 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().
08601 { 08602 struct sip_pvt *p = data; 08603 08604 ast_mutex_lock(&p->lock); 08605 08606 switch(state) { 08607 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08608 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08609 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08610 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08611 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08612 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); 08613 p->stateid = -1; 08614 p->subscribed = NONE; 08615 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08616 break; 08617 default: /* Tell user */ 08618 p->laststate = state; 08619 break; 08620 } 08621 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08622 if (!p->pendinginvite) { 08623 transmit_state_notify(p, state, 1, FALSE); 08624 } else { 08625 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08626 if many state changes happen meanwhile, we will only send a notification of the last one */ 08627 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08628 } 08629 } 08630 if (option_verbose > 1) 08631 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, 08632 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08633 08634 08635 ast_mutex_unlock(&p->lock); 08636 08637 return 0; 08638 }
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 4984 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().
04985 { 04986 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04987 sip_peer_hold(dialog, holdstate); 04988 if (global_callevents) 04989 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04990 "Channel: %s\r\n" 04991 "Uniqueid: %s\r\n", 04992 dialog->owner->name, 04993 dialog->owner->uniqueid); 04994 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04995 if (!holdstate) { /* Put off remote hold */ 04996 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04997 return; 04998 } 04999 /* No address for RTP, we're on hold */ 05000 05001 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05002 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05003 else if (sendonly == 2) /* Inactive stream */ 05004 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05005 else 05006 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05007 return; 05008 }
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 8405 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().
08408 { 08409 const char *response = "407 Proxy Authentication Required"; 08410 const char *reqheader = "Proxy-Authorization"; 08411 const char *respheader = "Proxy-Authenticate"; 08412 const char *authtoken; 08413 char a1_hash[256]; 08414 char resp_hash[256]=""; 08415 char *c; 08416 int wrongnonce = FALSE; 08417 int good_response; 08418 const char *usednonce = p->randdata; 08419 struct ast_dynamic_str *buf; 08420 int res; 08421 08422 /* table of recognised keywords, and their value in the digest */ 08423 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08424 struct x { 08425 const char *key; 08426 const char *s; 08427 } *i, keys[] = { 08428 [K_RESP] = { "response=", "" }, 08429 [K_URI] = { "uri=", "" }, 08430 [K_USER] = { "username=", "" }, 08431 [K_NONCE] = { "nonce=", "" }, 08432 [K_LAST] = { NULL, NULL} 08433 }; 08434 08435 /* Always OK if no secret */ 08436 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08437 return AUTH_SUCCESSFUL; 08438 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08439 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08440 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08441 different circumstances! What a surprise. */ 08442 response = "401 Unauthorized"; 08443 reqheader = "Authorization"; 08444 respheader = "WWW-Authenticate"; 08445 } 08446 authtoken = get_header(req, reqheader); 08447 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08448 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08449 information */ 08450 if (!reliable) { 08451 /* Resend message if this was NOT a reliable delivery. Otherwise the 08452 retransmission should get it */ 08453 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08454 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08455 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08456 } 08457 return AUTH_CHALLENGE_SENT; 08458 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08459 /* We have no auth, so issue challenge and request authentication */ 08460 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08461 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08462 /* Schedule auto destroy in 32 seconds */ 08463 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08464 return AUTH_CHALLENGE_SENT; 08465 } 08466 08467 /* --- We have auth, so check it */ 08468 08469 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08470 an example in the spec of just what it is you're doing a hash on. */ 08471 08472 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08473 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08474 08475 /* Make a copy of the response and parse it */ 08476 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08477 08478 if (res == AST_DYNSTR_BUILD_FAILED) 08479 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08480 08481 c = buf->str; 08482 08483 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08484 for (i = keys; i->key != NULL; i++) { 08485 const char *separator = ","; /* default */ 08486 08487 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08488 continue; 08489 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08490 c += strlen(i->key); 08491 if (*c == '"') { /* in quotes. Skip first and look for last */ 08492 c++; 08493 separator = "\""; 08494 } 08495 i->s = c; 08496 strsep(&c, separator); 08497 break; 08498 } 08499 if (i->key == NULL) /* not found, jump after space or comma */ 08500 strsep(&c, " ,"); 08501 } 08502 08503 /* Verify that digest username matches the username we auth as */ 08504 if (strcmp(username, keys[K_USER].s)) { 08505 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08506 username, keys[K_USER].s); 08507 /* Oops, we're trying something here */ 08508 return AUTH_USERNAME_MISMATCH; 08509 } 08510 08511 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08512 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08513 wrongnonce = TRUE; 08514 usednonce = keys[K_NONCE].s; 08515 } 08516 08517 if (!ast_strlen_zero(md5secret)) 08518 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08519 else { 08520 char a1[256]; 08521 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08522 ast_md5_hash(a1_hash, a1); 08523 } 08524 08525 /* compute the expected response to compare with what we received */ 08526 { 08527 char a2[256]; 08528 char a2_hash[256]; 08529 char resp[256]; 08530 08531 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08532 S_OR(keys[K_URI].s, uri)); 08533 ast_md5_hash(a2_hash, a2); 08534 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08535 ast_md5_hash(resp_hash, resp); 08536 } 08537 08538 good_response = keys[K_RESP].s && 08539 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08540 if (wrongnonce) { 08541 if (good_response) { 08542 if (sipdebug) 08543 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08544 /* We got working auth token, based on stale nonce . */ 08545 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08546 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08547 } else { 08548 /* Everything was wrong, so give the device one more try with a new challenge */ 08549 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08550 if (sipdebug) 08551 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08552 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08553 } else { 08554 if (sipdebug) 08555 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08556 } 08557 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08558 } 08559 08560 /* Schedule auto destroy in 32 seconds */ 08561 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08562 return AUTH_CHALLENGE_SENT; 08563 } 08564 if (good_response) { 08565 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08566 return AUTH_SUCCESSFUL; 08567 } 08568 08569 /* Ok, we have a bad username/secret pair */ 08570 /* Tell the UAS not to re-send this authentication data, because 08571 it will continue to fail 08572 */ 08573 08574 return AUTH_SECRET_FAILED; 08575 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12160 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().
12161 { 12162 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12163 /* if we can't BYE, then this is really a pending CANCEL */ 12164 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12165 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12166 /* Actually don't destroy us yet, wait for the 487 on our original 12167 INVITE, but do set an autodestruct just in case we never get it. */ 12168 else { 12169 /* We have a pending outbound invite, don't send someting 12170 new in-transaction */ 12171 if (p->pendinginvite) 12172 return; 12173 12174 /* Perhaps there is an SD change INVITE outstanding */ 12175 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12176 } 12177 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12178 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12179 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12180 /* if we can't REINVITE, hold it for later */ 12181 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12182 if (option_debug) 12183 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12184 } else { 12185 if (option_debug) 12186 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12187 /* Didn't get to reinvite yet, so do it now */ 12188 transmit_reinvite_with_sdp(p); 12189 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12190 } 12191 } 12192 }
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 16745 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().
16746 { 16747 struct domain *d; 16748 int result = 0; 16749 16750 AST_LIST_LOCK(&domain_list); 16751 AST_LIST_TRAVERSE(&domain_list, d, list) { 16752 if (strcasecmp(d->domain, domain)) 16753 continue; 16754 16755 if (len && !ast_strlen_zero(d->context)) 16756 ast_copy_string(context, d->context, len); 16757 16758 result = 1; 16759 break; 16760 } 16761 AST_LIST_UNLOCK(&domain_list); 16762 16763 return result; 16764 }
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 9796 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09797 { 09798 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09799 }
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 9476 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().
09479 { 09480 struct sip_user *user = NULL; 09481 struct sip_peer *peer; 09482 char from[256], *c; 09483 char *of; 09484 char rpid_num[50]; 09485 const char *rpid; 09486 enum check_auth_result res = AUTH_SUCCESSFUL; 09487 char *t; 09488 char calleridname[50]; 09489 int debug=sip_debug_test_addr(sin); 09490 struct ast_variable *tmpvar = NULL, *v = NULL; 09491 char *uri2 = ast_strdupa(uri); 09492 09493 /* Terminate URI */ 09494 t = uri2; 09495 while (*t && *t > 32 && *t != ';') 09496 t++; 09497 *t = '\0'; 09498 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09499 if (pedanticsipchecking) 09500 ast_uri_decode(from); 09501 /* XXX here tries to map the username for invite things */ 09502 memset(calleridname, 0, sizeof(calleridname)); 09503 get_calleridname(from, calleridname, sizeof(calleridname)); 09504 if (calleridname[0]) 09505 ast_string_field_set(p, cid_name, calleridname); 09506 09507 rpid = get_header(req, "Remote-Party-ID"); 09508 memset(rpid_num, 0, sizeof(rpid_num)); 09509 if (!ast_strlen_zero(rpid)) 09510 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09511 09512 of = get_in_brackets(from); 09513 if (ast_strlen_zero(p->exten)) { 09514 t = uri2; 09515 if (!strncasecmp(t, "sip:", 4)) 09516 t+= 4; 09517 ast_string_field_set(p, exten, t); 09518 t = strchr(p->exten, '@'); 09519 if (t) 09520 *t = '\0'; 09521 if (ast_strlen_zero(p->our_contact)) 09522 build_contact(p); 09523 } 09524 /* save the URI part of the From header */ 09525 ast_string_field_set(p, from, of); 09526 if (strncasecmp(of, "sip:", 4)) { 09527 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09528 } else 09529 of += 4; 09530 /* Get just the username part */ 09531 if ((c = strchr(of, '@'))) { 09532 char *tmp; 09533 *c = '\0'; 09534 if ((c = strchr(of, ':'))) 09535 *c = '\0'; 09536 tmp = ast_strdupa(of); 09537 /* We need to be able to handle auth-headers looking like 09538 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09539 */ 09540 tmp = strsep(&tmp, ";"); 09541 if (ast_is_shrinkable_phonenumber(tmp)) 09542 ast_shrink_phone_number(tmp); 09543 ast_string_field_set(p, cid_num, tmp); 09544 } 09545 09546 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09547 user = find_user(of, 1); 09548 09549 /* Find user based on user name in the from header */ 09550 if (user && ast_apply_ha(user->ha, sin)) { 09551 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09552 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09553 /* copy channel vars */ 09554 for (v = user->chanvars ; v ; v = v->next) { 09555 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09556 tmpvar->next = p->chanvars; 09557 p->chanvars = tmpvar; 09558 } 09559 } 09560 p->prefs = user->prefs; 09561 /* Set Frame packetization */ 09562 if (p->rtp) { 09563 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09564 p->autoframing = user->autoframing; 09565 } 09566 /* replace callerid if rpid found, and not restricted */ 09567 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09568 char *tmp; 09569 if (*calleridname) 09570 ast_string_field_set(p, cid_name, calleridname); 09571 tmp = ast_strdupa(rpid_num); 09572 if (ast_is_shrinkable_phonenumber(tmp)) 09573 ast_shrink_phone_number(tmp); 09574 ast_string_field_set(p, cid_num, tmp); 09575 } 09576 09577 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09578 09579 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09580 if (sip_cancel_destroy(p)) 09581 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09582 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09583 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09584 /* Copy SIP extensions profile from INVITE */ 09585 if (p->sipoptions) 09586 user->sipoptions = p->sipoptions; 09587 09588 /* If we have a call limit, set flag */ 09589 if (user->call_limit) 09590 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09591 if (!ast_strlen_zero(user->context)) 09592 ast_string_field_set(p, context, user->context); 09593 if (!ast_strlen_zero(user->cid_num)) { 09594 char *tmp = ast_strdupa(user->cid_num); 09595 if (ast_is_shrinkable_phonenumber(tmp)) 09596 ast_shrink_phone_number(tmp); 09597 ast_string_field_set(p, cid_num, tmp); 09598 } 09599 if (!ast_strlen_zero(user->cid_name)) 09600 ast_string_field_set(p, cid_name, user->cid_name); 09601 ast_string_field_set(p, username, user->name); 09602 ast_string_field_set(p, peername, user->name); 09603 ast_string_field_set(p, peersecret, user->secret); 09604 ast_string_field_set(p, peermd5secret, user->md5secret); 09605 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09606 ast_string_field_set(p, accountcode, user->accountcode); 09607 ast_string_field_set(p, language, user->language); 09608 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09609 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09610 p->allowtransfer = user->allowtransfer; 09611 p->amaflags = user->amaflags; 09612 p->callgroup = user->callgroup; 09613 p->pickupgroup = user->pickupgroup; 09614 if (user->callingpres) /* User callingpres setting will override RPID header */ 09615 p->callingpres = user->callingpres; 09616 09617 /* Set default codec settings for this call */ 09618 p->capability = user->capability; /* User codec choice */ 09619 p->jointcapability = user->capability; /* Our codecs */ 09620 if (p->peercapability) /* AND with peer's codecs */ 09621 p->jointcapability &= p->peercapability; 09622 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09623 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09624 p->noncodeccapability |= AST_RTP_DTMF; 09625 else 09626 p->noncodeccapability &= ~AST_RTP_DTMF; 09627 p->jointnoncodeccapability = p->noncodeccapability; 09628 if (p->t38.peercapability) 09629 p->t38.jointcapability &= p->t38.peercapability; 09630 p->maxcallbitrate = user->maxcallbitrate; 09631 /* If we do not support video, remove video from call structure */ 09632 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09633 ast_rtp_destroy(p->vrtp); 09634 p->vrtp = NULL; 09635 } 09636 } 09637 if (user && debug) 09638 ast_verbose("Found user '%s'\n", user->name); 09639 } else { 09640 if (user) { 09641 if (!authpeer && debug) 09642 ast_verbose("Found user '%s', but fails host access\n", user->name); 09643 ASTOBJ_UNREF(user,sip_destroy_user); 09644 } 09645 user = NULL; 09646 } 09647 09648 if (!user) { 09649 /* If we didn't find a user match, check for peers */ 09650 if (sipmethod == SIP_SUBSCRIBE) 09651 /* For subscribes, match on peer name only */ 09652 peer = find_peer(of, NULL, 1); 09653 else 09654 /* Look for peer based on the IP address we received data from */ 09655 /* If peer is registered from this IP address or have this as a default 09656 IP address, this call is from the peer 09657 */ 09658 peer = find_peer(NULL, &p->recv, 1); 09659 09660 if (peer) { 09661 /* Set Frame packetization */ 09662 if (p->rtp) { 09663 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09664 p->autoframing = peer->autoframing; 09665 } 09666 if (debug) 09667 ast_verbose("Found peer '%s'\n", peer->name); 09668 09669 /* Take the peer */ 09670 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09671 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09672 09673 /* Copy SIP extensions profile to peer */ 09674 if (p->sipoptions) 09675 peer->sipoptions = p->sipoptions; 09676 09677 /* replace callerid if rpid found, and not restricted */ 09678 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09679 char *tmp = ast_strdupa(rpid_num); 09680 if (*calleridname) 09681 ast_string_field_set(p, cid_name, calleridname); 09682 if (ast_is_shrinkable_phonenumber(tmp)) 09683 ast_shrink_phone_number(tmp); 09684 ast_string_field_set(p, cid_num, tmp); 09685 } 09686 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09687 09688 ast_string_field_set(p, peersecret, peer->secret); 09689 ast_string_field_set(p, peermd5secret, peer->md5secret); 09690 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09691 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09692 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09693 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09694 p->callingpres = peer->callingpres; 09695 if (peer->maxms && peer->lastms) 09696 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09697 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09698 /* Pretend there is no required authentication */ 09699 ast_string_field_free(p, peersecret); 09700 ast_string_field_free(p, peermd5secret); 09701 } 09702 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09703 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09704 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09705 /* If we have a call limit, set flag */ 09706 if (peer->call_limit) 09707 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09708 ast_string_field_set(p, peername, peer->name); 09709 ast_string_field_set(p, authname, peer->name); 09710 09711 /* copy channel vars */ 09712 for (v = peer->chanvars ; v ; v = v->next) { 09713 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09714 tmpvar->next = p->chanvars; 09715 p->chanvars = tmpvar; 09716 } 09717 } 09718 if (authpeer) { 09719 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09720 } 09721 09722 if (!ast_strlen_zero(peer->username)) { 09723 ast_string_field_set(p, username, peer->username); 09724 /* Use the default username for authentication on outbound calls */ 09725 /* XXX this takes the name from the caller... can we override ? */ 09726 ast_string_field_set(p, authname, peer->username); 09727 } 09728 if (!ast_strlen_zero(peer->cid_num)) { 09729 char *tmp = ast_strdupa(peer->cid_num); 09730 if (ast_is_shrinkable_phonenumber(tmp)) 09731 ast_shrink_phone_number(tmp); 09732 ast_string_field_set(p, cid_num, tmp); 09733 } 09734 if (!ast_strlen_zero(peer->cid_name)) 09735 ast_string_field_set(p, cid_name, peer->cid_name); 09736 ast_string_field_set(p, fullcontact, peer->fullcontact); 09737 if (!ast_strlen_zero(peer->context)) 09738 ast_string_field_set(p, context, peer->context); 09739 ast_string_field_set(p, peersecret, peer->secret); 09740 ast_string_field_set(p, peermd5secret, peer->md5secret); 09741 ast_string_field_set(p, language, peer->language); 09742 ast_string_field_set(p, accountcode, peer->accountcode); 09743 p->amaflags = peer->amaflags; 09744 p->callgroup = peer->callgroup; 09745 p->pickupgroup = peer->pickupgroup; 09746 p->capability = peer->capability; 09747 p->prefs = peer->prefs; 09748 p->jointcapability = peer->capability; 09749 if (p->peercapability) 09750 p->jointcapability &= p->peercapability; 09751 p->maxcallbitrate = peer->maxcallbitrate; 09752 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09753 ast_rtp_destroy(p->vrtp); 09754 p->vrtp = NULL; 09755 } 09756 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09757 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09758 p->noncodeccapability |= AST_RTP_DTMF; 09759 else 09760 p->noncodeccapability &= ~AST_RTP_DTMF; 09761 p->jointnoncodeccapability = p->noncodeccapability; 09762 if (p->t38.peercapability) 09763 p->t38.jointcapability &= p->t38.peercapability; 09764 } 09765 ASTOBJ_UNREF(peer, sip_destroy_peer); 09766 } else { 09767 if (debug) 09768 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09769 09770 /* do we allow guests? */ 09771 if (!global_allowguest) { 09772 if (global_alwaysauthreject) 09773 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09774 else 09775 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09776 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09777 char *tmp = ast_strdupa(rpid_num); 09778 if (*calleridname) 09779 ast_string_field_set(p, cid_name, calleridname); 09780 if (ast_is_shrinkable_phonenumber(tmp)) 09781 ast_shrink_phone_number(tmp); 09782 ast_string_field_set(p, cid_num, tmp); 09783 } 09784 } 09785 09786 } 09787 09788 if (user) 09789 ASTOBJ_UNREF(user, sip_destroy_user); 09790 return res; 09791 }
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 9344 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().
09345 { 09346 char via[512]; 09347 char *c, *pt; 09348 struct hostent *hp; 09349 struct ast_hostent ahp; 09350 09351 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09352 09353 /* Work on the leftmost value of the topmost Via header */ 09354 c = strchr(via, ','); 09355 if (c) 09356 *c = '\0'; 09357 09358 /* Check for rport */ 09359 c = strstr(via, ";rport"); 09360 if (c && (c[6] != '=')) /* rport query, not answer */ 09361 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09362 09363 c = strchr(via, ';'); 09364 if (c) 09365 *c = '\0'; 09366 09367 c = strchr(via, ' '); 09368 if (c) { 09369 *c = '\0'; 09370 c = ast_skip_blanks(c+1); 09371 if (strcasecmp(via, "SIP/2.0/UDP")) { 09372 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09373 return; 09374 } 09375 pt = strchr(c, ':'); 09376 if (pt) 09377 *pt++ = '\0'; /* remember port pointer */ 09378 hp = ast_gethostbyname(c, &ahp); 09379 if (!hp) { 09380 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09381 return; 09382 } 09383 memset(&p->sa, 0, sizeof(p->sa)); 09384 p->sa.sin_family = AF_INET; 09385 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09386 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09387 09388 if (sip_debug_test_pvt(p)) { 09389 const struct sockaddr_in *dst = sip_real_dst(p); 09390 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09391 } 09392 } 09393 }
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 10240 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
10241 { 10242 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10243 10244 while ((oldcontext = strsep(&old, "&"))) { 10245 stalecontext = '\0'; 10246 ast_copy_string(newlist, new, sizeof(newlist)); 10247 stringp = newlist; 10248 while ((newcontext = strsep(&stringp, "&"))) { 10249 if (strcmp(newcontext, oldcontext) == 0) { 10250 /* This is not the context you're looking for */ 10251 stalecontext = '\0'; 10252 break; 10253 } else if (strcmp(newcontext, oldcontext)) { 10254 stalecontext = oldcontext; 10255 } 10256 10257 } 10258 if (stalecontext) 10259 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10260 } 10261 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16838 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16839 { 16840 struct sip_auth *a = authlist; 16841 struct sip_auth *b; 16842 16843 while (a) { 16844 b = a; 16845 a = a->next; 16846 free(b); 16847 } 16848 16849 return 1; 16850 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16767 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().
16768 { 16769 struct domain *d; 16770 16771 AST_LIST_LOCK(&domain_list); 16772 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16773 free(d); 16774 AST_LIST_UNLOCK(&domain_list); 16775 }
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 11052 of file chan_sip.c.
References complete_sip_peer().
11053 { 11054 if (pos == 3) 11055 return complete_sip_peer(word, state, 0); 11056 11057 return NULL; 11058 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11026 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().
11027 { 11028 char *result = NULL; 11029 int wordlen = strlen(word); 11030 int which = 0; 11031 11032 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11033 /* locking of the object is not required because only the name and flags are being compared */ 11034 if (!strncasecmp(word, iterator->name, wordlen) && 11035 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11036 ++which > state) 11037 result = ast_strdup(iterator->name); 11038 } while(0) ); 11039 return result; 11040 }
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 11120 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11121 { 11122 if (pos == 4) 11123 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11124 return NULL; 11125 }
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 11128 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11129 { 11130 if (pos == 4) 11131 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11132 11133 return NULL; 11134 }
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 11043 of file chan_sip.c.
References complete_sip_peer().
11044 { 11045 if (pos == 3) 11046 return complete_sip_peer(word, state, 0); 11047 11048 return NULL; 11049 }
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 11081 of file chan_sip.c.
References complete_sip_user().
11082 { 11083 if (pos == 3) 11084 return complete_sip_user(word, state, 0); 11085 11086 return NULL; 11087 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11061 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().
11062 { 11063 char *result = NULL; 11064 int wordlen = strlen(word); 11065 int which = 0; 11066 11067 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11068 /* locking of the object is not required because only the name and flags are being compared */ 11069 if (!strncasecmp(word, iterator->name, wordlen)) { 11070 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11071 continue; 11072 if (++which > state) { 11073 result = ast_strdup(iterator->name); 11074 } 11075 } 11076 } while(0) ); 11077 return result; 11078 }
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 11003 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, iflist, and sip_pvt::next.
11004 { 11005 int which=0; 11006 struct sip_pvt *cur; 11007 char *c = NULL; 11008 int wordlen = strlen(word); 11009 11010 if (pos != 3) { 11011 return NULL; 11012 } 11013 11014 ast_mutex_lock(&iflock); 11015 for (cur = iflist; cur; cur = cur->next) { 11016 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11017 c = ast_strdup(cur->callid); 11018 break; 11019 } 11020 } 11021 ast_mutex_unlock(&iflock); 11022 return c; 11023 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11090 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11091 { 11092 char *c = NULL; 11093 11094 if (pos == 2) { 11095 int which = 0; 11096 char *cat = NULL; 11097 int wordlen = strlen(word); 11098 11099 /* do completion for notify type */ 11100 11101 if (!notify_types) 11102 return NULL; 11103 11104 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11105 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11106 c = ast_strdup(cat); 11107 break; 11108 } 11109 } 11110 return c; 11111 } 11112 11113 if (pos > 2) 11114 return complete_sip_peer(word, state, 0); 11115 11116 return NULL; 11117 }
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 5675 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05676 { 05677 int start = 0; 05678 int copied = 0; 05679 for (;;) { 05680 const char *tmp = __get_header(orig, field, &start); 05681 05682 if (ast_strlen_zero(tmp)) 05683 break; 05684 /* Add what we're responding to */ 05685 add_header(req, field, tmp); 05686 copied++; 05687 } 05688 return copied ? 0 : -1; 05689 }
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 5664 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05665 { 05666 const char *tmp = get_header(orig, field); 05667 05668 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05669 return add_header(req, field, tmp); 05670 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05671 return -1; 05672 }
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 6718 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().
06719 { 06720 long offset; 06721 int x; 06722 offset = ((void *)dst) - ((void *)src); 06723 /* First copy stuff */ 06724 memcpy(dst, src, sizeof(*dst)); 06725 /* Now fix pointer arithmetic */ 06726 for (x=0; x < src->headers; x++) 06727 dst->header[x] += offset; 06728 for (x=0; x < src->lines; x++) 06729 dst->line[x] += offset; 06730 dst->rlPart1 += offset; 06731 dst->rlPart2 += offset; 06732 }
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 5697 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().
05698 { 05699 int copied = 0; 05700 int start = 0; 05701 05702 for (;;) { 05703 char new[512]; 05704 const char *oh = __get_header(orig, field, &start); 05705 05706 if (ast_strlen_zero(oh)) 05707 break; 05708 05709 if (!copied) { /* Only check for empty rport in topmost via header */ 05710 char leftmost[512], *others, *rport; 05711 05712 /* Only work on leftmost value */ 05713 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05714 others = strchr(leftmost, ','); 05715 if (others) 05716 *others++ = '\0'; 05717 05718 /* Find ;rport; (empty request) */ 05719 rport = strstr(leftmost, ";rport"); 05720 if (rport && *(rport+6) == '=') 05721 rport = NULL; /* We already have a parameter to rport */ 05722 05723 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05724 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05725 /* We need to add received port - rport */ 05726 char *end; 05727 05728 rport = strstr(leftmost, ";rport"); 05729 05730 if (rport) { 05731 end = strchr(rport + 1, ';'); 05732 if (end) 05733 memmove(rport, end, strlen(end) + 1); 05734 else 05735 *rport = '\0'; 05736 } 05737 05738 /* Add rport to first VIA header if requested */ 05739 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05740 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05741 ntohs(p->recv.sin_port), 05742 others ? "," : "", others ? others : ""); 05743 } else { 05744 /* We should *always* add a received to the topmost via */ 05745 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05746 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05747 others ? "," : "", others ? others : ""); 05748 } 05749 oh = new; /* the header to copy */ 05750 } /* else add the following via headers untouched */ 05751 add_header(req, field, oh); 05752 copied++; 05753 } 05754 if (!copied) { 05755 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05756 return -1; 05757 } 05758 return 0; 05759 }
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 7898 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().
07899 { 07900 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07901 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07902 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07903 else 07904 ast_db_del("SIP/Registry", peer->name); 07905 } 07906 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6762 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06763 { 06764 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06765 06766 if (!*e) 06767 return -1; 06768 req->rlPart1 = e; /* method or protocol */ 06769 e = ast_skip_nonblanks(e); 06770 if (*e) 06771 *e++ = '\0'; 06772 /* Get URI or status code */ 06773 e = ast_skip_blanks(e); 06774 if ( !*e ) 06775 return -1; 06776 ast_trim_blanks(e); 06777 06778 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06779 if (strlen(e) < 3) /* status code is 3 digits */ 06780 return -1; 06781 req->rlPart2 = e; 06782 } else { /* We have a request */ 06783 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06784 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06785 e++; 06786 if (!*e) 06787 return -1; 06788 } 06789 req->rlPart2 = e; /* URI */ 06790 e = ast_skip_nonblanks(e); 06791 if (*e) 06792 *e++ = '\0'; 06793 e = ast_skip_blanks(e); 06794 if (strcasecmp(e, "SIP/2.0") ) { 06795 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06796 return -1; 06797 } 06798 } 06799 return 1; 06800 }
static void display_nat_warning | ( | const char * | cat, | |
int | reason, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 17307 of file chan_sip.c.
References ast_log(), ast_test_flag, CHANNEL_MODULE_LOAD, LOG_WARNING, nat2str(), and SIP_NAT.
Referenced by reload_config().
17307 { 17308 int global_nat, specific_nat; 17309 17310 if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT))) { 17311 ast_log(LOG_WARNING, "sip.conf: Different 'nat' settings between [general] and section [%s]. See /usr/share/doc/asterisk/README.Debian.gz (global='%s' peer/user='%s')\n", 17312 cat, nat2str(global_nat), nat2str(specific_nat)); 17313 } 17314 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16057 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.
16058 { 16059 int res; 16060 struct sip_pvt *sip; 16061 struct sip_peer *peer = NULL; 16062 time_t t; 16063 int fastrestart = FALSE; 16064 int lastpeernum = -1; 16065 int curpeernum; 16066 int reloading; 16067 16068 /* Add an I/O event to our SIP UDP socket */ 16069 if (sipsock > -1) 16070 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16071 16072 /* From here on out, we die whenever asked */ 16073 for(;;) { 16074 /* Check for a reload request */ 16075 ast_mutex_lock(&sip_reload_lock); 16076 reloading = sip_reloading; 16077 sip_reloading = FALSE; 16078 ast_mutex_unlock(&sip_reload_lock); 16079 if (reloading) { 16080 if (option_verbose > 0) 16081 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16082 sip_do_reload(sip_reloadreason); 16083 16084 /* Change the I/O fd of our UDP socket */ 16085 if (sipsock > -1) { 16086 if (sipsock_read_id) 16087 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16088 else 16089 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16090 } else if (sipsock_read_id) { 16091 ast_io_remove(io, sipsock_read_id); 16092 sipsock_read_id = NULL; 16093 } 16094 } 16095 restartsearch: 16096 /* Check for interfaces needing to be killed */ 16097 ast_mutex_lock(&iflock); 16098 t = time(NULL); 16099 /* don't scan the interface list if it hasn't been a reasonable period 16100 of time since the last time we did it (when MWI is being sent, we can 16101 get back to this point every millisecond or less) 16102 */ 16103 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16104 /*! \note If we can't get a lock on an interface, skip it and come 16105 * back later. Note that there is the possibility of a deadlock with 16106 * sip_hangup otherwise, because sip_hangup is called with the channel 16107 * locked first, and the iface lock is attempted second. 16108 */ 16109 if (ast_mutex_trylock(&sip->lock)) 16110 continue; 16111 16112 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16113 if (sip->rtp && sip->owner && 16114 (sip->owner->_state == AST_STATE_UP) && 16115 !sip->redirip.sin_addr.s_addr && 16116 sip->t38.state != T38_ENABLED) { 16117 if (sip->lastrtptx && 16118 ast_rtp_get_rtpkeepalive(sip->rtp) && 16119 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16120 /* Need to send an empty RTP packet */ 16121 sip->lastrtptx = time(NULL); 16122 ast_rtp_sendcng(sip->rtp, 0); 16123 } 16124 if (sip->lastrtprx && 16125 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16126 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16127 /* Might be a timeout now -- see if we're on hold */ 16128 struct sockaddr_in sin; 16129 ast_rtp_get_peer(sip->rtp, &sin); 16130 if (sin.sin_addr.s_addr || 16131 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16132 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16133 /* Needs a hangup */ 16134 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16135 while (sip->owner && ast_channel_trylock(sip->owner)) { 16136 DEADLOCK_AVOIDANCE(&sip->lock); 16137 } 16138 if (sip->owner) { 16139 ast_log(LOG_NOTICE, 16140 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16141 sip->owner->name, 16142 (long) (t - sip->lastrtprx)); 16143 /* Issue a softhangup */ 16144 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16145 ast_channel_unlock(sip->owner); 16146 /* forget the timeouts for this call, since a hangup 16147 has already been requested and we don't want to 16148 repeatedly request hangups 16149 */ 16150 ast_rtp_set_rtptimeout(sip->rtp, 0); 16151 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16152 if (sip->vrtp) { 16153 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16154 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16155 } 16156 } 16157 } 16158 } 16159 } 16160 } 16161 /* If we have sessions that needs to be destroyed, do it now */ 16162 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16163 !sip->owner) { 16164 ast_mutex_unlock(&sip->lock); 16165 __sip_destroy(sip, 1); 16166 ast_mutex_unlock(&iflock); 16167 usleep(1); 16168 goto restartsearch; 16169 } 16170 ast_mutex_unlock(&sip->lock); 16171 } 16172 ast_mutex_unlock(&iflock); 16173 16174 pthread_testcancel(); 16175 /* Wait for sched or io */ 16176 res = ast_sched_wait(sched); 16177 if ((res < 0) || (res > 1000)) 16178 res = 1000; 16179 /* If we might need to send more mailboxes, don't wait long at all.*/ 16180 if (fastrestart) 16181 res = 1; 16182 res = ast_io_wait(io, res); 16183 if (option_debug && res > 20) 16184 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16185 ast_mutex_lock(&monlock); 16186 if (res >= 0) { 16187 res = ast_sched_runq(sched); 16188 if (option_debug && res >= 20) 16189 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16190 } 16191 16192 /* Send MWI notifications to peers - static and cached realtime peers */ 16193 t = time(NULL); 16194 fastrestart = FALSE; 16195 curpeernum = 0; 16196 peer = NULL; 16197 /* Find next peer that needs mwi */ 16198 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16199 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16200 fastrestart = TRUE; 16201 lastpeernum = curpeernum; 16202 peer = ASTOBJ_REF(iterator); 16203 }; 16204 curpeernum++; 16205 } while (0) 16206 ); 16207 /* Send MWI to the peer */ 16208 if (peer) { 16209 ASTOBJ_WRLOCK(peer); 16210 sip_send_mwi_to_peer(peer); 16211 ASTOBJ_UNLOCK(peer); 16212 ASTOBJ_UNREF(peer,sip_destroy_peer); 16213 } else { 16214 /* Reset where we come from */ 16215 lastpeernum = -1; 16216 } 16217 ast_mutex_unlock(&monlock); 16218 } 16219 /* Never reached */ 16220 return NULL; 16221 16222 }
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 11593 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().
11594 { 11595 char digest[1024]; 11596 11597 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11598 return -2; 11599 11600 p->authtries++; 11601 if (option_debug > 1) 11602 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11603 memset(digest, 0, sizeof(digest)); 11604 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11605 /* No way to authenticate */ 11606 return -1; 11607 } 11608 /* Now we have a reply digest */ 11609 p->options->auth = digest; 11610 p->options->authheader = respheader; 11611 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11612 }
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 11572 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().
11573 { 11574 char digest[1024]; 11575 p->authtries++; 11576 memset(digest,0,sizeof(digest)); 11577 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11578 /* There's nothing to use for authentication */ 11579 /* No digest challenge in request */ 11580 if (sip_debug_test_pvt(p) && p->registry) 11581 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11582 /* No old challenge */ 11583 return -1; 11584 } 11585 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11586 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11587 if (sip_debug_test_pvt(p) && p->registry) 11588 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11589 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11590 }
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 16036 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().
16037 { 16038 time_t t = time(NULL); 16039 16040 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16041 !peer->mwipvt) { /* We don't have a subscription */ 16042 peer->lastmsgcheck = t; /* Reset timer */ 16043 return FALSE; 16044 } 16045 16046 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16047 return TRUE; 16048 16049 return FALSE; 16050 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10429 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10430 { 10431 switch (mode) { 10432 case SIP_DOMAIN_AUTO: 10433 return "[Automatic]"; 10434 case SIP_DOMAIN_CONFIG: 10435 return "[Configured]"; 10436 } 10437 10438 return ""; 10439 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 10209 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().
10210 { 10211 switch (mode) { 10212 case SIP_DTMF_RFC2833: 10213 return "rfc2833"; 10214 case SIP_DTMF_INFO: 10215 return "info"; 10216 case SIP_DTMF_INBAND: 10217 return "inband"; 10218 case SIP_DTMF_AUTO: 10219 return "auto"; 10220 } 10221 return "<error>"; 10222 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7909 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().
07910 { 07911 struct sip_peer *peer = (struct sip_peer *)data; 07912 07913 if (!peer) /* Hmmm. We have no peer. Weird. */ 07914 return 0; 07915 07916 memset(&peer->addr, 0, sizeof(peer->addr)); 07917 07918 destroy_association(peer); /* remove registration data from storage */ 07919 07920 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07921 register_peer_exten(peer, FALSE); /* Remove regexten */ 07922 peer->expire = -1; 07923 ast_device_state_changed("SIP/%s", peer->name); 07924 07925 /* Do we need to release this peer from memory? 07926 Only for realtime peers and autocreated peers 07927 */ 07928 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07929 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07930 struct sip_peer *peer_ptr = peer_ptr; 07931 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 07932 if (peer_ptr) { 07933 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 07934 } 07935 } 07936 07937 ASTOBJ_UNREF(peer, sip_destroy_peer); 07938 07939 return 0; 07940 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6852 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().
06853 { 06854 char stripped[SIPBUFSIZE]; 06855 char *c; 06856 06857 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06858 c = get_in_brackets(stripped); 06859 c = strsep(&c, ";"); /* trim ; and beyond */ 06860 if (!ast_strlen_zero(c)) 06861 ast_string_field_set(p, uri, c); 06862 }
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 4214 of file chan_sip.c.
References aliases.
04215 { 04216 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04217 static const struct cfalias { 04218 char * const fullname; 04219 char * const shortname; 04220 } aliases[] = { 04221 { "Content-Type", "c" }, 04222 { "Content-Encoding", "e" }, 04223 { "From", "f" }, 04224 { "Call-ID", "i" }, 04225 { "Contact", "m" }, 04226 { "Content-Length", "l" }, 04227 { "Subject", "s" }, 04228 { "To", "t" }, 04229 { "Supported", "k" }, 04230 { "Refer-To", "r" }, 04231 { "Referred-By", "b" }, 04232 { "Allow-Events", "u" }, 04233 { "Event", "o" }, 04234 { "Via", "v" }, 04235 { "Accept-Contact", "a" }, 04236 { "Reject-Contact", "j" }, 04237 { "Request-Disposition", "d" }, 04238 { "Session-Expires", "x" }, 04239 { "Identity", "y" }, 04240 { "Identity-Info", "n" }, 04241 }; 04242 int x; 04243 04244 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04245 if (!strcasecmp(aliases[x].fullname, name)) 04246 return aliases[x].shortname; 04247 04248 return _default; 04249 }
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 4573 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().
04574 { 04575 struct sip_pvt *p = NULL; 04576 char *tag = ""; /* note, tag is never NULL */ 04577 char totag[128]; 04578 char fromtag[128]; 04579 const char *callid = get_header(req, "Call-ID"); 04580 const char *from = get_header(req, "From"); 04581 const char *to = get_header(req, "To"); 04582 const char *cseq = get_header(req, "Cseq"); 04583 04584 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04585 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04586 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04587 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04588 return NULL; /* Invalid packet */ 04589 04590 if (pedanticsipchecking) { 04591 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04592 we need more to identify a branch - so we have to check branch, from 04593 and to tags to identify a call leg. 04594 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04595 in sip.conf 04596 */ 04597 if (gettag(req, "To", totag, sizeof(totag))) 04598 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04599 gettag(req, "From", fromtag, sizeof(fromtag)); 04600 04601 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04602 04603 if (option_debug > 4 ) 04604 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); 04605 } 04606 04607 ast_mutex_lock(&iflock); 04608 for (p = iflist; p; p = p->next) { 04609 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04610 int found = FALSE; 04611 if (ast_strlen_zero(p->callid)) 04612 continue; 04613 if (req->method == SIP_REGISTER) 04614 found = (!strcmp(p->callid, callid)); 04615 else 04616 found = (!strcmp(p->callid, callid) && 04617 (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04618 04619 if (option_debug > 4) 04620 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); 04621 04622 /* If we get a new request within an existing to-tag - check the to tag as well */ 04623 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04624 if (p->tag[0] == '\0' && totag[0]) { 04625 /* We have no to tag, but they have. Wrong dialog */ 04626 found = FALSE; 04627 } else if (totag[0]) { /* Both have tags, compare them */ 04628 if (strcmp(totag, p->tag)) { 04629 found = FALSE; /* This is not our packet */ 04630 } 04631 } 04632 if (!found && option_debug > 4) 04633 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); 04634 } 04635 if (found) { 04636 /* Found the call */ 04637 ast_mutex_lock(&p->lock); 04638 ast_mutex_unlock(&iflock); 04639 return p; 04640 } 04641 } 04642 ast_mutex_unlock(&iflock); 04643 04644 /* See if the method is capable of creating a dialog */ 04645 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04646 if (intended_method == SIP_REFER) { 04647 /* We do support REFER, but not outside of a dialog yet */ 04648 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04649 } else if (intended_method == SIP_NOTIFY) { 04650 /* We do not support out-of-dialog NOTIFY either, 04651 like voicemail notification, so cancel that early */ 04652 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04653 } else { 04654 /* Ok, time to create a new SIP dialog object, a pvt */ 04655 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04656 /* Ok, we've created a dialog, let's go and process it */ 04657 ast_mutex_lock(&p->lock); 04658 } else { 04659 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04660 getting a dialog from sip_alloc. 04661 04662 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04663 send an error message. 04664 04665 Sorry, we apologize for the inconvienience 04666 */ 04667 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04668 if (option_debug > 3) 04669 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04670 } 04671 } 04672 return p; 04673 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04674 /* A method we do not support, let's take it on the volley */ 04675 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04676 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04677 /* This is a request outside of a dialog that we don't know about 04678 ...never reply to an ACK! 04679 */ 04680 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04681 } 04682 /* We do not respond to responses for dialogs that we don't know about, we just drop 04683 the session quickly */ 04684 04685 return p; 04686 }
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 16853 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16854 { 16855 struct sip_auth *a; 16856 16857 for (a = authlist; a; a = a->next) { 16858 if (!strcasecmp(a->realm, realm)) 16859 break; 16860 } 16861 16862 return a; 16863 }
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 4892 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().
04893 { 04894 const char *content_type; 04895 const char *content_length; 04896 const char *search; 04897 char *boundary; 04898 unsigned int x; 04899 int boundaryisquoted = FALSE; 04900 int found_application_sdp = FALSE; 04901 int found_end_of_headers = FALSE; 04902 04903 content_length = get_header(req, "Content-Length"); 04904 04905 if (!ast_strlen_zero(content_length)) { 04906 if (sscanf(content_length, "%ud", &x) != 1) { 04907 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04908 return 0; 04909 } 04910 04911 /* Content-Length of zero means there can't possibly be an 04912 SDP here, even if the Content-Type says there is */ 04913 if (x == 0) 04914 return 0; 04915 } 04916 04917 content_type = get_header(req, "Content-Type"); 04918 04919 /* if the body contains only SDP, this is easy */ 04920 if (!strcasecmp(content_type, "application/sdp")) { 04921 req->sdp_start = 0; 04922 req->sdp_end = req->lines; 04923 return req->lines ? 1 : 0; 04924 } 04925 04926 /* if it's not multipart/mixed, there cannot be an SDP */ 04927 if (strncasecmp(content_type, "multipart/mixed", 15)) 04928 return 0; 04929 04930 /* if there is no boundary marker, it's invalid */ 04931 if ((search = strcasestr(content_type, ";boundary="))) 04932 search += 10; 04933 else if ((search = strcasestr(content_type, "; boundary="))) 04934 search += 11; 04935 else 04936 return 0; 04937 04938 if (ast_strlen_zero(search)) 04939 return 0; 04940 04941 /* If the boundary is quoted with ", remove quote */ 04942 if (*search == '\"') { 04943 search++; 04944 boundaryisquoted = TRUE; 04945 } 04946 04947 /* make a duplicate of the string, with two extra characters 04948 at the beginning */ 04949 boundary = ast_strdupa(search - 2); 04950 boundary[0] = boundary[1] = '-'; 04951 /* Remove final quote */ 04952 if (boundaryisquoted) 04953 boundary[strlen(boundary) - 1] = '\0'; 04954 04955 /* search for the boundary marker, the empty line delimiting headers from 04956 sdp part and the end boundry if it exists */ 04957 04958 for (x = 0; x < (req->lines ); x++) { 04959 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04960 if(found_application_sdp && found_end_of_headers){ 04961 req->sdp_end = x-1; 04962 return 1; 04963 } 04964 found_application_sdp = FALSE; 04965 } 04966 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04967 found_application_sdp = TRUE; 04968 04969 if(strlen(req->line[x]) == 0 ){ 04970 if(found_application_sdp && !found_end_of_headers){ 04971 req->sdp_start = x; 04972 found_end_of_headers = TRUE; 04973 } 04974 } 04975 } 04976 if(found_application_sdp && found_end_of_headers) { 04977 req->sdp_end = x; 04978 return TRUE; 04979 } 04980 return FALSE; 04981 }
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 10917 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10918 { 10919 int i; 10920 10921 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10922 if (subscription_types[i].type == subtype) { 10923 return &subscription_types[i]; 10924 } 10925 } 10926 return &subscription_types[0]; 10927 }
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 8269 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08270 { 08271 struct sip_route *next; 08272 08273 while (route) { 08274 next = route->next; 08275 free(route); 08276 route = next; 08277 } 08278 }
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 11926 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11927 { 11928 if (ast_strlen_zero(data)) { 11929 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11930 return -1; 11931 } 11932 if (check_sip_domain(data, NULL, 0)) 11933 ast_copy_string(buf, data, len); 11934 else 11935 buf[0] = '\0'; 11936 return 0; 11937 }
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 11862 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.
11863 { 11864 struct sip_pvt *p; 11865 const char *content = NULL; 11866 AST_DECLARE_APP_ARGS(args, 11867 AST_APP_ARG(header); 11868 AST_APP_ARG(number); 11869 ); 11870 int i, number, start = 0; 11871 11872 if (ast_strlen_zero(data)) { 11873 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11874 return -1; 11875 } 11876 11877 ast_channel_lock(chan); 11878 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11879 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11880 ast_channel_unlock(chan); 11881 return -1; 11882 } 11883 11884 AST_STANDARD_APP_ARGS(args, data); 11885 if (!args.number) { 11886 number = 1; 11887 } else { 11888 sscanf(args.number, "%d", &number); 11889 if (number < 1) 11890 number = 1; 11891 } 11892 11893 p = chan->tech_pvt; 11894 11895 /* If there is no private structure, this channel is no longer alive */ 11896 if (!p) { 11897 ast_channel_unlock(chan); 11898 return -1; 11899 } 11900 11901 for (i = 0; i < number; i++) 11902 content = __get_header(&p->initreq, args.header, &start); 11903 11904 if (ast_strlen_zero(content)) { 11905 ast_channel_unlock(chan); 11906 return -1; 11907 } 11908 11909 ast_copy_string(buf, content, len); 11910 ast_channel_unlock(chan); 11911 11912 return 0; 11913 }
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 12041 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.
12042 { 12043 struct sip_pvt *p; 12044 12045 *buf = 0; 12046 12047 if (!data) { 12048 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12049 return -1; 12050 } 12051 12052 ast_channel_lock(chan); 12053 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12054 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12055 ast_channel_unlock(chan); 12056 return -1; 12057 } 12058 12059 p = chan->tech_pvt; 12060 12061 /* If there is no private structure, this channel is no longer alive */ 12062 if (!p) { 12063 ast_channel_unlock(chan); 12064 return -1; 12065 } 12066 12067 if (!strcasecmp(data, "peerip")) { 12068 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12069 } else if (!strcasecmp(data, "recvip")) { 12070 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12071 } else if (!strcasecmp(data, "from")) { 12072 ast_copy_string(buf, p->from, len); 12073 } else if (!strcasecmp(data, "uri")) { 12074 ast_copy_string(buf, p->uri, len); 12075 } else if (!strcasecmp(data, "useragent")) { 12076 ast_copy_string(buf, p->useragent, len); 12077 } else if (!strcasecmp(data, "peername")) { 12078 ast_copy_string(buf, p->peername, len); 12079 } else if (!strcasecmp(data, "t38passthrough")) { 12080 if (p->t38.state == T38_DISABLED) 12081 ast_copy_string(buf, "0", sizeof("0")); 12082 else /* T38 is offered or enabled in this call */ 12083 ast_copy_string(buf, "1", sizeof("1")); 12084 } else { 12085 ast_channel_unlock(chan); 12086 return -1; 12087 } 12088 ast_channel_unlock(chan); 12089 12090 return 0; 12091 }
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 11951 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.
11952 { 11953 struct sip_peer *peer; 11954 char *colname; 11955 11956 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11957 *colname++ = '\0'; 11958 else if ((colname = strchr(data, '|'))) 11959 *colname++ = '\0'; 11960 else 11961 colname = "ip"; 11962 11963 if (!(peer = find_peer(data, NULL, 1))) 11964 return -1; 11965 11966 if (!strcasecmp(colname, "ip")) { 11967 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11968 } else if (!strcasecmp(colname, "status")) { 11969 peer_status(peer, buf, len); 11970 } else if (!strcasecmp(colname, "language")) { 11971 ast_copy_string(buf, peer->language, len); 11972 } else if (!strcasecmp(colname, "regexten")) { 11973 ast_copy_string(buf, peer->regexten, len); 11974 } else if (!strcasecmp(colname, "limit")) { 11975 snprintf(buf, len, "%d", peer->call_limit); 11976 } else if (!strcasecmp(colname, "curcalls")) { 11977 snprintf(buf, len, "%d", peer->inUse); 11978 } else if (!strcasecmp(colname, "accountcode")) { 11979 ast_copy_string(buf, peer->accountcode, len); 11980 } else if (!strcasecmp(colname, "useragent")) { 11981 ast_copy_string(buf, peer->useragent, len); 11982 } else if (!strcasecmp(colname, "mailbox")) { 11983 ast_copy_string(buf, peer->mailbox, len); 11984 } else if (!strcasecmp(colname, "context")) { 11985 ast_copy_string(buf, peer->context, len); 11986 } else if (!strcasecmp(colname, "expire")) { 11987 snprintf(buf, len, "%d", peer->expire); 11988 } else if (!strcasecmp(colname, "dynamic")) { 11989 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11990 } else if (!strcasecmp(colname, "callerid_name")) { 11991 ast_copy_string(buf, peer->cid_name, len); 11992 } else if (!strcasecmp(colname, "callerid_num")) { 11993 ast_copy_string(buf, peer->cid_num, len); 11994 } else if (!strcasecmp(colname, "codecs")) { 11995 ast_getformatname_multiple(buf, len -1, peer->capability); 11996 } else if (!strncasecmp(colname, "codec[", 6)) { 11997 char *codecnum; 11998 int index = 0, codec = 0; 11999 12000 codecnum = colname + 6; /* move past the '[' */ 12001 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12002 index = atoi(codecnum); 12003 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12004 ast_copy_string(buf, ast_getformatname(codec), len); 12005 } 12006 } 12007 12008 ASTOBJ_UNREF(peer, sip_destroy_peer); 12009 12010 return 0; 12011 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4404 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04405 { 04406 long val[4]; 04407 int x; 04408 04409 for (x=0; x<4; x++) 04410 val[x] = ast_random(); 04411 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04412 04413 return buf; 04414 }
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 9284 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().
09285 { 09286 char tmp[256] = "", *c, *a; 09287 struct sip_request *req = oreq ? oreq : &p->initreq; 09288 struct sip_refer *referdata = NULL; 09289 const char *transfer_context = NULL; 09290 09291 if (!p->refer && !sip_refer_allocate(p)) 09292 return -1; 09293 09294 referdata = p->refer; 09295 09296 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09297 c = get_in_brackets(tmp); 09298 09299 if (pedanticsipchecking) 09300 ast_uri_decode(c); 09301 09302 if (strncasecmp(c, "sip:", 4)) { 09303 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09304 return -1; 09305 } 09306 c += 4; 09307 if ((a = strchr(c, ';'))) /* Remove arguments */ 09308 *a = '\0'; 09309 09310 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09311 *a++ = '\0'; 09312 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09313 } 09314 09315 if (sip_debug_test_pvt(p)) 09316 ast_verbose("Looking for %s in %s\n", c, p->context); 09317 09318 if (p->owner) /* Mimic behaviour in res_features.c */ 09319 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09320 09321 /* By default, use the context in the channel sending the REFER */ 09322 if (ast_strlen_zero(transfer_context)) { 09323 transfer_context = S_OR(p->owner->macrocontext, 09324 S_OR(p->context, default_context)); 09325 } 09326 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09327 /* This is a blind transfer */ 09328 if (option_debug) 09329 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09330 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09331 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09332 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09333 referdata->refer_call = NULL; 09334 /* Set new context */ 09335 ast_string_field_set(p, context, transfer_context); 09336 return 0; 09337 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09338 return 1; 09339 } 09340 09341 return -1; 09342 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4198 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04199 { 04200 int x; 04201 int len = strlen(name); 04202 char *r; 04203 04204 for (x = 0; x < req->lines; x++) { 04205 r = get_body_by_line(req->line[x], name, len); 04206 if (r[0] != '\0') 04207 return r; 04208 } 04209 04210 return ""; 04211 }
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 4164 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04165 { 04166 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04167 return ast_skip_blanks(line + nameLen + 1); 04168 04169 return ""; 04170 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9396 of file chan_sip.c.
Referenced by check_user_full().
09397 { 09398 const char *end = strchr(input,'<'); /* first_bracket */ 09399 const char *tmp = strchr(input,'"'); /* first quote */ 09400 int bytes = 0; 09401 int maxbytes = outputsize - 1; 09402 09403 if (!end || end == input) /* we require a part in brackets */ 09404 return NULL; 09405 09406 end--; /* move just before "<" */ 09407 09408 if (tmp && tmp <= end) { 09409 /* The quote (tmp) precedes the bracket (end+1). 09410 * Find the matching quote and return the content. 09411 */ 09412 end = strchr(tmp+1, '"'); 09413 if (!end) 09414 return NULL; 09415 bytes = (int) (end - tmp); 09416 /* protect the output buffer */ 09417 if (bytes > maxbytes) 09418 bytes = maxbytes; 09419 ast_copy_string(output, tmp + 1, bytes); 09420 } else { 09421 /* No quoted string, or it is inside brackets. */ 09422 /* clear the empty characters in the begining*/ 09423 input = ast_skip_blanks(input); 09424 /* clear the empty characters in the end */ 09425 while(*end && *end < 33 && end > input) 09426 end--; 09427 if (end >= input) { 09428 bytes = (int) (end - input) + 2; 09429 /* protect the output buffer */ 09430 if (bytes > maxbytes) 09431 bytes = maxbytes; 09432 ast_copy_string(output, input, bytes); 09433 } else 09434 return NULL; 09435 } 09436 return output; 09437 }
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 8941 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().
08942 { 08943 char tmp[256] = "", *uri, *a; 08944 char tmpf[256] = "", *from; 08945 struct sip_request *req; 08946 char *colon; 08947 08948 req = oreq; 08949 if (!req) 08950 req = &p->initreq; 08951 08952 /* Find the request URI */ 08953 if (req->rlPart2) 08954 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08955 08956 if (pedanticsipchecking) 08957 ast_uri_decode(tmp); 08958 08959 uri = get_in_brackets(tmp); 08960 08961 if (strncasecmp(uri, "sip:", 4)) { 08962 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08963 return -1; 08964 } 08965 uri += 4; 08966 08967 /* Now find the From: caller ID and name */ 08968 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08969 if (!ast_strlen_zero(tmpf)) { 08970 if (pedanticsipchecking) 08971 ast_uri_decode(tmpf); 08972 from = get_in_brackets(tmpf); 08973 } else { 08974 from = NULL; 08975 } 08976 08977 if (!ast_strlen_zero(from)) { 08978 if (strncasecmp(from, "sip:", 4)) { 08979 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08980 return -1; 08981 } 08982 from += 4; 08983 if ((a = strchr(from, '@'))) 08984 *a++ = '\0'; 08985 else 08986 a = from; /* just a domain */ 08987 from = strsep(&from, ";"); /* Remove userinfo options */ 08988 a = strsep(&a, ";"); /* Remove URI options */ 08989 ast_string_field_set(p, fromdomain, a); 08990 } 08991 08992 /* Skip any options and find the domain */ 08993 08994 /* Get the target domain */ 08995 if ((a = strchr(uri, '@'))) { 08996 *a++ = '\0'; 08997 } else { /* No username part */ 08998 a = uri; 08999 uri = "s"; /* Set extension to "s" */ 09000 } 09001 colon = strchr(a, ':'); /* Remove :port */ 09002 if (colon) 09003 *colon = '\0'; 09004 09005 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09006 a = strsep(&a, ";"); /* Remove URI options */ 09007 09008 ast_string_field_set(p, domain, a); 09009 09010 if (!AST_LIST_EMPTY(&domain_list)) { 09011 char domain_context[AST_MAX_EXTENSION]; 09012 09013 domain_context[0] = '\0'; 09014 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09015 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09016 if (option_debug) 09017 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09018 return -2; 09019 } 09020 } 09021 /* If we have a context defined, overwrite the original context */ 09022 if (!ast_strlen_zero(domain_context)) 09023 ast_string_field_set(p, context, domain_context); 09024 } 09025 09026 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09027 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09028 ast_string_field_set(p, context, p->subscribecontext); 09029 09030 if (sip_debug_test_pvt(p)) 09031 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09032 09033 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09034 if (req->method == SIP_SUBSCRIBE) { 09035 char hint[AST_MAX_EXTENSION]; 09036 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09037 } else { 09038 /* Check the dialplan for the username part of the request URI, 09039 the domain will be stored in the SIPDOMAIN variable 09040 Since extensions.conf can have unescaped characters, try matching a decoded 09041 uri in addition to the non-decoded uri 09042 Return 0 if we have a matching extension */ 09043 char *decoded_uri = ast_strdupa(uri); 09044 ast_uri_decode(decoded_uri); 09045 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)) || 09046 !strcmp(uri, ast_pickup_ext())) { 09047 if (!oreq) 09048 ast_string_field_set(p, exten, uri); 09049 return 0; 09050 } 09051 } 09052 09053 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09054 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09055 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 09056 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 09057 return 1; 09058 } 09059 09060 return -1; 09061 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4287 of file chan_sip.c.
References __get_header().
04288 { 04289 int start = 0; 04290 return __get_header(req, name, &start); 04291 }
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 9802 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09803 { 09804 int x; 09805 int y; 09806 09807 buf[0] = '\0'; 09808 y = len - strlen(buf) - 5; 09809 if (y < 0) 09810 y = 0; 09811 for (x=0;x<req->lines;x++) { 09812 strncat(buf, req->line[x], y); /* safe */ 09813 y -= strlen(req->line[x]) + 1; 09814 if (y < 0) 09815 y = 0; 09816 if (y != 0) 09817 strcat(buf, "\n"); /* safe */ 09818 } 09819 return 0; 09820 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8912 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().
08913 { 08914 char tmp[256], *c, *a; 08915 struct sip_request *req; 08916 08917 req = oreq; 08918 if (!req) 08919 req = &p->initreq; 08920 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08921 if (ast_strlen_zero(tmp)) 08922 return 0; 08923 c = get_in_brackets(tmp); 08924 if (strncasecmp(c, "sip:", 4)) { 08925 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08926 return -1; 08927 } 08928 c += 4; 08929 a = c; 08930 strsep(&a, "@;"); /* trim anything after @ or ; */ 08931 if (sip_debug_test_pvt(p)) 08932 ast_verbose("RDNIS is %s\n", c); 08933 ast_string_field_set(p, rdnis, c); 08934 08935 return 0; 08936 }
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 9118 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().
09119 { 09120 09121 const char *p_referred_by = NULL; 09122 char *h_refer_to = NULL; 09123 char *h_referred_by = NULL; 09124 char *refer_to; 09125 const char *p_refer_to; 09126 char *referred_by_uri = NULL; 09127 char *ptr; 09128 struct sip_request *req = NULL; 09129 const char *transfer_context = NULL; 09130 struct sip_refer *referdata; 09131 09132 09133 req = outgoing_req; 09134 referdata = transferer->refer; 09135 09136 if (!req) 09137 req = &transferer->initreq; 09138 09139 p_refer_to = get_header(req, "Refer-To"); 09140 if (ast_strlen_zero(p_refer_to)) { 09141 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09142 return -2; /* Syntax error */ 09143 } 09144 h_refer_to = ast_strdupa(p_refer_to); 09145 refer_to = get_in_brackets(h_refer_to); 09146 if (pedanticsipchecking) 09147 ast_uri_decode(refer_to); 09148 09149 if (strncasecmp(refer_to, "sip:", 4)) { 09150 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09151 return -3; 09152 } 09153 refer_to += 4; /* Skip sip: */ 09154 09155 /* Get referred by header if it exists */ 09156 p_referred_by = get_header(req, "Referred-By"); 09157 if (!ast_strlen_zero(p_referred_by)) { 09158 char *lessthan; 09159 h_referred_by = ast_strdupa(p_referred_by); 09160 if (pedanticsipchecking) 09161 ast_uri_decode(h_referred_by); 09162 09163 /* Store referrer's caller ID name */ 09164 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09165 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09166 *(lessthan - 1) = '\0'; /* Space */ 09167 } 09168 09169 referred_by_uri = get_in_brackets(h_referred_by); 09170 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09171 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09172 referred_by_uri = (char *) NULL; 09173 } else { 09174 referred_by_uri += 4; /* Skip sip: */ 09175 } 09176 } 09177 09178 /* Check for arguments in the refer_to header */ 09179 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09180 *ptr++ = '\0'; 09181 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09182 char *to = NULL, *from = NULL; 09183 09184 /* This is an attended transfer */ 09185 referdata->attendedtransfer = 1; 09186 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09187 ast_uri_decode(referdata->replaces_callid); 09188 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09189 *ptr++ = '\0'; 09190 } 09191 09192 if (ptr) { 09193 /* Find the different tags before we destroy the string */ 09194 to = strcasestr(ptr, "to-tag="); 09195 from = strcasestr(ptr, "from-tag="); 09196 } 09197 09198 /* Grab the to header */ 09199 if (to) { 09200 ptr = to + 7; 09201 if ((to = strchr(ptr, '&'))) 09202 *to = '\0'; 09203 if ((to = strchr(ptr, ';'))) 09204 *to = '\0'; 09205 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09206 } 09207 09208 if (from) { 09209 ptr = from + 9; 09210 if ((to = strchr(ptr, '&'))) 09211 *to = '\0'; 09212 if ((to = strchr(ptr, ';'))) 09213 *to = '\0'; 09214 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09215 } 09216 09217 if (option_debug > 1) { 09218 if (!pedanticsipchecking) 09219 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09220 else 09221 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>" ); 09222 } 09223 } 09224 } 09225 09226 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09227 char *urioption = NULL, *domain; 09228 *ptr++ = '\0'; 09229 09230 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09231 *urioption++ = '\0'; 09232 09233 domain = ptr; 09234 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09235 *ptr = '\0'; 09236 09237 /* Save the domain for the dial plan */ 09238 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09239 if (urioption) 09240 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09241 } 09242 09243 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09244 *ptr = '\0'; 09245 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09246 09247 if (referred_by_uri) { 09248 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09249 *ptr = '\0'; 09250 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09251 } else { 09252 referdata->referred_by[0] = '\0'; 09253 } 09254 09255 /* Determine transfer context */ 09256 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09257 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09258 09259 /* By default, use the context in the channel sending the REFER */ 09260 if (ast_strlen_zero(transfer_context)) { 09261 transfer_context = S_OR(transferer->owner->macrocontext, 09262 S_OR(transferer->context, default_context)); 09263 } 09264 09265 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09266 09267 /* Either an existing extension or the parking extension */ 09268 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09269 if (sip_debug_test_pvt(transferer)) { 09270 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09271 } 09272 /* We are ready to transfer to the extension */ 09273 return 0; 09274 } 09275 if (sip_debug_test_pvt(transferer)) 09276 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09277 09278 /* Failure, we can't find this extension */ 09279 return -1; 09280 }
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 9443 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09444 { 09445 char *start; 09446 char *end; 09447 09448 start = strchr(input,':'); 09449 if (!start) { 09450 output[0] = '\0'; 09451 return 0; 09452 } 09453 start++; 09454 09455 /* we found "number" */ 09456 ast_copy_string(output,start,maxlen); 09457 output[maxlen-1] = '\0'; 09458 09459 end = strchr(output,'@'); 09460 if (end) 09461 *end = '\0'; 09462 else 09463 output[0] = '\0'; 09464 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09465 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09466 09467 return 0; 09468 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4190 of file chan_sip.c.
References get_sdp_iterate().
04191 { 04192 int dummy = 0; 04193 04194 return get_sdp_iterate(&dummy, req, name); 04195 }
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 4176 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04177 { 04178 int len = strlen(name); 04179 04180 while (*start < req->sdp_end) { 04181 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04182 if (r[0] != '\0') 04183 return r; 04184 } 04185 04186 return ""; 04187 }
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 9068 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().
09069 { 09070 struct sip_pvt *sip_pvt_ptr; 09071 09072 ast_mutex_lock(&iflock); 09073 09074 if (option_debug > 3 && totag) 09075 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09076 09077 /* Search interfaces and find the match */ 09078 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09079 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09080 int match = 1; 09081 char *ourtag = sip_pvt_ptr->tag; 09082 09083 /* Go ahead and lock it (and its owner) before returning */ 09084 ast_mutex_lock(&sip_pvt_ptr->lock); 09085 09086 /* Check if tags match. If not, this is not the call we want 09087 (With a forking SIP proxy, several call legs share the 09088 call id, but have different tags) 09089 */ 09090 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 09091 match = 0; 09092 09093 if (!match) { 09094 ast_mutex_unlock(&sip_pvt_ptr->lock); 09095 continue; 09096 } 09097 09098 if (option_debug > 3 && totag) 09099 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09100 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 09101 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09102 09103 /* deadlock avoidance... */ 09104 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09105 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09106 } 09107 break; 09108 } 09109 } 09110 ast_mutex_unlock(&iflock); 09111 if (option_debug > 3 && !sip_pvt_ptr) 09112 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09113 return sip_pvt_ptr; 09114 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13495 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13496 { 13497 const char *thetag; 13498 13499 if (!tagbuf) 13500 return NULL; 13501 tagbuf[0] = '\0'; /* reset the buffer */ 13502 thetag = get_header(req, header); 13503 thetag = strcasestr(thetag, ";tag="); 13504 if (thetag) { 13505 thetag += 5; 13506 ast_copy_string(tagbuf, thetag, tagbufsize); 13507 return strsep(&tagbuf, ";"); 13508 } 13509 return NULL; 13510 }
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 16603 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_set_flags_to, 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().
16604 { 16605 int res = 1; 16606 16607 if (!strcasecmp(v->name, "trustrpid")) { 16608 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16609 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16610 } else if (!strcasecmp(v->name, "sendrpid")) { 16611 ast_set_flag(&mask[0], SIP_SENDRPID); 16612 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16613 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16614 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16615 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16616 } else if (!strcasecmp(v->name, "useclientcode")) { 16617 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16618 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16619 } else if (!strcasecmp(v->name, "dtmfmode")) { 16620 ast_set_flag(&mask[0], SIP_DTMF); 16621 ast_clear_flag(&flags[0], SIP_DTMF); 16622 if (!strcasecmp(v->value, "inband")) 16623 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16624 else if (!strcasecmp(v->value, "rfc2833")) 16625 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16626 else if (!strcasecmp(v->value, "info")) 16627 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16628 else if (!strcasecmp(v->value, "auto")) 16629 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16630 else { 16631 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16632 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16633 } 16634 } else if (!strcasecmp(v->name, "nat")) { 16635 ast_set_flag(&mask[0], SIP_NAT); 16636 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16637 if (!strcasecmp(v->value, "never")) { 16638 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_NEVER); 16639 } else if (!strcasecmp(v->value, "route")) { 16640 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_ROUTE); 16641 } else if (ast_false(v->value)) { 16642 ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_RFC3581); 16643 } 16644 } else if (!strcasecmp(v->name, "canreinvite")) { 16645 ast_set_flag(&mask[0], SIP_REINVITE); 16646 ast_clear_flag(&flags[0], SIP_REINVITE); 16647 if(ast_true(v->value)) { 16648 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16649 } else if (!ast_false(v->value)) { 16650 char buf[64]; 16651 char *word, *next = buf; 16652 16653 ast_copy_string(buf, v->value, sizeof(buf)); 16654 while ((word = strsep(&next, ","))) { 16655 if(!strcasecmp(word, "update")) { 16656 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16657 } else if(!strcasecmp(word, "nonat")) { 16658 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16659 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16660 } else { 16661 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16662 } 16663 } 16664 } 16665 } else if (!strcasecmp(v->name, "insecure")) { 16666 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16667 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16668 set_insecure_flags(flags, v->value, v->lineno); 16669 } else if (!strcasecmp(v->name, "progressinband")) { 16670 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16671 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16672 if (ast_true(v->value)) 16673 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16674 else if (strcasecmp(v->value, "never")) 16675 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16676 } else if (!strcasecmp(v->name, "promiscredir")) { 16677 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16678 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16679 } else if (!strcasecmp(v->name, "videosupport")) { 16680 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16681 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16682 } else if (!strcasecmp(v->name, "allowoverlap")) { 16683 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16684 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16685 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16686 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16687 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16688 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16689 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16690 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16691 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16692 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16693 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16694 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16695 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16696 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16697 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16698 #endif 16699 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16700 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16701 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16702 } else if (!strcasecmp(v->name, "buggymwi")) { 16703 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16704 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16705 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16706 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16707 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16708 } else 16709 res = 0; 16710 16711 return res; 16712 }
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 13674 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().
13675 { 13676 struct ast_frame *f; 13677 int earlyreplace = 0; 13678 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13679 struct ast_channel *c = p->owner; /* Our incoming call */ 13680 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13681 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13682 13683 /* Check if we're in ring state */ 13684 if (replacecall->_state == AST_STATE_RING) 13685 earlyreplace = 1; 13686 13687 /* Check if we have a bridge */ 13688 if (!(targetcall = ast_bridged_channel(replacecall))) { 13689 /* We have no bridge */ 13690 if (!earlyreplace) { 13691 if (option_debug > 1) 13692 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13693 oneleggedreplace = 1; 13694 } 13695 } 13696 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13697 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13698 13699 if (option_debug > 3) { 13700 if (targetcall) 13701 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); 13702 else 13703 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13704 } 13705 13706 if (ignore) { 13707 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13708 /* We should answer something here. If we are here, the 13709 call we are replacing exists, so an accepted 13710 can't harm */ 13711 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13712 /* Do something more clever here */ 13713 ast_channel_unlock(c); 13714 ast_mutex_unlock(&p->refer->refer_call->lock); 13715 return 1; 13716 } 13717 if (!c) { 13718 /* What to do if no channel ??? */ 13719 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13720 transmit_response_reliable(p, "503 Service Unavailable", req); 13721 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13722 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13723 ast_mutex_unlock(&p->refer->refer_call->lock); 13724 return 1; 13725 } 13726 append_history(p, "Xfer", "INVITE/Replace received"); 13727 /* We have three channels to play with 13728 channel c: New incoming call 13729 targetcall: Call from PBX to target 13730 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13731 replacecall: The owner of the previous 13732 We need to masq C into refer_call to connect to 13733 targetcall; 13734 If we are talking to internal audio stream, target call is null. 13735 */ 13736 13737 /* Fake call progress */ 13738 transmit_response(p, "100 Trying", req); 13739 ast_setstate(c, AST_STATE_RING); 13740 13741 /* Masquerade the new call into the referred call to connect to target call 13742 Targetcall is not touched by the masq */ 13743 13744 /* Answer the incoming call and set channel to UP state */ 13745 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13746 13747 ast_setstate(c, AST_STATE_UP); 13748 13749 /* Stop music on hold and other generators */ 13750 ast_quiet_chan(replacecall); 13751 ast_quiet_chan(targetcall); 13752 if (option_debug > 3) 13753 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13754 /* Unlock clone, but not original (replacecall) */ 13755 if (!oneleggedreplace) 13756 ast_channel_unlock(c); 13757 13758 /* Unlock PVT */ 13759 ast_mutex_unlock(&p->refer->refer_call->lock); 13760 13761 /* Make sure that the masq does not free our PVT for the old call */ 13762 if (! earlyreplace && ! oneleggedreplace ) 13763 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13764 13765 /* Prepare the masquerade - if this does not happen, we will be gone */ 13766 if(ast_channel_masquerade(replacecall, c)) 13767 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13768 else if (option_debug > 3) 13769 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13770 13771 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13772 13773 /* C should now be in place of replacecall */ 13774 /* ast_read needs to lock channel */ 13775 ast_channel_unlock(c); 13776 13777 if (earlyreplace || oneleggedreplace ) { 13778 /* Force the masq to happen */ 13779 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13780 ast_frfree(f); 13781 f = NULL; 13782 if (option_debug > 3) 13783 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13784 } else { 13785 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13786 } 13787 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13788 if (!oneleggedreplace) 13789 ast_channel_unlock(replacecall); 13790 } else { /* Bridged call, UP channel */ 13791 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13792 /* Masq ok */ 13793 ast_frfree(f); 13794 f = NULL; 13795 if (option_debug > 2) 13796 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13797 } else { 13798 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13799 } 13800 ast_channel_unlock(replacecall); 13801 } 13802 ast_mutex_unlock(&p->refer->refer_call->lock); 13803 13804 ast_setstate(c, AST_STATE_DOWN); 13805 if (option_debug > 3) { 13806 struct ast_channel *test; 13807 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13808 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13809 if (replacecall) 13810 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13811 if (p->owner) { 13812 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13813 test = ast_bridged_channel(p->owner); 13814 if (test) 13815 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13816 else 13817 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13818 } else 13819 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13820 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13821 } 13822 13823 ast_channel_unlock(p->owner); /* Unlock new owner */ 13824 if (!oneleggedreplace) 13825 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13826 13827 /* The call should be down with no ast_channel, so hang it up */ 13828 c->tech_pvt = NULL; 13829 ast_hangup(c); 13830 return 0; 13831 }
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 15660 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.
15661 { 15662 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15663 relatively static */ 15664 const char *cmd; 15665 const char *cseq; 15666 const char *useragent; 15667 int seqno; 15668 int len; 15669 int ignore = FALSE; 15670 int respid; 15671 int res = 0; 15672 int debug = sip_debug_test_pvt(p); 15673 char *e; 15674 int error = 0; 15675 15676 /* Get Method and Cseq */ 15677 cseq = get_header(req, "Cseq"); 15678 cmd = req->header[0]; 15679 15680 /* Must have Cseq */ 15681 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15682 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15683 error = 1; 15684 } 15685 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15686 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15687 error = 1; 15688 } 15689 if (error) { 15690 if (!p->initreq.headers) /* New call */ 15691 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15692 return -1; 15693 } 15694 /* Get the command XXX */ 15695 15696 cmd = req->rlPart1; 15697 e = req->rlPart2; 15698 15699 /* Save useragent of the client */ 15700 useragent = get_header(req, "User-Agent"); 15701 if (!ast_strlen_zero(useragent)) 15702 ast_string_field_set(p, useragent, useragent); 15703 15704 /* Find out SIP method for incoming request */ 15705 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15706 /* Response to our request -- Do some sanity checks */ 15707 if (!p->initreq.headers) { 15708 if (option_debug) 15709 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15710 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15711 return 0; 15712 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15713 if (option_debug) 15714 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15715 return -1; 15716 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15717 /* ignore means "don't do anything with it" but still have to 15718 respond appropriately */ 15719 ignore = TRUE; 15720 ast_set_flag(req, SIP_PKT_IGNORE); 15721 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15722 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15723 } else if (e) { 15724 e = ast_skip_blanks(e); 15725 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15726 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15727 } else { 15728 if (respid <= 0) { 15729 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15730 return 0; 15731 } 15732 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15733 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15734 extract_uri(p, req); 15735 handle_response(p, respid, e + len, req, ignore, seqno); 15736 } 15737 } 15738 return 0; 15739 } 15740 15741 /* New SIP request coming in 15742 (could be new request in existing SIP dialog as well...) 15743 */ 15744 15745 p->method = req->method; /* Find out which SIP method they are using */ 15746 if (option_debug > 3) 15747 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15748 15749 if (p->icseq && (p->icseq > seqno) ) { 15750 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15751 if (option_debug > 2) 15752 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15753 } else { 15754 if (option_debug) 15755 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15756 if (req->method != SIP_ACK) 15757 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15758 return -1; 15759 } 15760 } else if (p->icseq && 15761 p->icseq == seqno && 15762 req->method != SIP_ACK && 15763 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15764 /* ignore means "don't do anything with it" but still have to 15765 respond appropriately. We do this if we receive a repeat of 15766 the last sequence number */ 15767 ignore = 2; 15768 ast_set_flag(req, SIP_PKT_IGNORE); 15769 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15770 if (option_debug > 2) 15771 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15772 } 15773 15774 if (seqno >= p->icseq) 15775 /* Next should follow monotonically (but not necessarily 15776 incrementally -- thanks again to the genius authors of SIP -- 15777 increasing */ 15778 p->icseq = seqno; 15779 15780 /* Find their tag if we haven't got it */ 15781 if (ast_strlen_zero(p->theirtag)) { 15782 char tag[128]; 15783 15784 gettag(req, "From", tag, sizeof(tag)); 15785 ast_string_field_set(p, theirtag, tag); 15786 } 15787 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15788 15789 if (pedanticsipchecking) { 15790 /* If this is a request packet without a from tag, it's not 15791 correct according to RFC 3261 */ 15792 /* Check if this a new request in a new dialog with a totag already attached to it, 15793 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15794 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15795 /* If this is a first request and it got a to-tag, it is not for us */ 15796 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15797 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15798 /* Will cease to exist after ACK */ 15799 } else if (req->method != SIP_ACK) { 15800 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15801 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15802 } 15803 return res; 15804 } 15805 } 15806 15807 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15808 transmit_response(p, "400 Bad request", req); 15809 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15810 return -1; 15811 } 15812 15813 /* Handle various incoming SIP methods in requests */ 15814 switch (p->method) { 15815 case SIP_OPTIONS: 15816 res = handle_request_options(p, req); 15817 break; 15818 case SIP_INVITE: 15819 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15820 break; 15821 case SIP_REFER: 15822 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15823 break; 15824 case SIP_CANCEL: 15825 res = handle_request_cancel(p, req); 15826 break; 15827 case SIP_BYE: 15828 res = handle_request_bye(p, req); 15829 break; 15830 case SIP_MESSAGE: 15831 res = handle_request_message(p, req); 15832 break; 15833 case SIP_SUBSCRIBE: 15834 res = handle_request_subscribe(p, req, sin, seqno, e); 15835 break; 15836 case SIP_REGISTER: 15837 res = handle_request_register(p, req, sin, e); 15838 break; 15839 case SIP_INFO: 15840 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15841 ast_verbose("Receiving INFO!\n"); 15842 if (!ignore) 15843 handle_request_info(p, req); 15844 else /* if ignoring, transmit response */ 15845 transmit_response(p, "200 OK", req); 15846 break; 15847 case SIP_NOTIFY: 15848 res = handle_request_notify(p, req, sin, seqno, e); 15849 break; 15850 case SIP_ACK: 15851 /* Make sure we don't ignore this */ 15852 if (seqno == p->pendinginvite) { 15853 p->invitestate = INV_TERMINATED; 15854 p->pendinginvite = 0; 15855 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15856 if (find_sdp(req)) { 15857 if (process_sdp(p, req)) 15858 return -1; 15859 } 15860 check_pendings(p); 15861 } 15862 /* Got an ACK that we did not match. Ignore silently */ 15863 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15864 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15865 break; 15866 default: 15867 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15868 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15869 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15870 /* If this is some new method, and we don't have a call, destroy it now */ 15871 if (!p->initreq.headers) 15872 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15873 break; 15874 } 15875 return res; 15876 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15225 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().
15226 { 15227 struct ast_channel *c=NULL; 15228 int res; 15229 struct ast_channel *bridged_to; 15230 15231 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15232 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 15233 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15234 15235 p->invitestate = INV_TERMINATED; 15236 15237 copy_request(&p->initreq, req); 15238 check_via(p, req); 15239 sip_alreadygone(p); 15240 15241 /* Get RTCP quality before end of call */ 15242 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15243 char *audioqos, *videoqos; 15244 if (p->rtp) { 15245 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15246 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15247 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15248 if (p->owner) 15249 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15250 } 15251 if (p->vrtp) { 15252 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15253 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15254 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15255 if (p->owner) 15256 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15257 } 15258 } 15259 15260 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15261 15262 if (!ast_strlen_zero(get_header(req, "Also"))) { 15263 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15264 ast_inet_ntoa(p->recv.sin_addr)); 15265 if (ast_strlen_zero(p->context)) 15266 ast_string_field_set(p, context, default_context); 15267 res = get_also_info(p, req); 15268 if (!res) { 15269 c = p->owner; 15270 if (c) { 15271 bridged_to = ast_bridged_channel(c); 15272 if (bridged_to) { 15273 /* Don't actually hangup here... */ 15274 ast_queue_control(c, AST_CONTROL_UNHOLD); 15275 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15276 } else 15277 ast_queue_hangup(p->owner); 15278 } 15279 } else { 15280 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15281 if (p->owner) 15282 ast_queue_hangup(p->owner); 15283 } 15284 } else if (p->owner) { 15285 ast_queue_hangup(p->owner); 15286 if (option_debug > 2) 15287 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15288 } else { 15289 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15290 if (option_debug > 2) 15291 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15292 } 15293 transmit_response(p, "200 OK", req); 15294 15295 return 1; 15296 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15119 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().
15120 { 15121 15122 check_via(p, req); 15123 sip_alreadygone(p); 15124 15125 /* At this point, we could have cancelled the invite at the same time 15126 as the other side sends a CANCEL. Our final reply with error code 15127 might not have been received by the other side before the CANCEL 15128 was sent, so let's just give up retransmissions and waiting for 15129 ACK on our error code. The call is hanging up any way. */ 15130 if (p->invitestate == INV_TERMINATED) 15131 __sip_pretend_ack(p); 15132 else 15133 p->invitestate = INV_CANCELLED; 15134 15135 if (p->owner && p->owner->_state == AST_STATE_UP) { 15136 /* This call is up, cancel is ignored, we need a bye */ 15137 transmit_response(p, "200 OK", req); 15138 if (option_debug) 15139 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15140 return 0; 15141 } 15142 15143 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15144 update_call_counter(p, DEC_CALL_LIMIT); 15145 15146 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15147 if (p->owner) 15148 ast_queue_hangup(p->owner); 15149 else 15150 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15151 if (p->initreq.len > 0) { 15152 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15153 transmit_response(p, "200 OK", req); 15154 return 1; 15155 } else { 15156 transmit_response(p, "481 Call Leg Does Not Exist", req); 15157 return 0; 15158 } 15159 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11275 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().
11276 { 11277 char buf[1024]; 11278 unsigned int event; 11279 const char *c = get_header(req, "Content-Type"); 11280 11281 /* Need to check the media/type */ 11282 if (!strcasecmp(c, "application/dtmf-relay") || 11283 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11284 unsigned int duration = 0; 11285 11286 /* Try getting the "signal=" part */ 11287 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11288 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11289 transmit_response(p, "200 OK", req); /* Should return error */ 11290 return; 11291 } else { 11292 ast_copy_string(buf, c, sizeof(buf)); 11293 } 11294 11295 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11296 duration = atoi(c); 11297 if (!duration) 11298 duration = 100; /* 100 ms */ 11299 11300 if (!p->owner) { /* not a PBX call */ 11301 transmit_response(p, "481 Call leg/transaction does not exist", req); 11302 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11303 return; 11304 } 11305 11306 if (ast_strlen_zero(buf)) { 11307 transmit_response(p, "200 OK", req); 11308 return; 11309 } 11310 11311 if (buf[0] == '*') 11312 event = 10; 11313 else if (buf[0] == '#') 11314 event = 11; 11315 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11316 event = 12 + buf[0] - 'A'; 11317 else 11318 event = atoi(buf); 11319 if (event == 16) { 11320 /* send a FLASH event */ 11321 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11322 ast_queue_frame(p->owner, &f); 11323 if (sipdebug) 11324 ast_verbose("* DTMF-relay event received: FLASH\n"); 11325 } else { 11326 /* send a DTMF event */ 11327 struct ast_frame f = { AST_FRAME_DTMF, }; 11328 if (event < 10) { 11329 f.subclass = '0' + event; 11330 } else if (event < 11) { 11331 f.subclass = '*'; 11332 } else if (event < 12) { 11333 f.subclass = '#'; 11334 } else if (event < 16) { 11335 f.subclass = 'A' + (event - 12); 11336 } 11337 f.len = duration; 11338 ast_queue_frame(p->owner, &f); 11339 if (sipdebug) 11340 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11341 } 11342 transmit_response(p, "200 OK", req); 11343 return; 11344 } else if (!strcasecmp(c, "application/media_control+xml")) { 11345 /* Eh, we'll just assume it's a fast picture update for now */ 11346 if (p->owner) 11347 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11348 transmit_response(p, "200 OK", req); 11349 return; 11350 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11351 /* Client code (from SNOM phone) */ 11352 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11353 if (p->owner && p->owner->cdr) 11354 ast_cdr_setuserfield(p->owner, c); 11355 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11356 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11357 transmit_response(p, "200 OK", req); 11358 } else { 11359 transmit_response(p, "403 Unauthorized", req); 11360 } 11361 return; 11362 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11363 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11364 transmit_response(p, "200 OK", req); 11365 return; 11366 } 11367 11368 /* Other type of INFO message, not really understood by Asterisk */ 11369 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11370 11371 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11372 transmit_response(p, "415 Unsupported media type", req); 11373 return; 11374 }
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 14122 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_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_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), AST_SCHED_DEL, 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(), create_addr(), 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, sip_pvt::icseq, 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(), sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pvt::packets, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pkt::retransid, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_pkt::seqno, 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, sip_uri_cmp(), 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_invite(), 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().
14123 { 14124 int res = 1; 14125 int gotdest; 14126 const char *p_replaces; 14127 char *replace_id = NULL; 14128 const char *required; 14129 unsigned int required_profile = 0; 14130 struct ast_channel *c = NULL; /* New channel */ 14131 int reinvite = 0; 14132 14133 /* Find out what they support */ 14134 if (!p->sipoptions) { 14135 const char *supported = get_header(req, "Supported"); 14136 if (!ast_strlen_zero(supported)) 14137 parse_sip_options(p, supported); 14138 } 14139 14140 /* Find out what they require */ 14141 required = get_header(req, "Require"); 14142 if (!ast_strlen_zero(required)) { 14143 required_profile = parse_sip_options(NULL, required); 14144 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14145 /* At this point we only support REPLACES */ 14146 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14147 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14148 p->invitestate = INV_COMPLETED; 14149 if (!p->lastinvite) 14150 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14151 return -1; 14152 } 14153 } 14154 14155 /* Check if this is a loop */ 14156 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 14157 /* This is a call to ourself. Send ourselves an error code and stop 14158 processing immediately, as SIP really has no good mechanism for 14159 being able to call yourself */ 14160 /* If pedantic is on, we need to check the tags. If they're different, this is 14161 in fact a forked call through a SIP proxy somewhere. */ 14162 int different; 14163 if (pedanticsipchecking) 14164 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14165 else 14166 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14167 if (!different) { 14168 transmit_response(p, "482 Loop Detected", req); 14169 p->invitestate = INV_COMPLETED; 14170 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14171 return 0; 14172 } else { 14173 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14174 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14175 * that should be all we need to do. 14176 */ 14177 char *uri = ast_strdupa(req->rlPart2); 14178 char *at = strchr(uri, '@'); 14179 char *peerorhost; 14180 struct sip_pkt *pkt = NULL; 14181 if (option_debug > 2) { 14182 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14183 } 14184 if (at) { 14185 *at = '\0'; 14186 } 14187 /* Parse out "sip:" */ 14188 if ((peerorhost = strchr(uri, ':'))) { 14189 *peerorhost++ = '\0'; 14190 } 14191 create_addr(p, peerorhost); 14192 ast_string_field_free(p, theirtag); 14193 for (pkt = p->packets; pkt; pkt = pkt->next) { 14194 if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) { 14195 AST_SCHED_DEL(sched, pkt->retransid); 14196 } 14197 } 14198 return transmit_invite(p, SIP_INVITE, 1, 3); 14199 } 14200 } 14201 14202 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14203 /* We already have a pending invite. Sorry. You are on hold. */ 14204 transmit_response(p, "491 Request Pending", req); 14205 if (option_debug) 14206 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14207 /* Don't destroy dialog here */ 14208 return 0; 14209 } 14210 14211 p_replaces = get_header(req, "Replaces"); 14212 if (!ast_strlen_zero(p_replaces)) { 14213 /* We have a replaces header */ 14214 char *ptr; 14215 char *fromtag = NULL; 14216 char *totag = NULL; 14217 char *start, *to; 14218 int error = 0; 14219 14220 if (p->owner) { 14221 if (option_debug > 2) 14222 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14223 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14224 /* Do not destroy existing call */ 14225 return -1; 14226 } 14227 14228 if (sipdebug && option_debug > 2) 14229 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14230 /* Create a buffer we can manipulate */ 14231 replace_id = ast_strdupa(p_replaces); 14232 ast_uri_decode(replace_id); 14233 14234 if (!p->refer && !sip_refer_allocate(p)) { 14235 transmit_response(p, "500 Server Internal Error", req); 14236 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14237 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14238 p->invitestate = INV_COMPLETED; 14239 return -1; 14240 } 14241 14242 /* Todo: (When we find phones that support this) 14243 if the replaces header contains ";early-only" 14244 we can only replace the call in early 14245 stage, not after it's up. 14246 14247 If it's not in early mode, 486 Busy. 14248 */ 14249 14250 /* Skip leading whitespace */ 14251 replace_id = ast_skip_blanks(replace_id); 14252 14253 start = replace_id; 14254 while ( (ptr = strsep(&start, ";")) ) { 14255 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14256 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14257 totag = to + 7; /* skip the keyword */ 14258 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14259 fromtag = to + 9; /* skip the keyword */ 14260 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14261 } 14262 } 14263 14264 if (sipdebug && option_debug > 3) 14265 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>"); 14266 14267 14268 /* Try to find call that we are replacing 14269 If we have a Replaces header, we need to cancel that call if we succeed with this call 14270 */ 14271 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14272 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14273 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 14274 error = 1; 14275 } 14276 14277 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14278 14279 /* The matched call is the call from the transferer to Asterisk . 14280 We want to bridge the bridged part of the call to the 14281 incoming invite, thus taking over the refered call */ 14282 14283 if (p->refer->refer_call == p) { 14284 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14285 p->refer->refer_call = NULL; 14286 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14287 error = 1; 14288 } 14289 14290 if (!error && !p->refer->refer_call->owner) { 14291 /* Oops, someting wrong anyway, no owner, no call */ 14292 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14293 /* Check for better return code */ 14294 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 14295 error = 1; 14296 } 14297 14298 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 ) { 14299 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14300 transmit_response(p, "603 Declined (Replaces)", req); 14301 error = 1; 14302 } 14303 14304 if (error) { /* Give up this dialog */ 14305 append_history(p, "Xfer", "INVITE/Replace Failed."); 14306 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14307 ast_mutex_unlock(&p->lock); 14308 if (p->refer->refer_call) { 14309 ast_mutex_unlock(&p->refer->refer_call->lock); 14310 ast_channel_unlock(p->refer->refer_call->owner); 14311 } 14312 p->invitestate = INV_COMPLETED; 14313 return -1; 14314 } 14315 } 14316 14317 14318 /* Check if this is an INVITE that sets up a new dialog or 14319 a re-invite in an existing dialog */ 14320 14321 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14322 int newcall = (p->initreq.headers ? TRUE : FALSE); 14323 14324 if (sip_cancel_destroy(p)) 14325 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14326 /* This also counts as a pending invite */ 14327 p->pendinginvite = seqno; 14328 check_via(p, req); 14329 14330 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14331 if (!p->owner) { /* Not a re-invite */ 14332 if (debug) 14333 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14334 if (newcall) 14335 append_history(p, "Invite", "New call: %s", p->callid); 14336 parse_ok_contact(p, req); 14337 } else { /* Re-invite on existing call */ 14338 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14339 /* Handle SDP here if we already have an owner */ 14340 if (find_sdp(req)) { 14341 if (process_sdp(p, req)) { 14342 transmit_response(p, "488 Not acceptable here", req); 14343 if (!p->lastinvite) 14344 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14345 return -1; 14346 } 14347 } else { 14348 p->jointcapability = p->capability; 14349 if (option_debug > 2) 14350 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14351 /* Some devices signal they want to be put off hold by sending a re-invite 14352 *without* an SDP, which is supposed to mean "Go back to your state" 14353 and since they put os on remote hold, we go back to off hold */ 14354 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14355 change_hold_state(p, req, FALSE, 0); 14356 } 14357 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14358 append_history(p, "ReInv", "Re-invite received"); 14359 } 14360 } else if (debug) 14361 ast_verbose("Ignoring this INVITE request\n"); 14362 14363 14364 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14365 /* This is a new invite */ 14366 /* Handle authentication if this is our first invite */ 14367 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14368 if (res == AUTH_CHALLENGE_SENT) { 14369 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14370 return 0; 14371 } 14372 if (res < 0) { /* Something failed in authentication */ 14373 if (res == AUTH_FAKE_AUTH) { 14374 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14375 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 14376 } else { 14377 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14378 transmit_response_reliable(p, "403 Forbidden", req); 14379 } 14380 p->invitestate = INV_COMPLETED; 14381 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14382 ast_string_field_free(p, theirtag); 14383 return 0; 14384 } 14385 14386 /* We have a succesful authentication, process the SDP portion if there is one */ 14387 if (find_sdp(req)) { 14388 if (process_sdp(p, req)) { 14389 /* Unacceptable codecs */ 14390 transmit_response_reliable(p, "488 Not acceptable here", req); 14391 p->invitestate = INV_COMPLETED; 14392 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14393 if (option_debug) 14394 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14395 return -1; 14396 } 14397 } else { /* No SDP in invite, call control session */ 14398 p->jointcapability = p->capability; 14399 if (option_debug > 1) 14400 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14401 } 14402 14403 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14404 /* This seems redundant ... see !p-owner above */ 14405 if (p->owner) 14406 ast_queue_frame(p->owner, &ast_null_frame); 14407 14408 14409 /* Initialize the context if it hasn't been already */ 14410 if (ast_strlen_zero(p->context)) 14411 ast_string_field_set(p, context, default_context); 14412 14413 14414 /* Check number of concurrent calls -vs- incoming limit HERE */ 14415 if (option_debug) 14416 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14417 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14418 if (res < 0) { 14419 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14420 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14421 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14422 p->invitestate = INV_COMPLETED; 14423 } 14424 return 0; 14425 } 14426 gotdest = get_destination(p, NULL); /* Get destination right away */ 14427 get_rdnis(p, NULL); /* Get redirect information */ 14428 extract_uri(p, req); /* Get the Contact URI */ 14429 build_contact(p); /* Build our contact header */ 14430 14431 if (p->rtp) { 14432 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14433 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14434 } 14435 14436 if (!replace_id && gotdest) { /* No matching extension found */ 14437 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14438 transmit_response_reliable(p, "484 Address Incomplete", req); 14439 else { 14440 transmit_response_reliable(p, "404 Not Found", req); 14441 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14442 " '%s' rejected because extension not found.\n", 14443 S_OR(p->username, p->peername), p->exten); 14444 } 14445 p->invitestate = INV_COMPLETED; 14446 update_call_counter(p, DEC_CALL_LIMIT); 14447 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14448 return 0; 14449 } else { 14450 /* If no extension was specified, use the s one */ 14451 /* Basically for calling to IP/Host name only */ 14452 if (ast_strlen_zero(p->exten)) 14453 ast_string_field_set(p, exten, "s"); 14454 /* Initialize our tag */ 14455 14456 make_our_tag(p->tag, sizeof(p->tag)); 14457 /* First invitation - create the channel */ 14458 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14459 *recount = 1; 14460 14461 /* Save Record-Route for any later requests we make on this dialogue */ 14462 build_route(p, req, 0); 14463 14464 if (c) { 14465 /* Pre-lock the call */ 14466 ast_channel_lock(c); 14467 } 14468 } 14469 } else { 14470 if (option_debug > 1 && sipdebug) { 14471 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14472 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14473 else 14474 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14475 } 14476 reinvite = 1; 14477 c = p->owner; 14478 } 14479 14480 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14481 p->lastinvite = seqno; 14482 14483 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14484 /* Go and take over the target call */ 14485 if (sipdebug && option_debug > 3) 14486 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14487 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14488 } 14489 14490 14491 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14492 switch(c->_state) { 14493 case AST_STATE_DOWN: 14494 if (option_debug > 1) 14495 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14496 transmit_response(p, "100 Trying", req); 14497 p->invitestate = INV_PROCEEDING; 14498 ast_setstate(c, AST_STATE_RING); 14499 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14500 enum ast_pbx_result res; 14501 14502 res = ast_pbx_start(c); 14503 14504 switch(res) { 14505 case AST_PBX_FAILED: 14506 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14507 p->invitestate = INV_COMPLETED; 14508 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14509 transmit_response(p, "503 Unavailable", req); 14510 else 14511 transmit_response_reliable(p, "503 Unavailable", req); 14512 break; 14513 case AST_PBX_CALL_LIMIT: 14514 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14515 p->invitestate = INV_COMPLETED; 14516 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14517 transmit_response(p, "480 Temporarily Unavailable", req); 14518 else 14519 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14520 break; 14521 case AST_PBX_SUCCESS: 14522 /* nothing to do */ 14523 break; 14524 } 14525 14526 if (res) { 14527 14528 /* Unlock locks so ast_hangup can do its magic */ 14529 ast_mutex_unlock(&c->lock); 14530 ast_mutex_unlock(&p->lock); 14531 ast_hangup(c); 14532 ast_mutex_lock(&p->lock); 14533 c = NULL; 14534 } 14535 } else { /* Pickup call in call group */ 14536 ast_channel_unlock(c); 14537 *nounlock = 1; 14538 if (ast_pickup_call(c)) { 14539 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14540 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14541 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14542 else 14543 transmit_response_reliable(p, "503 Unavailable", req); 14544 sip_alreadygone(p); 14545 /* Unlock locks so ast_hangup can do its magic */ 14546 ast_mutex_unlock(&p->lock); 14547 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14548 } else { 14549 ast_mutex_unlock(&p->lock); 14550 ast_setstate(c, AST_STATE_DOWN); 14551 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14552 } 14553 p->invitestate = INV_COMPLETED; 14554 ast_hangup(c); 14555 ast_mutex_lock(&p->lock); 14556 c = NULL; 14557 } 14558 break; 14559 case AST_STATE_RING: 14560 transmit_response(p, "100 Trying", req); 14561 p->invitestate = INV_PROCEEDING; 14562 break; 14563 case AST_STATE_RINGING: 14564 transmit_response(p, "180 Ringing", req); 14565 p->invitestate = INV_PROCEEDING; 14566 break; 14567 case AST_STATE_UP: 14568 if (option_debug > 1) 14569 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14570 14571 transmit_response(p, "100 Trying", req); 14572 14573 if (p->t38.state == T38_PEER_REINVITE) { 14574 struct ast_channel *bridgepeer = NULL; 14575 struct sip_pvt *bridgepvt = NULL; 14576 14577 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14578 /* 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*/ 14579 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14580 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14581 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14582 if (bridgepvt->t38.state == T38_DISABLED) { 14583 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14584 /* Send re-invite to the bridged channel */ 14585 sip_handle_t38_reinvite(bridgepeer, p, 1); 14586 } else { /* Something is wrong with peers udptl struct */ 14587 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14588 ast_mutex_lock(&bridgepvt->lock); 14589 bridgepvt->t38.state = T38_DISABLED; 14590 ast_mutex_unlock(&bridgepvt->lock); 14591 if (option_debug > 1) 14592 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14593 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14594 transmit_response(p, "488 Not acceptable here", req); 14595 else 14596 transmit_response_reliable(p, "488 Not acceptable here", req); 14597 14598 } 14599 } else { 14600 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14601 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14602 p->t38.state = T38_ENABLED; 14603 if (option_debug) 14604 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14605 } 14606 } else { 14607 /* Other side is not a SIP channel */ 14608 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14609 transmit_response(p, "488 Not acceptable here", req); 14610 else 14611 transmit_response_reliable(p, "488 Not acceptable here", req); 14612 p->t38.state = T38_DISABLED; 14613 if (option_debug > 1) 14614 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14615 14616 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14617 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14618 } 14619 } else { 14620 /* we are not bridged in a call */ 14621 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14622 p->t38.state = T38_ENABLED; 14623 if (option_debug) 14624 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14625 } 14626 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14627 int sendok = TRUE; 14628 14629 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14630 /* so handle it here (re-invite other party to RTP) */ 14631 struct ast_channel *bridgepeer = NULL; 14632 struct sip_pvt *bridgepvt = NULL; 14633 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14634 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14635 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14636 /* Does the bridged peer have T38 ? */ 14637 if (bridgepvt->t38.state == T38_ENABLED) { 14638 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14639 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14640 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14641 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14642 else 14643 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14644 sendok = FALSE; 14645 } 14646 /* No bridged peer with T38 enabled*/ 14647 } 14648 } 14649 /* Respond to normal re-invite */ 14650 if (sendok) 14651 /* If this is not a re-invite or something to ignore - it's critical */ 14652 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14653 } 14654 p->invitestate = INV_TERMINATED; 14655 break; 14656 default: 14657 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14658 transmit_response(p, "100 Trying", req); 14659 break; 14660 } 14661 } else { 14662 if (p && (p->autokillid == -1)) { 14663 const char *msg; 14664 14665 if (!p->jointcapability) 14666 msg = "488 Not Acceptable Here (codec error)"; 14667 else { 14668 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14669 msg = "503 Unavailable"; 14670 } 14671 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14672 transmit_response(p, msg, req); 14673 else 14674 transmit_response_reliable(p, msg, req); 14675 p->invitestate = INV_COMPLETED; 14676 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14677 } 14678 } 14679 return res; 14680 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15299 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().
15300 { 15301 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15302 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15303 ast_verbose("Receiving message!\n"); 15304 receive_message(p, req); 15305 } else 15306 transmit_response(p, "202 Accepted", req); 15307 return 1; 15308 }
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 13513 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().
13514 { 13515 /* This is mostly a skeleton for future improvements */ 13516 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13517 int res = 0; 13518 const char *event = get_header(req, "Event"); 13519 char *eventid = NULL; 13520 char *sep; 13521 13522 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13523 *sep++ = '\0'; 13524 eventid = sep; 13525 } 13526 13527 if (option_debug > 1 && sipdebug) 13528 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13529 13530 if (strcmp(event, "refer")) { 13531 /* We don't understand this event. */ 13532 /* Here's room to implement incoming voicemail notifications :-) */ 13533 transmit_response(p, "489 Bad event", req); 13534 res = -1; 13535 } else { 13536 /* Save nesting depth for now, since there might be other events we will 13537 support in the future */ 13538 13539 /* Handle REFER notifications */ 13540 13541 char buf[1024]; 13542 char *cmd, *code; 13543 int respcode; 13544 int success = TRUE; 13545 13546 /* EventID for each transfer... EventID is basically the REFER cseq 13547 13548 We are getting notifications on a call that we transfered 13549 We should hangup when we are getting a 200 OK in a sipfrag 13550 Check if we have an owner of this event */ 13551 13552 /* Check the content type */ 13553 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13554 /* We need a sipfrag */ 13555 transmit_response(p, "400 Bad request", req); 13556 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13557 return -1; 13558 } 13559 13560 /* Get the text of the attachment */ 13561 if (get_msg_text(buf, sizeof(buf), req)) { 13562 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13563 transmit_response(p, "400 Bad request", req); 13564 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13565 return -1; 13566 } 13567 13568 /* 13569 From the RFC... 13570 A minimal, but complete, implementation can respond with a single 13571 NOTIFY containing either the body: 13572 SIP/2.0 100 Trying 13573 13574 if the subscription is pending, the body: 13575 SIP/2.0 200 OK 13576 if the reference was successful, the body: 13577 SIP/2.0 503 Service Unavailable 13578 if the reference failed, or the body: 13579 SIP/2.0 603 Declined 13580 13581 if the REFER request was accepted before approval to follow the 13582 reference could be obtained and that approval was subsequently denied 13583 (see Section 2.4.7). 13584 13585 If there are several REFERs in the same dialog, we need to 13586 match the ID of the event header... 13587 */ 13588 if (option_debug > 2) 13589 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13590 cmd = ast_skip_blanks(buf); 13591 code = cmd; 13592 /* We are at SIP/2.0 */ 13593 while(*code && (*code > 32)) { /* Search white space */ 13594 code++; 13595 } 13596 *code++ = '\0'; 13597 code = ast_skip_blanks(code); 13598 sep = code; 13599 sep++; 13600 while(*sep && (*sep > 32)) { /* Search white space */ 13601 sep++; 13602 } 13603 *sep++ = '\0'; /* Response string */ 13604 respcode = atoi(code); 13605 switch (respcode) { 13606 case 100: /* Trying: */ 13607 case 101: /* dialog establishment */ 13608 /* Don't do anything yet */ 13609 break; 13610 case 183: /* Ringing: */ 13611 /* Don't do anything yet */ 13612 break; 13613 case 200: /* OK: The new call is up, hangup this call */ 13614 /* Hangup the call that we are replacing */ 13615 break; 13616 case 301: /* Moved permenantly */ 13617 case 302: /* Moved temporarily */ 13618 /* Do we get the header in the packet in this case? */ 13619 success = FALSE; 13620 break; 13621 case 503: /* Service Unavailable: The new call failed */ 13622 /* Cancel transfer, continue the call */ 13623 success = FALSE; 13624 break; 13625 case 603: /* Declined: Not accepted */ 13626 /* Cancel transfer, continue the current call */ 13627 success = FALSE; 13628 break; 13629 } 13630 if (!success) { 13631 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13632 } 13633 13634 /* Confirm that we received this packet */ 13635 transmit_response(p, "200 OK", req); 13636 }; 13637 13638 if (!p->lastinvite) 13639 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13640 13641 return res; 13642 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13645 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().
13646 { 13647 int res; 13648 13649 res = get_destination(p, req); 13650 build_contact(p); 13651 13652 /* XXX Should we authenticate OPTIONS? XXX */ 13653 13654 if (ast_strlen_zero(p->context)) 13655 ast_string_field_set(p, context, default_context); 13656 13657 if (ast_shutting_down()) 13658 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13659 else if (res < 0) 13660 transmit_response_with_allow(p, "404 Not Found", req, 0); 13661 else 13662 transmit_response_with_allow(p, "200 OK", req, 0); 13663 13664 /* Destroy if this OPTIONS was the opening request, but not if 13665 it's in the middle of a normal call flow. */ 13666 if (!p->lastinvite) 13667 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13668 13669 return res; 13670 }
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 14848 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().
14849 { 14850 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14851 /* Chan2: Call between asterisk and transferee */ 14852 14853 int res = 0; 14854 14855 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14856 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"); 14857 14858 if (!p->owner) { 14859 /* This is a REFER outside of an existing SIP dialog */ 14860 /* We can't handle that, so decline it */ 14861 if (option_debug > 2) 14862 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14863 transmit_response(p, "603 Declined (No dialog)", req); 14864 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14865 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14866 sip_alreadygone(p); 14867 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14868 } 14869 return 0; 14870 } 14871 14872 14873 /* Check if transfer is allowed from this device */ 14874 if (p->allowtransfer == TRANSFER_CLOSED ) { 14875 /* Transfer not allowed, decline */ 14876 transmit_response(p, "603 Declined (policy)", req); 14877 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14878 /* Do not destroy SIP session */ 14879 return 0; 14880 } 14881 14882 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14883 /* Already have a pending REFER */ 14884 transmit_response(p, "491 Request pending", req); 14885 append_history(p, "Xfer", "Refer failed. Request pending."); 14886 return 0; 14887 } 14888 14889 /* Allocate memory for call transfer data */ 14890 if (!p->refer && !sip_refer_allocate(p)) { 14891 transmit_response(p, "500 Internal Server Error", req); 14892 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14893 return -3; 14894 } 14895 14896 res = get_refer_info(p, req); /* Extract headers */ 14897 14898 p->refer->status = REFER_SENT; 14899 14900 if (res != 0) { 14901 switch (res) { 14902 case -2: /* Syntax error */ 14903 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14904 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14905 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14906 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14907 break; 14908 case -3: 14909 transmit_response(p, "603 Declined (Non sip: uri)", req); 14910 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14911 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14912 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14913 break; 14914 default: 14915 /* Refer-to extension not found, fake a failed transfer */ 14916 transmit_response(p, "202 Accepted", req); 14917 append_history(p, "Xfer", "Refer failed. Bad extension."); 14918 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14919 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14920 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14921 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14922 break; 14923 } 14924 return 0; 14925 } 14926 if (ast_strlen_zero(p->context)) 14927 ast_string_field_set(p, context, default_context); 14928 14929 /* If we do not support SIP domains, all transfers are local */ 14930 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14931 p->refer->localtransfer = 1; 14932 if (sipdebug && option_debug > 2) 14933 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14934 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14935 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14936 p->refer->localtransfer = 1; 14937 } else if (sipdebug && option_debug > 2) 14938 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14939 14940 /* Is this a repeat of a current request? Ignore it */ 14941 /* Don't know what else to do right now. */ 14942 if (ignore) 14943 return res; 14944 14945 /* If this is a blind transfer, we have the following 14946 channels to work with: 14947 - chan1, chan2: The current call between transferer and transferee (2 channels) 14948 - target_channel: A new call from the transferee to the target (1 channel) 14949 We need to stay tuned to what happens in order to be able 14950 to bring back the call to the transferer */ 14951 14952 /* If this is a attended transfer, we should have all call legs within reach: 14953 - chan1, chan2: The call between the transferer and transferee (2 channels) 14954 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14955 We want to bridge chan2 with targetcall_pvt! 14956 14957 The replaces call id in the refer message points 14958 to the call leg between Asterisk and the transferer. 14959 So we need to connect the target and the transferee channel 14960 and hangup the two other channels silently 14961 14962 If the target is non-local, the call ID could be on a remote 14963 machine and we need to send an INVITE with replaces to the 14964 target. We basically handle this as a blind transfer 14965 and let the sip_call function catch that we need replaces 14966 header in the INVITE. 14967 */ 14968 14969 14970 /* Get the transferer's channel */ 14971 current.chan1 = p->owner; 14972 14973 /* Find the other part of the bridge (2) - transferee */ 14974 current.chan2 = ast_bridged_channel(current.chan1); 14975 14976 if (sipdebug && option_debug > 2) 14977 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>"); 14978 14979 if (!current.chan2 && !p->refer->attendedtransfer) { 14980 /* No bridged channel, propably IVR or echo or similar... */ 14981 /* Guess we should masquerade or something here */ 14982 /* Until we figure it out, refuse transfer of such calls */ 14983 if (sipdebug && option_debug > 2) 14984 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14985 p->refer->status = REFER_FAILED; 14986 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14987 transmit_response(p, "603 Declined", req); 14988 return -1; 14989 } 14990 14991 if (current.chan2) { 14992 if (sipdebug && option_debug > 3) 14993 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14994 14995 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14996 } 14997 14998 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14999 15000 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15001 if (p->refer->attendedtransfer) { 15002 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15003 return res; /* We're done with the transfer */ 15004 /* Fall through for remote transfers that we did not find locally */ 15005 if (sipdebug && option_debug > 3) 15006 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15007 /* Fallthrough if we can't find the call leg internally */ 15008 } 15009 15010 15011 /* Parking a call */ 15012 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15013 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15014 *nounlock = 1; 15015 ast_channel_unlock(current.chan1); 15016 copy_request(¤t.req, req); 15017 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15018 p->refer->status = REFER_200OK; 15019 append_history(p, "Xfer", "REFER to call parking."); 15020 if (sipdebug && option_debug > 3) 15021 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15022 sip_park(current.chan2, current.chan1, req, seqno); 15023 return res; 15024 } 15025 15026 /* Blind transfers and remote attended xfers */ 15027 transmit_response(p, "202 Accepted", req); 15028 15029 if (current.chan1 && current.chan2) { 15030 if (option_debug > 2) 15031 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15032 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15033 } 15034 if (current.chan2) { 15035 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15036 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15037 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15038 /* One for the new channel */ 15039 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15040 /* Attended transfer to remote host, prepare headers for the INVITE */ 15041 if (p->refer->referred_by) 15042 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15043 } 15044 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15045 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15046 char tempheader[SIPBUFSIZE]; 15047 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15048 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15049 p->refer->replaces_callid_totag, 15050 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15051 p->refer->replaces_callid_fromtag); 15052 if (current.chan2) 15053 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15054 } 15055 /* Must release lock now, because it will not longer 15056 be accessible after the transfer! */ 15057 *nounlock = 1; 15058 ast_channel_unlock(current.chan1); 15059 15060 /* Connect the call */ 15061 15062 /* FAKE ringing if not attended transfer */ 15063 if (!p->refer->attendedtransfer) 15064 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15065 15066 /* For blind transfer, this will lead to a new call */ 15067 /* For attended transfer to remote host, this will lead to 15068 a new SIP call with a replaces header, if the dial plan allows it 15069 */ 15070 if (!current.chan2) { 15071 /* We have no bridge, so we're talking with Asterisk somehow */ 15072 /* We need to masquerade this call */ 15073 /* What to do to fix this situation: 15074 * Set up the new call in a new channel 15075 * Let the new channel masq into this channel 15076 Please add that code here :-) 15077 */ 15078 p->refer->status = REFER_FAILED; 15079 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15080 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15081 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15082 return -1; 15083 } 15084 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15085 15086 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15087 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15088 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15089 15090 if (!res) { 15091 /* Success - we have a new channel */ 15092 if (option_debug > 2) 15093 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15094 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15095 if (p->refer->localtransfer) 15096 p->refer->status = REFER_200OK; 15097 if (p->owner) 15098 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15099 append_history(p, "Xfer", "Refer succeeded."); 15100 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15101 /* Do not hangup call, the other side do that when we say 200 OK */ 15102 /* We could possibly implement a timer here, auto congestion */ 15103 res = 0; 15104 } else { 15105 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15106 if (option_debug > 2) 15107 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15108 append_history(p, "Xfer", "Refer failed."); 15109 /* Failure of some kind */ 15110 p->refer->status = REFER_FAILED; 15111 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15112 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15113 res = -1; 15114 } 15115 return res; 15116 }
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 15607 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().
15608 { 15609 enum check_auth_result res; 15610 15611 /* Use this as the basis */ 15612 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15613 ast_verbose("Using latest REGISTER request as basis request\n"); 15614 copy_request(&p->initreq, req); 15615 check_via(p, req); 15616 if ((res = register_verify(p, sin, req, e)) < 0) { 15617 const char *reason; 15618 15619 switch (res) { 15620 case AUTH_SECRET_FAILED: 15621 reason = "Wrong password"; 15622 break; 15623 case AUTH_USERNAME_MISMATCH: 15624 reason = "Username/auth name mismatch"; 15625 break; 15626 case AUTH_NOT_FOUND: 15627 reason = "No matching peer found"; 15628 break; 15629 case AUTH_UNKNOWN_DOMAIN: 15630 reason = "Not a local domain"; 15631 break; 15632 case AUTH_PEER_NOT_DYNAMIC: 15633 reason = "Peer is not supposed to register"; 15634 break; 15635 case AUTH_ACL_FAILED: 15636 reason = "Device does not match ACL"; 15637 break; 15638 default: 15639 reason = "Unknown failure"; 15640 break; 15641 } 15642 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15643 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15644 reason); 15645 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15646 } else 15647 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15648 15649 if (res < 1) { 15650 /* Destroy the session, but keep us around for just a bit in case they don't 15651 get our 200 OK */ 15652 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15653 } 15654 return res; 15655 }
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 15311 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(), XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
15312 { 15313 int gotdest; 15314 int res = 0; 15315 int firststate = AST_EXTENSION_REMOVED; 15316 struct sip_peer *authpeer = NULL; 15317 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15318 const char *accept = get_header(req, "Accept"); 15319 int resubscribe = (p->subscribed != NONE); 15320 char *temp, *event; 15321 15322 if (p->initreq.headers) { 15323 /* We already have a dialog */ 15324 if (p->initreq.method != SIP_SUBSCRIBE) { 15325 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15326 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15327 transmit_response(p, "403 Forbidden (within dialog)", req); 15328 /* Do not destroy session, since we will break the call if we do */ 15329 if (option_debug) 15330 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); 15331 return 0; 15332 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15333 if (option_debug) { 15334 if (resubscribe) 15335 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15336 else 15337 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15338 } 15339 } 15340 } 15341 15342 /* Check if we have a global disallow setting on subscriptions. 15343 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15344 */ 15345 if (!global_allowsubscribe) { 15346 transmit_response(p, "403 Forbidden (policy)", req); 15347 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15348 return 0; 15349 } 15350 15351 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15352 const char *to = get_header(req, "To"); 15353 char totag[128]; 15354 15355 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15356 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15357 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15358 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15359 transmit_response(p, "481 Subscription does not exist", req); 15360 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15361 return 0; 15362 } 15363 15364 /* Use this as the basis */ 15365 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15366 ast_verbose("Creating new subscription\n"); 15367 15368 copy_request(&p->initreq, req); 15369 check_via(p, req); 15370 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15371 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15372 15373 /* Find parameters to Event: header value and remove them for now */ 15374 if (ast_strlen_zero(eventheader)) { 15375 transmit_response(p, "489 Bad Event", req); 15376 if (option_debug > 1) 15377 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15378 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15379 return 0; 15380 } 15381 15382 if ( (strchr(eventheader, ';'))) { 15383 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15384 temp = strchr(event, ';'); 15385 *temp = '\0'; /* Remove any options for now */ 15386 /* We might need to use them later :-) */ 15387 } else 15388 event = (char *) eventheader; /* XXX is this legal ? */ 15389 15390 /* Handle authentication */ 15391 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15392 /* if an authentication response was sent, we are done here */ 15393 if (res == AUTH_CHALLENGE_SENT) { 15394 if (authpeer) 15395 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15396 return 0; 15397 } 15398 if (res < 0) { 15399 if (res == AUTH_FAKE_AUTH) { 15400 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15401 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 15402 } else { 15403 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15404 transmit_response_reliable(p, "403 Forbidden", req); 15405 } 15406 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15407 if (authpeer) 15408 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15409 return 0; 15410 } 15411 15412 /* Check if this user/peer is allowed to subscribe at all */ 15413 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15414 transmit_response(p, "403 Forbidden (policy)", req); 15415 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15416 if (authpeer) 15417 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15418 return 0; 15419 } 15420 15421 /* Get destination right away */ 15422 gotdest = get_destination(p, NULL); 15423 15424 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15425 parse_ok_contact(p, req); 15426 15427 build_contact(p); 15428 if (strcmp(event, "message-summary") && gotdest) { 15429 transmit_response(p, "404 Not Found", req); 15430 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15431 if (authpeer) 15432 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15433 return 0; 15434 } 15435 15436 /* Initialize tag for new subscriptions */ 15437 if (ast_strlen_zero(p->tag)) 15438 make_our_tag(p->tag, sizeof(p->tag)); 15439 15440 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15441 if (authpeer) /* No need for authpeer here */ 15442 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15443 15444 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15445 /* Polycom phones only handle xpidf+xml, even if they say they can 15446 handle pidf+xml as well 15447 */ 15448 if (strstr(p->useragent, "Polycom")) { 15449 p->subscribed = XPIDF_XML; 15450 } else if (strstr(accept, "application/pidf+xml")) { 15451 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15452 } else if (strstr(accept, "application/dialog-info+xml")) { 15453 p->subscribed = DIALOG_INFO_XML; 15454 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15455 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15456 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15457 } else if (strstr(accept, "application/xpidf+xml")) { 15458 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15459 } else if (ast_strlen_zero(accept)) { 15460 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15461 transmit_response(p, "489 Bad Event", req); 15462 15463 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15464 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15465 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15466 return 0; 15467 } 15468 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15469 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15470 } else { 15471 /* Can't find a format for events that we know about */ 15472 char mybuf[200]; 15473 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15474 transmit_response(p, mybuf, req); 15475 15476 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15477 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15478 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15479 return 0; 15480 } 15481 } else if (!strcmp(event, "message-summary")) { 15482 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15483 /* Format requested that we do not support */ 15484 transmit_response(p, "406 Not Acceptable", req); 15485 if (option_debug > 1) 15486 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15487 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15488 if (authpeer) /* No need for authpeer here */ 15489 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15490 return 0; 15491 } 15492 /* Looks like they actually want a mailbox status 15493 This version of Asterisk supports mailbox subscriptions 15494 The subscribed URI needs to exist in the dial plan 15495 In most devices, this is configurable to the voicemailmain extension you use 15496 */ 15497 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15498 transmit_response(p, "404 Not found (no mailbox)", req); 15499 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15500 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15501 if (authpeer) /* No need for authpeer here */ 15502 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15503 return 0; 15504 } 15505 15506 p->subscribed = MWI_NOTIFICATION; 15507 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15508 /* We only allow one subscription per peer */ 15509 sip_destroy(authpeer->mwipvt); 15510 authpeer->mwipvt = p; /* Link from peer to pvt */ 15511 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15512 } else { /* At this point, Asterisk does not understand the specified event */ 15513 transmit_response(p, "489 Bad Event", req); 15514 if (option_debug > 1) 15515 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15516 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15517 if (authpeer) /* No need for authpeer here */ 15518 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15519 return 0; 15520 } 15521 15522 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15523 if (p->stateid > -1) 15524 ast_extension_state_del(p->stateid, cb_extensionstate); 15525 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15526 } 15527 15528 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15529 p->lastinvite = seqno; 15530 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15531 p->expiry = atoi(get_header(req, "Expires")); 15532 15533 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15534 if (p->expiry > max_expiry) 15535 p->expiry = max_expiry; 15536 if (p->expiry < min_expiry && p->expiry > 0) 15537 p->expiry = min_expiry; 15538 15539 if (sipdebug || option_debug > 1) { 15540 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15541 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15542 else 15543 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15544 } 15545 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15546 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15547 if (p->expiry > 0) 15548 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15549 15550 if (p->subscribed == MWI_NOTIFICATION) { 15551 transmit_response(p, "200 OK", req); 15552 if (p->relatedpeer) { /* Send first notification */ 15553 ASTOBJ_WRLOCK(p->relatedpeer); 15554 sip_send_mwi_to_peer(p->relatedpeer); 15555 ASTOBJ_UNLOCK(p->relatedpeer); 15556 } 15557 } else { 15558 struct sip_pvt *p_old; 15559 15560 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15561 15562 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)); 15563 transmit_response(p, "404 Not found", req); 15564 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15565 return 0; 15566 } 15567 15568 transmit_response(p, "200 OK", req); 15569 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15570 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15571 /* hide the 'complete' exten/context in the refer_to field for later display */ 15572 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15573 15574 /* remove any old subscription from this peer for the same exten/context, 15575 as the peer has obviously forgotten about it and it's wasteful to wait 15576 for it to expire and send NOTIFY messages to the peer only to have them 15577 ignored (or generate errors) 15578 */ 15579 ast_mutex_lock(&iflock); 15580 for (p_old = iflist; p_old; p_old = p_old->next) { 15581 if (p_old == p) 15582 continue; 15583 if (p_old->initreq.method != SIP_SUBSCRIBE) 15584 continue; 15585 if (p_old->subscribed == NONE) 15586 continue; 15587 ast_mutex_lock(&p_old->lock); 15588 if (!strcmp(p_old->username, p->username)) { 15589 if (!strcmp(p_old->exten, p->exten) && 15590 !strcmp(p_old->context, p->context)) { 15591 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15592 ast_mutex_unlock(&p_old->lock); 15593 break; 15594 } 15595 } 15596 ast_mutex_unlock(&p_old->lock); 15597 } 15598 ast_mutex_unlock(&iflock); 15599 } 15600 if (!p->expiry) 15601 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15602 } 15603 return 1; 15604 }
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 12798 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.
12799 { 12800 struct ast_channel *owner; 12801 int sipmethod; 12802 int res = 1; 12803 const char *c = get_header(req, "Cseq"); 12804 const char *msg = strchr(c, ' '); 12805 12806 if (!msg) 12807 msg = ""; 12808 else 12809 msg++; 12810 sipmethod = find_sip_method(msg); 12811 12812 owner = p->owner; 12813 if (owner) 12814 owner->hangupcause = hangup_sip2cause(resp); 12815 12816 /* Acknowledge whatever it is destined for */ 12817 if ((resp >= 100) && (resp <= 199)) 12818 __sip_semi_ack(p, seqno, 0, sipmethod); 12819 else 12820 __sip_ack(p, seqno, 0, sipmethod); 12821 12822 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12823 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12824 p->pendinginvite = 0; 12825 12826 /* Get their tag if we haven't already */ 12827 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12828 char tag[128]; 12829 12830 gettag(req, "To", tag, sizeof(tag)); 12831 ast_string_field_set(p, theirtag, tag); 12832 } 12833 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12834 /* We don't really care what the response is, just that it replied back. 12835 Well, as long as it's not a 100 response... since we might 12836 need to hang around for something more "definitive" */ 12837 if (resp != 100) 12838 handle_response_peerpoke(p, resp, req); 12839 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12840 switch(resp) { 12841 case 100: /* 100 Trying */ 12842 case 101: /* 101 Dialog establishment */ 12843 if (sipmethod == SIP_INVITE) 12844 handle_response_invite(p, resp, rest, req, seqno); 12845 break; 12846 case 183: /* 183 Session Progress */ 12847 if (sipmethod == SIP_INVITE) 12848 handle_response_invite(p, resp, rest, req, seqno); 12849 break; 12850 case 180: /* 180 Ringing */ 12851 if (sipmethod == SIP_INVITE) 12852 handle_response_invite(p, resp, rest, req, seqno); 12853 break; 12854 case 182: /* 182 Queued */ 12855 if (sipmethod == SIP_INVITE) 12856 handle_response_invite(p, resp, rest, req, seqno); 12857 break; 12858 case 200: /* 200 OK */ 12859 p->authtries = 0; /* Reset authentication counter */ 12860 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12861 /* We successfully transmitted a message 12862 or a video update request in INFO */ 12863 /* Nothing happens here - the message is inside a dialog */ 12864 } else if (sipmethod == SIP_INVITE) { 12865 handle_response_invite(p, resp, rest, req, seqno); 12866 } else if (sipmethod == SIP_NOTIFY) { 12867 /* They got the notify, this is the end */ 12868 if (p->owner) { 12869 if (!p->refer) { 12870 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12871 ast_queue_hangup(p->owner); 12872 } else if (option_debug > 3) 12873 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12874 } else { 12875 if (p->subscribed == NONE) 12876 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12877 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12878 /* Ready to send the next state we have on queue */ 12879 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12880 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 12881 } 12882 } 12883 } else if (sipmethod == SIP_REGISTER) 12884 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12885 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12886 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12887 break; 12888 case 202: /* Transfer accepted */ 12889 if (sipmethod == SIP_REFER) 12890 handle_response_refer(p, resp, rest, req, seqno); 12891 break; 12892 case 401: /* Not www-authorized on SIP method */ 12893 if (sipmethod == SIP_INVITE) 12894 handle_response_invite(p, resp, rest, req, seqno); 12895 else if (sipmethod == SIP_REFER) 12896 handle_response_refer(p, resp, rest, req, seqno); 12897 else if (p->registry && sipmethod == SIP_REGISTER) 12898 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12899 else if (sipmethod == SIP_BYE) { 12900 if (ast_strlen_zero(p->authname)) { 12901 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12902 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12903 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12904 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12905 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12906 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12907 /* We fail to auth bye on our own call, but still needs to tear down the call. 12908 Life, they call it. */ 12909 } 12910 } else { 12911 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12912 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12913 } 12914 break; 12915 case 403: /* Forbidden - we failed authentication */ 12916 if (sipmethod == SIP_INVITE) 12917 handle_response_invite(p, resp, rest, req, seqno); 12918 else if (p->registry && sipmethod == SIP_REGISTER) 12919 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12920 else { 12921 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12922 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12923 } 12924 break; 12925 case 404: /* Not found */ 12926 if (p->registry && sipmethod == SIP_REGISTER) 12927 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12928 else if (sipmethod == SIP_INVITE) 12929 handle_response_invite(p, resp, rest, req, seqno); 12930 else if (owner) 12931 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12932 break; 12933 case 407: /* Proxy auth required */ 12934 if (sipmethod == SIP_INVITE) 12935 handle_response_invite(p, resp, rest, req, seqno); 12936 else if (sipmethod == SIP_REFER) 12937 handle_response_refer(p, resp, rest, req, seqno); 12938 else if (p->registry && sipmethod == SIP_REGISTER) 12939 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12940 else if (sipmethod == SIP_BYE) { 12941 if (ast_strlen_zero(p->authname)) { 12942 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12943 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12944 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12945 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12946 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12947 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12948 } 12949 } else /* We can't handle this, giving up in a bad way */ 12950 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12951 12952 break; 12953 case 408: /* Request timeout - terminate dialog */ 12954 if (sipmethod == SIP_INVITE) 12955 handle_response_invite(p, resp, rest, req, seqno); 12956 else if (sipmethod == SIP_REGISTER) 12957 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12958 else if (sipmethod == SIP_BYE) { 12959 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12960 if (option_debug) 12961 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12962 } else { 12963 if (owner) 12964 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12965 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12966 } 12967 break; 12968 case 481: /* Call leg does not exist */ 12969 if (sipmethod == SIP_INVITE) { 12970 handle_response_invite(p, resp, rest, req, seqno); 12971 } else if (sipmethod == SIP_REFER) { 12972 handle_response_refer(p, resp, rest, req, seqno); 12973 } else if (sipmethod == SIP_BYE) { 12974 /* The other side has no transaction to bye, 12975 just assume it's all right then */ 12976 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12977 } else if (sipmethod == SIP_CANCEL) { 12978 /* The other side has no transaction to cancel, 12979 just assume it's all right then */ 12980 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12981 } else { 12982 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12983 /* Guessing that this is not an important request */ 12984 } 12985 break; 12986 case 487: 12987 if (sipmethod == SIP_INVITE) 12988 handle_response_invite(p, resp, rest, req, seqno); 12989 break; 12990 case 488: /* Not acceptable here - codec error */ 12991 if (sipmethod == SIP_INVITE) 12992 handle_response_invite(p, resp, rest, req, seqno); 12993 break; 12994 case 491: /* Pending */ 12995 if (sipmethod == SIP_INVITE) 12996 handle_response_invite(p, resp, rest, req, seqno); 12997 else { 12998 if (option_debug) 12999 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13000 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13001 } 13002 break; 13003 case 501: /* Not Implemented */ 13004 if (sipmethod == SIP_INVITE) 13005 handle_response_invite(p, resp, rest, req, seqno); 13006 else if (sipmethod == SIP_REFER) 13007 handle_response_refer(p, resp, rest, req, seqno); 13008 else 13009 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13010 break; 13011 case 603: /* Declined transfer */ 13012 if (sipmethod == SIP_REFER) { 13013 handle_response_refer(p, resp, rest, req, seqno); 13014 break; 13015 } 13016 /* Fallthrough */ 13017 default: 13018 if ((resp >= 300) && (resp < 700)) { 13019 /* Fatal response */ 13020 if ((option_verbose > 2) && (resp != 487)) 13021 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13022 13023 if (sipmethod == SIP_INVITE) 13024 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13025 13026 /* XXX Locking issues?? XXX */ 13027 switch(resp) { 13028 case 300: /* Multiple Choices */ 13029 case 301: /* Moved permenantly */ 13030 case 302: /* Moved temporarily */ 13031 case 305: /* Use Proxy */ 13032 parse_moved_contact(p, req); 13033 /* Fall through */ 13034 case 486: /* Busy here */ 13035 case 600: /* Busy everywhere */ 13036 case 603: /* Decline */ 13037 if (p->owner) 13038 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13039 break; 13040 case 482: /* 13041 \note SIP is incapable of performing a hairpin call, which 13042 is yet another failure of not having a layer 2 (again, YAY 13043 IETF for thinking ahead). So we treat this as a call 13044 forward and hope we end up at the right place... */ 13045 if (option_debug) 13046 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13047 if (p->owner) 13048 ast_string_field_build(p->owner, call_forward, 13049 "Local/%s@%s", p->username, p->context); 13050 /* Fall through */ 13051 case 480: /* Temporarily Unavailable */ 13052 case 404: /* Not Found */ 13053 case 410: /* Gone */ 13054 case 400: /* Bad Request */ 13055 case 500: /* Server error */ 13056 if (sipmethod == SIP_REFER) { 13057 handle_response_refer(p, resp, rest, req, seqno); 13058 break; 13059 } 13060 /* Fall through */ 13061 case 502: /* Bad gateway */ 13062 case 503: /* Service Unavailable */ 13063 case 504: /* Server Timeout */ 13064 if (owner) 13065 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13066 break; 13067 default: 13068 /* Send hangup */ 13069 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13070 ast_queue_hangup(p->owner); 13071 break; 13072 } 13073 /* ACK on invite */ 13074 if (sipmethod == SIP_INVITE) 13075 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13076 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13077 sip_alreadygone(p); 13078 if (!p->owner) 13079 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13080 } else if ((resp >= 100) && (resp < 200)) { 13081 if (sipmethod == SIP_INVITE) { 13082 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13083 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13084 if (find_sdp(req)) 13085 process_sdp(p, req); 13086 if (p->owner) { 13087 /* Queue a progress frame */ 13088 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13089 } 13090 } 13091 } else 13092 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)); 13093 } 13094 } else { 13095 /* Responses to OUTGOING SIP requests on INCOMING calls 13096 get handled here. As well as out-of-call message responses */ 13097 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13098 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13099 13100 if (sipmethod == SIP_INVITE && resp == 200) { 13101 /* Tags in early session is replaced by the tag in 200 OK, which is 13102 the final reply to our INVITE */ 13103 char tag[128]; 13104 13105 gettag(req, "To", tag, sizeof(tag)); 13106 ast_string_field_set(p, theirtag, tag); 13107 } 13108 13109 switch(resp) { 13110 case 200: 13111 if (sipmethod == SIP_INVITE) { 13112 handle_response_invite(p, resp, rest, req, seqno); 13113 } else if (sipmethod == SIP_CANCEL) { 13114 if (option_debug) 13115 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13116 13117 /* Wait for 487, then destroy */ 13118 } else if (sipmethod == SIP_NOTIFY) { 13119 /* They got the notify, this is the end */ 13120 if (p->owner) { 13121 if (p->refer) { 13122 if (option_debug) 13123 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13124 } else 13125 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13126 /* ast_queue_hangup(p->owner); Disabled */ 13127 } else { 13128 if (!p->subscribed && !p->refer) 13129 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13130 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13131 /* Ready to send the next state we have on queue */ 13132 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13133 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 13134 } 13135 } 13136 } else if (sipmethod == SIP_BYE) 13137 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13138 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13139 /* We successfully transmitted a message or 13140 a video update request in INFO */ 13141 ; 13142 else if (sipmethod == SIP_BYE) 13143 /* Ok, we're ready to go */ 13144 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13145 break; 13146 case 202: /* Transfer accepted */ 13147 if (sipmethod == SIP_REFER) 13148 handle_response_refer(p, resp, rest, req, seqno); 13149 break; 13150 case 401: /* www-auth */ 13151 case 407: 13152 if (sipmethod == SIP_REFER) 13153 handle_response_refer(p, resp, rest, req, seqno); 13154 else if (sipmethod == SIP_INVITE) 13155 handle_response_invite(p, resp, rest, req, seqno); 13156 else if (sipmethod == SIP_BYE) { 13157 char *auth, *auth2; 13158 13159 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13160 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13161 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13162 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13163 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13164 } 13165 } 13166 break; 13167 case 481: /* Call leg does not exist */ 13168 if (sipmethod == SIP_INVITE) { 13169 /* Re-invite failed */ 13170 handle_response_invite(p, resp, rest, req, seqno); 13171 } else if (sipmethod == SIP_BYE) { 13172 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13173 } else if (sipdebug) { 13174 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13175 } 13176 break; 13177 case 501: /* Not Implemented */ 13178 if (sipmethod == SIP_INVITE) 13179 handle_response_invite(p, resp, rest, req, seqno); 13180 else if (sipmethod == SIP_REFER) 13181 handle_response_refer(p, resp, rest, req, seqno); 13182 break; 13183 case 603: /* Declined transfer */ 13184 if (sipmethod == SIP_REFER) { 13185 handle_response_refer(p, resp, rest, req, seqno); 13186 break; 13187 } 13188 /* Fallthrough */ 13189 default: /* Errors without handlers */ 13190 if ((resp >= 100) && (resp < 200)) { 13191 if (sipmethod == SIP_INVITE) { /* re-invite */ 13192 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13193 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13194 } 13195 } 13196 if ((resp >= 300) && (resp < 700)) { 13197 if ((option_verbose > 2) && (resp != 487)) 13198 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)); 13199 switch(resp) { 13200 case 488: /* Not acceptable here - codec error */ 13201 case 603: /* Decline */ 13202 case 500: /* Server error */ 13203 case 502: /* Bad gateway */ 13204 case 503: /* Service Unavailable */ 13205 case 504: /* Server timeout */ 13206 13207 /* re-invite failed */ 13208 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13209 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13210 break; 13211 } 13212 } 13213 break; 13214 } 13215 } 13216 }
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 12209 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().
12210 { 12211 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12212 int res = 0; 12213 int xmitres = 0; 12214 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12215 struct ast_channel *bridgepeer = NULL; 12216 12217 if (option_debug > 3) { 12218 if (reinvite) 12219 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12220 else 12221 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12222 } 12223 12224 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12225 if (option_debug) 12226 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12227 return; 12228 } 12229 12230 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12231 /* Don't auto congest anymore since we've gotten something useful back */ 12232 AST_SCHED_DEL(sched, p->initid); 12233 12234 /* RFC3261 says we must treat every 1xx response (but not 100) 12235 that we don't recognize as if it was 183. 12236 */ 12237 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12238 resp = 183; 12239 12240 /* Any response between 100 and 199 is PROCEEDING */ 12241 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12242 p->invitestate = INV_PROCEEDING; 12243 12244 /* Final response, not 200 ? */ 12245 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12246 p->invitestate = INV_COMPLETED; 12247 12248 12249 switch (resp) { 12250 case 100: /* Trying */ 12251 case 101: /* Dialog establishment */ 12252 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12253 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12254 check_pendings(p); 12255 break; 12256 12257 case 180: /* 180 Ringing */ 12258 case 182: /* 182 Queued */ 12259 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12260 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12261 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12262 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12263 if (p->owner->_state != AST_STATE_UP) { 12264 ast_setstate(p->owner, AST_STATE_RINGING); 12265 } 12266 } 12267 if (find_sdp(req)) { 12268 if (p->invitestate != INV_CANCELLED) 12269 p->invitestate = INV_EARLY_MEDIA; 12270 res = process_sdp(p, req); 12271 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12272 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12273 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12274 } 12275 } 12276 check_pendings(p); 12277 break; 12278 12279 case 183: /* Session progress */ 12280 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12281 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12282 /* Ignore 183 Session progress without SDP */ 12283 if (find_sdp(req)) { 12284 if (p->invitestate != INV_CANCELLED) 12285 p->invitestate = INV_EARLY_MEDIA; 12286 res = process_sdp(p, req); 12287 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12288 /* Queue a progress frame */ 12289 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12290 } 12291 } 12292 check_pendings(p); 12293 break; 12294 12295 case 200: /* 200 OK on invite - someone's answering our call */ 12296 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12297 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12298 p->authtries = 0; 12299 if (find_sdp(req)) { 12300 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12301 if (!reinvite) 12302 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12303 /* For re-invites, we try to recover */ 12304 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12305 } 12306 12307 /* Parse contact header for continued conversation */ 12308 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12309 /* This is important when we have a SIP proxy between us and the phone */ 12310 if (outgoing) { 12311 update_call_counter(p, DEC_CALL_RINGING); 12312 parse_ok_contact(p, req); 12313 if(set_address_from_contact(p)) { 12314 /* Bad contact - we don't know how to reach this device */ 12315 /* We need to ACK, but then send a bye */ 12316 /* OEJ: Possible issue that may need a check: 12317 If we have a proxy route between us and the device, 12318 should we care about resolving the contact 12319 or should we just send it? 12320 */ 12321 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12322 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12323 } 12324 12325 /* Save Record-Route for any later requests we make on this dialogue */ 12326 if (!reinvite) 12327 build_route(p, req, 1); 12328 } 12329 12330 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12331 struct sip_pvt *bridgepvt = NULL; 12332 12333 if (!bridgepeer->tech) { 12334 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12335 break; 12336 } 12337 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12338 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12339 if (bridgepvt->udptl) { 12340 if (p->t38.state == T38_PEER_REINVITE) { 12341 sip_handle_t38_reinvite(bridgepeer, p, 0); 12342 ast_rtp_set_rtptimers_onhold(p->rtp); 12343 if (p->vrtp) 12344 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12345 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12346 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12347 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12348 /* XXXX Should we really destroy this session here, without any response at all??? */ 12349 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12350 } 12351 } else { 12352 if (option_debug > 1) 12353 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12354 ast_mutex_lock(&bridgepvt->lock); 12355 bridgepvt->t38.state = T38_DISABLED; 12356 ast_mutex_unlock(&bridgepvt->lock); 12357 if (option_debug) 12358 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12359 p->t38.state = T38_DISABLED; 12360 if (option_debug > 1) 12361 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12362 } 12363 } else { 12364 /* Other side is not a SIP channel */ 12365 if (option_debug > 1) 12366 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12367 p->t38.state = T38_DISABLED; 12368 if (option_debug > 1) 12369 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12370 } 12371 } 12372 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12373 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12374 p->t38.state = T38_ENABLED; 12375 if (option_debug) 12376 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12377 } 12378 12379 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12380 if (!reinvite) { 12381 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12382 } else { /* RE-invite */ 12383 ast_queue_frame(p->owner, &ast_null_frame); 12384 } 12385 } else { 12386 /* It's possible we're getting an 200 OK after we've tried to disconnect 12387 by sending CANCEL */ 12388 /* First send ACK, then send bye */ 12389 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12390 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12391 } 12392 /* If I understand this right, the branch is different for a non-200 ACK only */ 12393 p->invitestate = INV_TERMINATED; 12394 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12395 check_pendings(p); 12396 break; 12397 case 407: /* Proxy authentication */ 12398 case 401: /* Www auth */ 12399 /* First we ACK */ 12400 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12401 if (p->options) 12402 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12403 12404 /* Then we AUTH */ 12405 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12406 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12407 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12408 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12409 if (p->authtries < MAX_AUTHTRIES) 12410 p->invitestate = INV_CALLING; 12411 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12412 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12413 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12414 sip_alreadygone(p); 12415 if (p->owner) 12416 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12417 } 12418 } 12419 break; 12420 12421 case 403: /* Forbidden */ 12422 /* First we ACK */ 12423 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12424 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12425 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12426 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12427 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12428 sip_alreadygone(p); 12429 break; 12430 12431 case 404: /* Not found */ 12432 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12433 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12434 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12435 sip_alreadygone(p); 12436 break; 12437 12438 case 408: /* Request timeout */ 12439 case 481: /* Call leg does not exist */ 12440 /* Could be REFER caused INVITE with replaces */ 12441 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 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 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12446 break; 12447 case 487: /* Cancelled transaction */ 12448 /* We have sent CANCEL on an outbound INVITE 12449 This transaction is already scheduled to be killed by sip_hangup(). 12450 */ 12451 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12452 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12453 ast_queue_hangup(p->owner); 12454 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12455 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12456 update_call_counter(p, DEC_CALL_LIMIT); 12457 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12458 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12459 sip_alreadygone(p); 12460 } 12461 break; 12462 case 488: /* Not acceptable here */ 12463 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12464 if (reinvite && p->udptl) { 12465 /* If this is a T.38 call, we should go back to 12466 audio. If this is an audio call - something went 12467 terribly wrong since we don't renegotiate codecs, 12468 only IP/port . 12469 */ 12470 p->t38.state = T38_DISABLED; 12471 /* Try to reset RTP timers */ 12472 ast_rtp_set_rtptimers_onhold(p->rtp); 12473 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12474 12475 /*! \bug Is there any way we can go back to the audio call on both 12476 sides here? 12477 */ 12478 /* While figuring that out, hangup the call */ 12479 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12480 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12481 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12482 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12483 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12484 right now we can't fall back to audio so totally abort. 12485 */ 12486 p->t38.state = T38_DISABLED; 12487 /* Try to reset RTP timers */ 12488 ast_rtp_set_rtptimers_onhold(p->rtp); 12489 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12490 12491 /* The dialog is now terminated */ 12492 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12493 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12494 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12495 sip_alreadygone(p); 12496 } else { 12497 /* We can't set up this call, so give up */ 12498 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12499 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12500 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12501 /* If there's no dialog to end, then mark p as already gone */ 12502 if (!reinvite) 12503 sip_alreadygone(p); 12504 } 12505 break; 12506 case 491: /* Pending */ 12507 /* we really should have to wait a while, then retransmit 12508 * We should support the retry-after at some point 12509 * At this point, we treat this as a congestion if the call is not in UP state 12510 */ 12511 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12512 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12513 if (p->owner->_state != AST_STATE_UP) { 12514 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12515 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12516 } else { 12517 /* This is a re-invite that failed. 12518 * Reset the flag after a while 12519 */ 12520 int wait = 3 + ast_random() % 5; 12521 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12522 if (option_debug > 2) 12523 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12524 } 12525 } 12526 break; 12527 12528 case 501: /* Not implemented */ 12529 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12530 if (p->owner) 12531 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12532 break; 12533 } 12534 if (xmitres == XMIT_ERROR) 12535 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12536 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12731 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().
12732 { 12733 struct sip_peer *peer = p->relatedpeer; 12734 int statechanged, is_reachable, was_reachable; 12735 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12736 12737 /* 12738 * Compute the response time to a ping (goes in peer->lastms.) 12739 * -1 means did not respond, 0 means unknown, 12740 * 1..maxms is a valid response, >maxms means late response. 12741 */ 12742 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12743 pingtime = 1; 12744 12745 /* Now determine new state and whether it has changed. 12746 * Use some helper variables to simplify the writing 12747 * of the expressions. 12748 */ 12749 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12750 is_reachable = pingtime <= peer->maxms; 12751 statechanged = peer->lastms == 0 /* yes, unknown before */ 12752 || was_reachable != is_reachable; 12753 12754 peer->lastms = pingtime; 12755 peer->call = NULL; 12756 if (statechanged) { 12757 const char *s = is_reachable ? "Reachable" : "Lagged"; 12758 12759 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12760 peer->name, s, pingtime, peer->maxms); 12761 ast_device_state_changed("SIP/%s", peer->name); 12762 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12763 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12764 peer->name, s, pingtime); 12765 } 12766 12767 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12768 struct sip_peer *peer_ptr = peer; 12769 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12770 } 12771 12772 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12773 12774 /* Try again eventually */ 12775 peer->pokeexpire = ast_sched_add(sched, 12776 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12777 sip_poke_peer_s, ASTOBJ_REF(peer)); 12778 12779 if (peer->pokeexpire == -1) { 12780 ASTOBJ_UNREF(peer, sip_destroy_peer); 12781 } 12782 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12541 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().
12542 { 12543 char *auth = "Proxy-Authenticate"; 12544 char *auth2 = "Proxy-Authorization"; 12545 12546 /* If no refer structure exists, then do nothing */ 12547 if (!p->refer) 12548 return; 12549 12550 switch (resp) { 12551 case 202: /* Transfer accepted */ 12552 /* We need to do something here */ 12553 /* The transferee is now sending INVITE to target */ 12554 p->refer->status = REFER_ACCEPTED; 12555 /* Now wait for next message */ 12556 if (option_debug > 2) 12557 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12558 /* We should hang along, waiting for NOTIFY's here */ 12559 break; 12560 12561 case 401: /* Not www-authorized on SIP method */ 12562 case 407: /* Proxy auth */ 12563 if (ast_strlen_zero(p->authname)) { 12564 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12565 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12566 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12567 } 12568 if (resp == 401) { 12569 auth = "WWW-Authenticate"; 12570 auth2 = "Authorization"; 12571 } 12572 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12573 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12574 p->refer->status = REFER_NOAUTH; 12575 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12576 } 12577 break; 12578 case 481: /* Call leg does not exist */ 12579 12580 /* A transfer with Replaces did not work */ 12581 /* OEJ: We should Set flag, cancel the REFER, go back 12582 to original call - but right now we can't */ 12583 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12584 if (p->owner) 12585 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12586 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12587 break; 12588 12589 case 500: /* Server error */ 12590 case 501: /* Method not implemented */ 12591 /* Return to the current call onhold */ 12592 /* Status flag needed to be reset */ 12593 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12594 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12595 p->refer->status = REFER_FAILED; 12596 break; 12597 case 603: /* Transfer declined */ 12598 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12599 p->refer->status = REFER_FAILED; 12600 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12601 break; 12602 } 12603 }
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 12606 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().
12607 { 12608 int expires, expires_ms; 12609 struct sip_registry *r; 12610 r=p->registry; 12611 12612 switch (resp) { 12613 case 401: /* Unauthorized */ 12614 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12615 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12616 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12617 } 12618 break; 12619 case 403: /* Forbidden */ 12620 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12621 if (global_regattempts_max) 12622 p->registry->regattempts = global_regattempts_max+1; 12623 AST_SCHED_DEL(sched, r->timeout); 12624 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12625 break; 12626 case 404: /* Not found */ 12627 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12628 if (global_regattempts_max) 12629 p->registry->regattempts = global_regattempts_max+1; 12630 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12631 r->call = NULL; 12632 AST_SCHED_DEL(sched, r->timeout); 12633 break; 12634 case 407: /* Proxy auth */ 12635 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12636 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12637 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12638 } 12639 break; 12640 case 408: /* Request timeout */ 12641 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12642 r->call = NULL; 12643 AST_SCHED_DEL(sched, r->timeout); 12644 break; 12645 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12646 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12647 if (global_regattempts_max) 12648 p->registry->regattempts = global_regattempts_max+1; 12649 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12650 r->call = NULL; 12651 AST_SCHED_DEL(sched, r->timeout); 12652 break; 12653 case 200: /* 200 OK */ 12654 if (!r) { 12655 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12656 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12657 return 0; 12658 } 12659 12660 r->regstate = REG_STATE_REGISTERED; 12661 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12662 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12663 r->regattempts = 0; 12664 if (option_debug) 12665 ast_log(LOG_DEBUG, "Registration successful\n"); 12666 if (r->timeout > -1) { 12667 if (option_debug) 12668 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12669 } 12670 AST_SCHED_DEL(sched, r->timeout); 12671 r->call = NULL; 12672 p->registry = NULL; 12673 /* Let this one hang around until we have all the responses */ 12674 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12675 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12676 12677 /* set us up for re-registering */ 12678 /* figure out how long we got registered for */ 12679 AST_SCHED_DEL(sched, r->expire); 12680 /* according to section 6.13 of RFC, contact headers override 12681 expires headers, so check those first */ 12682 expires = 0; 12683 12684 /* XXX todo: try to save the extra call */ 12685 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12686 const char *contact = NULL; 12687 const char *tmptmp = NULL; 12688 int start = 0; 12689 for(;;) { 12690 contact = __get_header(req, "Contact", &start); 12691 /* this loop ensures we get a contact header about our register request */ 12692 if(!ast_strlen_zero(contact)) { 12693 if( (tmptmp=strstr(contact, p->our_contact))) { 12694 contact=tmptmp; 12695 break; 12696 } 12697 } else 12698 break; 12699 } 12700 tmptmp = strcasestr(contact, "expires="); 12701 if (tmptmp) { 12702 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12703 expires = 0; 12704 } 12705 12706 } 12707 if (!expires) 12708 expires=atoi(get_header(req, "expires")); 12709 if (!expires) 12710 expires=default_expiry; 12711 12712 expires_ms = expires * 1000; 12713 if (expires <= EXPIRY_GUARD_LIMIT) 12714 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12715 else 12716 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12717 if (sipdebug) 12718 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12719 12720 r->refresh= (int) expires_ms / 1000; 12721 12722 /* Schedule re-registration before we expire */ 12723 AST_SCHED_DEL(sched, r->expire); 12724 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12725 ASTOBJ_UNREF(r, sip_registry_destroy); 12726 } 12727 return 1; 12728 }
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 5867 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.
05868 { 05869 /* Initialize a request */ 05870 memset(req, 0, sizeof(*req)); 05871 req->method = sipmethod; 05872 req->header[0] = req->data; 05873 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05874 req->len = strlen(req->header[0]); 05875 req->headers++; 05876 return 0; 05877 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5854 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
05855 { 05856 /* Initialize a response */ 05857 memset(resp, 0, sizeof(*resp)); 05858 resp->method = SIP_RESPONSE; 05859 resp->header[0] = resp->data; 05860 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05861 resp->len = strlen(resp->header[0]); 05862 resp->headers++; 05863 return 0; 05864 }
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 6954 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().
06955 { 06956 char invite_buf[256] = ""; 06957 char *invite = invite_buf; 06958 size_t invite_max = sizeof(invite_buf); 06959 char from[256]; 06960 char to[256]; 06961 char tmp[SIPBUFSIZE/2]; 06962 char tmp2[SIPBUFSIZE/2]; 06963 const char *l = NULL, *n = NULL; 06964 const char *urioptions = ""; 06965 06966 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06967 const char *s = p->username; /* being a string field, cannot be NULL */ 06968 06969 /* Test p->username against allowed characters in AST_DIGIT_ANY 06970 If it matches the allowed characters list, then sipuser = ";user=phone" 06971 If not, then sipuser = "" 06972 */ 06973 /* + is allowed in first position in a tel: uri */ 06974 if (*s == '+') 06975 s++; 06976 for (; *s; s++) { 06977 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06978 break; 06979 } 06980 /* If we have only digits, add ;user=phone to the uri */ 06981 if (*s) 06982 urioptions = ";user=phone"; 06983 } 06984 06985 06986 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06987 06988 if (p->owner) { 06989 l = p->owner->cid.cid_num; 06990 n = p->owner->cid.cid_name; 06991 } 06992 /* if we are not sending RPID and user wants his callerid restricted */ 06993 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06994 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06995 l = CALLERID_UNKNOWN; 06996 n = l; 06997 } 06998 if (ast_strlen_zero(l)) 06999 l = default_callerid; 07000 if (ast_strlen_zero(n)) 07001 n = l; 07002 /* Allow user to be overridden */ 07003 if (!ast_strlen_zero(p->fromuser)) 07004 l = p->fromuser; 07005 else /* Save for any further attempts */ 07006 ast_string_field_set(p, fromuser, l); 07007 07008 /* Allow user to be overridden */ 07009 if (!ast_strlen_zero(p->fromname)) 07010 n = p->fromname; 07011 else /* Save for any further attempts */ 07012 ast_string_field_set(p, fromname, n); 07013 07014 if (pedanticsipchecking) { 07015 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07016 n = tmp; 07017 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07018 l = tmp2; 07019 } 07020 07021 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07022 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); 07023 else 07024 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07025 07026 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07027 if (!ast_strlen_zero(p->fullcontact)) { 07028 /* If we have full contact, trust it */ 07029 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07030 } else { 07031 /* Otherwise, use the username while waiting for registration */ 07032 ast_build_string(&invite, &invite_max, "sip:"); 07033 if (!ast_strlen_zero(p->username)) { 07034 n = p->username; 07035 if (pedanticsipchecking) { 07036 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07037 n = tmp; 07038 } 07039 ast_build_string(&invite, &invite_max, "%s@", n); 07040 } 07041 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07042 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07043 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07044 ast_build_string(&invite, &invite_max, "%s", urioptions); 07045 } 07046 07047 /* If custom URI options have been provided, append them */ 07048 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07049 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07050 07051 ast_string_field_set(p, uri, invite_buf); 07052 07053 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07054 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07055 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07056 } else if (p->options && p->options->vxml_url) { 07057 /* If there is a VXML URL append it to the SIP URL */ 07058 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07059 } else 07060 snprintf(to, sizeof(to), "<%s>", p->uri); 07061 07062 init_req(req, sipmethod, p->uri); 07063 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07064 07065 add_header(req, "Via", p->via); 07066 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07067 * OTOH, then we won't have anything in p->route anyway */ 07068 /* Build Remote Party-ID and From */ 07069 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07070 build_rpid(p); 07071 add_header(req, "From", p->rpid_from); 07072 } else 07073 add_header(req, "From", from); 07074 add_header(req, "To", to); 07075 ast_string_field_set(p, exten, l); 07076 build_contact(p); 07077 add_header(req, "Contact", p->our_contact); 07078 add_header(req, "Call-ID", p->callid); 07079 add_header(req, "CSeq", tmp); 07080 if (!ast_strlen_zero(global_useragent)) 07081 add_header(req, "User-Agent", global_useragent); 07082 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07083 if (!ast_strlen_zero(p->rpid)) 07084 add_header(req, "Remote-Party-ID", p->rpid); 07085 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 10225 of file chan_sip.c.
Referenced by _sip_show_peer().
10226 { 10227 if (port && invite) 10228 return "port,invite"; 10229 else if (port) 10230 return "port"; 10231 else if (invite) 10232 return "invite"; 10233 else 10234 return "no"; 10235 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8281 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08282 { 08283 if (!route) 08284 ast_verbose("list_route: no route\n"); 08285 else { 08286 for (;route; route = route->next) 08287 ast_verbose("list_route: hop: <%s>\n", route->hop); 08288 } 08289 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18556 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.
18557 { 18558 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18559 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18560 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18561 18562 if (!(sched = sched_context_create())) { 18563 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18564 return AST_MODULE_LOAD_FAILURE; 18565 } 18566 18567 if (!(io = io_context_create())) { 18568 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18569 sched_context_destroy(sched); 18570 return AST_MODULE_LOAD_FAILURE; 18571 } 18572 18573 sip_reloadreason = CHANNEL_MODULE_LOAD; 18574 18575 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18576 return AST_MODULE_LOAD_DECLINE; 18577 18578 /* Make sure we can register our sip channel type */ 18579 if (ast_channel_register(&sip_tech)) { 18580 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18581 io_context_destroy(io); 18582 sched_context_destroy(sched); 18583 return AST_MODULE_LOAD_FAILURE; 18584 } 18585 18586 /* Register all CLI functions for SIP */ 18587 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18588 18589 /* Tell the RTP subdriver that we're here */ 18590 ast_rtp_proto_register(&sip_rtp); 18591 18592 /* Tell the UDPTL subdriver that we're here */ 18593 ast_udptl_proto_register(&sip_udptl); 18594 18595 /* Register dialplan applications */ 18596 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18597 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18598 18599 /* Register dialplan functions */ 18600 ast_custom_function_register(&sip_header_function); 18601 ast_custom_function_register(&sippeer_function); 18602 ast_custom_function_register(&sipchaninfo_function); 18603 ast_custom_function_register(&checksipdomain_function); 18604 18605 /* Register manager commands */ 18606 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18607 "List SIP peers (text format)", mandescr_show_peers); 18608 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18609 "Show SIP peer (text format)", mandescr_show_peer); 18610 18611 sip_poke_all_peers(); 18612 sip_send_all_registers(); 18613 18614 /* And start the monitor for the first time */ 18615 restart_monitor(); 18616 18617 return AST_MODULE_LOAD_SUCCESS; 18618 }
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 14684 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().
14685 { 14686 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14687 /* Chan 2: Call from Asterisk to target */ 14688 int res = 0; 14689 struct sip_pvt *targetcall_pvt; 14690 14691 /* Check if the call ID of the replaces header does exist locally */ 14692 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14693 transferer->refer->replaces_callid_fromtag))) { 14694 if (transferer->refer->localtransfer) { 14695 /* We did not find the refered call. Sorry, can't accept then */ 14696 transmit_response(transferer, "202 Accepted", req); 14697 /* Let's fake a response from someone else in order 14698 to follow the standard */ 14699 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14700 append_history(transferer, "Xfer", "Refer failed"); 14701 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14702 transferer->refer->status = REFER_FAILED; 14703 return -1; 14704 } 14705 /* Fall through for remote transfers that we did not find locally */ 14706 if (option_debug > 2) 14707 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14708 return 0; 14709 } 14710 14711 /* Ok, we can accept this transfer */ 14712 transmit_response(transferer, "202 Accepted", req); 14713 append_history(transferer, "Xfer", "Refer accepted"); 14714 if (!targetcall_pvt->owner) { /* No active channel */ 14715 if (option_debug > 3) 14716 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14717 /* Cancel transfer */ 14718 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14719 append_history(transferer, "Xfer", "Refer failed"); 14720 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14721 transferer->refer->status = REFER_FAILED; 14722 ast_mutex_unlock(&targetcall_pvt->lock); 14723 ast_channel_unlock(current->chan1); 14724 return -1; 14725 } 14726 14727 /* We have a channel, find the bridge */ 14728 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14729 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14730 14731 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14732 /* Wrong state of new channel */ 14733 if (option_debug > 3) { 14734 if (target.chan2) 14735 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14736 else if (target.chan1->_state != AST_STATE_RING) 14737 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14738 else 14739 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14740 } 14741 } 14742 14743 /* Transfer */ 14744 if (option_debug > 3 && sipdebug) { 14745 if (current->chan2) /* We have two bridges */ 14746 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14747 else /* One bridge, propably transfer of IVR/voicemail etc */ 14748 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14749 } 14750 14751 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14752 14753 /* Perform the transfer */ 14754 res = attempt_transfer(current, &target); 14755 ast_mutex_unlock(&targetcall_pvt->lock); 14756 if (res) { 14757 /* Failed transfer */ 14758 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14759 append_history(transferer, "Xfer", "Refer failed"); 14760 transferer->refer->status = REFER_FAILED; 14761 if (targetcall_pvt->owner) 14762 ast_channel_unlock(targetcall_pvt->owner); 14763 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14764 if (res != -2) 14765 ast_hangup(transferer->owner); 14766 else 14767 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14768 } else { 14769 /* Transfer succeeded! */ 14770 14771 /* Tell transferer that we're done. */ 14772 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14773 append_history(transferer, "Xfer", "Refer succeeded"); 14774 transferer->refer->status = REFER_200OK; 14775 if (targetcall_pvt->owner) { 14776 if (option_debug) 14777 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14778 ast_channel_unlock(targetcall_pvt->owner); 14779 } 14780 } 14781 return 1; 14782 }
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 4767 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04768 { 04769 int h = 0, t = 0; 04770 int lws = 0; 04771 04772 for (; h < len;) { 04773 /* Eliminate all CRs */ 04774 if (msgbuf[h] == '\r') { 04775 h++; 04776 continue; 04777 } 04778 /* Check for end-of-line */ 04779 if (msgbuf[h] == '\n') { 04780 /* Check for end-of-message */ 04781 if (h + 1 == len) 04782 break; 04783 /* Check for a continuation line */ 04784 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04785 /* Merge continuation line */ 04786 h++; 04787 continue; 04788 } 04789 /* Propagate LF and start new line */ 04790 msgbuf[t++] = msgbuf[h++]; 04791 lws = 0; 04792 continue; 04793 } 04794 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04795 if (lws) { 04796 h++; 04797 continue; 04798 } 04799 msgbuf[t++] = msgbuf[h++]; 04800 lws = 1; 04801 continue; 04802 } 04803 msgbuf[t++] = msgbuf[h++]; 04804 if (lws) 04805 lws = 0; 04806 } 04807 msgbuf[t] = '\0'; 04808 return t; 04809 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4438 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().
04439 { 04440 snprintf(tagbuf, len, "as%08lx", ast_random()); 04441 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10470 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().
10471 { 10472 const char *a[4]; 10473 const char *peer; 10474 int ret; 10475 10476 peer = astman_get_header(m,"Peer"); 10477 if (ast_strlen_zero(peer)) { 10478 astman_send_error(s, m, "Peer: <name> missing.\n"); 10479 return 0; 10480 } 10481 a[0] = "sip"; 10482 a[1] = "show"; 10483 a[2] = "peer"; 10484 a[3] = peer; 10485 10486 ret = _sip_show_peer(1, -1, s, m, 4, a); 10487 astman_append(s, "\r\n\r\n" ); 10488 return ret; 10489 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10021 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().
10022 { 10023 const char *id = astman_get_header(m,"ActionID"); 10024 const char *a[] = {"sip", "show", "peers"}; 10025 char idtext[256] = ""; 10026 int total = 0; 10027 10028 if (!ast_strlen_zero(id)) 10029 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10030 10031 astman_send_ack(s, m, "Peer status list will follow"); 10032 /* List the peers in separate manager events */ 10033 _sip_show_peers(-1, &total, s, m, 3, a); 10034 /* Send final confirmation */ 10035 astman_append(s, 10036 "Event: PeerlistComplete\r\n" 10037 "ListItems: %d\r\n" 10038 "%s" 10039 "\r\n", total, idtext); 10040 return 0; 10041 }
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 9924 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), display_nat_warning(), sip_show_channel(), sip_show_settings(), and sip_show_users().
09925 { 09926 switch(nat) { 09927 case SIP_NAT_NEVER: 09928 return "No"; 09929 case SIP_NAT_ROUTE: 09930 return "Route"; 09931 case SIP_NAT_ALWAYS: 09932 return "Always"; 09933 case SIP_NAT_RFC3581: 09934 return "RFC3581"; 09935 default: 09936 return "Unknown"; 09937 } 09938 }
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 12110 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().
12111 { 12112 char tmp[SIPBUFSIZE]; 12113 char *s, *e, *uri, *t; 12114 char *domain; 12115 12116 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12117 if ((t = strchr(tmp, ','))) 12118 *t = '\0'; 12119 s = get_in_brackets(tmp); 12120 uri = ast_strdupa(s); 12121 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12122 if (!strncasecmp(s, "sip:", 4)) 12123 s += 4; 12124 e = strchr(s, ';'); 12125 if (e) 12126 *e = '\0'; 12127 if (option_debug) 12128 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12129 if (p->owner) 12130 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12131 } else { 12132 e = strchr(tmp, '@'); 12133 if (e) { 12134 *e++ = '\0'; 12135 domain = e; 12136 } else { 12137 /* No username part */ 12138 domain = tmp; 12139 } 12140 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12141 if (e) 12142 *e = '\0'; 12143 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12144 if (e) 12145 *e = '\0'; 12146 12147 if (!strncasecmp(s, "sip:", 4)) 12148 s += 4; 12149 if (option_debug > 1) 12150 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12151 if (p->owner) { 12152 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12153 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12154 ast_string_field_set(p->owner, call_forward, s); 12155 } 12156 } 12157 }
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 8029 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().
08030 { 08031 char contact[SIPBUFSIZE]; 08032 char *c; 08033 08034 /* Look for brackets */ 08035 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08036 c = get_in_brackets(contact); 08037 08038 /* Save full contact to call pvt for later bye or re-invite */ 08039 ast_string_field_set(pvt, fullcontact, c); 08040 08041 /* Save URI for later ACKs, BYE or RE-invites */ 08042 ast_string_field_set(pvt, okcontacturi, c); 08043 08044 /* We should return false for URI:s we can't handle, 08045 like sips:, tel:, mailto:,ldap: etc */ 08046 return TRUE; 08047 }
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 8113 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().
08114 { 08115 char contact[SIPBUFSIZE]; 08116 char data[SIPBUFSIZE]; 08117 const char *expires = get_header(req, "Expires"); 08118 int expiry = atoi(expires); 08119 char *curi, *n, *pt; 08120 int port; 08121 const char *useragent; 08122 struct hostent *hp; 08123 struct ast_hostent ahp; 08124 struct sockaddr_in oldsin; 08125 08126 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08127 08128 if (ast_strlen_zero(expires)) { /* No expires header */ 08129 expires = strcasestr(contact, ";expires="); 08130 if (expires) { 08131 /* XXX bug here, we overwrite the string */ 08132 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08133 if (sscanf(expires + 9, "%d", &expiry) != 1) 08134 expiry = default_expiry; 08135 } else { 08136 /* Nothing has been specified */ 08137 expiry = default_expiry; 08138 } 08139 } 08140 08141 /* Look for brackets */ 08142 curi = contact; 08143 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08144 strsep(&curi, ";"); /* This is Header options, not URI options */ 08145 curi = get_in_brackets(contact); 08146 08147 /* if they did not specify Contact: or Expires:, they are querying 08148 what we currently have stored as their contact address, so return 08149 it 08150 */ 08151 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08152 /* If we have an active registration, tell them when the registration is going to expire */ 08153 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08154 pvt->expiry = ast_sched_when(sched, peer->expire); 08155 return PARSE_REGISTER_QUERY; 08156 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08157 /* This means remove all registrations and return OK */ 08158 memset(&peer->addr, 0, sizeof(peer->addr)); 08159 if (!AST_SCHED_DEL(sched, peer->expire)) { 08160 struct sip_peer *peer_ptr = peer; 08161 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08162 } 08163 08164 destroy_association(peer); 08165 08166 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08167 peer->fullcontact[0] = '\0'; 08168 peer->useragent[0] = '\0'; 08169 peer->sipoptions = 0; 08170 peer->lastms = 0; 08171 08172 if (option_verbose > 2) 08173 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08174 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08175 return PARSE_REGISTER_UPDATE; 08176 } 08177 08178 /* Store whatever we got as a contact from the client */ 08179 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08180 08181 /* For the 200 OK, we should use the received contact */ 08182 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08183 08184 /* Make sure it's a SIP URL */ 08185 if (strncasecmp(curi, "sip:", 4)) { 08186 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08187 } else 08188 curi += 4; 08189 /* Ditch q */ 08190 curi = strsep(&curi, ";"); 08191 /* Grab host */ 08192 n = strchr(curi, '@'); 08193 if (!n) { 08194 n = curi; 08195 curi = NULL; 08196 } else 08197 *n++ = '\0'; 08198 pt = strchr(n, ':'); 08199 if (pt) { 08200 *pt++ = '\0'; 08201 port = atoi(pt); 08202 } else 08203 port = STANDARD_SIP_PORT; 08204 oldsin = peer->addr; 08205 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08206 /* XXX This could block for a long time XXX */ 08207 hp = ast_gethostbyname(n, &ahp); 08208 if (!hp) { 08209 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08210 return PARSE_REGISTER_FAILED; 08211 } 08212 peer->addr.sin_family = AF_INET; 08213 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08214 peer->addr.sin_port = htons(port); 08215 } else { 08216 /* Don't trust the contact field. Just use what they came to us 08217 with */ 08218 peer->addr = pvt->recv; 08219 } 08220 08221 /* Save SIP options profile */ 08222 peer->sipoptions = pvt->sipoptions; 08223 08224 if (curi && ast_strlen_zero(peer->username)) 08225 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08226 08227 if (!AST_SCHED_DEL(sched, peer->expire)) { 08228 struct sip_peer *peer_ptr = peer; 08229 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08230 } 08231 if (expiry > max_expiry) 08232 expiry = max_expiry; 08233 if (expiry < min_expiry) 08234 expiry = min_expiry; 08235 if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) { 08236 peer->expire = -1; 08237 } else { 08238 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08239 if (peer->expire == -1) { 08240 struct sip_peer *peer_ptr = peer; 08241 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08242 } 08243 } 08244 pvt->expiry = expiry; 08245 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); 08246 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08247 ast_db_put("SIP/Registry", peer->name, data); 08248 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08249 08250 /* Is this a new IP address for us? */ 08251 if (inaddrcmp(&peer->addr, &oldsin)) { 08252 sip_poke_peer(peer); 08253 if (option_verbose > 2) 08254 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); 08255 register_peer_exten(peer, 1); 08256 } 08257 08258 /* Save User agent */ 08259 useragent = get_header(req, "User-Agent"); 08260 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08261 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08262 if (option_verbose > 3) 08263 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08264 } 08265 return PARSE_REGISTER_UPDATE; 08266 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4814 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().
04815 { 04816 /* Divide fields by NULL's */ 04817 char *c; 04818 int f = 0; 04819 04820 c = req->data; 04821 04822 /* First header starts immediately */ 04823 req->header[f] = c; 04824 while(*c) { 04825 if (*c == '\n') { 04826 /* We've got a new header */ 04827 *c = 0; 04828 04829 if (sipdebug && option_debug > 3) 04830 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04831 if (ast_strlen_zero(req->header[f])) { 04832 /* Line by itself means we're now in content */ 04833 c++; 04834 break; 04835 } 04836 if (f >= SIP_MAX_HEADERS - 1) { 04837 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04838 } else 04839 f++; 04840 req->header[f] = c + 1; 04841 } else if (*c == '\r') { 04842 /* Ignore but eliminate \r's */ 04843 *c = 0; 04844 } 04845 c++; 04846 } 04847 /* Check for last header */ 04848 if (!ast_strlen_zero(req->header[f])) { 04849 if (sipdebug && option_debug > 3) 04850 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04851 f++; 04852 } 04853 req->headers = f; 04854 /* Now we process any mime content */ 04855 f = 0; 04856 req->line[f] = c; 04857 while(*c) { 04858 if (*c == '\n') { 04859 /* We've got a new line */ 04860 *c = 0; 04861 if (sipdebug && option_debug > 3) 04862 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04863 if (f >= SIP_MAX_LINES - 1) { 04864 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04865 } else 04866 f++; 04867 req->line[f] = c + 1; 04868 } else if (*c == '\r') { 04869 /* Ignore and eliminate \r's */ 04870 *c = 0; 04871 } 04872 c++; 04873 } 04874 /* Check for last line */ 04875 if (!ast_strlen_zero(req->line[f])) 04876 f++; 04877 req->lines = f; 04878 if (*c) 04879 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04880 /* Split up the first line parts */ 04881 return determine_firstline_parts(req); 04882 }
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 9943 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09944 { 09945 int res = 0; 09946 if (peer->maxms) { 09947 if (peer->lastms < 0) { 09948 ast_copy_string(status, "UNREACHABLE", statuslen); 09949 } else if (peer->lastms > peer->maxms) { 09950 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09951 res = 1; 09952 } else if (peer->lastms) { 09953 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09954 res = 1; 09955 } else { 09956 ast_copy_string(status, "UNKNOWN", statuslen); 09957 } 09958 } else { 09959 ast_copy_string(status, "Unmonitored", statuslen); 09960 /* Checking if port is 0 */ 09961 res = -1; 09962 } 09963 return res; 09964 }
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 10411 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().
10412 { 10413 int x, codec; 10414 10415 for(x = 0; x < 32 ; x++) { 10416 codec = ast_codec_pref_index(pref, x); 10417 if (!codec) 10418 break; 10419 ast_cli(fd, "%s", ast_getformatname(codec)); 10420 ast_cli(fd, ":%d", pref->framing[x]); 10421 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10422 ast_cli(fd, ","); 10423 } 10424 if (!x) 10425 ast_cli(fd, "none"); 10426 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10202 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10203 { 10204 char buf[256]; 10205 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10206 }
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 5015 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.
05016 { 05017 const char *m; /* SDP media offer */ 05018 const char *c; 05019 const char *a; 05020 char host[258]; 05021 int len = -1; 05022 int portno = -1; /*!< RTP Audio port number */ 05023 int vportno = -1; /*!< RTP Video port number */ 05024 int udptlportno = -1; 05025 int peert38capability = 0; 05026 char s[256]; 05027 int old = 0; 05028 05029 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05030 int peercapability = 0, peernoncodeccapability = 0; 05031 int vpeercapability = 0, vpeernoncodeccapability = 0; 05032 struct sockaddr_in sin; /*!< media socket address */ 05033 struct sockaddr_in vsin; /*!< Video socket address */ 05034 05035 const char *codecs; 05036 struct hostent *hp; /*!< RTP Audio host IP */ 05037 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05038 struct ast_hostent audiohp; 05039 struct ast_hostent videohp; 05040 int codec; 05041 int destiterator = 0; 05042 int iterator; 05043 int sendonly = -1; 05044 int numberofports; 05045 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05046 int newjointcapability; /* Negotiated capability */ 05047 int newpeercapability; 05048 int newnoncodeccapability; 05049 int numberofmediastreams = 0; 05050 int debug = sip_debug_test_pvt(p); 05051 05052 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05053 int last_rtpmap_codec=0; 05054 05055 if (!p->rtp) { 05056 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05057 return -1; 05058 } 05059 05060 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05061 newaudiortp = alloca(ast_rtp_alloc_size()); 05062 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05063 ast_rtp_new_init(newaudiortp); 05064 ast_rtp_pt_clear(newaudiortp); 05065 05066 newvideortp = alloca(ast_rtp_alloc_size()); 05067 memset(newvideortp, 0, ast_rtp_alloc_size()); 05068 ast_rtp_new_init(newvideortp); 05069 ast_rtp_pt_clear(newvideortp); 05070 05071 /* Update our last rtprx when we receive an SDP, too */ 05072 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05073 05074 05075 /* Try to find first media stream */ 05076 m = get_sdp(req, "m"); 05077 destiterator = req->sdp_start; 05078 c = get_sdp_iterate(&destiterator, req, "c"); 05079 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05080 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05081 return -1; 05082 } 05083 05084 /* Check for IPv4 address (not IPv6 yet) */ 05085 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05086 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05087 return -1; 05088 } 05089 05090 /* XXX This could block for a long time, and block the main thread! XXX */ 05091 hp = ast_gethostbyname(host, &audiohp); 05092 if (!hp) { 05093 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05094 return -1; 05095 } 05096 vhp = hp; /* Copy to video address as default too */ 05097 05098 iterator = req->sdp_start; 05099 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05100 05101 05102 /* Find media streams in this SDP offer */ 05103 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05104 int x; 05105 int audio = FALSE; 05106 05107 numberofports = 1; 05108 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05109 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05110 audio = TRUE; 05111 numberofmediastreams++; 05112 /* Found audio stream in this media definition */ 05113 portno = x; 05114 /* Scan through the RTP payload types specified in a "m=" line: */ 05115 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05116 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05117 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05118 return -1; 05119 } 05120 if (debug) 05121 ast_verbose("Found RTP audio format %d\n", codec); 05122 ast_rtp_set_m_type(newaudiortp, codec); 05123 } 05124 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05125 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05126 /* If it is not audio - is it video ? */ 05127 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05128 numberofmediastreams++; 05129 vportno = x; 05130 /* Scan through the RTP payload types specified in a "m=" line: */ 05131 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05132 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05133 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05134 return -1; 05135 } 05136 if (debug) 05137 ast_verbose("Found RTP video format %d\n", codec); 05138 ast_rtp_set_m_type(newvideortp, codec); 05139 } 05140 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05141 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05142 if (debug) 05143 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05144 udptlportno = x; 05145 numberofmediastreams++; 05146 05147 if (p->owner && p->lastinvite) { 05148 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05149 if (option_debug > 1) 05150 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05151 } else { 05152 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05153 if (option_debug > 1) 05154 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05155 } 05156 } else 05157 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05158 if (numberofports > 1) 05159 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05160 05161 05162 /* Check for Media-description-level-address for audio */ 05163 c = get_sdp_iterate(&destiterator, req, "c"); 05164 if (!ast_strlen_zero(c)) { 05165 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05166 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05167 } else { 05168 /* XXX This could block for a long time, and block the main thread! XXX */ 05169 if (audio) { 05170 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05171 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05172 return -2; 05173 } 05174 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05175 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05176 return -2; 05177 } 05178 } 05179 05180 } 05181 } 05182 if (portno == -1 && vportno == -1 && udptlportno == -1) 05183 /* No acceptable offer found in SDP - we have no ports */ 05184 /* Do not change RTP or VRTP if this is a re-invite */ 05185 return -2; 05186 05187 if (numberofmediastreams > 2) 05188 /* We have too many fax, audio and/or video media streams, fail this offer */ 05189 return -3; 05190 05191 /* RTP addresses and ports for audio and video */ 05192 sin.sin_family = AF_INET; 05193 vsin.sin_family = AF_INET; 05194 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05195 if (vhp) 05196 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05197 05198 /* Setup UDPTL port number */ 05199 if (p->udptl) { 05200 if (udptlportno > 0) { 05201 sin.sin_port = htons(udptlportno); 05202 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05203 struct sockaddr_in peer; 05204 ast_rtp_get_peer(p->rtp, &peer); 05205 if (peer.sin_addr.s_addr) { 05206 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(&sin.sin_addr)); 05207 if (debug) { 05208 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)); 05209 } 05210 } 05211 } 05212 ast_udptl_set_peer(p->udptl, &sin); 05213 if (debug) 05214 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05215 } else { 05216 ast_udptl_stop(p->udptl); 05217 if (debug) 05218 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05219 } 05220 } 05221 05222 05223 if (p->rtp) { 05224 if (portno > 0) { 05225 sin.sin_port = htons(portno); 05226 ast_rtp_set_peer(p->rtp, &sin); 05227 if (debug) 05228 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05229 } else { 05230 if (udptlportno > 0) { 05231 if (debug) 05232 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05233 } else { 05234 ast_rtp_stop(p->rtp); 05235 if (debug) 05236 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05237 } 05238 } 05239 } 05240 /* Setup video port number */ 05241 if (vportno != -1) 05242 vsin.sin_port = htons(vportno); 05243 05244 /* Next, scan through each "a=rtpmap:" line, noting each 05245 * specified RTP payload type (with corresponding MIME subtype): 05246 */ 05247 /* XXX This needs to be done per media stream, since it's media stream specific */ 05248 iterator = req->sdp_start; 05249 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05250 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05251 if (option_debug > 1) { 05252 int breakout = FALSE; 05253 05254 /* If we're debugging, check for unsupported sdp options */ 05255 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05256 if (debug) 05257 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05258 breakout = TRUE; 05259 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05260 /* Format parameters: Not supported */ 05261 /* Note: This is used for codec parameters, like bitrate for 05262 G722 and video formats for H263 and H264 05263 See RFC2327 for an example */ 05264 if (debug) 05265 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05266 breakout = TRUE; 05267 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05268 /* Video stuff: Not supported */ 05269 if (debug) 05270 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05271 breakout = TRUE; 05272 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05273 /* Video stuff: Not supported */ 05274 if (debug) 05275 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05276 breakout = TRUE; 05277 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05278 /* SRTP stuff, not yet supported */ 05279 if (debug) 05280 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05281 breakout = TRUE; 05282 } 05283 if (breakout) /* We have a match, skip to next header */ 05284 continue; 05285 } 05286 if (!strcasecmp(a, "sendonly")) { 05287 if (sendonly == -1) 05288 sendonly = 1; 05289 continue; 05290 } else if (!strcasecmp(a, "inactive")) { 05291 if (sendonly == -1) 05292 sendonly = 2; 05293 continue; 05294 } else if (!strcasecmp(a, "sendrecv")) { 05295 if (sendonly == -1) 05296 sendonly = 0; 05297 continue; 05298 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05299 char *tmp = strrchr(a, ':'); 05300 long int framing = 0; 05301 if (tmp) { 05302 tmp++; 05303 framing = strtol(tmp, NULL, 10); 05304 if (framing == LONG_MIN || framing == LONG_MAX) { 05305 framing = 0; 05306 if (option_debug) 05307 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05308 } 05309 } 05310 if (framing && p->autoframing) { 05311 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05312 int codec_n; 05313 int format = 0; 05314 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05315 format = ast_rtp_codec_getformat(codec_n); 05316 if (!format) /* non-codec or not found */ 05317 continue; 05318 if (option_debug) 05319 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05320 ast_codec_pref_setsize(pref, format, framing); 05321 } 05322 ast_rtp_codec_setpref(p->rtp, pref); 05323 } 05324 continue; 05325 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05326 /* We have a rtpmap to handle */ 05327 int found = FALSE; 05328 /* We should propably check if this is an audio or video codec 05329 so we know where to look */ 05330 05331 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05332 /* Note: should really look at the 'freq' and '#chans' params too */ 05333 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05334 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05335 if (debug) 05336 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05337 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05338 last_rtpmap_codec++; 05339 found = TRUE; 05340 05341 } else if (p->vrtp) { 05342 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05343 if (debug) 05344 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05345 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05346 last_rtpmap_codec++; 05347 found = TRUE; 05348 } 05349 } 05350 } else { 05351 if (debug) 05352 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05353 } 05354 05355 if (!found) { 05356 /* Remove this codec since it's an unknown media type for us */ 05357 /* XXX This is buggy since the media line for audio and video can have the 05358 same numbers. We need to check as described above, but for testing this works... */ 05359 ast_rtp_unset_m_type(newaudiortp, codec); 05360 ast_rtp_unset_m_type(newvideortp, codec); 05361 if (debug) 05362 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05363 } 05364 } 05365 } 05366 05367 if (udptlportno != -1) { 05368 int found = 0, x; 05369 05370 old = 0; 05371 05372 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05373 iterator = req->sdp_start; 05374 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05375 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05376 found = 1; 05377 if (option_debug > 2) 05378 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05379 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05380 found = 1; 05381 if (option_debug > 2) 05382 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05383 switch (x) { 05384 case 14400: 05385 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05386 break; 05387 case 12000: 05388 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05389 break; 05390 case 9600: 05391 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05392 break; 05393 case 7200: 05394 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05395 break; 05396 case 4800: 05397 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05398 break; 05399 case 2400: 05400 peert38capability |= T38FAX_RATE_2400; 05401 break; 05402 } 05403 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05404 found = 1; 05405 if (option_debug > 2) 05406 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05407 if (x == 0) 05408 peert38capability |= T38FAX_VERSION_0; 05409 else if (x == 1) 05410 peert38capability |= T38FAX_VERSION_1; 05411 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05412 found = 1; 05413 if (option_debug > 2) 05414 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05415 ast_udptl_set_far_max_datagram(p->udptl, x); 05416 ast_udptl_set_local_max_datagram(p->udptl, x); 05417 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05418 found = 1; 05419 if (option_debug > 2) 05420 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05421 if (x == 1) 05422 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05423 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05424 found = 1; 05425 if (option_debug > 2) 05426 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05427 if (x == 1) 05428 peert38capability |= T38FAX_TRANSCODING_MMR; 05429 } 05430 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05431 found = 1; 05432 if (option_debug > 2) 05433 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05434 if (x == 1) 05435 peert38capability |= T38FAX_TRANSCODING_JBIG; 05436 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05437 found = 1; 05438 if (option_debug > 2) 05439 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05440 if (!strcasecmp(s, "localTCF")) 05441 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05442 else if (!strcasecmp(s, "transferredTCF")) 05443 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05444 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05445 found = 1; 05446 if (option_debug > 2) 05447 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05448 if (!strcasecmp(s, "t38UDPRedundancy")) { 05449 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05450 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05451 } else if (!strcasecmp(s, "t38UDPFEC")) { 05452 peert38capability |= T38FAX_UDP_EC_FEC; 05453 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05454 } else { 05455 peert38capability |= T38FAX_UDP_EC_NONE; 05456 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05457 } 05458 } 05459 } 05460 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05461 p->t38.peercapability = peert38capability; 05462 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05463 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05464 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05465 } 05466 if (debug) 05467 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05468 p->t38.capability, 05469 p->t38.peercapability, 05470 p->t38.jointcapability); 05471 } else { 05472 p->t38.state = T38_DISABLED; 05473 if (option_debug > 2) 05474 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05475 } 05476 05477 /* Now gather all of the codecs that we are asked for: */ 05478 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05479 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05480 05481 newjointcapability = p->capability & (peercapability | vpeercapability); 05482 newpeercapability = (peercapability | vpeercapability); 05483 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05484 05485 05486 if (debug) { 05487 /* shame on whoever coded this.... */ 05488 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05489 05490 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05491 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05492 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05493 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05494 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05495 05496 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05497 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05498 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05499 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05500 } 05501 if (!newjointcapability) { 05502 /* If T.38 was not negotiated either, totally bail out... */ 05503 if (!p->t38.jointcapability || !udptlportno) { 05504 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05505 /* Do NOT Change current setting */ 05506 return -1; 05507 } else { 05508 if (option_debug > 2) 05509 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05510 return 0; 05511 } 05512 } 05513 05514 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05515 they are acceptable */ 05516 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05517 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05518 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05519 05520 ast_rtp_pt_copy(p->rtp, newaudiortp); 05521 if (p->vrtp) 05522 ast_rtp_pt_copy(p->vrtp, newvideortp); 05523 05524 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05525 ast_clear_flag(&p->flags[0], SIP_DTMF); 05526 if (newnoncodeccapability & AST_RTP_DTMF) { 05527 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05528 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05529 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05530 ast_rtp_setdtmf(p->rtp, 1); 05531 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05532 } else { 05533 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05534 } 05535 } 05536 05537 /* Setup audio port number */ 05538 if (p->rtp && sin.sin_port) { 05539 ast_rtp_set_peer(p->rtp, &sin); 05540 if (debug) 05541 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05542 } 05543 05544 /* Setup video port number */ 05545 if (p->vrtp && vsin.sin_port) { 05546 ast_rtp_set_peer(p->vrtp, &vsin); 05547 if (debug) 05548 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05549 } 05550 05551 /* Ok, we're going with this offer */ 05552 if (option_debug > 1) { 05553 char buf[SIPBUFSIZE]; 05554 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05555 } 05556 05557 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05558 return 0; 05559 05560 if (option_debug > 3) 05561 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05562 05563 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05564 if (debug) { 05565 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05566 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05567 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05568 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05569 } 05570 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05571 ast_set_read_format(p->owner, p->owner->readformat); 05572 ast_set_write_format(p->owner, p->owner->writeformat); 05573 } 05574 05575 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05576 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05577 /* Activate a re-invite */ 05578 ast_queue_frame(p->owner, &ast_null_frame); 05579 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05580 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05581 S_OR(p->mohsuggest, NULL), 05582 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05583 if (sendonly) 05584 ast_rtp_stop(p->rtp); 05585 /* RTCP needs to go ahead, even if we're on hold!!! */ 05586 /* Activate a re-invite */ 05587 ast_queue_frame(p->owner, &ast_null_frame); 05588 } 05589 05590 /* Manager Hold and Unhold events must be generated, if necessary */ 05591 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05592 change_hold_state(p, req, FALSE, sendonly); 05593 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05594 change_hold_state(p, req, TRUE, sendonly); 05595 return 0; 05596 }
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 9826 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().
09827 { 09828 char buf[1024]; 09829 struct ast_frame f; 09830 const char *content_type = get_header(req, "Content-Type"); 09831 09832 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09833 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09834 if (!p->owner) 09835 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09836 return; 09837 } 09838 09839 if (get_msg_text(buf, sizeof(buf), req)) { 09840 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09841 transmit_response(p, "202 Accepted", req); 09842 if (!p->owner) 09843 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09844 return; 09845 } 09846 09847 if (p->owner) { 09848 if (sip_debug_test_pvt(p)) 09849 ast_verbose("Message received: '%s'\n", buf); 09850 memset(&f, 0, sizeof(f)); 09851 f.frametype = AST_FRAME_TEXT; 09852 f.subclass = 0; 09853 f.offset = 0; 09854 f.data = buf; 09855 f.datalen = strlen(buf); 09856 ast_queue_frame(p->owner, &f); 09857 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09858 } else { /* Message outside of a call, we do not support that */ 09859 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); 09860 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09861 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09862 } 09863 return; 09864 }
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 7957 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.
07958 { 07959 char data[256]; 07960 struct in_addr in; 07961 int expiry; 07962 int port; 07963 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07964 07965 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07966 return; 07967 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07968 return; 07969 07970 scan = data; 07971 addr = strsep(&scan, ":"); 07972 port_str = strsep(&scan, ":"); 07973 expiry_str = strsep(&scan, ":"); 07974 username = strsep(&scan, ":"); 07975 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07976 07977 if (!inet_aton(addr, &in)) 07978 return; 07979 07980 if (port_str) 07981 port = atoi(port_str); 07982 else 07983 return; 07984 07985 if (expiry_str) 07986 expiry = atoi(expiry_str); 07987 else 07988 return; 07989 07990 if (username) 07991 ast_copy_string(peer->username, username, sizeof(peer->username)); 07992 if (contact) 07993 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07994 07995 if (option_debug > 1) 07996 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07997 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07998 07999 memset(&peer->addr, 0, sizeof(peer->addr)); 08000 peer->addr.sin_family = AF_INET; 08001 peer->addr.sin_addr = in; 08002 peer->addr.sin_port = htons(port); 08003 if (sipsock < 0) { 08004 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08005 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08006 struct sip_peer *peer_ptr = peer; 08007 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08008 } 08009 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08010 if (peer->pokeexpire == -1) { 08011 struct sip_peer *peer_ptr = peer; 08012 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08013 } 08014 } else 08015 sip_poke_peer(peer); 08016 if (!AST_SCHED_DEL(sched, peer->expire)) { 08017 struct sip_peer *peer_ptr = peer; 08018 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08019 } 08020 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08021 if (peer->expire == -1) { 08022 struct sip_peer *peer_ptr = peer; 08023 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08024 } 08025 register_peer_exten(peer, TRUE); 08026 }
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 8740 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.
08742 { 08743 enum check_auth_result res = AUTH_NOT_FOUND; 08744 struct sip_peer *peer; 08745 char tmp[256]; 08746 char *name, *c; 08747 char *t; 08748 char *domain; 08749 08750 /* Terminate URI */ 08751 t = uri; 08752 while(*t && (*t > 32) && (*t != ';')) 08753 t++; 08754 *t = '\0'; 08755 08756 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08757 if (pedanticsipchecking) 08758 ast_uri_decode(tmp); 08759 08760 c = get_in_brackets(tmp); 08761 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08762 08763 if (!strncasecmp(c, "sip:", 4)) { 08764 name = c + 4; 08765 } else { 08766 name = c; 08767 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08768 } 08769 08770 /* Strip off the domain name */ 08771 if ((c = strchr(name, '@'))) { 08772 *c++ = '\0'; 08773 domain = c; 08774 if ((c = strchr(domain, ':'))) /* Remove :port */ 08775 *c = '\0'; 08776 if (!AST_LIST_EMPTY(&domain_list)) { 08777 if (!check_sip_domain(domain, NULL, 0)) { 08778 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08779 return AUTH_UNKNOWN_DOMAIN; 08780 } 08781 } 08782 } 08783 08784 ast_string_field_set(p, exten, name); 08785 build_contact(p); 08786 peer = find_peer(name, NULL, 1); 08787 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08788 /* Peer fails ACL check */ 08789 if (peer) { 08790 ASTOBJ_UNREF(peer, sip_destroy_peer); 08791 res = AUTH_ACL_FAILED; 08792 } else 08793 res = AUTH_NOT_FOUND; 08794 } 08795 if (peer) { 08796 /* Set Frame packetization */ 08797 if (p->rtp) { 08798 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08799 p->autoframing = peer->autoframing; 08800 } 08801 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08802 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08803 res = AUTH_PEER_NOT_DYNAMIC; 08804 } else { 08805 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08806 transmit_response(p, "100 Trying", req); 08807 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08808 if (sip_cancel_destroy(p)) 08809 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08810 08811 /* We have a succesful registration attemp with proper authentication, 08812 now, update the peer */ 08813 switch (parse_register_contact(p, peer, req)) { 08814 case PARSE_REGISTER_FAILED: 08815 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08816 transmit_response_with_date(p, "400 Bad Request", req); 08817 peer->lastmsgssent = -1; 08818 res = 0; 08819 break; 08820 case PARSE_REGISTER_QUERY: 08821 transmit_response_with_date(p, "200 OK", req); 08822 peer->lastmsgssent = -1; 08823 res = 0; 08824 break; 08825 case PARSE_REGISTER_UPDATE: 08826 update_peer(peer, p->expiry); 08827 /* Say OK and ask subsystem to retransmit msg counter */ 08828 transmit_response_with_date(p, "200 OK", req); 08829 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08830 peer->lastmsgssent = -1; 08831 res = 0; 08832 break; 08833 } 08834 } 08835 } 08836 } 08837 if (!peer && autocreatepeer) { 08838 /* Create peer if we have autocreate mode enabled */ 08839 peer = temp_peer(name); 08840 if (peer) { 08841 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08842 if (sip_cancel_destroy(p)) 08843 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08844 switch (parse_register_contact(p, peer, req)) { 08845 case PARSE_REGISTER_FAILED: 08846 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08847 transmit_response_with_date(p, "400 Bad Request", req); 08848 peer->lastmsgssent = -1; 08849 res = 0; 08850 break; 08851 case PARSE_REGISTER_QUERY: 08852 transmit_response_with_date(p, "200 OK", req); 08853 peer->lastmsgssent = -1; 08854 res = 0; 08855 break; 08856 case PARSE_REGISTER_UPDATE: 08857 /* Say OK and ask subsystem to retransmit msg counter */ 08858 transmit_response_with_date(p, "200 OK", req); 08859 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08860 peer->lastmsgssent = -1; 08861 res = 0; 08862 break; 08863 } 08864 } 08865 } 08866 if (!peer && global_alwaysauthreject) { 08867 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 08868 * trying to avoid leaking information, we MUST also transmit the same 08869 * response when we DON'T find a peer. */ 08870 transmit_response(p, "100 Trying", req); 08871 /* Insert a fake delay between the 100 and the subsequent failure. */ 08872 sched_yield(); 08873 } 08874 if (!res) { 08875 ast_device_state_changed("SIP/%s", peer->name); 08876 } 08877 if (res < 0) { 08878 switch (res) { 08879 case AUTH_SECRET_FAILED: 08880 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08881 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08882 break; 08883 case AUTH_USERNAME_MISMATCH: 08884 /* Username and digest username does not match. 08885 Asterisk uses the From: username for authentication. We need the 08886 users to use the same authentication user name until we support 08887 proper authentication by digest auth name */ 08888 case AUTH_NOT_FOUND: 08889 case AUTH_PEER_NOT_DYNAMIC: 08890 case AUTH_ACL_FAILED: 08891 if (global_alwaysauthreject) { 08892 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 08893 } else { 08894 /* URI not found */ 08895 if (res == AUTH_PEER_NOT_DYNAMIC) 08896 transmit_response(p, "403 Forbidden", &p->initreq); 08897 else 08898 transmit_response(p, "404 Not found", &p->initreq); 08899 } 08900 break; 08901 default: 08902 break; 08903 } 08904 } 08905 if (peer) 08906 ASTOBJ_UNREF(peer, sip_destroy_peer); 08907 08908 return res; 08909 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 7446 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.
07447 { 07448 switch(regstate) { 07449 case REG_STATE_FAILED: 07450 return "Failed"; 07451 case REG_STATE_UNREGISTERED: 07452 return "Unregistered"; 07453 case REG_STATE_REGSENT: 07454 return "Request Sent"; 07455 case REG_STATE_AUTHSENT: 07456 return "Auth. Sent"; 07457 case REG_STATE_REGISTERED: 07458 return "Registered"; 07459 case REG_STATE_REJECTED: 07460 return "Rejected"; 07461 case REG_STATE_TIMEOUT: 07462 return "Timeout"; 07463 case REG_STATE_NOAUTH: 07464 return "No Authentication"; 07465 default: 07466 return "Unknown"; 07467 } 07468 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18442 of file chan_sip.c.
References sip_reload().
18443 { 18444 return sip_reload(0, 0, NULL); 18445 }
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
< Default to nat=yes
Definition at line 17322 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, display_nat_warning(), errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, sip_peer::flags, sip_user::flags, 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_ALWAYS, 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.
17323 { 17324 struct ast_config *cfg, *ucfg; 17325 struct ast_variable *v; 17326 struct sip_peer *peer; 17327 struct sip_user *user; 17328 struct ast_hostent ahp; 17329 char *cat, *stringp, *context, *oldregcontext; 17330 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17331 struct hostent *hp; 17332 int format; 17333 struct ast_flags dummy[2]; 17334 int auto_sip_domains = FALSE; 17335 struct sockaddr_in old_bindaddr = bindaddr; 17336 int registry_count = 0, peer_count = 0, user_count = 0; 17337 unsigned int temp_tos = 0; 17338 struct ast_flags debugflag = {0}; 17339 17340 cfg = ast_config_load(config); 17341 17342 /* We *must* have a config file otherwise stop immediately */ 17343 if (!cfg) { 17344 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17345 return -1; 17346 } 17347 17348 if (option_debug > 3) 17349 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17350 17351 clear_realm_authentication(authl); 17352 clear_sip_domains(); 17353 authl = NULL; 17354 17355 /* First, destroy all outstanding registry calls */ 17356 /* This is needed, since otherwise active registry entries will not be destroyed */ 17357 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17358 ASTOBJ_RDLOCK(iterator); 17359 if (iterator->call) { 17360 if (option_debug > 2) 17361 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17362 /* This will also remove references to the registry */ 17363 sip_destroy(iterator->call); 17364 } 17365 ASTOBJ_UNLOCK(iterator); 17366 17367 } while(0)); 17368 17369 /* Then, actually destroy users and registry */ 17370 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17371 if (option_debug > 3) 17372 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17373 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17374 if (option_debug > 3) 17375 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17376 ASTOBJ_CONTAINER_MARKALL(&peerl); 17377 17378 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17379 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17380 oldregcontext = oldcontexts; 17381 17382 /* Clear all flags before setting default values */ 17383 /* Preserve debugging settings for console */ 17384 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17385 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17386 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17387 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17388 17389 /* Reset IP addresses */ 17390 memset(&bindaddr, 0, sizeof(bindaddr)); 17391 ast_free_ha(localaddr); 17392 memset(&localaddr, 0, sizeof(localaddr)); 17393 memset(&externip, 0, sizeof(externip)); 17394 memset(&default_prefs, 0 , sizeof(default_prefs)); 17395 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17396 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17397 ourport = STANDARD_SIP_PORT; 17398 srvlookup = DEFAULT_SRVLOOKUP; 17399 global_tos_sip = DEFAULT_TOS_SIP; 17400 global_tos_audio = DEFAULT_TOS_AUDIO; 17401 global_tos_video = DEFAULT_TOS_VIDEO; 17402 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17403 externexpire = 0; /* Expiration for DNS re-issuing */ 17404 externrefresh = 10; 17405 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17406 17407 /* Reset channel settings to default before re-configuring */ 17408 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17409 global_regcontext[0] = '\0'; 17410 expiry = DEFAULT_EXPIRY; 17411 global_notifyringing = DEFAULT_NOTIFYRINGING; 17412 global_limitonpeers = FALSE; 17413 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17414 global_notifyhold = FALSE; 17415 global_alwaysauthreject = 0; 17416 global_allowsubscribe = FALSE; 17417 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17418 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17419 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17420 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17421 else 17422 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17423 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17424 compactheaders = DEFAULT_COMPACTHEADERS; 17425 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17426 global_regattempts_max = 0; 17427 pedanticsipchecking = DEFAULT_PEDANTIC; 17428 global_mwitime = DEFAULT_MWITIME; 17429 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17430 global_autoframing = 0; 17431 global_allowguest = DEFAULT_ALLOWGUEST; 17432 global_rtptimeout = 0; 17433 global_rtpholdtimeout = 0; 17434 global_rtpkeepalive = 0; 17435 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17436 global_rtautoclear = 120; 17437 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17438 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17439 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17440 17441 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17442 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17443 default_subscribecontext[0] = '\0'; 17444 default_language[0] = '\0'; 17445 default_fromdomain[0] = '\0'; 17446 default_qualify = DEFAULT_QUALIFY; 17447 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17448 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17449 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17450 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17451 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17452 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17453 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17454 ast_set_flag(&global_flags[0], SIP_NAT_ALWAYS); /*!< Default to nat=yes */ 17455 17456 /* Debugging settings, always default to off */ 17457 dumphistory = FALSE; 17458 recordhistory = FALSE; 17459 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17460 17461 /* Misc settings for the channel */ 17462 global_relaxdtmf = FALSE; 17463 global_callevents = FALSE; 17464 global_t1min = DEFAULT_T1MIN; 17465 17466 global_matchexterniplocally = FALSE; 17467 17468 /* Copy the default jb config over global_jbconf */ 17469 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17470 17471 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17472 17473 /* Read the [general] config section of sip.conf (or from realtime config) */ 17474 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17475 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17476 continue; 17477 /* handle jb conf */ 17478 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17479 continue; 17480 17481 /* Create the interface list */ 17482 if (!strcasecmp(v->name, "context")) { 17483 ast_copy_string(default_context, v->value, sizeof(default_context)); 17484 } else if (!strcasecmp(v->name, "subscribecontext")) { 17485 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17486 } else if (!strcasecmp(v->name, "allowguest")) { 17487 global_allowguest = ast_true(v->value) ? 1 : 0; 17488 } else if (!strcasecmp(v->name, "realm")) { 17489 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17490 } else if (!strcasecmp(v->name, "useragent")) { 17491 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17492 if (option_debug) 17493 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17494 } else if (!strcasecmp(v->name, "allowtransfer")) { 17495 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17496 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17497 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17498 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17499 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17500 } else if (!strcasecmp(v->name, "rtupdate")) { 17501 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17502 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17503 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17504 } else if (!strcasecmp(v->name, "t1min")) { 17505 global_t1min = atoi(v->value); 17506 } else if (!strcasecmp(v->name, "rtautoclear")) { 17507 int i = atoi(v->value); 17508 if (i > 0) 17509 global_rtautoclear = i; 17510 else 17511 i = 0; 17512 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17513 } else if (!strcasecmp(v->name, "usereqphone")) { 17514 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17515 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17516 global_relaxdtmf = ast_true(v->value); 17517 } else if (!strcasecmp(v->name, "checkmwi")) { 17518 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17519 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17520 global_mwitime = DEFAULT_MWITIME; 17521 } 17522 } else if (!strcasecmp(v->name, "vmexten")) { 17523 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17524 } else if (!strcasecmp(v->name, "rtptimeout")) { 17525 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17526 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17527 global_rtptimeout = 0; 17528 } 17529 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17530 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17531 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17532 global_rtpholdtimeout = 0; 17533 } 17534 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17535 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17536 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17537 global_rtpkeepalive = 0; 17538 } 17539 } else if (!strcasecmp(v->name, "compactheaders")) { 17540 compactheaders = ast_true(v->value); 17541 } else if (!strcasecmp(v->name, "notifymimetype")) { 17542 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17543 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17544 global_limitonpeers = ast_true(v->value); 17545 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17546 global_directrtpsetup = ast_true(v->value); 17547 } else if (!strcasecmp(v->name, "notifyringing")) { 17548 global_notifyringing = ast_true(v->value); 17549 } else if (!strcasecmp(v->name, "notifyhold")) { 17550 global_notifyhold = ast_true(v->value); 17551 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17552 global_alwaysauthreject = ast_true(v->value); 17553 } else if (!strcasecmp(v->name, "mohinterpret") 17554 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17555 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17556 } else if (!strcasecmp(v->name, "mohsuggest")) { 17557 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17558 } else if (!strcasecmp(v->name, "language")) { 17559 ast_copy_string(default_language, v->value, sizeof(default_language)); 17560 } else if (!strcasecmp(v->name, "regcontext")) { 17561 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17562 stringp = newcontexts; 17563 /* Let's remove any contexts that are no longer defined in regcontext */ 17564 cleanup_stale_contexts(stringp, oldregcontext); 17565 /* Create contexts if they don't exist already */ 17566 while ((context = strsep(&stringp, "&"))) { 17567 if (!ast_context_find(context)) 17568 ast_context_create(NULL, context,"SIP"); 17569 } 17570 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17571 } else if (!strcasecmp(v->name, "callerid")) { 17572 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17573 } else if (!strcasecmp(v->name, "fromdomain")) { 17574 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17575 } else if (!strcasecmp(v->name, "outboundproxy")) { 17576 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17577 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17578 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17579 /* Port needs to be after IP */ 17580 sscanf(v->value, "%d", &format); 17581 outboundproxyip.sin_port = htons(format); 17582 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17583 autocreatepeer = ast_true(v->value); 17584 } else if (!strcasecmp(v->name, "srvlookup")) { 17585 srvlookup = ast_true(v->value); 17586 } else if (!strcasecmp(v->name, "pedantic")) { 17587 pedanticsipchecking = ast_true(v->value); 17588 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17589 max_expiry = atoi(v->value); 17590 if (max_expiry < 1) 17591 max_expiry = DEFAULT_MAX_EXPIRY; 17592 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17593 min_expiry = atoi(v->value); 17594 if (min_expiry < 1) 17595 min_expiry = DEFAULT_MIN_EXPIRY; 17596 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17597 default_expiry = atoi(v->value); 17598 if (default_expiry < 1) 17599 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17600 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17601 if (ast_true(v->value)) 17602 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17603 } else if (!strcasecmp(v->name, "dumphistory")) { 17604 dumphistory = ast_true(v->value); 17605 } else if (!strcasecmp(v->name, "recordhistory")) { 17606 recordhistory = ast_true(v->value); 17607 } else if (!strcasecmp(v->name, "registertimeout")) { 17608 global_reg_timeout = atoi(v->value); 17609 if (global_reg_timeout < 1) 17610 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17611 } else if (!strcasecmp(v->name, "registerattempts")) { 17612 global_regattempts_max = atoi(v->value); 17613 } else if (!strcasecmp(v->name, "bindaddr")) { 17614 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17615 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17616 } else { 17617 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17618 } 17619 } else if (!strcasecmp(v->name, "localnet")) { 17620 struct ast_ha *na; 17621 if (!(na = ast_append_ha("d", v->value, localaddr))) 17622 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17623 else 17624 localaddr = na; 17625 } else if (!strcasecmp(v->name, "localmask")) { 17626 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17627 } else if (!strcasecmp(v->name, "externip")) { 17628 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17629 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17630 else 17631 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17632 externexpire = 0; 17633 } else if (!strcasecmp(v->name, "externhost")) { 17634 ast_copy_string(externhost, v->value, sizeof(externhost)); 17635 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17636 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17637 else 17638 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17639 externexpire = time(NULL); 17640 } else if (!strcasecmp(v->name, "externrefresh")) { 17641 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17642 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17643 externrefresh = 10; 17644 } 17645 } else if (!strcasecmp(v->name, "allow")) { 17646 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17647 } else if (!strcasecmp(v->name, "disallow")) { 17648 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17649 } else if (!strcasecmp(v->name, "autoframing")) { 17650 global_autoframing = ast_true(v->value); 17651 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17652 allow_external_domains = ast_true(v->value); 17653 } else if (!strcasecmp(v->name, "autodomain")) { 17654 auto_sip_domains = ast_true(v->value); 17655 } else if (!strcasecmp(v->name, "domain")) { 17656 char *domain = ast_strdupa(v->value); 17657 char *context = strchr(domain, ','); 17658 17659 if (context) 17660 *context++ = '\0'; 17661 17662 if (option_debug && ast_strlen_zero(context)) 17663 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17664 if (ast_strlen_zero(domain)) 17665 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17666 else 17667 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17668 } else if (!strcasecmp(v->name, "register")) { 17669 if (sip_register(v->value, v->lineno) == 0) 17670 registry_count++; 17671 } else if (!strcasecmp(v->name, "tos")) { 17672 if (!ast_str2tos(v->value, &temp_tos)) { 17673 global_tos_sip = temp_tos; 17674 global_tos_audio = temp_tos; 17675 global_tos_video = temp_tos; 17676 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17677 } else 17678 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17679 } else if (!strcasecmp(v->name, "tos_sip")) { 17680 if (ast_str2tos(v->value, &global_tos_sip)) 17681 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17682 } else if (!strcasecmp(v->name, "tos_audio")) { 17683 if (ast_str2tos(v->value, &global_tos_audio)) 17684 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17685 } else if (!strcasecmp(v->name, "tos_video")) { 17686 if (ast_str2tos(v->value, &global_tos_video)) 17687 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17688 } else if (!strcasecmp(v->name, "bindport")) { 17689 if (sscanf(v->value, "%d", &ourport) == 1) { 17690 bindaddr.sin_port = htons(ourport); 17691 } else { 17692 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17693 } 17694 } else if (!strcasecmp(v->name, "qualify")) { 17695 if (!strcasecmp(v->value, "no")) { 17696 default_qualify = 0; 17697 } else if (!strcasecmp(v->value, "yes")) { 17698 default_qualify = DEFAULT_MAXMS; 17699 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17700 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17701 default_qualify = 0; 17702 } 17703 } else if (!strcasecmp(v->name, "callevents")) { 17704 global_callevents = ast_true(v->value); 17705 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17706 default_maxcallbitrate = atoi(v->value); 17707 if (default_maxcallbitrate < 0) 17708 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17709 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17710 global_matchexterniplocally = ast_true(v->value); 17711 } 17712 } 17713 17714 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17715 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17716 allow_external_domains = 1; 17717 } 17718 17719 /* Build list of authentication to various SIP realms, i.e. service providers */ 17720 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17721 /* Format for authentication is auth = username:password@realm */ 17722 if (!strcasecmp(v->name, "auth")) 17723 authl = add_realm_authentication(authl, v->value, v->lineno); 17724 } 17725 17726 ucfg = ast_config_load("users.conf"); 17727 if (ucfg) { 17728 struct ast_variable *gen; 17729 int genhassip, genregistersip; 17730 const char *hassip, *registersip; 17731 17732 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17733 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17734 gen = ast_variable_browse(ucfg, "general"); 17735 cat = ast_category_browse(ucfg, NULL); 17736 while (cat) { 17737 if (strcasecmp(cat, "general")) { 17738 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17739 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17740 if (ast_true(hassip) || (!hassip && genhassip)) { 17741 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17742 if (user) { 17743 ASTOBJ_CONTAINER_LINK(&userl,user); 17744 ASTOBJ_UNREF(user, sip_destroy_user); 17745 user_count++; 17746 } 17747 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17748 if (peer) { 17749 ast_device_state_changed("SIP/%s", peer->name); 17750 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17751 ASTOBJ_UNREF(peer, sip_destroy_peer); 17752 peer_count++; 17753 } 17754 } 17755 if (ast_true(registersip) || (!registersip && genregistersip)) { 17756 char tmp[256]; 17757 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17758 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17759 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17760 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17761 if (!host) 17762 host = ast_variable_retrieve(ucfg, "general", "host"); 17763 if (!username) 17764 username = ast_variable_retrieve(ucfg, "general", "username"); 17765 if (!secret) 17766 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17767 if (!contact) 17768 contact = "s"; 17769 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17770 if (!ast_strlen_zero(secret)) 17771 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17772 else 17773 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17774 if (sip_register(tmp, 0) == 0) 17775 registry_count++; 17776 } 17777 } 17778 } 17779 cat = ast_category_browse(ucfg, cat); 17780 } 17781 ast_config_destroy(ucfg); 17782 } 17783 17784 17785 /* Load peers, users and friends */ 17786 cat = NULL; 17787 while ( (cat = ast_category_browse(cfg, cat)) ) { 17788 const char *utype; 17789 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17790 continue; 17791 utype = ast_variable_retrieve(cfg, cat, "type"); 17792 if (!utype) { 17793 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17794 continue; 17795 } else { 17796 int is_user = 0, is_peer = 0; 17797 if (!strcasecmp(utype, "user")) 17798 is_user = 1; 17799 else if (!strcasecmp(utype, "friend")) 17800 is_user = is_peer = 1; 17801 else if (!strcasecmp(utype, "peer")) 17802 is_peer = 1; 17803 else { 17804 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17805 continue; 17806 } 17807 if (is_user) { 17808 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17809 if (user) { 17810 display_nat_warning(cat, reason, &user->flags[0]); 17811 ASTOBJ_CONTAINER_LINK(&userl,user); 17812 ASTOBJ_UNREF(user, sip_destroy_user); 17813 user_count++; 17814 } 17815 } 17816 if (is_peer) { 17817 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17818 if (peer) { 17819 if (!is_user) { 17820 display_nat_warning(cat, reason, &peer->flags[0]); 17821 } 17822 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17823 ASTOBJ_UNREF(peer, sip_destroy_peer); 17824 peer_count++; 17825 } 17826 } 17827 } 17828 } 17829 17830 if (ast_find_ourip(&__ourip, bindaddr)) { 17831 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17832 ast_config_destroy(cfg); 17833 return 0; 17834 } 17835 if (!ntohs(bindaddr.sin_port)) 17836 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17837 bindaddr.sin_family = AF_INET; 17838 ast_mutex_lock(&netlock); 17839 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17840 close(sipsock); 17841 sipsock = -1; 17842 } 17843 if (sipsock < 0) { 17844 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17845 if (sipsock < 0) { 17846 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17847 ast_config_destroy(cfg); 17848 return -1; 17849 } else { 17850 /* Allow SIP clients on the same host to access us: */ 17851 const int reuseFlag = 1; 17852 17853 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17854 (const char*)&reuseFlag, 17855 sizeof reuseFlag); 17856 17857 ast_enable_packet_fragmentation(sipsock); 17858 17859 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17860 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17861 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17862 strerror(errno)); 17863 close(sipsock); 17864 sipsock = -1; 17865 } else { 17866 if (option_verbose > 1) { 17867 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17868 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17869 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17870 } 17871 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17872 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17873 } 17874 } 17875 } 17876 ast_mutex_unlock(&netlock); 17877 17878 /* Add default domains - host name, IP address and IP:port */ 17879 /* Only do this if user added any sip domain with "localdomains" */ 17880 /* In order to *not* break backwards compatibility */ 17881 /* Some phones address us at IP only, some with additional port number */ 17882 if (auto_sip_domains) { 17883 char temp[MAXHOSTNAMELEN]; 17884 17885 /* First our default IP address */ 17886 if (bindaddr.sin_addr.s_addr) 17887 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17888 else 17889 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17890 17891 /* Our extern IP address, if configured */ 17892 if (externip.sin_addr.s_addr) 17893 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17894 17895 /* Extern host name (NAT traversal support) */ 17896 if (!ast_strlen_zero(externhost)) 17897 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17898 17899 /* Our host name */ 17900 if (!gethostname(temp, sizeof(temp))) 17901 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17902 } 17903 17904 /* Release configuration from memory */ 17905 ast_config_destroy(cfg); 17906 17907 /* Load the list of manual NOTIFY types to support */ 17908 if (notify_types) 17909 ast_config_destroy(notify_types); 17910 notify_types = ast_config_load(notify_config); 17911 17912 /* Done, tell the manager */ 17913 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); 17914 17915 return 0; 17916 }
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 11618 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().
11619 { 11620 char tmp[512]; 11621 char *c; 11622 char oldnonce[256]; 11623 11624 /* table of recognised keywords, and places where they should be copied */ 11625 const struct x { 11626 const char *key; 11627 int field_index; 11628 } *i, keys[] = { 11629 { "realm=", ast_string_field_index(p, realm) }, 11630 { "nonce=", ast_string_field_index(p, nonce) }, 11631 { "opaque=", ast_string_field_index(p, opaque) }, 11632 { "qop=", ast_string_field_index(p, qop) }, 11633 { "domain=", ast_string_field_index(p, domain) }, 11634 { NULL, 0 }, 11635 }; 11636 11637 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11638 if (ast_strlen_zero(tmp)) 11639 return -1; 11640 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11641 ast_log(LOG_WARNING, "missing Digest.\n"); 11642 return -1; 11643 } 11644 c = tmp + strlen("Digest "); 11645 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11646 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11647 for (i = keys; i->key != NULL; i++) { 11648 char *src, *separator; 11649 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11650 continue; 11651 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11652 c += strlen(i->key); 11653 if (*c == '"') { 11654 src = ++c; 11655 separator = "\""; 11656 } else { 11657 src = c; 11658 separator = ","; 11659 } 11660 strsep(&c, separator); /* clear separator and move ptr */ 11661 ast_string_field_index_set(p, i->field_index, src); 11662 break; 11663 } 11664 if (i->key == NULL) /* not found, try ',' */ 11665 strsep(&c, ","); 11666 } 11667 /* Reset nonce count */ 11668 if (strcmp(p->nonce, oldnonce)) 11669 p->noncecount = 0; 11670 11671 /* Save auth data for following registrations */ 11672 if (p->registry) { 11673 struct sip_registry *r = p->registry; 11674 11675 if (strcmp(r->nonce, p->nonce)) { 11676 ast_string_field_set(r, realm, p->realm); 11677 ast_string_field_set(r, nonce, p->nonce); 11678 ast_string_field_set(r, domain, p->domain); 11679 ast_string_field_set(r, opaque, p->opaque); 11680 ast_string_field_set(r, qop, p->qop); 11681 r->noncecount = 0; 11682 } 11683 } 11684 return build_reply_digest(p, sipmethod, digest, digest_len); 11685 }
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 5929 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.
05930 { 05931 struct sip_request *orig = &p->initreq; 05932 char stripped[80]; 05933 char tmp[80]; 05934 char newto[256]; 05935 const char *c; 05936 const char *ot, *of; 05937 int is_strict = FALSE; /*!< Strict routing flag */ 05938 05939 memset(req, 0, sizeof(struct sip_request)); 05940 05941 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05942 05943 if (!seqno) { 05944 p->ocseq++; 05945 seqno = p->ocseq; 05946 } 05947 05948 if (newbranch) { 05949 p->branch ^= ast_random(); 05950 build_via(p); 05951 } 05952 05953 /* Check for strict or loose router */ 05954 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05955 is_strict = TRUE; 05956 if (sipdebug) 05957 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05958 } 05959 05960 if (sipmethod == SIP_CANCEL) 05961 c = p->initreq.rlPart2; /* Use original URI */ 05962 else if (sipmethod == SIP_ACK) { 05963 /* Use URI from Contact: in 200 OK (if INVITE) 05964 (we only have the contacturi on INVITEs) */ 05965 if (!ast_strlen_zero(p->okcontacturi)) 05966 c = is_strict ? p->route->hop : p->okcontacturi; 05967 else 05968 c = p->initreq.rlPart2; 05969 } else if (!ast_strlen_zero(p->okcontacturi)) 05970 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05971 else if (!ast_strlen_zero(p->uri)) 05972 c = p->uri; 05973 else { 05974 char *n; 05975 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05976 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05977 sizeof(stripped)); 05978 n = get_in_brackets(stripped); 05979 c = strsep(&n, ";"); /* trim ; and beyond */ 05980 } 05981 init_req(req, sipmethod, c); 05982 05983 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05984 05985 add_header(req, "Via", p->via); 05986 if (p->route) { 05987 set_destination(p, p->route->hop); 05988 add_route(req, is_strict ? p->route->next : p->route); 05989 } 05990 05991 ot = get_header(orig, "To"); 05992 of = get_header(orig, "From"); 05993 05994 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05995 as our original request, including tag (or presumably lack thereof) */ 05996 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05997 /* Add the proper tag if we don't have it already. If they have specified 05998 their tag, use it. Otherwise, use our own tag */ 05999 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06000 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06001 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06002 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06003 else 06004 snprintf(newto, sizeof(newto), "%s", ot); 06005 ot = newto; 06006 } 06007 06008 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06009 add_header(req, "From", of); 06010 add_header(req, "To", ot); 06011 } else { 06012 add_header(req, "From", ot); 06013 add_header(req, "To", of); 06014 } 06015 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06016 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06017 add_header(req, "Contact", p->our_contact); 06018 06019 copy_header(req, orig, "Call-ID"); 06020 add_header(req, "CSeq", tmp); 06021 06022 if (!ast_strlen_zero(global_useragent)) 06023 add_header(req, "User-Agent", global_useragent); 06024 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06025 06026 if (!ast_strlen_zero(p->rpid)) 06027 add_header(req, "Remote-Party-ID", p->rpid); 06028 06029 return 0; 06030 }
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 5881 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.
05882 { 05883 char newto[256]; 05884 const char *ot; 05885 05886 init_resp(resp, msg); 05887 copy_via_headers(p, resp, req, "Via"); 05888 if (msg[0] == '1' || msg[0] == '2') 05889 copy_all_header(resp, req, "Record-Route"); 05890 copy_header(resp, req, "From"); 05891 ot = get_header(req, "To"); 05892 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05893 /* Add the proper tag if we don't have it already. If they have specified 05894 their tag, use it. Otherwise, use our own tag */ 05895 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05896 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05897 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05898 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05899 else 05900 ast_copy_string(newto, ot, sizeof(newto)); 05901 ot = newto; 05902 } 05903 add_header(resp, "To", ot); 05904 copy_header(resp, req, "Call-ID"); 05905 copy_header(resp, req, "CSeq"); 05906 if (!ast_strlen_zero(global_useragent)) 05907 add_header(resp, "User-Agent", global_useragent); 05908 add_header(resp, "Allow", ALLOWED_METHODS); 05909 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05910 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05911 /* For registration responses, we also need expiry and 05912 contact info */ 05913 char tmp[256]; 05914 05915 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05916 add_header(resp, "Expires", tmp); 05917 if (p->expiry) { /* Only add contact if we have an expiry time */ 05918 char contact[SIPBUFSIZE]; 05919 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05920 add_header(resp, "Contact", contact); /* Not when we unregister */ 05921 } 05922 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05923 add_header(resp, "Contact", p->our_contact); 05924 } 05925 return 0; 05926 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16225 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.
16226 { 16227 /* If we're supposed to be stopped -- stay stopped */ 16228 if (monitor_thread == AST_PTHREADT_STOP) 16229 return 0; 16230 ast_mutex_lock(&monlock); 16231 if (monitor_thread == pthread_self()) { 16232 ast_mutex_unlock(&monlock); 16233 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16234 return -1; 16235 } 16236 if (monitor_thread != AST_PTHREADT_NULL) { 16237 /* Wake up the thread */ 16238 pthread_kill(monitor_thread, SIGURG); 16239 } else { 16240 /* Start a new monitor */ 16241 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16242 ast_mutex_unlock(&monlock); 16243 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16244 return -1; 16245 } 16246 } 16247 ast_mutex_unlock(&monlock); 16248 return 0; 16249 }
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 8050 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().
08051 { 08052 struct hostent *hp; 08053 struct ast_hostent ahp; 08054 int port; 08055 char *c, *host, *pt; 08056 char contact_buf[256]; 08057 char *contact; 08058 08059 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08060 /* NAT: Don't trust the contact field. Just use what they came to us 08061 with. */ 08062 pvt->sa = pvt->recv; 08063 return 0; 08064 } 08065 08066 /* Work on a copy */ 08067 ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); 08068 contact = contact_buf; 08069 08070 /* Make sure it's a SIP URL */ 08071 if (strncasecmp(contact, "sip:", 4)) { 08072 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08073 } else 08074 contact += 4; 08075 08076 /* Ditch arguments */ 08077 /* XXX this code is replicated also shortly below */ 08078 08079 /* Grab host */ 08080 host = strchr(contact, '@'); 08081 if (!host) { /* No username part */ 08082 host = contact; 08083 c = NULL; 08084 } else { 08085 *host++ = '\0'; 08086 } 08087 pt = strchr(host, ':'); 08088 if (pt) { 08089 *pt++ = '\0'; 08090 port = atoi(pt); 08091 } else 08092 port = STANDARD_SIP_PORT; 08093 08094 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08095 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08096 08097 /* XXX This could block for a long time XXX */ 08098 /* We should only do this if it's a name, not an IP */ 08099 hp = ast_gethostbyname(host, &ahp); 08100 if (!hp) { 08101 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08102 return -1; 08103 } 08104 pvt->sa.sin_family = AF_INET; 08105 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08106 pvt->sa.sin_port = htons(port); 08107 08108 return 0; 08109 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5790 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().
05791 { 05792 char *h, *maddr, hostname[256]; 05793 int port, hn; 05794 struct hostent *hp; 05795 struct ast_hostent ahp; 05796 int debug=sip_debug_test_pvt(p); 05797 05798 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05799 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05800 05801 if (debug) 05802 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05803 05804 /* Find and parse hostname */ 05805 h = strchr(uri, '@'); 05806 if (h) 05807 ++h; 05808 else { 05809 h = uri; 05810 if (strncasecmp(h, "sip:", 4) == 0) 05811 h += 4; 05812 else if (strncasecmp(h, "sips:", 5) == 0) 05813 h += 5; 05814 } 05815 hn = strcspn(h, ":;>") + 1; 05816 if (hn > sizeof(hostname)) 05817 hn = sizeof(hostname); 05818 ast_copy_string(hostname, h, hn); 05819 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05820 h += hn - 1; 05821 05822 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05823 if (*h == ':') { 05824 /* Parse port */ 05825 ++h; 05826 port = strtol(h, &h, 10); 05827 } 05828 else 05829 port = STANDARD_SIP_PORT; 05830 05831 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05832 maddr = strstr(h, "maddr="); 05833 if (maddr) { 05834 maddr += 6; 05835 hn = strspn(maddr, "0123456789.") + 1; 05836 if (hn > sizeof(hostname)) 05837 hn = sizeof(hostname); 05838 ast_copy_string(hostname, maddr, hn); 05839 } 05840 05841 hp = ast_gethostbyname(hostname, &ahp); 05842 if (hp == NULL) { 05843 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05844 return; 05845 } 05846 p->sa.sin_family = AF_INET; 05847 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05848 p->sa.sin_port = htons(port); 05849 if (debug) 05850 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05851 }
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 16552 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().
16553 { 16554 static int dep_insecure_very = 0; 16555 static int dep_insecure_yes = 0; 16556 16557 if (ast_strlen_zero(value)) 16558 return; 16559 16560 if (!strcasecmp(value, "very")) { 16561 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16562 if(!dep_insecure_very) { 16563 if(lineno != -1) 16564 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16565 else 16566 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16567 dep_insecure_very = 1; 16568 } 16569 } 16570 else if (ast_true(value)) { 16571 ast_set_flag(flags, SIP_INSECURE_PORT); 16572 if(!dep_insecure_yes) { 16573 if(lineno != -1) 16574 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16575 else 16576 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16577 dep_insecure_yes = 1; 16578 } 16579 } 16580 else if (!ast_false(value)) { 16581 char buf[64]; 16582 char *word, *next; 16583 ast_copy_string(buf, value, sizeof(buf)); 16584 next = buf; 16585 while ((word = strsep(&next, ","))) { 16586 if (!strcasecmp(word, "port")) 16587 ast_set_flag(flags, SIP_INSECURE_PORT); 16588 else if (!strcasecmp(word, "invite")) 16589 ast_set_flag(flags, SIP_INSECURE_INVITE); 16590 else 16591 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16592 } 16593 } 16594 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16982 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().
16983 { 16984 if (peer->expire == 0) { 16985 /* Don't reset expire or port time during reload 16986 if we have an active registration 16987 */ 16988 peer->expire = -1; 16989 peer->pokeexpire = -1; 16990 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16991 } 16992 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16993 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16994 strcpy(peer->context, default_context); 16995 strcpy(peer->subscribecontext, default_subscribecontext); 16996 strcpy(peer->language, default_language); 16997 strcpy(peer->mohinterpret, default_mohinterpret); 16998 strcpy(peer->mohsuggest, default_mohsuggest); 16999 peer->addr.sin_family = AF_INET; 17000 peer->defaddr.sin_family = AF_INET; 17001 peer->capability = global_capability; 17002 peer->maxcallbitrate = default_maxcallbitrate; 17003 peer->rtptimeout = global_rtptimeout; 17004 peer->rtpholdtimeout = global_rtpholdtimeout; 17005 peer->rtpkeepalive = global_rtpkeepalive; 17006 peer->allowtransfer = global_allowtransfer; 17007 peer->autoframing = global_autoframing; 17008 strcpy(peer->vmexten, default_vmexten); 17009 peer->secret[0] = '\0'; 17010 peer->md5secret[0] = '\0'; 17011 peer->cid_num[0] = '\0'; 17012 peer->cid_name[0] = '\0'; 17013 peer->fromdomain[0] = '\0'; 17014 peer->fromuser[0] = '\0'; 17015 peer->regexten[0] = '\0'; 17016 peer->mailbox[0] = '\0'; 17017 peer->callgroup = 0; 17018 peer->pickupgroup = 0; 17019 peer->maxms = default_qualify; 17020 peer->prefs = default_prefs; 17021 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18255 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().
18256 { 18257 int no = 0; 18258 int ok = FALSE; 18259 char varbuf[30]; 18260 char *inbuf = (char *) data; 18261 18262 if (ast_strlen_zero(inbuf)) { 18263 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18264 return 0; 18265 } 18266 ast_channel_lock(chan); 18267 18268 /* Check for headers */ 18269 while (!ok && no <= 50) { 18270 no++; 18271 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 18272 18273 /* Compare without the leading underscore */ 18274 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 18275 ok = TRUE; 18276 } 18277 if (ok) { 18278 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18279 if (sipdebug) 18280 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18281 } else { 18282 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18283 } 18284 ast_channel_unlock(chan); 18285 return 0; 18286 }
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 4444 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().
04446 { 04447 struct sip_pvt *p; 04448 04449 if (!(p = ast_calloc(1, sizeof(*p)))) 04450 return NULL; 04451 04452 if (ast_string_field_init(p, 512)) { 04453 free(p); 04454 return NULL; 04455 } 04456 04457 ast_mutex_init(&p->lock); 04458 04459 p->method = intended_method; 04460 p->initid = -1; 04461 p->waitid = -1; 04462 p->autokillid = -1; 04463 p->subscribed = NONE; 04464 p->stateid = -1; 04465 p->prefs = default_prefs; /* Set default codecs for this call */ 04466 04467 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04468 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04469 04470 if (sin) { 04471 p->sa = *sin; 04472 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04473 p->ourip = __ourip; 04474 } else 04475 p->ourip = __ourip; 04476 04477 /* Copy global flags to this PVT at setup. */ 04478 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04479 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04480 04481 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04482 04483 p->branch = ast_random(); 04484 make_our_tag(p->tag, sizeof(p->tag)); 04485 p->ocseq = INITIAL_CSEQ; 04486 04487 if (sip_methods[intended_method].need_rtp) { 04488 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04489 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04490 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04491 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04492 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04493 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04494 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04495 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04496 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04497 ast_mutex_destroy(&p->lock); 04498 if (p->chanvars) { 04499 ast_variables_destroy(p->chanvars); 04500 p->chanvars = NULL; 04501 } 04502 free(p); 04503 return NULL; 04504 } 04505 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04506 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04507 ast_rtp_settos(p->rtp, global_tos_audio); 04508 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04509 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04510 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04511 if (p->vrtp) { 04512 ast_rtp_settos(p->vrtp, global_tos_video); 04513 ast_rtp_setdtmf(p->vrtp, 0); 04514 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04515 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04516 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04517 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04518 } 04519 if (p->udptl) 04520 ast_udptl_settos(p->udptl, global_tos_audio); 04521 p->maxcallbitrate = default_maxcallbitrate; 04522 p->autoframing = global_autoframing; 04523 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04524 } 04525 04526 if (useglobal_nat && sin) { 04527 /* Setup NAT structure according to global settings if we have an address */ 04528 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04529 p->recv = *sin; 04530 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04531 } 04532 04533 if (p->method != SIP_REGISTER) 04534 ast_string_field_set(p, fromdomain, default_fromdomain); 04535 build_via(p); 04536 if (!callid) 04537 build_callid_pvt(p); 04538 else 04539 ast_string_field_set(p, callid, callid); 04540 /* Assign default music on hold class */ 04541 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04542 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04543 p->capability = global_capability; 04544 p->allowtransfer = global_allowtransfer; 04545 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04546 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04547 p->noncodeccapability |= AST_RTP_DTMF; 04548 if (p->udptl) { 04549 p->t38.capability = global_t38_capability; 04550 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04551 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04552 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04553 p->t38.capability |= T38FAX_UDP_EC_FEC; 04554 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04555 p->t38.capability |= T38FAX_UDP_EC_NONE; 04556 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04557 p->t38.jointcapability = p->t38.capability; 04558 } 04559 ast_string_field_set(p, context, default_context); 04560 04561 /* Add to active dialog list */ 04562 ast_mutex_lock(&iflock); 04563 p->next = iflist; 04564 iflist = p; 04565 ast_mutex_unlock(&iflock); 04566 if (option_debug) 04567 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"); 04568 return p; 04569 }
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 16394 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().
16395 { 16396 char *host; 16397 char *tmp; 16398 16399 struct hostent *hp; 16400 struct ast_hostent ahp; 16401 struct sip_peer *p; 16402 16403 int res = AST_DEVICE_INVALID; 16404 16405 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16406 host = ast_strdupa(data ? data : ""); 16407 if ((tmp = strchr(host, '@'))) 16408 host = tmp + 1; 16409 16410 if (option_debug > 2) 16411 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16412 16413 if ((p = find_peer(host, NULL, 1))) { 16414 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16415 /* we have an address for the peer */ 16416 16417 /* Check status in this order 16418 - Hold 16419 - Ringing 16420 - Busy (enforced only by call limit) 16421 - Inuse (we have a call) 16422 - Unreachable (qualify) 16423 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16424 for registered devices */ 16425 16426 if (p->onHold) 16427 /* First check for hold or ring states */ 16428 res = AST_DEVICE_ONHOLD; 16429 else if (p->inRinging) { 16430 if (p->inRinging == p->inUse) 16431 res = AST_DEVICE_RINGING; 16432 else 16433 res = AST_DEVICE_RINGINUSE; 16434 } else if (p->call_limit && (p->inUse == p->call_limit)) 16435 /* check call limit */ 16436 res = AST_DEVICE_BUSY; 16437 else if (p->call_limit && p->inUse) 16438 /* Not busy, but we do have a call */ 16439 res = AST_DEVICE_INUSE; 16440 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16441 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16442 res = AST_DEVICE_UNAVAILABLE; 16443 else /* Default reply if we're registered and have no other data */ 16444 res = AST_DEVICE_NOT_INUSE; 16445 } else { 16446 /* there is no address, it's unavailable */ 16447 res = AST_DEVICE_UNAVAILABLE; 16448 } 16449 ASTOBJ_UNREF(p,sip_destroy_peer); 16450 } else { 16451 char *port = strchr(host, ':'); 16452 if (port) 16453 *port = '\0'; 16454 hp = ast_gethostbyname(host, &ahp); 16455 if (hp) 16456 res = AST_DEVICE_UNKNOWN; 16457 } 16458 16459 return res; 16460 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11431 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.
11432 { 11433 int oldsipdebug = sipdebug_console; 11434 if (argc != 3) { 11435 if (argc != 5) 11436 return RESULT_SHOWUSAGE; 11437 else if (strcmp(argv[3], "ip") == 0) 11438 return sip_do_debug_ip(fd, argc, argv); 11439 else if (strcmp(argv[3], "peer") == 0) 11440 return sip_do_debug_peer(fd, argc, argv); 11441 else 11442 return RESULT_SHOWUSAGE; 11443 } 11444 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11445 memset(&debugaddr, 0, sizeof(debugaddr)); 11446 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11447 return RESULT_SUCCESS; 11448 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11450 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.
11451 { 11452 int oldsipdebug = sipdebug_console; 11453 char *newargv[6] = { "sip", "set", "debug", NULL }; 11454 if (argc != 2) { 11455 if (argc != 4) 11456 return RESULT_SHOWUSAGE; 11457 else if (strcmp(argv[2], "ip") == 0) { 11458 newargv[3] = argv[2]; 11459 newargv[4] = argv[3]; 11460 return sip_do_debug_ip(fd, argc + 1, newargv); 11461 } else if (strcmp(argv[2], "peer") == 0) { 11462 newargv[3] = argv[2]; 11463 newargv[4] = argv[3]; 11464 return sip_do_debug_peer(fd, argc + 1, newargv); 11465 } else 11466 return RESULT_SHOWUSAGE; 11467 } 11468 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11469 memset(&debugaddr, 0, sizeof(debugaddr)); 11470 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11471 return RESULT_SUCCESS; 11472 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11377 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().
11378 { 11379 struct hostent *hp; 11380 struct ast_hostent ahp; 11381 int port = 0; 11382 char *p, *arg; 11383 11384 /* sip set debug ip <ip> */ 11385 if (argc != 5) 11386 return RESULT_SHOWUSAGE; 11387 p = arg = argv[4]; 11388 strsep(&p, ":"); 11389 if (p) 11390 port = atoi(p); 11391 hp = ast_gethostbyname(arg, &ahp); 11392 if (hp == NULL) 11393 return RESULT_SHOWUSAGE; 11394 11395 debugaddr.sin_family = AF_INET; 11396 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11397 debugaddr.sin_port = htons(port); 11398 if (port == 0) 11399 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11400 else 11401 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11402 11403 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11404 11405 return RESULT_SUCCESS; 11406 }
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 11409 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().
11410 { 11411 struct sip_peer *peer; 11412 if (argc != 5) 11413 return RESULT_SHOWUSAGE; 11414 peer = find_peer(argv[4], NULL, 1); 11415 if (peer) { 11416 if (peer->addr.sin_addr.s_addr) { 11417 debugaddr.sin_family = AF_INET; 11418 debugaddr.sin_addr = peer->addr.sin_addr; 11419 debugaddr.sin_port = peer->addr.sin_port; 11420 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11421 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11422 } else 11423 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11424 ASTOBJ_UNREF(peer,sip_destroy_peer); 11425 } else 11426 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11427 return RESULT_SUCCESS; 11428 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11550 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11551 { 11552 if (argc != 2) { 11553 return RESULT_SHOWUSAGE; 11554 } 11555 recordhistory = TRUE; 11556 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11557 return RESULT_SUCCESS; 11558 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18401 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().
18402 { 18403 reload_config(reason); 18404 18405 /* Prune peers who still are supposed to be deleted */ 18406 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18407 if (option_debug > 3) 18408 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18409 18410 /* Send qualify (OPTIONS) to all peers */ 18411 sip_poke_all_peers(); 18412 18413 /* Register with all services */ 18414 sip_send_all_registers(); 18415 18416 if (option_debug > 3) 18417 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18418 18419 return 0; 18420 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18200 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().
18201 { 18202 struct sip_pvt *p; 18203 char *mode; 18204 if (data) 18205 mode = (char *)data; 18206 else { 18207 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18208 return 0; 18209 } 18210 ast_channel_lock(chan); 18211 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18212 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18213 ast_channel_unlock(chan); 18214 return 0; 18215 } 18216 p = chan->tech_pvt; 18217 if (!p) { 18218 ast_channel_unlock(chan); 18219 return 0; 18220 } 18221 ast_mutex_lock(&p->lock); 18222 if (!strcasecmp(mode,"info")) { 18223 ast_clear_flag(&p->flags[0], SIP_DTMF); 18224 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18225 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18226 } else if (!strcasecmp(mode,"rfc2833")) { 18227 ast_clear_flag(&p->flags[0], SIP_DTMF); 18228 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18229 p->jointnoncodeccapability |= AST_RTP_DTMF; 18230 } else if (!strcasecmp(mode,"inband")) { 18231 ast_clear_flag(&p->flags[0], SIP_DTMF); 18232 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18233 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18234 } else 18235 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18236 if (p->rtp) 18237 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18238 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18239 if (!p->vad) { 18240 p->vad = ast_dsp_new(); 18241 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18242 } 18243 } else { 18244 if (p->vad) { 18245 ast_dsp_free(p->vad); 18246 p->vad = NULL; 18247 } 18248 } 18249 ast_mutex_unlock(&p->lock); 18250 ast_channel_unlock(chan); 18251 return 0; 18252 }
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 11242 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().
11243 { 11244 int x = 0; 11245 struct sip_history *hist; 11246 static int errmsg = 0; 11247 11248 if (!dialog) 11249 return; 11250 11251 if (!option_debug && !sipdebug) { 11252 if (!errmsg) { 11253 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11254 errmsg = 1; 11255 } 11256 return; 11257 } 11258 11259 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11260 if (dialog->subscribed) 11261 ast_log(LOG_DEBUG, " * Subscription\n"); 11262 else 11263 ast_log(LOG_DEBUG, " * SIP Call\n"); 11264 if (dialog->history) 11265 AST_LIST_TRAVERSE(dialog->history, hist, list) 11266 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11267 if (!x) 11268 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11269 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11270 }
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 18345 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
18346 { 18347 struct sip_pvt *p = chan->tech_pvt; 18348 return p->peercapability ? p->peercapability : p->capability; 18349 }
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 18053 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.
18054 { 18055 struct sip_pvt *p = NULL; 18056 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18057 18058 if (!(p = chan->tech_pvt)) 18059 return AST_RTP_GET_FAILED; 18060 18061 ast_mutex_lock(&p->lock); 18062 if (!(p->rtp)) { 18063 ast_mutex_unlock(&p->lock); 18064 return AST_RTP_GET_FAILED; 18065 } 18066 18067 *rtp = p->rtp; 18068 18069 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18070 res = AST_RTP_TRY_PARTIAL; 18071 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18072 res = AST_RTP_TRY_NATIVE; 18073 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18074 res = AST_RTP_GET_FAILED; 18075 18076 ast_mutex_unlock(&p->lock); 18077 18078 return res; 18079 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 17918 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.
17919 { 17920 struct sip_pvt *p; 17921 struct ast_udptl *udptl = NULL; 17922 17923 p = chan->tech_pvt; 17924 if (!p) 17925 return NULL; 17926 17927 ast_mutex_lock(&p->lock); 17928 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17929 udptl = p->udptl; 17930 ast_mutex_unlock(&p->lock); 17931 return udptl; 17932 }
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 18082 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.
18083 { 18084 struct sip_pvt *p = NULL; 18085 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18086 18087 if (!(p = chan->tech_pvt)) 18088 return AST_RTP_GET_FAILED; 18089 18090 ast_mutex_lock(&p->lock); 18091 if (!(p->vrtp)) { 18092 ast_mutex_unlock(&p->lock); 18093 return AST_RTP_GET_FAILED; 18094 } 18095 18096 *rtp = p->vrtp; 18097 18098 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18099 res = AST_RTP_TRY_NATIVE; 18100 18101 ast_mutex_unlock(&p->lock); 18102 18103 return res; 18104 }
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 17970 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().
17971 { 17972 struct sip_pvt *p; 17973 int flag = 0; 17974 17975 p = chan->tech_pvt; 17976 if (!p || !pvt->udptl) 17977 return -1; 17978 17979 /* Setup everything on the other side like offered/responded from first side */ 17980 ast_mutex_lock(&p->lock); 17981 17982 /*! \todo check if this is not set earlier when setting up the PVT. If not 17983 maybe it should move there. */ 17984 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17985 17986 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17987 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17988 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17989 17990 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17991 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17992 not really T38 re-invites which are different. In this 17993 case it's used properly, to see if we can reinvite over 17994 NAT 17995 */ 17996 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17997 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17998 flag =1; 17999 } else { 18000 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18001 } 18002 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18003 if (!p->pendinginvite) { 18004 if (option_debug > 2) { 18005 if (flag) 18006 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)); 18007 else 18008 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)); 18009 } 18010 transmit_reinvite_with_t38_sdp(p); 18011 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18012 if (option_debug > 2) { 18013 if (flag) 18014 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)); 18015 else 18016 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)); 18017 } 18018 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18019 } 18020 } 18021 /* Reset lastrtprx timer */ 18022 p->lastrtprx = p->lastrtptx = time(NULL); 18023 ast_mutex_unlock(&p->lock); 18024 return 0; 18025 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18026 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18027 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18028 flag = 1; 18029 } else { 18030 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18031 } 18032 if (option_debug > 2) { 18033 if (flag) 18034 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)); 18035 else 18036 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)); 18037 } 18038 pvt->t38.state = T38_ENABLED; 18039 p->t38.state = T38_ENABLED; 18040 if (option_debug > 1) { 18041 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18042 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18043 } 18044 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18045 p->lastrtprx = p->lastrtptx = time(NULL); 18046 ast_mutex_unlock(&p->lock); 18047 return 0; 18048 } 18049 }
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_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_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_new_source(p->rtp); 03958 ast_moh_start(ast, data, p->mohinterpret); 03959 break; 03960 case AST_CONTROL_UNHOLD: 03961 ast_rtp_new_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_new_source(p->rtp); 03973 break; 03974 case -1: 03975 res = -1; 03976 break; 03977 default: 03978 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03979 res = -1; 03980 break; 03981 } 03982 ast_mutex_unlock(&p->lock); 03983 return res; 03984 }
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 3992 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().
03993 { 03994 struct ast_channel *tmp; 03995 struct ast_variable *v = NULL; 03996 int fmt; 03997 int what; 03998 int needvideo = 0, video = 0; 03999 char *decoded_exten; 04000 { 04001 const char *my_name; /* pick a good name */ 04002 04003 if (title) 04004 my_name = title; 04005 else if ( (my_name = strchr(i->fromdomain,':')) ) 04006 my_name++; /* skip ':' */ 04007 else 04008 my_name = i->fromdomain; 04009 04010 ast_mutex_unlock(&i->lock); 04011 /* Don't hold a sip pvt lock while we allocate a channel */ 04012 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); 04013 04014 } 04015 if (!tmp) { 04016 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04017 ast_mutex_lock(&i->lock); 04018 return NULL; 04019 } 04020 ast_mutex_lock(&i->lock); 04021 04022 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04023 tmp->tech = &sip_tech_info; 04024 else 04025 tmp->tech = &sip_tech; 04026 04027 /* Select our native format based on codec preference until we receive 04028 something from another device to the contrary. */ 04029 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04030 what = i->jointcapability; 04031 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04032 } else if (i->capability) { /* Our configured capability for this peer */ 04033 what = i->capability; 04034 video = i->capability & AST_FORMAT_VIDEO_MASK; 04035 } else { 04036 what = global_capability; /* Global codec support */ 04037 video = global_capability & AST_FORMAT_VIDEO_MASK; 04038 } 04039 04040 /* Set the native formats for audio and merge in video */ 04041 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04042 if (option_debug > 2) { 04043 char buf[SIPBUFSIZE]; 04044 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04045 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04046 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04047 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04048 if (i->prefcodec) 04049 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04050 } 04051 04052 /* XXX Why are we choosing a codec from the native formats?? */ 04053 fmt = ast_best_codec(tmp->nativeformats); 04054 04055 /* If we have a prefcodec setting, we have an inbound channel that set a 04056 preferred format for this call. Otherwise, we check the jointcapability 04057 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04058 */ 04059 if (i->vrtp) { 04060 if (i->prefcodec) 04061 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04062 else 04063 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04064 } 04065 04066 if (option_debug > 2) { 04067 if (needvideo) 04068 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04069 else 04070 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04071 } 04072 04073 04074 04075 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04076 i->vad = ast_dsp_new(); 04077 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04078 if (global_relaxdtmf) 04079 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04080 } 04081 if (i->rtp) { 04082 tmp->fds[0] = ast_rtp_fd(i->rtp); 04083 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04084 } 04085 if (needvideo && i->vrtp) { 04086 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04087 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04088 } 04089 if (i->udptl) { 04090 tmp->fds[5] = ast_udptl_fd(i->udptl); 04091 } 04092 if (state == AST_STATE_RING) 04093 tmp->rings = 1; 04094 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04095 tmp->writeformat = fmt; 04096 tmp->rawwriteformat = fmt; 04097 tmp->readformat = fmt; 04098 tmp->rawreadformat = fmt; 04099 tmp->tech_pvt = i; 04100 04101 tmp->callgroup = i->callgroup; 04102 tmp->pickupgroup = i->pickupgroup; 04103 tmp->cid.cid_pres = i->callingpres; 04104 if (!ast_strlen_zero(i->accountcode)) 04105 ast_string_field_set(tmp, accountcode, i->accountcode); 04106 if (i->amaflags) 04107 tmp->amaflags = i->amaflags; 04108 if (!ast_strlen_zero(i->language)) 04109 ast_string_field_set(tmp, language, i->language); 04110 i->owner = tmp; 04111 ast_module_ref(ast_module_info->self); 04112 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04113 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04114 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04115 * structure so that there aren't issues when forming URI's 04116 */ 04117 decoded_exten = ast_strdupa(i->exten); 04118 ast_uri_decode(decoded_exten); 04119 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04120 04121 /* Don't use ast_set_callerid() here because it will 04122 * generate an unnecessary NewCallerID event */ 04123 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04124 if (!ast_strlen_zero(i->rdnis)) 04125 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04126 04127 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04128 tmp->cid.cid_dnid = ast_strdup(i->exten); 04129 04130 tmp->priority = 1; 04131 if (!ast_strlen_zero(i->uri)) 04132 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04133 if (!ast_strlen_zero(i->domain)) 04134 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04135 if (!ast_strlen_zero(i->useragent)) 04136 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04137 if (!ast_strlen_zero(i->callid)) 04138 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04139 if (i->rtp) 04140 ast_jb_configure(tmp, &global_jbconf); 04141 04142 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04143 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04144 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04145 04146 /* Set channel variables for this call from configuration */ 04147 for (v = i->chanvars ; v ; v = v->next) 04148 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04149 04150 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04151 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04152 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04153 ast_hangup(tmp); 04154 tmp = NULL; 04155 } 04156 04157 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04158 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04159 04160 return tmp; 04161 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11531 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11532 { 11533 if (argc != 4) 11534 return RESULT_SHOWUSAGE; 11535 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11536 ast_cli(fd, "SIP Debugging Disabled\n"); 11537 return RESULT_SUCCESS; 11538 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11540 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11541 { 11542 if (argc != 3) 11543 return RESULT_SHOWUSAGE; 11544 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11545 ast_cli(fd, "SIP Debugging Disabled\n"); 11546 return RESULT_SUCCESS; 11547 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11561 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11562 { 11563 if (argc != 3) { 11564 return RESULT_SHOWUSAGE; 11565 } 11566 recordhistory = FALSE; 11567 ast_cli(fd, "SIP History Recording Disabled\n"); 11568 return RESULT_SUCCESS; 11569 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11475 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.
11476 { 11477 struct ast_variable *varlist; 11478 int i; 11479 11480 if (argc < 4) 11481 return RESULT_SHOWUSAGE; 11482 11483 if (!notify_types) { 11484 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11485 return RESULT_FAILURE; 11486 } 11487 11488 varlist = ast_variable_browse(notify_types, argv[2]); 11489 11490 if (!varlist) { 11491 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11492 return RESULT_FAILURE; 11493 } 11494 11495 for (i = 3; i < argc; i++) { 11496 struct sip_pvt *p; 11497 struct sip_request req; 11498 struct ast_variable *var; 11499 11500 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11501 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11502 return RESULT_FAILURE; 11503 } 11504 11505 if (create_addr(p, argv[i])) { 11506 /* Maybe they're not registered, etc. */ 11507 sip_destroy(p); 11508 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11509 continue; 11510 } 11511 11512 initreqprep(&req, p, SIP_NOTIFY); 11513 11514 for (var = varlist; var; var = var->next) 11515 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11516 11517 /* Recalculate our side, and recalculate Call ID */ 11518 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11519 p->ourip = __ourip; 11520 build_via(p); 11521 build_callid_pvt(p); 11522 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11523 transmit_sip_request(p, &req); 11524 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11525 } 11526 11527 return RESULT_SUCCESS; 11528 }
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 13291 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().
13292 { 13293 struct sip_dual *d; 13294 struct ast_channel *transferee, *transferer; 13295 /* Chan2m: The transferer, chan1m: The transferee */ 13296 pthread_t th; 13297 13298 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13299 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13300 if ((!transferer) || (!transferee)) { 13301 if (transferee) { 13302 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13303 ast_hangup(transferee); 13304 } 13305 if (transferer) { 13306 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13307 ast_hangup(transferer); 13308 } 13309 return -1; 13310 } 13311 13312 /* Make formats okay */ 13313 transferee->readformat = chan1->readformat; 13314 transferee->writeformat = chan1->writeformat; 13315 13316 /* Prepare for taking over the channel */ 13317 ast_channel_masquerade(transferee, chan1); 13318 13319 /* Setup the extensions and such */ 13320 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13321 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13322 transferee->priority = chan1->priority; 13323 13324 /* We make a clone of the peer channel too, so we can play 13325 back the announcement */ 13326 13327 /* Make formats okay */ 13328 transferer->readformat = chan2->readformat; 13329 transferer->writeformat = chan2->writeformat; 13330 13331 /* Prepare for taking over the channel. Go ahead and grab this channel 13332 * lock here to avoid a deadlock with callbacks into the channel driver 13333 * that hold the channel lock and want the pvt lock. */ 13334 while (ast_channel_trylock(chan2)) { 13335 struct sip_pvt *pvt = chan2->tech_pvt; 13336 DEADLOCK_AVOIDANCE(&pvt->lock); 13337 } 13338 ast_channel_masquerade(transferer, chan2); 13339 ast_channel_unlock(chan2); 13340 13341 /* Setup the extensions and such */ 13342 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13343 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13344 transferer->priority = chan2->priority; 13345 13346 ast_channel_lock(transferer); 13347 if (ast_do_masquerade(transferer)) { 13348 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13349 ast_channel_unlock(transferer); 13350 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13351 ast_hangup(transferer); 13352 return -1; 13353 } 13354 ast_channel_unlock(transferer); 13355 if (!transferer || !transferee) { 13356 if (!transferer) { 13357 if (option_debug) 13358 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13359 } 13360 if (!transferee) { 13361 if (option_debug) 13362 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13363 } 13364 return -1; 13365 } 13366 if ((d = ast_calloc(1, sizeof(*d)))) { 13367 pthread_attr_t attr; 13368 13369 pthread_attr_init(&attr); 13370 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13371 13372 /* Save original request for followup */ 13373 copy_request(&d->req, req); 13374 d->chan1 = transferee; /* Transferee */ 13375 d->chan2 = transferer; /* Transferer */ 13376 d->seqno = seqno; 13377 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13378 /* Could not start thread */ 13379 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13380 by sip_park_thread() */ 13381 pthread_attr_destroy(&attr); 13382 return 0; 13383 } 13384 pthread_attr_destroy(&attr); 13385 } 13386 return -1; 13387 }
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 13224 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().
13225 { 13226 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13227 struct sip_dual *d; 13228 struct sip_request req; 13229 int ext; 13230 int res; 13231 13232 d = stuff; 13233 transferee = d->chan1; 13234 transferer = d->chan2; 13235 copy_request(&req, &d->req); 13236 free(d); 13237 13238 if (!transferee || !transferer) { 13239 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13240 return NULL; 13241 } 13242 if (option_debug > 3) 13243 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13244 13245 ast_channel_lock(transferee); 13246 if (ast_do_masquerade(transferee)) { 13247 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13248 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13249 ast_channel_unlock(transferee); 13250 return NULL; 13251 } 13252 ast_channel_unlock(transferee); 13253 13254 res = ast_park_call(transferee, transferer, 0, &ext); 13255 13256 13257 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13258 if (!res) { 13259 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13260 } else { 13261 /* Then tell the transferer what happened */ 13262 sprintf(buf, "Call parked on extension '%d'", ext); 13263 transmit_message_with_text(transferer->tech_pvt, buf); 13264 } 13265 #endif 13266 13267 /* Any way back to the current call??? */ 13268 /* Transmit response to the REFER request */ 13269 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13270 if (!res) { 13271 /* Transfer succeeded */ 13272 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13273 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13274 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13275 ast_hangup(transferer); /* This will cause a BYE */ 13276 if (option_debug) 13277 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13278 } else { 13279 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13280 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13281 if (option_debug) 13282 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13283 /* Do not hangup call */ 13284 } 13285 return NULL; 13286 }
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 8578 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().
08579 { 08580 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08581 08582 if (!peer) 08583 return; 08584 08585 /* If they put someone on hold, increment the value... otherwise decrement it */ 08586 if (hold) 08587 peer->onHold++; 08588 else 08589 peer->onHold--; 08590 08591 /* Request device state update */ 08592 ast_device_state_changed("SIP/%s", peer->name); 08593 08594 return; 08595 }
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 18355 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().
18356 { 18357 int ms = 0; 18358 18359 if (!speerobjs) /* No peers, just give up */ 18360 return; 18361 18362 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18363 ASTOBJ_WRLOCK(iterator); 18364 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18365 struct sip_peer *peer_ptr = iterator; 18366 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18367 } 18368 ms += 100; 18369 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18370 if (iterator->pokeexpire == -1) { 18371 struct sip_peer *peer_ptr = iterator; 18372 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18373 } 18374 ASTOBJ_UNLOCK(iterator); 18375 } while (0) 18376 ); 18377 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16252 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().
16253 { 16254 struct sip_peer *peer = (struct sip_peer *)data; 16255 16256 peer->pokeexpire = -1; 16257 if (peer->lastms > -1) { 16258 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16259 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16260 } 16261 if (peer->call) 16262 sip_destroy(peer->call); 16263 peer->call = NULL; 16264 peer->lastms = -1; 16265 ast_device_state_changed("SIP/%s", peer->name); 16266 16267 /* This function gets called one place outside of the scheduler ... */ 16268 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16269 struct sip_peer *peer_ptr = peer; 16270 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16271 } 16272 16273 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16274 * inherit the reference that the current callback already has. */ 16275 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16276 if (peer->pokeexpire == -1) { 16277 ASTOBJ_UNREF(peer, sip_destroy_peer); 16278 } 16279 16280 return 0; 16281 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16286 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().
16287 { 16288 struct sip_pvt *p; 16289 int xmitres = 0; 16290 16291 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16292 /* IF we have no IP, or this isn't to be monitored, return 16293 imeediately after clearing things out */ 16294 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16295 struct sip_peer *peer_ptr = peer; 16296 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16297 } 16298 peer->lastms = 0; 16299 peer->call = NULL; 16300 return 0; 16301 } 16302 if (peer->call) { 16303 if (sipdebug) 16304 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16305 sip_destroy(peer->call); 16306 } 16307 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16308 return -1; 16309 16310 p->sa = peer->addr; 16311 p->recv = peer->addr; 16312 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16313 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16314 16315 /* Send OPTIONs to peer's fullcontact */ 16316 if (!ast_strlen_zero(peer->fullcontact)) 16317 ast_string_field_set(p, fullcontact, peer->fullcontact); 16318 16319 if (!ast_strlen_zero(peer->tohost)) 16320 ast_string_field_set(p, tohost, peer->tohost); 16321 else 16322 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16323 16324 /* Recalculate our side, and recalculate Call ID */ 16325 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16326 p->ourip = __ourip; 16327 build_via(p); 16328 build_callid_pvt(p); 16329 16330 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16331 struct sip_peer *peer_ptr = peer; 16332 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16333 } 16334 16335 p->relatedpeer = ASTOBJ_REF(peer); 16336 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16337 #ifdef VOCAL_DATA_HACK 16338 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16339 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16340 #else 16341 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16342 #endif 16343 gettimeofday(&peer->ps, NULL); 16344 if (xmitres == XMIT_ERROR) { 16345 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16346 } else { 16347 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16348 struct sip_peer *peer_ptr = peer; 16349 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16350 } 16351 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16352 if (peer->pokeexpire == -1) { 16353 struct sip_peer *peer_ptr = peer; 16354 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16355 } 16356 } 16357 16358 return 0; 16359 }
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 7943 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().
07944 { 07945 struct sip_peer *peer = (struct sip_peer *) data; 07946 07947 peer->pokeexpire = -1; 07948 07949 sip_poke_peer(peer); 07950 07951 ASTOBJ_UNREF(peer, sip_destroy_peer); 07952 07953 return 0; 07954 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10264 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.
10265 { 10266 struct sip_peer *peer; 10267 struct sip_user *user; 10268 int pruneuser = FALSE; 10269 int prunepeer = FALSE; 10270 int multi = FALSE; 10271 char *name = NULL; 10272 regex_t regexbuf; 10273 10274 switch (argc) { 10275 case 4: 10276 if (!strcasecmp(argv[3], "user")) 10277 return RESULT_SHOWUSAGE; 10278 if (!strcasecmp(argv[3], "peer")) 10279 return RESULT_SHOWUSAGE; 10280 if (!strcasecmp(argv[3], "like")) 10281 return RESULT_SHOWUSAGE; 10282 if (!strcasecmp(argv[3], "all")) { 10283 multi = TRUE; 10284 pruneuser = prunepeer = TRUE; 10285 } else { 10286 pruneuser = prunepeer = TRUE; 10287 name = argv[3]; 10288 } 10289 break; 10290 case 5: 10291 if (!strcasecmp(argv[4], "like")) 10292 return RESULT_SHOWUSAGE; 10293 if (!strcasecmp(argv[3], "all")) 10294 return RESULT_SHOWUSAGE; 10295 if (!strcasecmp(argv[3], "like")) { 10296 multi = TRUE; 10297 name = argv[4]; 10298 pruneuser = prunepeer = TRUE; 10299 } else if (!strcasecmp(argv[3], "user")) { 10300 pruneuser = TRUE; 10301 if (!strcasecmp(argv[4], "all")) 10302 multi = TRUE; 10303 else 10304 name = argv[4]; 10305 } else if (!strcasecmp(argv[3], "peer")) { 10306 prunepeer = TRUE; 10307 if (!strcasecmp(argv[4], "all")) 10308 multi = TRUE; 10309 else 10310 name = argv[4]; 10311 } else 10312 return RESULT_SHOWUSAGE; 10313 break; 10314 case 6: 10315 if (strcasecmp(argv[4], "like")) 10316 return RESULT_SHOWUSAGE; 10317 if (!strcasecmp(argv[3], "user")) { 10318 pruneuser = TRUE; 10319 name = argv[5]; 10320 } else if (!strcasecmp(argv[3], "peer")) { 10321 prunepeer = TRUE; 10322 name = argv[5]; 10323 } else 10324 return RESULT_SHOWUSAGE; 10325 break; 10326 default: 10327 return RESULT_SHOWUSAGE; 10328 } 10329 10330 if (multi && name) { 10331 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10332 return RESULT_SHOWUSAGE; 10333 } 10334 10335 if (multi) { 10336 if (prunepeer) { 10337 int pruned = 0; 10338 10339 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10340 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10341 ASTOBJ_RDLOCK(iterator); 10342 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10343 ASTOBJ_UNLOCK(iterator); 10344 continue; 10345 }; 10346 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10347 ASTOBJ_MARK(iterator); 10348 pruned++; 10349 } 10350 ASTOBJ_UNLOCK(iterator); 10351 } while (0) ); 10352 if (pruned) { 10353 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10354 ast_cli(fd, "%d peers pruned.\n", pruned); 10355 } else 10356 ast_cli(fd, "No peers found to prune.\n"); 10357 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10358 } 10359 if (pruneuser) { 10360 int pruned = 0; 10361 10362 ASTOBJ_CONTAINER_WRLOCK(&userl); 10363 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10364 ASTOBJ_RDLOCK(iterator); 10365 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10366 ASTOBJ_UNLOCK(iterator); 10367 continue; 10368 }; 10369 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10370 ASTOBJ_MARK(iterator); 10371 pruned++; 10372 } 10373 ASTOBJ_UNLOCK(iterator); 10374 } while (0) ); 10375 if (pruned) { 10376 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10377 ast_cli(fd, "%d users pruned.\n", pruned); 10378 } else 10379 ast_cli(fd, "No users found to prune.\n"); 10380 ASTOBJ_CONTAINER_UNLOCK(&userl); 10381 } 10382 } else { 10383 if (prunepeer) { 10384 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10385 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10386 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10387 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10388 } else 10389 ast_cli(fd, "Peer '%s' pruned.\n", name); 10390 ASTOBJ_UNREF(peer, sip_destroy_peer); 10391 } else 10392 ast_cli(fd, "Peer '%s' not found.\n", name); 10393 } 10394 if (pruneuser) { 10395 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10396 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10397 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10398 ASTOBJ_CONTAINER_LINK(&userl, user); 10399 } else 10400 ast_cli(fd, "User '%s' pruned.\n", name); 10401 ASTOBJ_UNREF(user, sip_destroy_user); 10402 } else 10403 ast_cli(fd, "User '%s' not found.\n", name); 10404 } 10405 } 10406 10407 return RESULT_SUCCESS; 10408 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4364 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().
04365 { 04366 struct ast_frame *fr; 04367 struct sip_pvt *p = ast->tech_pvt; 04368 int faxdetected = FALSE; 04369 04370 ast_mutex_lock(&p->lock); 04371 fr = sip_rtp_read(ast, p, &faxdetected); 04372 p->lastrtprx = time(NULL); 04373 04374 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04375 /* 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 */ 04376 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04377 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04378 if (!p->pendinginvite) { 04379 if (option_debug > 2) 04380 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04381 p->t38.state = T38_LOCAL_REINVITE; 04382 transmit_reinvite_with_t38_sdp(p); 04383 if (option_debug > 1) 04384 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04385 } 04386 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04387 if (option_debug > 2) 04388 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04389 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04390 } 04391 } 04392 04393 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04394 if (fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04395 fr = &ast_null_frame; 04396 } 04397 04398 ast_mutex_unlock(&p->lock); 04399 return fr; 04400 }
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 7748 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().
07749 { 07750 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07751 return p->refer ? 1 : 0; 07752 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7503 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().
07504 { 07505 07506 /* if we are here, our registration timed out, so we'll just do it over */ 07507 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07508 struct sip_pvt *p; 07509 int res; 07510 07511 /* if we couldn't get a reference to the registry object, punt */ 07512 if (!r) 07513 return 0; 07514 07515 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07516 if (r->call) { 07517 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07518 in the single SIP manager thread. */ 07519 p = r->call; 07520 ast_mutex_lock(&p->lock); 07521 if (p->registry) 07522 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07523 r->call = NULL; 07524 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07525 /* Pretend to ACK anything just in case */ 07526 __sip_pretend_ack(p); 07527 ast_mutex_unlock(&p->lock); 07528 } 07529 /* If we have a limit, stop registration and give up */ 07530 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07531 /* Ok, enough is enough. Don't try any more */ 07532 /* We could add an external notification here... 07533 steal it from app_voicemail :-) */ 07534 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07535 r->regstate = REG_STATE_FAILED; 07536 } else { 07537 r->regstate = REG_STATE_UNREGISTERED; 07538 r->timeout = -1; 07539 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07540 } 07541 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)); 07542 ASTOBJ_UNREF(r, sip_registry_destroy); 07543 return 0; 07544 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4689 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().
04690 { 04691 struct sip_registry *reg; 04692 int portnum = 0; 04693 char username[256] = ""; 04694 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04695 char *porta=NULL; 04696 char *contact=NULL; 04697 04698 if (!value) 04699 return -1; 04700 ast_copy_string(username, value, sizeof(username)); 04701 /* First split around the last '@' then parse the two components. */ 04702 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04703 if (hostname) 04704 *hostname++ = '\0'; 04705 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04706 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04707 return -1; 04708 } 04709 /* split user[:secret[:authuser]] */ 04710 secret = strchr(username, ':'); 04711 if (secret) { 04712 *secret++ = '\0'; 04713 authuser = strchr(secret, ':'); 04714 if (authuser) 04715 *authuser++ = '\0'; 04716 } 04717 /* split host[:port][/contact] */ 04718 contact = strchr(hostname, '/'); 04719 if (contact) 04720 *contact++ = '\0'; 04721 if (ast_strlen_zero(contact)) 04722 contact = "s"; 04723 porta = strchr(hostname, ':'); 04724 if (porta) { 04725 *porta++ = '\0'; 04726 portnum = atoi(porta); 04727 if (portnum == 0) { 04728 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04729 return -1; 04730 } 04731 } 04732 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04733 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04734 return -1; 04735 } 04736 04737 if (ast_string_field_init(reg, 256)) { 04738 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04739 free(reg); 04740 return -1; 04741 } 04742 04743 regobjs++; 04744 ASTOBJ_INIT(reg); 04745 ast_string_field_set(reg, contact, contact); 04746 if (!ast_strlen_zero(username)) 04747 ast_string_field_set(reg, username, username); 04748 if (hostname) 04749 ast_string_field_set(reg, hostname, hostname); 04750 if (authuser) 04751 ast_string_field_set(reg, authuser, authuser); 04752 if (secret) 04753 ast_string_field_set(reg, secret, secret); 04754 reg->expire = -1; 04755 reg->timeout = -1; 04756 reg->refresh = default_expiry; 04757 reg->portno = portnum; 04758 reg->callid_valid = FALSE; 04759 reg->ocseq = INITIAL_CSEQ; 04760 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04761 ASTOBJ_UNREF(reg,sip_registry_destroy); 04762 return 0; 04763 }
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 12198 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12199 { 12200 struct sip_pvt *p = (struct sip_pvt *) data; 12201 12202 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12203 p->waitid = -1; 12204 return 0; 12205 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18423 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().
18424 { 18425 ast_mutex_lock(&sip_reload_lock); 18426 if (sip_reloading) 18427 ast_verbose("Previous SIP reload not yet done\n"); 18428 else { 18429 sip_reloading = TRUE; 18430 if (fd) 18431 sip_reloadreason = CHANNEL_CLI_RELOAD; 18432 else 18433 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18434 } 18435 ast_mutex_unlock(&sip_reload_lock); 18436 restart_monitor(); 18437 18438 return 0; 18439 }
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 16464 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.
16465 { 16466 int oldformat; 16467 struct sip_pvt *p; 16468 struct ast_channel *tmpc = NULL; 16469 char *ext, *host; 16470 char tmp[256]; 16471 char *dest = data; 16472 16473 oldformat = format; 16474 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16475 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)); 16476 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16477 return NULL; 16478 } 16479 if (option_debug) 16480 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16481 16482 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16483 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16484 *cause = AST_CAUSE_SWITCH_CONGESTION; 16485 return NULL; 16486 } 16487 16488 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16489 16490 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16491 sip_destroy(p); 16492 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16493 *cause = AST_CAUSE_SWITCH_CONGESTION; 16494 return NULL; 16495 } 16496 16497 ast_copy_string(tmp, dest, sizeof(tmp)); 16498 host = strchr(tmp, '@'); 16499 if (host) { 16500 *host++ = '\0'; 16501 ext = tmp; 16502 } else { 16503 ext = strchr(tmp, '/'); 16504 if (ext) 16505 *ext++ = '\0'; 16506 host = tmp; 16507 } 16508 16509 if (create_addr(p, host)) { 16510 *cause = AST_CAUSE_UNREGISTERED; 16511 if (option_debug > 2) 16512 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16513 sip_destroy(p); 16514 return NULL; 16515 } 16516 if (ast_strlen_zero(p->peername) && ext) 16517 ast_string_field_set(p, peername, ext); 16518 /* Recalculate our side, and recalculate Call ID */ 16519 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16520 p->ourip = __ourip; 16521 build_via(p); 16522 build_callid_pvt(p); 16523 16524 /* We have an extension to call, don't use the full contact here */ 16525 /* This to enable dialing registered peers with extension dialling, 16526 like SIP/peername/extension 16527 SIP/peername will still use the full contact */ 16528 if (ext) { 16529 ast_string_field_set(p, username, ext); 16530 ast_string_field_free(p, fullcontact); 16531 } 16532 #if 0 16533 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16534 #endif 16535 p->prefcodec = oldformat; /* Format for this call */ 16536 ast_mutex_lock(&p->lock); 16537 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16538 ast_mutex_unlock(&p->lock); 16539 if (!tmpc) 16540 sip_destroy(p); 16541 ast_update_use_count(); 16542 restart_monitor(); 16543 return tmpc; 16544 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7471 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().
07472 { 07473 /* if we are here, we know that we need to reregister. */ 07474 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07475 07476 /* if we couldn't get a reference to the registry object, punt */ 07477 if (!r) 07478 return 0; 07479 07480 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07481 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07482 /* Since registry's are only added/removed by the the monitor thread, this 07483 may be overkill to reference/dereference at all here */ 07484 if (sipdebug) 07485 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07486 07487 r->expire = -1; 07488 __sip_do_register(r); 07489 ASTOBJ_UNREF(r, sip_registry_destroy); 07490 return 0; 07491 }
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 4294 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().
04295 { 04296 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04297 struct ast_frame *f; 04298 04299 if (!p->rtp) { 04300 /* We have no RTP allocated for this channel */ 04301 return &ast_null_frame; 04302 } 04303 04304 switch(ast->fdno) { 04305 case 0: 04306 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04307 break; 04308 case 1: 04309 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04310 break; 04311 case 2: 04312 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04313 break; 04314 case 3: 04315 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04316 break; 04317 case 5: 04318 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04319 break; 04320 default: 04321 f = &ast_null_frame; 04322 } 04323 /* Don't forward RFC2833 if we're not supposed to */ 04324 if (f && (f->frametype == AST_FRAME_DTMF) && 04325 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04326 return &ast_null_frame; 04327 04328 /* We already hold the channel lock */ 04329 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04330 return f; 04331 04332 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04333 if (!(f->subclass & p->jointcapability)) { 04334 if (option_debug) { 04335 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04336 ast_getformatname(f->subclass), p->owner->name); 04337 } 04338 return &ast_null_frame; 04339 } 04340 if (option_debug) 04341 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04342 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04343 ast_set_read_format(p->owner, p->owner->readformat); 04344 ast_set_write_format(p->owner, p->owner->writeformat); 04345 } 04346 04347 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04348 f = ast_dsp_process(p->owner, p->vad, f); 04349 if (f && f->frametype == AST_FRAME_DTMF) { 04350 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04351 if (option_debug) 04352 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04353 *faxdetect = 1; 04354 } else if (option_debug) { 04355 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04356 } 04357 } 04358 } 04359 04360 return f; 04361 }
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(), sip_sipredirect(), and transmit_fake_auth_response().
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 18380 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().
18381 { 18382 int ms; 18383 int regspacing; 18384 if (!regobjs) 18385 return; 18386 regspacing = default_expiry * 1000/regobjs; 18387 if (regspacing > 100) 18388 regspacing = 100; 18389 ms = regspacing; 18390 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18391 ASTOBJ_WRLOCK(iterator); 18392 AST_SCHED_DEL(sched, iterator->expire); 18393 ms += regspacing; 18394 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18395 ASTOBJ_UNLOCK(iterator); 18396 } while (0) 18397 ); 18398 }
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 15986 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().
15987 { 15988 /* Called with peerl lock, but releases it */ 15989 struct sip_pvt *p; 15990 int newmsgs, oldmsgs; 15991 15992 /* Do we have an IP address? If not, skip this peer */ 15993 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15994 return 0; 15995 15996 /* Check for messages */ 15997 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15998 15999 peer->lastmsgcheck = time(NULL); 16000 16001 /* Return now if it's the same thing we told them last time */ 16002 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16003 return 0; 16004 } 16005 16006 16007 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16008 16009 if (peer->mwipvt) { 16010 /* Base message on subscription */ 16011 p = peer->mwipvt; 16012 } else { 16013 /* Build temporary dialog for this message */ 16014 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16015 return -1; 16016 if (create_addr_from_peer(p, peer)) { 16017 /* Maybe they're not registered, etc. */ 16018 sip_destroy(p); 16019 return 0; 16020 } 16021 /* Recalculate our side, and recalculate Call ID */ 16022 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16023 p->ourip = __ourip; 16024 build_via(p); 16025 build_callid_pvt(p); 16026 /* Destroy this session after 32 secs */ 16027 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16028 } 16029 /* Send MWI */ 16030 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16031 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16032 return 0; 16033 }
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 18107 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().
18108 { 18109 struct sip_pvt *p; 18110 int changed = 0; 18111 18112 p = chan->tech_pvt; 18113 if (!p) 18114 return -1; 18115 18116 /* Disable early RTP bridge */ 18117 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 18118 return 0; 18119 18120 ast_mutex_lock(&p->lock); 18121 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18122 /* If we're destroyed, don't bother */ 18123 ast_mutex_unlock(&p->lock); 18124 return 0; 18125 } 18126 18127 /* if this peer cannot handle reinvites of the media stream to devices 18128 that are known to be behind a NAT, then stop the process now 18129 */ 18130 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18131 ast_mutex_unlock(&p->lock); 18132 return 0; 18133 } 18134 18135 if (rtp) { 18136 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18137 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18138 memset(&p->redirip, 0, sizeof(p->redirip)); 18139 changed = 1; 18140 } 18141 if (vrtp) { 18142 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18143 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18144 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18145 changed = 1; 18146 } 18147 if (codecs) { 18148 if ((p->redircodecs != codecs)) { 18149 p->redircodecs = codecs; 18150 changed = 1; 18151 } 18152 if ((p->capability & codecs) != p->capability) { 18153 p->jointcapability &= codecs; 18154 p->capability &= codecs; 18155 changed = 1; 18156 } 18157 } 18158 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18159 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18160 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18161 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18162 if (option_debug) 18163 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)); 18164 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18165 if (option_debug > 2) { 18166 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)); 18167 } 18168 transmit_reinvite_with_sdp(p); 18169 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18170 if (option_debug > 2) { 18171 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)); 18172 } 18173 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18174 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18175 } 18176 } 18177 /* Reset lastrtprx timer */ 18178 p->lastrtprx = p->lastrtptx = time(NULL); 18179 ast_mutex_unlock(&p->lock); 18180 return 0; 18181 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17934 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.
17935 { 17936 struct sip_pvt *p; 17937 17938 p = chan->tech_pvt; 17939 if (!p) 17940 return -1; 17941 ast_mutex_lock(&p->lock); 17942 if (udptl) 17943 ast_udptl_get_peer(udptl, &p->udptlredirip); 17944 else 17945 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17946 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17947 if (!p->pendinginvite) { 17948 if (option_debug > 2) { 17949 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); 17950 } 17951 transmit_reinvite_with_t38_sdp(p); 17952 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17953 if (option_debug > 2) { 17954 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); 17955 } 17956 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17957 } 17958 } 17959 /* Reset lastrtprx timer */ 17960 p->lastrtprx = p->lastrtptx = time(NULL); 17961 ast_mutex_unlock(&p->lock); 17962 return 0; 17963 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11137 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().
11138 { 11139 struct sip_pvt *cur; 11140 size_t len; 11141 int found = 0; 11142 11143 if (argc != 4) 11144 return RESULT_SHOWUSAGE; 11145 len = strlen(argv[3]); 11146 ast_mutex_lock(&iflock); 11147 for (cur = iflist; cur; cur = cur->next) { 11148 if (!strncasecmp(cur->callid, argv[3], len)) { 11149 char formatbuf[SIPBUFSIZE/2]; 11150 ast_cli(fd,"\n"); 11151 if (cur->subscribed != NONE) 11152 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11153 else 11154 ast_cli(fd, " * SIP Call\n"); 11155 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11156 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11157 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11158 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11159 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11160 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11161 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11162 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11163 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11164 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11165 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11166 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11167 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11168 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)" ); 11169 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11170 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11171 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11172 if (!ast_strlen_zero(cur->username)) 11173 ast_cli(fd, " Username: %s\n", cur->username); 11174 if (!ast_strlen_zero(cur->peername)) 11175 ast_cli(fd, " Peername: %s\n", cur->peername); 11176 if (!ast_strlen_zero(cur->uri)) 11177 ast_cli(fd, " Original uri: %s\n", cur->uri); 11178 if (!ast_strlen_zero(cur->cid_num)) 11179 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11180 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11181 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11182 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11183 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11184 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11185 ast_cli(fd, " SIP Options: "); 11186 if (cur->sipoptions) { 11187 int x; 11188 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11189 if (cur->sipoptions & sip_options[x].id) 11190 ast_cli(fd, "%s ", sip_options[x].text); 11191 } 11192 } else 11193 ast_cli(fd, "(none)\n"); 11194 ast_cli(fd, "\n\n"); 11195 found++; 11196 } 11197 } 11198 ast_mutex_unlock(&iflock); 11199 if (!found) 11200 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11201 return RESULT_SUCCESS; 11202 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10930 of file chan_sip.c.
References __sip_show_channels().
10931 { 10932 return __sip_show_channels(fd, argc, argv, 0); 10933 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10442 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.
10443 { 10444 struct domain *d; 10445 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10446 10447 if (AST_LIST_EMPTY(&domain_list)) { 10448 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10449 return RESULT_SUCCESS; 10450 } else { 10451 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10452 AST_LIST_LOCK(&domain_list); 10453 AST_LIST_TRAVERSE(&domain_list, d, list) 10454 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10455 domain_mode_to_text(d->mode)); 10456 AST_LIST_UNLOCK(&domain_list); 10457 ast_cli(fd, "\n"); 10458 return RESULT_SUCCESS; 10459 } 10460 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11205 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.
11206 { 11207 struct sip_pvt *cur; 11208 size_t len; 11209 int found = 0; 11210 11211 if (argc != 4) 11212 return RESULT_SHOWUSAGE; 11213 if (!recordhistory) 11214 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11215 len = strlen(argv[3]); 11216 ast_mutex_lock(&iflock); 11217 for (cur = iflist; cur; cur = cur->next) { 11218 if (!strncasecmp(cur->callid, argv[3], len)) { 11219 struct sip_history *hist; 11220 int x = 0; 11221 11222 ast_cli(fd,"\n"); 11223 if (cur->subscribed != NONE) 11224 ast_cli(fd, " * Subscription\n"); 11225 else 11226 ast_cli(fd, " * SIP Call\n"); 11227 if (cur->history) 11228 AST_LIST_TRAVERSE(cur->history, hist, list) 11229 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11230 if (x == 0) 11231 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11232 found++; 11233 } 11234 } 11235 ast_mutex_unlock(&iflock); 11236 if (!found) 11237 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11238 return RESULT_SUCCESS; 11239 }
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 9867 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.
09868 { 09869 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09870 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09871 char ilimits[40]; 09872 char iused[40]; 09873 int showall = FALSE; 09874 09875 if (argc < 3) 09876 return RESULT_SHOWUSAGE; 09877 09878 if (argc == 4 && !strcmp(argv[3],"all")) 09879 showall = TRUE; 09880 09881 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09882 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09883 ASTOBJ_RDLOCK(iterator); 09884 if (iterator->call_limit) 09885 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09886 else 09887 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09888 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09889 if (showall || iterator->call_limit) 09890 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09891 ASTOBJ_UNLOCK(iterator); 09892 } while (0) ); 09893 09894 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09895 09896 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09897 ASTOBJ_RDLOCK(iterator); 09898 if (iterator->call_limit) 09899 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09900 else 09901 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09902 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09903 if (showall || iterator->call_limit) 09904 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09905 ASTOBJ_UNLOCK(iterator); 09906 } while (0) ); 09907 09908 return RESULT_SUCCESS; 09909 #undef FORMAT 09910 #undef FORMAT2 09911 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10188 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10189 { 10190 char tmp[256]; 10191 if (argc != 3) 10192 return RESULT_SHOWUSAGE; 10193 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10194 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10195 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10196 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10197 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10198 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10199 return RESULT_SUCCESS; 10200 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10494 of file chan_sip.c.
References _sip_show_peer().
10495 { 10496 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10497 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10044 of file chan_sip.c.
References _sip_show_peers().
10045 { 10046 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10047 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10767 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.
10768 { 10769 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10770 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10771 char host[80]; 10772 char tmpdat[256]; 10773 struct tm tm; 10774 10775 10776 if (argc != 3) 10777 return RESULT_SHOWUSAGE; 10778 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10779 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10780 ASTOBJ_RDLOCK(iterator); 10781 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10782 if (iterator->regtime) { 10783 ast_localtime(&iterator->regtime, &tm, NULL); 10784 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10785 } else { 10786 tmpdat[0] = 0; 10787 } 10788 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10789 ASTOBJ_UNLOCK(iterator); 10790 } while(0)); 10791 return RESULT_SUCCESS; 10792 #undef FORMAT 10793 #undef FORMAT2 10794 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10797 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().
10798 { 10799 int realtimepeers; 10800 int realtimeusers; 10801 char codec_buf[SIPBUFSIZE]; 10802 10803 realtimepeers = ast_check_realtime("sippeers"); 10804 realtimeusers = ast_check_realtime("sipusers"); 10805 10806 if (argc != 3) 10807 return RESULT_SHOWUSAGE; 10808 ast_cli(fd, "\n\nGlobal Settings:\n"); 10809 ast_cli(fd, "----------------\n"); 10810 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10811 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10812 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10813 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10814 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10815 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10816 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10817 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10818 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10819 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10820 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10821 ast_cli(fd, " Our auth realm %s\n", global_realm); 10822 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10823 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10824 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10825 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10826 ast_cli(fd, " User Agent: %s\n", global_useragent); 10827 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10828 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10829 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10830 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10831 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10832 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10833 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10834 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10835 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10836 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10837 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10838 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10839 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10840 #endif 10841 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10842 if (!realtimepeers && !realtimeusers) 10843 ast_cli(fd, " SIP realtime: Disabled\n" ); 10844 else 10845 ast_cli(fd, " SIP realtime: Enabled\n" ); 10846 10847 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10848 ast_cli(fd, "---------------------------\n"); 10849 ast_cli(fd, " Codecs: "); 10850 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10851 ast_cli(fd, "%s\n", codec_buf); 10852 ast_cli(fd, " Codec Order: "); 10853 print_codec_to_cli(fd, &default_prefs); 10854 ast_cli(fd, "\n"); 10855 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10856 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10857 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10858 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10859 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10860 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10861 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10862 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10863 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10864 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10865 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10866 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10867 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10868 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10869 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10870 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10871 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10872 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10873 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10874 ast_cli(fd, "\nDefault Settings:\n"); 10875 ast_cli(fd, "-----------------\n"); 10876 ast_cli(fd, " Context: %s\n", default_context); 10877 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10878 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10879 ast_cli(fd, " Qualify: %d\n", default_qualify); 10880 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10881 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" ); 10882 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10883 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10884 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10885 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10886 10887 10888 if (realtimepeers || realtimeusers) { 10889 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10890 ast_cli(fd, "----------------------\n"); 10891 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10892 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10893 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10894 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10895 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10896 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10897 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10898 } 10899 ast_cli(fd, "\n----\n"); 10900 return RESULT_SUCCESS; 10901 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10936 of file chan_sip.c.
References __sip_show_channels().
10937 { 10938 return __sip_show_channels(fd, argc, argv, 1); 10939 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10712 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.
10713 { 10714 char cbuf[256]; 10715 struct sip_user *user; 10716 struct ast_variable *v; 10717 int load_realtime; 10718 10719 if (argc < 4) 10720 return RESULT_SHOWUSAGE; 10721 10722 /* Load from realtime storage? */ 10723 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10724 10725 user = find_user(argv[3], load_realtime); 10726 if (user) { 10727 ast_cli(fd,"\n\n"); 10728 ast_cli(fd, " * Name : %s\n", user->name); 10729 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10730 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10731 ast_cli(fd, " Context : %s\n", user->context); 10732 ast_cli(fd, " Language : %s\n", user->language); 10733 if (!ast_strlen_zero(user->accountcode)) 10734 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10735 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10736 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10737 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10738 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10739 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10740 ast_cli(fd, " Callgroup : "); 10741 print_group(fd, user->callgroup, 0); 10742 ast_cli(fd, " Pickupgroup : "); 10743 print_group(fd, user->pickupgroup, 0); 10744 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10745 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10746 ast_cli(fd, " Codec Order : ("); 10747 print_codec_to_cli(fd, &user->prefs); 10748 ast_cli(fd, ")\n"); 10749 10750 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10751 if (user->chanvars) { 10752 ast_cli(fd, " Variables :\n"); 10753 for (v = user->chanvars ; v ; v = v->next) 10754 ast_cli(fd, " %s = %s\n", v->name, v->value); 10755 } 10756 ast_cli(fd,"\n"); 10757 ASTOBJ_UNREF(user,sip_destroy_user); 10758 } else { 10759 ast_cli(fd,"User %s not found.\n", argv[3]); 10760 ast_cli(fd,"\n"); 10761 } 10762 10763 return RESULT_SUCCESS; 10764 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9967 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.
09968 { 09969 regex_t regexbuf; 09970 int havepattern = FALSE; 09971 09972 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09973 09974 switch (argc) { 09975 case 5: 09976 if (!strcasecmp(argv[3], "like")) { 09977 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09978 return RESULT_SHOWUSAGE; 09979 havepattern = TRUE; 09980 } else 09981 return RESULT_SHOWUSAGE; 09982 case 3: 09983 break; 09984 default: 09985 return RESULT_SHOWUSAGE; 09986 } 09987 09988 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09989 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09990 ASTOBJ_RDLOCK(iterator); 09991 09992 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09993 ASTOBJ_UNLOCK(iterator); 09994 continue; 09995 } 09996 09997 ast_cli(fd, FORMAT, iterator->name, 09998 iterator->secret, 09999 iterator->accountcode, 10000 iterator->context, 10001 iterator->ha ? "Yes" : "No", 10002 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10003 ASTOBJ_UNLOCK(iterator); 10004 } while (0) 10005 ); 10006 10007 if (havepattern) 10008 regfree(®exbuf); 10009 10010 return RESULT_SUCCESS; 10011 #undef FORMAT 10012 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18294 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().
18295 { 18296 char *cdest; 18297 char *extension, *host, *port; 18298 char tmp[80]; 18299 18300 cdest = ast_strdupa(dest); 18301 18302 extension = strsep(&cdest, "@"); 18303 host = strsep(&cdest, ":"); 18304 port = strsep(&cdest, ":"); 18305 if (ast_strlen_zero(extension)) { 18306 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18307 return 0; 18308 } 18309 18310 /* we'll issue the redirect message here */ 18311 if (!host) { 18312 char *localtmp; 18313 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18314 if (ast_strlen_zero(tmp)) { 18315 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18316 return 0; 18317 } 18318 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18319 char lhost[80], lport[80]; 18320 memset(lhost, 0, sizeof(lhost)); 18321 memset(lport, 0, sizeof(lport)); 18322 localtmp++; 18323 /* This is okey because lhost and lport are as big as tmp */ 18324 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18325 if (ast_strlen_zero(lhost)) { 18326 ast_log(LOG_ERROR, "Can't find the host address\n"); 18327 return 0; 18328 } 18329 host = ast_strdupa(lhost); 18330 if (!ast_strlen_zero(lport)) { 18331 port = ast_strdupa(lport); 18332 } 18333 } 18334 } 18335 18336 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18337 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18338 18339 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18340 sip_alreadygone(p); 18341 return 0; 18342 }
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_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14033 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), sip_uri_params_cmp(), and strsep().
Referenced by handle_request_invite().
14034 { 14035 char *uri1 = ast_strdupa(input1); 14036 char *uri2 = ast_strdupa(input2); 14037 char *host1; 14038 char *host2; 14039 char *params1; 14040 char *params2; 14041 char *headers1; 14042 char *headers2; 14043 14044 /* Strip off "sip:" from the URI. We know this is present 14045 * because it was checked back in parse_request() 14046 */ 14047 strsep(&uri1, ":"); 14048 strsep(&uri2, ":"); 14049 14050 if ((host1 = strchr(uri1, '@'))) { 14051 *host1++ = '\0'; 14052 } 14053 if ((host2 = strchr(uri2, '@'))) { 14054 *host2++ = '\0'; 14055 } 14056 14057 /* Check for mismatched username and passwords. This is the 14058 * only case-sensitive comparison of a SIP URI 14059 */ 14060 if ((host1 && !host2) || 14061 (host2 && !host1) || 14062 (host1 && host2 && strcmp(uri1, uri2))) { 14063 return 1; 14064 } 14065 14066 if (!host1) 14067 host1 = uri1; 14068 if (!host2) 14069 host2 = uri2; 14070 14071 /* Strip off the parameters and headers so we can compare 14072 * host and port 14073 */ 14074 14075 if ((params1 = strchr(host1, ';'))) { 14076 *params1++ = '\0'; 14077 } 14078 if ((params2 = strchr(host2, ';'))) { 14079 *params2++ = '\0'; 14080 } 14081 14082 /* Headers come after parameters, but there may be headers without 14083 * parameters, thus the S_OR 14084 */ 14085 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14086 *headers1++ = '\0'; 14087 } 14088 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14089 *headers2++ = '\0'; 14090 } 14091 14092 /* Now the host/port are properly isolated. We can get by with a string comparison 14093 * because the SIP URI checking rules have some interesting exceptions that make 14094 * this possible. I will note 2 in particular 14095 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14096 * IP address are not considered a match with SIP URI's. 14097 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14098 * This includes if one URI explicitly contains port 5060 and the other implies it 14099 * by not having a port specified. 14100 */ 14101 14102 if (strcasecmp(host1, host2)) { 14103 return 1; 14104 } 14105 14106 /* Headers have easier rules to follow, so do those first */ 14107 if (sip_uri_headers_cmp(headers1, headers2)) { 14108 return 1; 14109 } 14110 14111 /* And now the parameters. Ugh */ 14112 return sip_uri_params_cmp(params1, params2); 14113 }
static int sip_uri_headers_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.
input1 | Headers from URI 1 | |
input2 | Headers from URI 2 |
Definition at line 13987 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().
Referenced by sip_uri_cmp().
13988 { 13989 char *headers1 = NULL; 13990 char *headers2 = NULL; 13991 int zerolength1 = 0; 13992 int zerolength2 = 0; 13993 int different = 0; 13994 char *header1; 13995 13996 if (ast_strlen_zero(input1)) { 13997 zerolength1 = 1; 13998 } else { 13999 headers1 = ast_strdupa(input1); 14000 } 14001 14002 if (ast_strlen_zero(input2)) { 14003 zerolength2 = 1; 14004 } else { 14005 headers2 = ast_strdupa(input2); 14006 } 14007 14008 if ((zerolength1 && !zerolength2) || 14009 (zerolength2 && !zerolength1)) 14010 return 1; 14011 14012 if (zerolength1 && zerolength2) 14013 return 0; 14014 14015 /* At this point, we can definitively state that both inputs are 14016 * not zero-length. First, one more optimization. If the length 14017 * of the headers is not equal, then we definitely have no match 14018 */ 14019 if (strlen(headers1) != strlen(headers2)) { 14020 return 1; 14021 } 14022 14023 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14024 if (!strcasestr(headers2, header1)) { 14025 different = 1; 14026 break; 14027 } 14028 } 14029 14030 return different; 14031 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 13849 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
13850 { 13851 char *params1 = NULL; 13852 char *params2 = NULL; 13853 char *pos1; 13854 char *pos2; 13855 int zerolength1 = 0; 13856 int zerolength2 = 0; 13857 int maddrmatch = 0; 13858 int ttlmatch = 0; 13859 int usermatch = 0; 13860 int methodmatch = 0; 13861 13862 if (ast_strlen_zero(input1)) { 13863 zerolength1 = 1; 13864 } else { 13865 params1 = ast_strdupa(input1); 13866 } 13867 if (ast_strlen_zero(input2)) { 13868 zerolength2 = 1; 13869 } else { 13870 params2 = ast_strdupa(input2); 13871 } 13872 13873 /*Quick optimization. If both params are zero-length, then 13874 * they match 13875 */ 13876 if (zerolength1 && zerolength2) { 13877 return 0; 13878 } 13879 13880 pos1 = params1; 13881 while (!ast_strlen_zero(pos1)) { 13882 char *name1 = pos1; 13883 char *value1 = strchr(pos1, '='); 13884 char *semicolon1 = strchr(pos1, ';'); 13885 int matched = 0; 13886 if (semicolon1) { 13887 *semicolon1++ = '\0'; 13888 } 13889 if (!value1) { 13890 goto fail; 13891 } 13892 *value1++ = '\0'; 13893 /* Checkpoint reached. We have the name and value parsed for param1 13894 * We have to duplicate params2 each time through the second loop 13895 * or else we can't search and replace the semicolons with \0 each 13896 * time 13897 */ 13898 pos2 = ast_strdupa(params2); 13899 while (!ast_strlen_zero(pos2)) { 13900 char *name2 = pos2; 13901 char *value2 = strchr(pos2, '='); 13902 char *semicolon2 = strchr(pos2, ';'); 13903 if (semicolon2) { 13904 *semicolon2++ = '\0'; 13905 } 13906 if (!value2) { 13907 goto fail; 13908 } 13909 if (!strcasecmp(name1, name2)) { 13910 if (strcasecmp(value1, value2)) { 13911 goto fail; 13912 } else { 13913 matched = 1; 13914 break; 13915 } 13916 } 13917 pos2 = semicolon2; 13918 } 13919 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 13920 if (!strcasecmp(name1, "maddr")) { 13921 if (matched) { 13922 maddrmatch = 1; 13923 } else { 13924 goto fail; 13925 } 13926 } else if (!strcasecmp(name1, "ttl")) { 13927 if (matched) { 13928 ttlmatch = 1; 13929 } else { 13930 goto fail; 13931 } 13932 } else if (!strcasecmp(name1, "user")) { 13933 if (matched) { 13934 usermatch = 1; 13935 } else { 13936 goto fail; 13937 } 13938 } else if (!strcasecmp(name1, "method")) { 13939 if (matched) { 13940 methodmatch = 1; 13941 } else { 13942 goto fail; 13943 } 13944 } 13945 pos1 = semicolon1; 13946 } 13947 13948 /* We've made it out of that horrible O(m*n) construct and there are no 13949 * failures yet. We're not done yet, though, because params2 could have 13950 * an maddr, ttl, user, or method header and params1 did not. 13951 */ 13952 pos2 = params2; 13953 while (!ast_strlen_zero(pos2)) { 13954 char *name2 = pos2; 13955 char *value2 = strchr(pos2, '='); 13956 char *semicolon2 = strchr(pos2, ';'); 13957 if (semicolon2) { 13958 *semicolon2++ = '\0'; 13959 } 13960 if (!value2) { 13961 goto fail; 13962 } 13963 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 13964 (!strcasecmp(name2, "ttl") && !ttlmatch) || 13965 (!strcasecmp(name2, "user") && !usermatch) || 13966 (!strcasecmp(name2, "method") && !methodmatch)) { 13967 goto fail; 13968 } 13969 } 13970 return 0; 13971 13972 fail: 13973 return 1; 13974 }
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_new_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_new_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 15883 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().
15884 { 15885 struct sip_request req; 15886 struct sockaddr_in sin = { 0, }; 15887 struct sip_pvt *p; 15888 int res; 15889 socklen_t len = sizeof(sin); 15890 int nounlock; 15891 int recount = 0; 15892 int lockretry; 15893 15894 memset(&req, 0, sizeof(req)); 15895 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15896 if (res < 0) { 15897 #if !defined(__FreeBSD__) 15898 if (errno == EAGAIN) 15899 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15900 else 15901 #endif 15902 if (errno != ECONNREFUSED) 15903 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15904 return 1; 15905 } 15906 if (option_debug && res == sizeof(req.data) - 1) 15907 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15908 15909 req.data[res] = '\0'; 15910 /* req.data will have the correct length in case of nulls */ 15911 req.len = strlen(req.data); 15912 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15913 ast_set_flag(&req, SIP_PKT_DEBUG); 15914 if (pedanticsipchecking) 15915 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15916 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15917 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15918 15919 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 15920 return 1; 15921 15922 req.method = find_sip_method(req.rlPart1); 15923 15924 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15925 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15926 15927 if (req.headers < 2) /* Must have at least two headers */ 15928 return 1; 15929 15930 /* Process request, with netlock held, and with usual deadlock avoidance */ 15931 for (lockretry = 100; lockretry > 0; lockretry--) { 15932 ast_mutex_lock(&netlock); 15933 15934 /* Find the active SIP dialog or create a new one */ 15935 p = find_call(&req, &sin, req.method); /* returns p locked */ 15936 if (p == NULL) { 15937 if (option_debug) 15938 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15939 ast_mutex_unlock(&netlock); 15940 return 1; 15941 } 15942 /* Go ahead and lock the owner if it has one -- we may need it */ 15943 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15944 if (!p->owner || !ast_channel_trylock(p->owner)) 15945 break; /* locking succeeded */ 15946 if (option_debug) 15947 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15948 ast_mutex_unlock(&p->lock); 15949 ast_mutex_unlock(&netlock); 15950 /* Sleep for a very short amount of time */ 15951 usleep(1); 15952 } 15953 p->recv = sin; 15954 15955 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15956 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15957 15958 if (!lockretry) { 15959 if (p->owner) 15960 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15961 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15962 if (req.method != SIP_ACK) 15963 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15964 /* XXX We could add retry-after to make sure they come back */ 15965 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15966 return 1; 15967 } 15968 nounlock = 0; 15969 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15970 /* Request failed */ 15971 if (option_debug) 15972 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15973 } 15974 15975 if (p->owner && !nounlock) 15976 ast_channel_unlock(p->owner); 15977 ast_mutex_unlock(&p->lock); 15978 ast_mutex_unlock(&netlock); 15979 if (recount) 15980 ast_update_use_count(); 15981 15982 return 1; 15983 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12785 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().
12786 { 12787 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12788 if (p->rtp) 12789 ast_rtp_stop(p->rtp); 12790 if (p->vrtp) 12791 ast_rtp_stop(p->vrtp); 12792 if (p->udptl) 12793 ast_udptl_stop(p->udptl); 12794 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10904 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
10905 { 10906 int i; 10907 10908 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10909 if (subscription_types[i].type == subtype) { 10910 return subscription_types[i].text; 10911 } 10912 } 10913 return subscription_types[0].text; 10914 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6281 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().
06282 { 06283 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06284 06285 if (maxrate & T38FAX_RATE_14400) { 06286 if (option_debug > 1) 06287 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06288 return 14400; 06289 } else if (maxrate & T38FAX_RATE_12000) { 06290 if (option_debug > 1) 06291 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06292 return 12000; 06293 } else if (maxrate & T38FAX_RATE_9600) { 06294 if (option_debug > 1) 06295 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06296 return 9600; 06297 } else if (maxrate & T38FAX_RATE_7200) { 06298 if (option_debug > 1) 06299 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06300 return 7200; 06301 } else if (maxrate & T38FAX_RATE_4800) { 06302 if (option_debug > 1) 06303 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06304 return 4800; 06305 } else if (maxrate & T38FAX_RATE_2400) { 06306 if (option_debug > 1) 06307 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06308 return 2400; 06309 } else { 06310 if (option_debug > 1) 06311 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06312 return 0; 06313 } 06314 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17024 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().
17025 { 17026 struct sip_peer *peer; 17027 17028 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17029 return NULL; 17030 17031 apeerobjs++; 17032 ASTOBJ_INIT(peer); 17033 set_peer_defaults(peer); 17034 17035 ast_copy_string(peer->name, name, sizeof(peer->name)); 17036 17037 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17038 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17039 peer->prefs = default_prefs; 17040 reg_source_db(peer); 17041 17042 return peer; 17043 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 6056 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06057 { 06058 struct sip_pvt *p = data; 06059 06060 ast_string_field_free_memory(p); 06061 06062 free(data); 06063 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 9914 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().
09915 { 09916 if (mode == TRANSFER_OPENFORALL) 09917 return "open"; 09918 else if (mode == TRANSFER_CLOSED) 09919 return "closed"; 09920 return "strict"; 09921 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
struct sip_request * | req, | |||
enum xmittype | 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 8643 of file chan_sip.c.
References ast_random(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_pvt::initreq, keys, s, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, strsep(), transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08644 { 08645 /* We have to emulate EXACTLY what we'd get with a good peer 08646 * and a bad password, or else we leak information. */ 08647 const char *response = "407 Proxy Authentication Required"; 08648 const char *reqheader = "Proxy-Authorization"; 08649 const char *respheader = "Proxy-Authenticate"; 08650 const char *authtoken; 08651 struct ast_dynamic_str *buf; 08652 char *c; 08653 08654 /* table of recognised keywords, and their value in the digest */ 08655 enum keys { K_NONCE, K_LAST }; 08656 struct x { 08657 const char *key; 08658 const char *s; 08659 } *i, keys[] = { 08660 [K_NONCE] = { "nonce=", "" }, 08661 [K_LAST] = { NULL, NULL} 08662 }; 08663 08664 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08665 response = "401 Unauthorized"; 08666 reqheader = "Authorization"; 08667 respheader = "WWW-Authenticate"; 08668 } 08669 authtoken = get_header(req, reqheader); 08670 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08671 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08672 * information */ 08673 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08674 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08675 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08676 return; 08677 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08678 /* We have no auth, so issue challenge and request authentication */ 08679 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08680 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08681 /* Schedule auto destroy in 32 seconds */ 08682 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08683 return; 08684 } 08685 08686 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 08687 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08688 return; 08689 } 08690 08691 /* Make a copy of the response and parse it */ 08692 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 08693 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08694 return; 08695 } 08696 08697 c = buf->str; 08698 08699 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08700 for (i = keys; i->key != NULL; i++) { 08701 const char *separator = ","; /* default */ 08702 08703 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 08704 continue; 08705 } 08706 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08707 c += strlen(i->key); 08708 if (*c == '"') { /* in quotes. Skip first and look for last */ 08709 c++; 08710 separator = "\""; 08711 } 08712 i->s = c; 08713 strsep(&c, separator); 08714 break; 08715 } 08716 if (i->key == NULL) { /* not found, jump after space or comma */ 08717 strsep(&c, " ,"); 08718 } 08719 } 08720 08721 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08722 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 08723 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08724 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08725 } 08726 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08727 08728 /* Schedule auto destroy in 32 seconds */ 08729 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08730 } else { 08731 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08732 } 08733 }
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 7829 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07830 { 07831 struct sip_request req; 07832 07833 reqprep(&req, p, SIP_INFO, 0, 1); 07834 add_digit(&req, digit, duration); 07835 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07836 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7839 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07840 { 07841 struct sip_request req; 07842 07843 reqprep(&req, p, SIP_INFO, 0, 1); 07844 add_vidupdate(&req); 07845 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07846 }
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 7088 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(), handle_request_invite(), sip_call(), and sip_poke_peer().
07089 { 07090 struct sip_request req; 07091 07092 req.method = sipmethod; 07093 if (init) { /* Seems like init always is 2 */ 07094 /* Bump branch even on initial requests */ 07095 p->branch ^= ast_random(); 07096 build_via(p); 07097 if (init > 1) 07098 initreqprep(&req, p, sipmethod); 07099 else 07100 reqprep(&req, p, sipmethod, 0, 1); 07101 } else 07102 reqprep(&req, p, sipmethod, 0, 1); 07103 07104 if (p->options && p->options->auth) 07105 add_header(&req, p->options->authheader, p->options->auth); 07106 append_date(&req); 07107 if (sipmethod == SIP_REFER) { /* Call transfer */ 07108 if (p->refer) { 07109 char buf[SIPBUFSIZE]; 07110 if (!ast_strlen_zero(p->refer->refer_to)) 07111 add_header(&req, "Refer-To", p->refer->refer_to); 07112 if (!ast_strlen_zero(p->refer->referred_by)) { 07113 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07114 add_header(&req, "Referred-By", buf); 07115 } 07116 } 07117 } 07118 /* This new INVITE is part of an attended transfer. Make sure that the 07119 other end knows and replace the current call with this new call */ 07120 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07121 add_header(&req, "Replaces", p->options->replaces); 07122 add_header(&req, "Require", "replaces"); 07123 } 07124 07125 add_header(&req, "Allow", ALLOWED_METHODS); 07126 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07127 if (p->options && p->options->addsipheaders && p->owner) { 07128 struct ast_channel *chan = p->owner; /* The owner channel */ 07129 struct varshead *headp; 07130 07131 ast_channel_lock(chan); 07132 07133 headp = &chan->varshead; 07134 07135 if (!headp) 07136 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07137 else { 07138 const struct ast_var_t *current; 07139 AST_LIST_TRAVERSE(headp, current, entries) { 07140 /* SIPADDHEADER: Add SIP header to outgoing call */ 07141 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07142 char *content, *end; 07143 const char *header = ast_var_value(current); 07144 char *headdup = ast_strdupa(header); 07145 07146 /* Strip of the starting " (if it's there) */ 07147 if (*headdup == '"') 07148 headdup++; 07149 if ((content = strchr(headdup, ':'))) { 07150 *content++ = '\0'; 07151 content = ast_skip_blanks(content); /* Skip white space */ 07152 /* Strip the ending " (if it's there) */ 07153 end = content + strlen(content) -1; 07154 if (*end == '"') 07155 *end = '\0'; 07156 07157 add_header(&req, headdup, content); 07158 if (sipdebug) 07159 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07160 } 07161 } 07162 } 07163 } 07164 07165 ast_channel_unlock(chan); 07166 } 07167 if (sdp) { 07168 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07169 ast_udptl_offered_from_local(p->udptl, 1); 07170 if (option_debug) 07171 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07172 add_t38_sdp(&req, p); 07173 } else if (p->rtp) 07174 add_sdp(&req, p); 07175 } else { 07176 add_header_contentLength(&req, 0); 07177 } 07178 07179 if (!p->initreq.headers || init > 2) 07180 initialize_initreq(p, &req); 07181 p->lastinvite = p->ocseq; 07182 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07183 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7738 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().
07739 { 07740 struct sip_request req; 07741 07742 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07743 add_text(&req, text); 07744 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07745 }
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 7374 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().
07375 { 07376 struct sip_request req; 07377 char tmp[500]; 07378 char *t = tmp; 07379 size_t maxbytes = sizeof(tmp); 07380 07381 initreqprep(&req, p, SIP_NOTIFY); 07382 add_header(&req, "Event", "message-summary"); 07383 add_header(&req, "Content-Type", default_notifymime); 07384 07385 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07386 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07387 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07388 /* Cisco has a bug in the SIP stack where it can't accept the 07389 (0/0) notification. This can temporarily be disabled in 07390 sip.conf with the "buggymwi" option */ 07391 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)")); 07392 07393 if (p->subscribed) { 07394 if (p->expiry) 07395 add_header(&req, "Subscription-State", "active"); 07396 else /* Expired */ 07397 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07398 } 07399 07400 if (t > tmp + sizeof(tmp)) 07401 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07402 07403 add_header_contentLength(&req, strlen(tmp)); 07404 add_line(&req, tmp); 07405 07406 if (!p->initreq.headers) 07407 initialize_initreq(p, &req); 07408 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07409 }
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 7420 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().
07421 { 07422 struct sip_request req; 07423 char tmp[SIPBUFSIZE/2]; 07424 07425 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07426 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07427 add_header(&req, "Event", tmp); 07428 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07429 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07430 add_header(&req, "Allow", ALLOWED_METHODS); 07431 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07432 07433 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07434 add_header_contentLength(&req, strlen(tmp)); 07435 add_line(&req, tmp); 07436 07437 if (!p->initreq.headers) 07438 initialize_initreq(p, &req); 07439 07440 p->lastnoninvite = p->ocseq; 07441 07442 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07443 }
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 7759 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().
07760 { 07761 struct sip_request req = { 07762 .headers = 0, 07763 }; 07764 char from[256]; 07765 const char *of; 07766 char *c; 07767 char referto[256]; 07768 char *ttag, *ftag; 07769 char *theirtag = ast_strdupa(p->theirtag); 07770 07771 if (option_debug || sipdebug) 07772 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07773 07774 /* Are we transfering an inbound or outbound call ? */ 07775 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07776 of = get_header(&p->initreq, "To"); 07777 ttag = theirtag; 07778 ftag = p->tag; 07779 } else { 07780 of = get_header(&p->initreq, "From"); 07781 ftag = theirtag; 07782 ttag = p->tag; 07783 } 07784 07785 ast_copy_string(from, of, sizeof(from)); 07786 of = get_in_brackets(from); 07787 ast_string_field_set(p, from, of); 07788 if (strncasecmp(of, "sip:", 4)) 07789 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07790 else 07791 of += 4; 07792 /* Get just the username part */ 07793 if ((c = strchr(dest, '@'))) 07794 c = NULL; 07795 else if ((c = strchr(of, '@'))) 07796 *c++ = '\0'; 07797 if (c) 07798 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07799 else 07800 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07801 07802 /* save in case we get 407 challenge */ 07803 sip_refer_allocate(p); 07804 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07805 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07806 p->refer->status = REFER_SENT; /* Set refer status */ 07807 07808 reqprep(&req, p, SIP_REFER, 0, 1); 07809 07810 add_header(&req, "Refer-To", referto); 07811 add_header(&req, "Allow", ALLOWED_METHODS); 07812 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07813 if (!ast_strlen_zero(p->our_contact)) 07814 add_header(&req, "Referred-By", p->our_contact); 07815 07816 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07817 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07818 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07819 07820 /*! \todo In theory, we should hang around and wait for a reply, before 07821 returning to the dial plan here. Don't know really how that would 07822 affect the transfer() app or the pbx, but, well, to make this 07823 useful we should have a STATUS code on transfer(). 07824 */ 07825 }
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 7547 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().
07548 { 07549 struct sip_request req; 07550 char from[256]; 07551 char to[256]; 07552 char tmp[80]; 07553 char addr[80]; 07554 struct sip_pvt *p; 07555 07556 /* exit if we are already in process with this registrar ?*/ 07557 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07558 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07559 return 0; 07560 } 07561 07562 if (r->call) { /* We have a registration */ 07563 if (!auth) { 07564 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07565 return 0; 07566 } else { 07567 p = r->call; 07568 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07569 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07570 } 07571 } else { 07572 /* Build callid for registration if we haven't registered before */ 07573 if (!r->callid_valid) { 07574 build_callid_registry(r, __ourip, default_fromdomain); 07575 r->callid_valid = TRUE; 07576 } 07577 /* Allocate SIP packet for registration */ 07578 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07579 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07580 return 0; 07581 } 07582 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07583 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07584 /* Find address to hostname */ 07585 if (create_addr(p, r->hostname)) { 07586 /* we have what we hope is a temporary network error, 07587 * probably DNS. We need to reschedule a registration try */ 07588 sip_destroy(p); 07589 07590 if (r->timeout > -1) 07591 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07592 else 07593 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); 07594 07595 AST_SCHED_DEL(sched, r->timeout); 07596 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07597 r->regattempts++; 07598 return 0; 07599 } 07600 /* Copy back Call-ID in case create_addr changed it */ 07601 ast_string_field_set(r, callid, p->callid); 07602 if (r->portno) { 07603 p->sa.sin_port = htons(r->portno); 07604 p->recv.sin_port = htons(r->portno); 07605 } else /* Set registry port to the port set from the peer definition/srv or default */ 07606 r->portno = ntohs(p->sa.sin_port); 07607 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07608 r->call=p; /* Save pointer to SIP packet */ 07609 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07610 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07611 ast_string_field_set(p, peersecret, r->secret); 07612 if (!ast_strlen_zero(r->md5secret)) 07613 ast_string_field_set(p, peermd5secret, r->md5secret); 07614 /* User name in this realm 07615 - if authuser is set, use that, otherwise use username */ 07616 if (!ast_strlen_zero(r->authuser)) { 07617 ast_string_field_set(p, peername, r->authuser); 07618 ast_string_field_set(p, authname, r->authuser); 07619 } else if (!ast_strlen_zero(r->username)) { 07620 ast_string_field_set(p, peername, r->username); 07621 ast_string_field_set(p, authname, r->username); 07622 ast_string_field_set(p, fromuser, r->username); 07623 } 07624 if (!ast_strlen_zero(r->username)) 07625 ast_string_field_set(p, username, r->username); 07626 /* Save extension in packet */ 07627 ast_string_field_set(p, exten, r->contact); 07628 07629 /* 07630 check which address we should use in our contact header 07631 based on whether the remote host is on the external or 07632 internal network so we can register through nat 07633 */ 07634 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07635 p->ourip = bindaddr.sin_addr; 07636 build_contact(p); 07637 } 07638 07639 /* set up a timeout */ 07640 if (auth == NULL) { 07641 if (r->timeout > -1) 07642 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07643 AST_SCHED_DEL(sched, r->timeout); 07644 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07645 if (option_debug) 07646 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07647 } 07648 07649 if (strchr(r->username, '@')) { 07650 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07651 if (!ast_strlen_zero(p->theirtag)) 07652 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07653 else 07654 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07655 } else { 07656 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07657 if (!ast_strlen_zero(p->theirtag)) 07658 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07659 else 07660 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07661 } 07662 07663 /* Fromdomain is what we are registering to, regardless of actual 07664 host name from SRV */ 07665 if (!ast_strlen_zero(p->fromdomain)) { 07666 if (r->portno && r->portno != STANDARD_SIP_PORT) 07667 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07668 else 07669 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07670 } else { 07671 if (r->portno && r->portno != STANDARD_SIP_PORT) 07672 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07673 else 07674 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07675 } 07676 ast_string_field_set(p, uri, addr); 07677 07678 p->branch ^= ast_random(); 07679 07680 init_req(&req, sipmethod, addr); 07681 07682 /* Add to CSEQ */ 07683 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07684 p->ocseq = r->ocseq; 07685 07686 build_via(p); 07687 add_header(&req, "Via", p->via); 07688 add_header(&req, "From", from); 07689 add_header(&req, "To", to); 07690 add_header(&req, "Call-ID", p->callid); 07691 add_header(&req, "CSeq", tmp); 07692 if (!ast_strlen_zero(global_useragent)) 07693 add_header(&req, "User-Agent", global_useragent); 07694 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07695 07696 07697 if (auth) /* Add auth header */ 07698 add_header(&req, authheader, auth); 07699 else if (!ast_strlen_zero(r->nonce)) { 07700 char digest[1024]; 07701 07702 /* We have auth data to reuse, build a digest header! */ 07703 if (sipdebug) 07704 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07705 ast_string_field_set(p, realm, r->realm); 07706 ast_string_field_set(p, nonce, r->nonce); 07707 ast_string_field_set(p, domain, r->domain); 07708 ast_string_field_set(p, opaque, r->opaque); 07709 ast_string_field_set(p, qop, r->qop); 07710 r->noncecount++; 07711 p->noncecount = r->noncecount; 07712 07713 memset(digest,0,sizeof(digest)); 07714 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07715 add_header(&req, "Authorization", digest); 07716 else 07717 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07718 07719 } 07720 07721 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07722 add_header(&req, "Expires", tmp); 07723 add_header(&req, "Contact", p->our_contact); 07724 add_header(&req, "Event", "registration"); 07725 add_header_contentLength(&req, 0); 07726 07727 initialize_initreq(p, &req); 07728 if (sip_debug_test_pvt(p)) 07729 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07730 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07731 r->regattempts++; /* Another attempt */ 07732 if (option_debug > 3) 07733 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07734 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07735 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6808 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().
06809 { 06810 struct sip_request req; 06811 06812 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06813 06814 add_header(&req, "Allow", ALLOWED_METHODS); 06815 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06816 if (sipdebug) 06817 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06818 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06819 append_history(p, "ReInv", "Re-invite sent"); 06820 add_sdp(&req, p); 06821 /* Use this as the basis */ 06822 initialize_initreq(p, &req); 06823 p->lastinvite = p->ocseq; 06824 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06825 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06826 }
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 6832 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().
06833 { 06834 struct sip_request req; 06835 06836 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06837 06838 add_header(&req, "Allow", ALLOWED_METHODS); 06839 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06840 if (sipdebug) 06841 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06842 ast_udptl_offered_from_local(p->udptl, 1); 06843 add_t38_sdp(&req, p); 06844 /* Use this as the basis */ 06845 initialize_initreq(p, &req); 06846 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06847 p->lastinvite = p->ocseq; 06848 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06849 }
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 7851 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().
07852 { 07853 struct sip_request resp; 07854 07855 if (sipmethod == SIP_ACK) 07856 p->invitestate = INV_CONFIRMED; 07857 07858 reqprep(&resp, p, sipmethod, seqno, newbranch); 07859 add_header_contentLength(&resp, 0); 07860 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07861 }
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 7864 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().
07865 { 07866 struct sip_request resp; 07867 07868 reqprep(&resp, p, sipmethod, seqno, newbranch); 07869 if (!ast_strlen_zero(p->realm)) { 07870 char digest[1024]; 07871 07872 memset(digest, 0, sizeof(digest)); 07873 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07874 if (p->options && p->options->auth_type == PROXY_AUTH) 07875 add_header(&resp, "Proxy-Authorization", digest); 07876 else if (p->options && p->options->auth_type == WWW_AUTH) 07877 add_header(&resp, "Authorization", digest); 07878 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07879 add_header(&resp, "Proxy-Authorization", digest); 07880 } else 07881 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07882 } 07883 /* If we are hanging up and know a cause for that, send it in clear text to make 07884 debugging easier. */ 07885 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07886 char buf[10]; 07887 07888 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07889 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07890 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07891 } 07892 07893 add_header_contentLength(&resp, 0); 07894 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07895 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6117 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06118 { 06119 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06120 }
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 6136 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().
06137 { 06138 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06139 }
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 6066 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().
06067 { 06068 struct sip_pvt *p = NULL; 06069 06070 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06071 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06072 return -1; 06073 } 06074 06075 /* if the structure was just allocated, initialize it */ 06076 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06077 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06078 if (ast_string_field_init(p, 512)) 06079 return -1; 06080 } 06081 06082 /* Initialize the bare minimum */ 06083 p->method = intended_method; 06084 06085 if (sin) { 06086 p->sa = *sin; 06087 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06088 p->ourip = __ourip; 06089 } else 06090 p->ourip = __ourip; 06091 06092 p->branch = ast_random(); 06093 make_our_tag(p->tag, sizeof(p->tag)); 06094 p->ocseq = INITIAL_CSEQ; 06095 06096 if (useglobal_nat && sin) { 06097 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06098 p->recv = *sin; 06099 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06100 } 06101 check_via(p, req); 06102 06103 ast_string_field_set(p, fromdomain, default_fromdomain); 06104 build_via(p); 06105 ast_string_field_set(p, callid, callid); 06106 06107 /* Use this temporary pvt structure to send the message */ 06108 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06109 06110 /* Free the string fields, but not the pool space */ 06111 ast_string_field_reset_all(p); 06112 06113 return 0; 06114 }
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 6164 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06165 { 06166 struct sip_request resp; 06167 respprep(&resp, p, msg, req); 06168 add_header(&resp, "Accept", "application/sdp"); 06169 add_header_contentLength(&resp, 0); 06170 return send_response(p, &resp, reliable, 0); 06171 }
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 6174 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().
06175 { 06176 struct sip_request resp; 06177 char tmp[512]; 06178 int seqno = 0; 06179 06180 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06181 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06182 return -1; 06183 } 06184 /* Stale means that they sent us correct authentication, but 06185 based it on an old challenge (nonce) */ 06186 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06187 respprep(&resp, p, msg, req); 06188 add_header(&resp, header, tmp); 06189 add_header_contentLength(&resp, 0); 06190 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06191 return send_response(p, &resp, reliable, seqno); 06192 }
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 6154 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06155 { 06156 struct sip_request resp; 06157 respprep(&resp, p, msg, req); 06158 append_date(&resp); 06159 add_header_contentLength(&resp, 0); 06160 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06161 }
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 6737 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().
06738 { 06739 struct sip_request resp; 06740 int seqno; 06741 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06742 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06743 return -1; 06744 } 06745 respprep(&resp, p, msg, req); 06746 if (p->rtp) { 06747 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06748 if (option_debug) 06749 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06750 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06751 } 06752 try_suggested_sip_codec(p); 06753 add_sdp(&resp, p); 06754 } else 06755 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06756 if (reliable && !p->pendinginvite) 06757 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06758 return send_response(p, &resp, reliable, seqno); 06759 }
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 6697 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().
06698 { 06699 struct sip_request resp; 06700 int seqno; 06701 06702 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06703 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06704 return -1; 06705 } 06706 respprep(&resp, p, msg, req); 06707 if (p->udptl) { 06708 ast_udptl_offered_from_local(p->udptl, 0); 06709 add_t38_sdp(&resp, p); 06710 } else 06711 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06712 if (retrans && !p->pendinginvite) 06713 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06714 return send_response(p, &resp, retrans, seqno); 06715 }
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 6123 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06124 { 06125 struct sip_request resp; 06126 respprep(&resp, p, msg, req); 06127 append_date(&resp); 06128 add_header(&resp, "Unsupported", unsupported); 06129 add_header_contentLength(&resp, 0); 06130 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06131 }
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 7412 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().
07413 { 07414 if (!p->initreq.headers) /* Initialize first request before sending */ 07415 initialize_initreq(p, req); 07416 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07417 }
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 7186 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().
07187 { 07188 char tmp[4000], from[256], to[256]; 07189 char *t = tmp, *c, *mfrom, *mto; 07190 size_t maxbytes = sizeof(tmp); 07191 struct sip_request req; 07192 char hint[AST_MAX_EXTENSION]; 07193 char *statestring = "terminated"; 07194 const struct cfsubscription_types *subscriptiontype; 07195 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07196 char *pidfstate = "--"; 07197 char *pidfnote= "Ready"; 07198 07199 memset(from, 0, sizeof(from)); 07200 memset(to, 0, sizeof(to)); 07201 memset(tmp, 0, sizeof(tmp)); 07202 07203 switch (state) { 07204 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07205 statestring = (global_notifyringing) ? "early" : "confirmed"; 07206 local_state = NOTIFY_INUSE; 07207 pidfstate = "busy"; 07208 pidfnote = "Ringing"; 07209 break; 07210 case AST_EXTENSION_RINGING: 07211 statestring = "early"; 07212 local_state = NOTIFY_INUSE; 07213 pidfstate = "busy"; 07214 pidfnote = "Ringing"; 07215 break; 07216 case AST_EXTENSION_INUSE: 07217 statestring = "confirmed"; 07218 local_state = NOTIFY_INUSE; 07219 pidfstate = "busy"; 07220 pidfnote = "On the phone"; 07221 break; 07222 case AST_EXTENSION_BUSY: 07223 statestring = "confirmed"; 07224 local_state = NOTIFY_CLOSED; 07225 pidfstate = "busy"; 07226 pidfnote = "On the phone"; 07227 break; 07228 case AST_EXTENSION_UNAVAILABLE: 07229 statestring = "terminated"; 07230 local_state = NOTIFY_CLOSED; 07231 pidfstate = "away"; 07232 pidfnote = "Unavailable"; 07233 break; 07234 case AST_EXTENSION_ONHOLD: 07235 statestring = "confirmed"; 07236 local_state = NOTIFY_CLOSED; 07237 pidfstate = "busy"; 07238 pidfnote = "On Hold"; 07239 break; 07240 case AST_EXTENSION_NOT_INUSE: 07241 default: 07242 /* Default setting */ 07243 break; 07244 } 07245 07246 subscriptiontype = find_subscription_type(p->subscribed); 07247 07248 /* Check which device/devices we are watching and if they are registered */ 07249 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07250 char *hint2 = hint, *individual_hint = NULL; 07251 int hint_count = 0, unavailable_count = 0; 07252 07253 while ((individual_hint = strsep(&hint2, "&"))) { 07254 hint_count++; 07255 07256 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07257 unavailable_count++; 07258 } 07259 07260 /* If none of the hinted devices are registered, we will 07261 * override notification and show no availability. 07262 */ 07263 if (hint_count > 0 && hint_count == unavailable_count) { 07264 local_state = NOTIFY_CLOSED; 07265 pidfstate = "away"; 07266 pidfnote = "Not online"; 07267 } 07268 } 07269 07270 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07271 c = get_in_brackets(from); 07272 if (strncasecmp(c, "sip:", 4)) { 07273 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07274 return -1; 07275 } 07276 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07277 07278 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07279 c = get_in_brackets(to); 07280 if (strncasecmp(c, "sip:", 4)) { 07281 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07282 return -1; 07283 } 07284 mto = strsep(&c, ";"); /* trim ; and beyond */ 07285 07286 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07287 07288 07289 add_header(&req, "Event", subscriptiontype->event); 07290 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07291 switch(state) { 07292 case AST_EXTENSION_DEACTIVATED: 07293 if (timeout) 07294 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07295 else { 07296 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07297 add_header(&req, "Retry-After", "60"); 07298 } 07299 break; 07300 case AST_EXTENSION_REMOVED: 07301 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07302 break; 07303 default: 07304 if (p->expiry) 07305 add_header(&req, "Subscription-State", "active"); 07306 else /* Expired */ 07307 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07308 } 07309 switch (p->subscribed) { 07310 case XPIDF_XML: 07311 case CPIM_PIDF_XML: 07312 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07313 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07314 ast_build_string(&t, &maxbytes, "<presence>\n"); 07315 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07316 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07317 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07318 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07319 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07320 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07321 break; 07322 case PIDF_XML: /* Eyebeam supports this format */ 07323 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07324 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); 07325 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07326 if (pidfstate[0] != '-') 07327 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07328 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07329 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07330 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07331 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07332 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07333 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07334 else 07335 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07336 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07337 break; 07338 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07339 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07340 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); 07341 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07342 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07343 else 07344 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07345 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07346 if (state == AST_EXTENSION_ONHOLD) { 07347 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07348 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07349 "</target>\n</local>\n", mto); 07350 } 07351 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07352 break; 07353 case NONE: 07354 default: 07355 break; 07356 } 07357 07358 if (t > tmp + sizeof(tmp)) 07359 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07360 07361 add_header_contentLength(&req, strlen(tmp)); 07362 add_line(&req, tmp); 07363 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07364 07365 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07366 }
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 18621 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.
18622 { 18623 struct sip_pvt *p, *pl; 18624 18625 /* First, take us out of the channel type list */ 18626 ast_channel_unregister(&sip_tech); 18627 18628 /* Unregister dial plan functions */ 18629 ast_custom_function_unregister(&sipchaninfo_function); 18630 ast_custom_function_unregister(&sippeer_function); 18631 ast_custom_function_unregister(&sip_header_function); 18632 ast_custom_function_unregister(&checksipdomain_function); 18633 18634 /* Unregister dial plan applications */ 18635 ast_unregister_application(app_dtmfmode); 18636 ast_unregister_application(app_sipaddheader); 18637 18638 /* Unregister CLI commands */ 18639 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18640 18641 /* Disconnect from the RTP subsystem */ 18642 ast_rtp_proto_unregister(&sip_rtp); 18643 18644 /* Disconnect from UDPTL */ 18645 ast_udptl_proto_unregister(&sip_udptl); 18646 18647 /* Unregister AMI actions */ 18648 ast_manager_unregister("SIPpeers"); 18649 ast_manager_unregister("SIPshowpeer"); 18650 18651 ast_mutex_lock(&iflock); 18652 /* Hangup all interfaces if they have an owner */ 18653 for (p = iflist; p ; p = p->next) { 18654 if (p->owner) 18655 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18656 } 18657 ast_mutex_unlock(&iflock); 18658 18659 ast_mutex_lock(&monlock); 18660 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18661 pthread_cancel(monitor_thread); 18662 pthread_kill(monitor_thread, SIGURG); 18663 pthread_join(monitor_thread, NULL); 18664 } 18665 monitor_thread = AST_PTHREADT_STOP; 18666 ast_mutex_unlock(&monlock); 18667 18668 restartdestroy: 18669 ast_mutex_lock(&iflock); 18670 /* Destroy all the interfaces and free their memory */ 18671 p = iflist; 18672 while (p) { 18673 pl = p; 18674 p = p->next; 18675 if (__sip_destroy(pl, TRUE) < 0) { 18676 /* Something is still bridged, let it react to getting a hangup */ 18677 iflist = p; 18678 ast_mutex_unlock(&iflock); 18679 usleep(1); 18680 goto restartdestroy; 18681 } 18682 } 18683 iflist = NULL; 18684 ast_mutex_unlock(&iflock); 18685 18686 /* Free memory for local network address mask */ 18687 ast_free_ha(localaddr); 18688 18689 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18690 ASTOBJ_CONTAINER_DESTROY(&userl); 18691 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18692 ASTOBJ_CONTAINER_DESTROY(&peerl); 18693 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18694 ASTOBJ_CONTAINER_DESTROY(®l); 18695 18696 clear_realm_authentication(authl); 18697 clear_sip_domains(); 18698 close(sipsock); 18699 sched_context_destroy(sched); 18700 18701 return 0; 18702 }
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 18185 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18187 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 11939 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
Definition at line 18457 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 18447 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 18452 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 11823 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 18184 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18190 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 11840 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 10463 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 10014 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 11832 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 11836 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 11772 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 11814 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 11796 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 11792 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 11767 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 11800 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 11787 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 11853 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 11809 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 11804 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 11819 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 11857 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 11849 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 11782 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 11777 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 11915 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 11845 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 18183 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18188 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.