#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"
Include dependency graph for chan_sip.c:
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets called with p locked. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
Add realm authentication in list. | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add T.38 Session Description Protocol message. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the SIP dialog list (of sip_pvt's). | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
AST_THREADSTORAGE (check_auth_buf, check_auth_buf_init) | |
AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
A per-thread temporary pvt structure. | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock
| |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
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 |
Definition at line 369 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 370 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 368 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
#define DEC_CALL_LIMIT 0 |
Definition at line 609 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 611 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 504 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 495 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 172 of file chan_sip.c.
#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) |
Max bitrate for video
Definition at line 515 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 174 of file chan_sip.c.
#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 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 497 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 513 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 175 of file chan_sip.c.
#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 |
Recommended setting is ON
Definition at line 503 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 514 of file chan_sip.c.
#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.
#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.
#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.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 211 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 517 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 498 of file chan_sip.c.
#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 6441 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(), 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(), 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(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 214 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 215 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 216 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 742 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 739 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 740 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#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(), 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(), 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) |
Definition at line 778 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 779 of file chan_sip.c.
Referenced by 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(), 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) |
#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(), 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(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
#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(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 722 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 805 of file chan_sip.c.
Referenced by handle_request(), handle_request_message(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), initialize_initreq(), and sipsock_read().
#define SIP_PKT_IGNORE (1 << 2) |
This is a re-transmit, ignore it
Definition at line 807 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 806 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 754 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 755 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 720 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 724 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 727 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), 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(), 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(), 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.
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.
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 |
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, sched, 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, 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_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, cfsip_methods::text, UNLINK, update_call_counter(), and sip_pvt::vrtp.
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 7496 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07497 { 07498 int res; 07499 07500 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07501 return res; 07502 }
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, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::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, sched, 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 10852 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10853 { 10854 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10855 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10856 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10857 struct sip_pvt *cur; 10858 int numchans = 0; 10859 char *referstatus = NULL; 10860 10861 if (argc != 3) 10862 return RESULT_SHOWUSAGE; 10863 ast_mutex_lock(&iflock); 10864 cur = iflist; 10865 if (!subscriptions) 10866 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10867 else 10868 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10869 for (; cur; cur = cur->next) { 10870 referstatus = ""; 10871 if (cur->refer) { /* SIP transfer in progress */ 10872 referstatus = referstatus2str(cur->refer->status); 10873 } 10874 if (cur->subscribed == NONE && !subscriptions) { 10875 char formatbuf[SIPBUFSIZE/2]; 10876 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10877 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10878 cur->callid, 10879 cur->ocseq, cur->icseq, 10880 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10881 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10882 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10883 cur->lastmsg , 10884 referstatus 10885 ); 10886 numchans++; 10887 } 10888 if (cur->subscribed != NONE && subscriptions) { 10889 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10890 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10891 cur->callid, 10892 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10893 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10894 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10895 subscription_type2str(cur->subscribed), 10896 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10897 ); 10898 numchans++; 10899 } 10900 } 10901 ast_mutex_unlock(&iflock); 10902 if (!subscriptions) 10903 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10904 else 10905 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10906 return RESULT_SUCCESS; 10907 #undef FORMAT 10908 #undef FORMAT2 10909 #undef FORMAT3 10910 }
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 6035 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06036 { 06037 struct sip_request resp; 06038 int seqno = 0; 06039 06040 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06041 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06042 return -1; 06043 } 06044 respprep(&resp, p, msg, req); 06045 add_header_contentLength(&resp, 0); 06046 /* If we are cancelling an incoming invite for some reason, add information 06047 about the reason why we are doing this in clear text */ 06048 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06049 char buf[10]; 06050 06051 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06052 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06053 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06054 } 06055 return send_response(p, &resp, reliable, seqno); 06056 }
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 10410 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, 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, S_OR, sched, 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().
10411 { 10412 char status[30] = ""; 10413 char cbuf[256]; 10414 struct sip_peer *peer; 10415 char codec_buf[512]; 10416 struct ast_codec_pref *pref; 10417 struct ast_variable *v; 10418 struct sip_auth *auth; 10419 int x = 0, codec = 0, load_realtime; 10420 int realtimepeers; 10421 10422 realtimepeers = ast_check_realtime("sippeers"); 10423 10424 if (argc < 4) 10425 return RESULT_SHOWUSAGE; 10426 10427 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10428 peer = find_peer(argv[3], NULL, load_realtime); 10429 if (s) { /* Manager */ 10430 if (peer) { 10431 const char *id = astman_get_header(m,"ActionID"); 10432 10433 astman_append(s, "Response: Success\r\n"); 10434 if (!ast_strlen_zero(id)) 10435 astman_append(s, "ActionID: %s\r\n",id); 10436 } else { 10437 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10438 astman_send_error(s, m, cbuf); 10439 return 0; 10440 } 10441 } 10442 if (peer && type==0 ) { /* Normal listing */ 10443 ast_cli(fd,"\n\n"); 10444 ast_cli(fd, " * Name : %s\n", peer->name); 10445 if (realtimepeers) { /* Realtime is enabled */ 10446 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10447 } 10448 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10449 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10450 for (auth = peer->auth; auth; auth = auth->next) { 10451 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10452 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10453 } 10454 ast_cli(fd, " Context : %s\n", peer->context); 10455 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10456 ast_cli(fd, " Language : %s\n", peer->language); 10457 if (!ast_strlen_zero(peer->accountcode)) 10458 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10459 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10460 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10461 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10462 if (!ast_strlen_zero(peer->fromuser)) 10463 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10464 if (!ast_strlen_zero(peer->fromdomain)) 10465 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10466 ast_cli(fd, " Callgroup : "); 10467 print_group(fd, peer->callgroup, 0); 10468 ast_cli(fd, " Pickupgroup : "); 10469 print_group(fd, peer->pickupgroup, 0); 10470 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10471 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10472 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10473 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10474 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10475 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10476 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10477 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10478 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))); 10479 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10480 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10481 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10482 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10483 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10484 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10485 #endif 10486 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10487 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10488 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10489 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10490 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10491 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10492 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10493 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10494 10495 /* - is enumerated */ 10496 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10497 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10498 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10499 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)); 10500 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10501 if (!ast_strlen_zero(global_regcontext)) 10502 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10503 ast_cli(fd, " Def. Username: %s\n", peer->username); 10504 ast_cli(fd, " SIP Options : "); 10505 if (peer->sipoptions) { 10506 int lastoption = -1; 10507 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10508 if (sip_options[x].id != lastoption) { 10509 if (peer->sipoptions & sip_options[x].id) 10510 ast_cli(fd, "%s ", sip_options[x].text); 10511 lastoption = x; 10512 } 10513 } 10514 } else 10515 ast_cli(fd, "(none)"); 10516 10517 ast_cli(fd, "\n"); 10518 ast_cli(fd, " Codecs : "); 10519 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10520 ast_cli(fd, "%s\n", codec_buf); 10521 ast_cli(fd, " Codec Order : ("); 10522 print_codec_to_cli(fd, &peer->prefs); 10523 ast_cli(fd, ")\n"); 10524 10525 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10526 ast_cli(fd, " Status : "); 10527 peer_status(peer, status, sizeof(status)); 10528 ast_cli(fd, "%s\n",status); 10529 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10530 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10531 if (peer->chanvars) { 10532 ast_cli(fd, " Variables :\n"); 10533 for (v = peer->chanvars ; v ; v = v->next) 10534 ast_cli(fd, " %s = %s\n", v->name, v->value); 10535 } 10536 ast_cli(fd,"\n"); 10537 ASTOBJ_UNREF(peer,sip_destroy_peer); 10538 } else if (peer && type == 1) { /* manager listing */ 10539 char buf[256]; 10540 astman_append(s, "Channeltype: SIP\r\n"); 10541 astman_append(s, "ObjectName: %s\r\n", peer->name); 10542 astman_append(s, "ChanObjectType: peer\r\n"); 10543 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10544 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10545 astman_append(s, "Context: %s\r\n", peer->context); 10546 astman_append(s, "Language: %s\r\n", peer->language); 10547 if (!ast_strlen_zero(peer->accountcode)) 10548 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10549 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10550 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10551 if (!ast_strlen_zero(peer->fromuser)) 10552 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10553 if (!ast_strlen_zero(peer->fromdomain)) 10554 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10555 astman_append(s, "Callgroup: "); 10556 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10557 astman_append(s, "Pickupgroup: "); 10558 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10559 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10560 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10561 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10562 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10563 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10564 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10565 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10566 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10567 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))); 10568 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10569 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10570 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10571 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10572 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10573 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10574 10575 /* - is enumerated */ 10576 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10577 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10578 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10579 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)); 10580 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)); 10581 astman_append(s, "Default-Username: %s\r\n", peer->username); 10582 if (!ast_strlen_zero(global_regcontext)) 10583 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10584 astman_append(s, "Codecs: "); 10585 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10586 astman_append(s, "%s\r\n", codec_buf); 10587 astman_append(s, "CodecOrder: "); 10588 pref = &peer->prefs; 10589 for(x = 0; x < 32 ; x++) { 10590 codec = ast_codec_pref_index(pref,x); 10591 if (!codec) 10592 break; 10593 astman_append(s, "%s", ast_getformatname(codec)); 10594 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10595 astman_append(s, ","); 10596 } 10597 10598 astman_append(s, "\r\n"); 10599 astman_append(s, "Status: "); 10600 peer_status(peer, status, sizeof(status)); 10601 astman_append(s, "%s\r\n", status); 10602 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10603 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10604 if (peer->chanvars) { 10605 for (v = peer->chanvars ; v ; v = v->next) { 10606 astman_append(s, "ChanVariable:\n"); 10607 astman_append(s, " %s,%s\r\n", v->name, v->value); 10608 } 10609 } 10610 10611 ASTOBJ_UNREF(peer,sip_destroy_peer); 10612 10613 } else { 10614 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10615 ast_cli(fd,"\n"); 10616 } 10617 10618 return RESULT_SUCCESS; 10619 }
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 9960 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, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09961 { 09962 regex_t regexbuf; 09963 int havepattern = FALSE; 09964 09965 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09966 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09967 09968 char name[256]; 09969 int total_peers = 0; 09970 int peers_mon_online = 0; 09971 int peers_mon_offline = 0; 09972 int peers_unmon_offline = 0; 09973 int peers_unmon_online = 0; 09974 const char *id; 09975 char idtext[256] = ""; 09976 int realtimepeers; 09977 09978 realtimepeers = ast_check_realtime("sippeers"); 09979 09980 if (s) { /* Manager - get ActionID */ 09981 id = astman_get_header(m,"ActionID"); 09982 if (!ast_strlen_zero(id)) 09983 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09984 } 09985 09986 switch (argc) { 09987 case 5: 09988 if (!strcasecmp(argv[3], "like")) { 09989 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09990 return RESULT_SHOWUSAGE; 09991 havepattern = TRUE; 09992 } else 09993 return RESULT_SHOWUSAGE; 09994 case 3: 09995 break; 09996 default: 09997 return RESULT_SHOWUSAGE; 09998 } 09999 10000 if (!s) /* Normal list */ 10001 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10002 10003 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10004 char status[20] = ""; 10005 char srch[2000]; 10006 char pstatus; 10007 10008 ASTOBJ_RDLOCK(iterator); 10009 10010 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10011 ASTOBJ_UNLOCK(iterator); 10012 continue; 10013 } 10014 10015 if (!ast_strlen_zero(iterator->username) && !s) 10016 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10017 else 10018 ast_copy_string(name, iterator->name, sizeof(name)); 10019 10020 pstatus = peer_status(iterator, status, sizeof(status)); 10021 if (pstatus == 1) 10022 peers_mon_online++; 10023 else if (pstatus == 0) 10024 peers_mon_offline++; 10025 else { 10026 if (iterator->addr.sin_port == 0) 10027 peers_unmon_offline++; 10028 else 10029 peers_unmon_online++; 10030 } 10031 10032 snprintf(srch, sizeof(srch), FORMAT, name, 10033 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10034 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10035 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10036 iterator->ha ? " A " : " ", /* permit/deny */ 10037 ntohs(iterator->addr.sin_port), status, 10038 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10039 10040 if (!s) {/* Normal CLI list */ 10041 ast_cli(fd, FORMAT, name, 10042 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10043 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10044 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10045 iterator->ha ? " A " : " ", /* permit/deny */ 10046 10047 ntohs(iterator->addr.sin_port), status, 10048 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10049 } else { /* Manager format */ 10050 /* The names here need to be the same as other channels */ 10051 astman_append(s, 10052 "Event: PeerEntry\r\n%s" 10053 "Channeltype: SIP\r\n" 10054 "ObjectName: %s\r\n" 10055 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10056 "IPaddress: %s\r\n" 10057 "IPport: %d\r\n" 10058 "Dynamic: %s\r\n" 10059 "Natsupport: %s\r\n" 10060 "VideoSupport: %s\r\n" 10061 "ACL: %s\r\n" 10062 "Status: %s\r\n" 10063 "RealtimeDevice: %s\r\n\r\n", 10064 idtext, 10065 iterator->name, 10066 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10067 ntohs(iterator->addr.sin_port), 10068 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10069 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10070 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10071 iterator->ha ? "yes" : "no", /* permit/deny */ 10072 status, 10073 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10074 } 10075 10076 ASTOBJ_UNLOCK(iterator); 10077 10078 total_peers++; 10079 } while(0) ); 10080 10081 if (!s) 10082 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10083 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10084 10085 if (havepattern) 10086 regfree(®exbuf); 10087 10088 if (total) 10089 *total = total_peers; 10090 10091 10092 return RESULT_SUCCESS; 10093 #undef FORMAT 10094 #undef FORMAT2 10095 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14755 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(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14756 { 14757 struct ast_rtp_quality qos; 14758 struct sip_pvt *p = chan->tech_pvt; 14759 char *all = "", *parse = ast_strdupa(preparse); 14760 AST_DECLARE_APP_ARGS(args, 14761 AST_APP_ARG(param); 14762 AST_APP_ARG(type); 14763 AST_APP_ARG(field); 14764 ); 14765 AST_STANDARD_APP_ARGS(args, parse); 14766 14767 /* Sanity check */ 14768 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14769 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14770 return 0; 14771 } 14772 14773 if (strcasecmp(args.param, "rtpqos")) 14774 return 0; 14775 14776 /* Default arguments of audio,all */ 14777 if (ast_strlen_zero(args.type)) 14778 args.type = "audio"; 14779 if (ast_strlen_zero(args.field)) 14780 args.field = "all"; 14781 14782 memset(buf, 0, buflen); 14783 memset(&qos, 0, sizeof(qos)); 14784 14785 if (strcasecmp(args.type, "AUDIO") == 0) { 14786 all = ast_rtp_get_quality(p->rtp, &qos); 14787 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14788 all = ast_rtp_get_quality(p->vrtp, &qos); 14789 } 14790 14791 if (strcasecmp(args.field, "local_ssrc") == 0) 14792 snprintf(buf, buflen, "%u", qos.local_ssrc); 14793 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14794 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14795 else if (strcasecmp(args.field, "local_jitter") == 0) 14796 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14797 else if (strcasecmp(args.field, "local_count") == 0) 14798 snprintf(buf, buflen, "%u", qos.local_count); 14799 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14800 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14801 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14802 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14803 else if (strcasecmp(args.field, "remote_jitter") == 0) 14804 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14805 else if (strcasecmp(args.field, "remote_count") == 0) 14806 snprintf(buf, buflen, "%u", qos.remote_count); 14807 else if (strcasecmp(args.field, "rtt") == 0) 14808 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14809 else if (strcasecmp(args.field, "all") == 0) 14810 ast_copy_string(buf, all, buflen); 14811 else { 14812 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14813 return -1; 14814 } 14815 return 0; 14816 }
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 6240 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(), sip_pvt::flags, fmt, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06243 { 06244 int rtp_code; 06245 struct ast_format_list fmt; 06246 06247 06248 if (debug) 06249 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06250 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06251 return; 06252 06253 if (p->rtp) { 06254 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06255 fmt = ast_codec_pref_getsize(pref, codec); 06256 } 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 */ 06257 return; 06258 ast_build_string(m_buf, m_size, " %d", rtp_code); 06259 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06260 ast_rtp_lookup_mime_subtype(1, codec, 06261 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06262 sample_rate); 06263 if (codec == AST_FORMAT_G729A) { 06264 /* Indicate that we don't support VAD (G.729 annex B) */ 06265 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06266 } else if (codec == AST_FORMAT_G723_1) { 06267 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06268 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06269 } else if (codec == AST_FORMAT_ILBC) { 06270 /* Add information about us using only 20/30 ms packetization */ 06271 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06272 } 06273 06274 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06275 *min_packet_size = fmt.cur_ms; 06276 06277 /* Our first codec packetization processed cannot be less than zero */ 06278 if ((*min_packet_size) == 0 && fmt.cur_ms) 06279 *min_packet_size = fmt.cur_ms; 06280 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6208 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06209 { 06210 char tmp[256]; 06211 06212 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06213 add_header(req, "Content-Type", "application/dtmf-relay"); 06214 add_header_contentLength(req, strlen(tmp)); 06215 add_line(req, tmp); 06216 return 0; 06217 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5602 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, and SIP_MAX_HEADERS.
05603 { 05604 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05605 05606 if (req->headers == SIP_MAX_HEADERS) { 05607 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05608 return -1; 05609 } 05610 05611 if (req->lines) { 05612 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05613 return -1; 05614 } 05615 05616 if (maxlen <= 0) { 05617 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05618 return -1; 05619 } 05620 05621 req->header[req->headers] = req->data + req->len; 05622 05623 if (compactheaders) 05624 var = find_alias(var, var); 05625 05626 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05627 req->len += strlen(req->header[req->headers]); 05628 req->headers++; 05629 05630 return 0; 05631 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5634 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().
05635 { 05636 char clen[10]; 05637 05638 snprintf(clen, sizeof(clen), "%d", len); 05639 return add_header(req, "Content-Length", clen); 05640 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5643 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05644 { 05645 if (req->lines == SIP_MAX_LINES) { 05646 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05647 return -1; 05648 } 05649 if (!req->lines) { 05650 /* Add extra empty return */ 05651 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05652 req->len += strlen(req->data + req->len); 05653 } 05654 if (req->len >= sizeof(req->data) - 4) { 05655 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05656 return -1; 05657 } 05658 req->line[req->lines] = req->data + req->len; 05659 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05660 req->len += strlen(req->line[req->lines]); 05661 req->lines++; 05662 return 0; 05663 }
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 6416 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().
06419 { 06420 int rtp_code; 06421 06422 if (debug) 06423 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06424 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06425 return; 06426 06427 ast_build_string(m_buf, m_size, " %d", rtp_code); 06428 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06429 ast_rtp_lookup_mime_subtype(0, format, 0), 06430 sample_rate); 06431 if (format == AST_RTP_DTMF) 06432 /* Indicate we support DTMF and FLASH... */ 06433 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06434 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 16373 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, strsep(), and username.
Referenced by build_peer().
16374 { 16375 char authcopy[256]; 16376 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16377 char *stringp; 16378 struct sip_auth *a, *b, *auth; 16379 16380 if (ast_strlen_zero(configuration)) 16381 return authlist; 16382 16383 if (option_debug) 16384 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16385 16386 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16387 stringp = authcopy; 16388 16389 username = stringp; 16390 realm = strrchr(stringp, '@'); 16391 if (realm) 16392 *realm++ = '\0'; 16393 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16394 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16395 return authlist; 16396 } 16397 stringp = username; 16398 username = strsep(&stringp, ":"); 16399 if (username) { 16400 secret = strsep(&stringp, ":"); 16401 if (!secret) { 16402 stringp = username; 16403 md5secret = strsep(&stringp,"#"); 16404 } 16405 } 16406 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16407 return authlist; 16408 16409 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16410 ast_copy_string(auth->username, username, sizeof(auth->username)); 16411 if (secret) 16412 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16413 if (md5secret) 16414 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16415 16416 /* find the end of the list */ 16417 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16418 ; 16419 if (b) 16420 b->next = auth; /* Add structure add end of list */ 16421 else 16422 authlist = auth; 16423 16424 if (option_verbose > 2) 16425 ast_verbose("Added authentication for realm %s\n", realm); 16426 16427 return authlist; 16428 16429 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5764 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05765 { 05766 char r[SIPBUFSIZE*2], *p; 05767 int n, rem = sizeof(r); 05768 05769 if (!route) 05770 return; 05771 05772 p = r; 05773 for (;route ; route = route->next) { 05774 n = strlen(route->hop); 05775 if (rem < n+3) /* we need room for ",<route>" */ 05776 break; 05777 if (p != r) { /* add a separator after fist route */ 05778 *p++ = ','; 05779 --rem; 05780 } 05781 *p++ = '<'; 05782 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05783 p += n; 05784 *p++ = '>'; 05785 rem -= (n+2); 05786 } 05787 *p = '\0'; 05788 add_header(req, "Route", r); 05789 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6444 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, 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.
06445 { 06446 int len = 0; 06447 int alreadysent = 0; 06448 06449 struct sockaddr_in sin; 06450 struct sockaddr_in vsin; 06451 struct sockaddr_in dest; 06452 struct sockaddr_in vdest = { 0, }; 06453 06454 /* SDP fields */ 06455 char *version = "v=0\r\n"; /* Protocol version */ 06456 char *subject = "s=session\r\n"; /* Subject of the session */ 06457 char owner[256]; /* Session owner/creator */ 06458 char connection[256]; /* Connection data */ 06459 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06460 char bandwidth[256] = ""; /* Max bitrate */ 06461 char *hold; 06462 char m_audio[256]; /* Media declaration line for audio */ 06463 char m_video[256]; /* Media declaration line for video */ 06464 char a_audio[1024]; /* Attributes for audio */ 06465 char a_video[1024]; /* Attributes for video */ 06466 char *m_audio_next = m_audio; 06467 char *m_video_next = m_video; 06468 size_t m_audio_left = sizeof(m_audio); 06469 size_t m_video_left = sizeof(m_video); 06470 char *a_audio_next = a_audio; 06471 char *a_video_next = a_video; 06472 size_t a_audio_left = sizeof(a_audio); 06473 size_t a_video_left = sizeof(a_video); 06474 06475 int x; 06476 int capability; 06477 int needvideo = FALSE; 06478 int debug = sip_debug_test_pvt(p); 06479 int min_audio_packet_size = 0; 06480 int min_video_packet_size = 0; 06481 06482 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06483 06484 if (!p->rtp) { 06485 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06486 return AST_FAILURE; 06487 } 06488 06489 /* Set RTP Session ID and version */ 06490 if (!p->sessionid) { 06491 p->sessionid = getpid(); 06492 p->sessionversion = p->sessionid; 06493 } else 06494 p->sessionversion++; 06495 06496 /* Get our addresses */ 06497 ast_rtp_get_us(p->rtp, &sin); 06498 if (p->vrtp) 06499 ast_rtp_get_us(p->vrtp, &vsin); 06500 06501 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06502 if (p->redirip.sin_addr.s_addr) { 06503 dest.sin_port = p->redirip.sin_port; 06504 dest.sin_addr = p->redirip.sin_addr; 06505 } else { 06506 dest.sin_addr = p->ourip; 06507 dest.sin_port = sin.sin_port; 06508 } 06509 06510 capability = p->jointcapability; 06511 06512 06513 if (option_debug > 1) { 06514 char codecbuf[SIPBUFSIZE]; 06515 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"); 06516 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06517 } 06518 06519 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06520 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06521 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06522 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06523 } 06524 #endif 06525 06526 /* Check if we need video in this call */ 06527 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06528 if (p->vrtp) { 06529 needvideo = TRUE; 06530 if (option_debug > 1) 06531 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06532 } else if (option_debug > 1) 06533 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06534 } 06535 06536 06537 /* Ok, we need video. Let's add what we need for video and set codecs. 06538 Video is handled differently than audio since we can not transcode. */ 06539 if (needvideo) { 06540 /* Determine video destination */ 06541 if (p->vredirip.sin_addr.s_addr) { 06542 vdest.sin_addr = p->vredirip.sin_addr; 06543 vdest.sin_port = p->vredirip.sin_port; 06544 } else { 06545 vdest.sin_addr = p->ourip; 06546 vdest.sin_port = vsin.sin_port; 06547 } 06548 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06549 06550 /* Build max bitrate string */ 06551 if (p->maxcallbitrate) 06552 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06553 if (debug) 06554 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06555 } 06556 06557 if (debug) 06558 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06559 06560 /* Start building generic SDP headers */ 06561 06562 /* We break with the "recommendation" and send our IP, in order that our 06563 peer doesn't have to ast_gethostbyname() us */ 06564 06565 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06566 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06567 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06568 06569 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06570 hold = "a=recvonly\r\n"; 06571 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06572 hold = "a=inactive\r\n"; 06573 else 06574 hold = "a=sendrecv\r\n"; 06575 06576 /* Now, start adding audio codecs. These are added in this order: 06577 - First what was requested by the calling channel 06578 - Then preferences in order from sip.conf device config for this peer/user 06579 - Then other codecs in capabilities, including video 06580 */ 06581 06582 /* Prefer the audio codec we were requested to use, first, no matter what 06583 Note that p->prefcodec can include video codecs, so mask them out 06584 */ 06585 if (capability & p->prefcodec) { 06586 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06587 06588 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06589 &m_audio_next, &m_audio_left, 06590 &a_audio_next, &a_audio_left, 06591 debug, &min_audio_packet_size); 06592 alreadysent |= codec; 06593 } 06594 06595 /* Start by sending our preferred audio codecs */ 06596 for (x = 0; x < 32; x++) { 06597 int codec; 06598 06599 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06600 break; 06601 06602 if (!(capability & codec)) 06603 continue; 06604 06605 if (alreadysent & codec) 06606 continue; 06607 06608 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06609 &m_audio_next, &m_audio_left, 06610 &a_audio_next, &a_audio_left, 06611 debug, &min_audio_packet_size); 06612 alreadysent |= codec; 06613 } 06614 06615 /* Now send any other common audio and video codecs, and non-codec formats: */ 06616 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06617 if (!(capability & x)) /* Codec not requested */ 06618 continue; 06619 06620 if (alreadysent & x) /* Already added to SDP */ 06621 continue; 06622 06623 if (x <= AST_FORMAT_MAX_AUDIO) 06624 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06625 &m_audio_next, &m_audio_left, 06626 &a_audio_next, &a_audio_left, 06627 debug, &min_audio_packet_size); 06628 else 06629 add_codec_to_sdp(p, x, 90000, 06630 &m_video_next, &m_video_left, 06631 &a_video_next, &a_video_left, 06632 debug, &min_video_packet_size); 06633 } 06634 06635 /* Now add DTMF RFC2833 telephony-event as a codec */ 06636 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06637 if (!(p->jointnoncodeccapability & x)) 06638 continue; 06639 06640 add_noncodec_to_sdp(p, x, 8000, 06641 &m_audio_next, &m_audio_left, 06642 &a_audio_next, &a_audio_left, 06643 debug); 06644 } 06645 06646 if (option_debug > 2) 06647 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06648 06649 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06650 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06651 06652 if (min_audio_packet_size) 06653 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06654 06655 if (min_video_packet_size) 06656 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06657 06658 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06659 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06660 06661 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06662 if (needvideo) 06663 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06664 06665 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06666 if (needvideo) /* only if video response is appropriate */ 06667 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06668 06669 add_header(resp, "Content-Type", "application/sdp"); 06670 add_header_contentLength(resp, len); 06671 add_line(resp, version); 06672 add_line(resp, owner); 06673 add_line(resp, subject); 06674 add_line(resp, connection); 06675 if (needvideo) /* only if video response is appropriate */ 06676 add_line(resp, bandwidth); 06677 add_line(resp, stime); 06678 add_line(resp, m_audio); 06679 add_line(resp, a_audio); 06680 add_line(resp, hold); 06681 if (needvideo) { /* only if video response is appropriate */ 06682 add_line(resp, m_video); 06683 add_line(resp, a_video); 06684 add_line(resp, hold); /* Repeat hold for the video stream */ 06685 } 06686 06687 /* Update lastrtprx when we send our SDP */ 06688 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06689 06690 if (option_debug > 2) { 06691 char buf[SIPBUFSIZE]; 06692 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06693 } 06694 06695 return AST_SUCCESS; 06696 }
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 16309 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, and sipdebug.
16310 { 16311 struct domain *d; 16312 16313 if (ast_strlen_zero(domain)) { 16314 ast_log(LOG_WARNING, "Zero length domain.\n"); 16315 return 1; 16316 } 16317 16318 if (!(d = ast_calloc(1, sizeof(*d)))) 16319 return 0; 16320 16321 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16322 16323 if (!ast_strlen_zero(context)) 16324 ast_copy_string(d->context, context, sizeof(d->context)); 16325 16326 d->mode = mode; 16327 16328 AST_LIST_LOCK(&domain_list); 16329 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16330 AST_LIST_UNLOCK(&domain_list); 16331 16332 if (sipdebug) 16333 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16334 16335 return 1; 16336 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6319 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, 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().
06320 { 06321 int len = 0; 06322 int x = 0; 06323 struct sockaddr_in udptlsin; 06324 char v[256] = ""; 06325 char s[256] = ""; 06326 char o[256] = ""; 06327 char c[256] = ""; 06328 char t[256] = ""; 06329 char m_modem[256]; 06330 char a_modem[1024]; 06331 char *m_modem_next = m_modem; 06332 size_t m_modem_left = sizeof(m_modem); 06333 char *a_modem_next = a_modem; 06334 size_t a_modem_left = sizeof(a_modem); 06335 struct sockaddr_in udptldest = { 0, }; 06336 int debug; 06337 06338 debug = sip_debug_test_pvt(p); 06339 len = 0; 06340 if (!p->udptl) { 06341 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06342 return -1; 06343 } 06344 06345 if (!p->sessionid) { 06346 p->sessionid = getpid(); 06347 p->sessionversion = p->sessionid; 06348 } else 06349 p->sessionversion++; 06350 06351 /* Our T.38 end is */ 06352 ast_udptl_get_us(p->udptl, &udptlsin); 06353 06354 /* Determine T.38 UDPTL destination */ 06355 if (p->udptlredirip.sin_addr.s_addr) { 06356 udptldest.sin_port = p->udptlredirip.sin_port; 06357 udptldest.sin_addr = p->udptlredirip.sin_addr; 06358 } else { 06359 udptldest.sin_addr = p->ourip; 06360 udptldest.sin_port = udptlsin.sin_port; 06361 } 06362 06363 if (debug) 06364 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06365 06366 /* We break with the "recommendation" and send our IP, in order that our 06367 peer doesn't have to ast_gethostbyname() us */ 06368 06369 if (debug) { 06370 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06371 p->t38.capability, 06372 p->t38.peercapability, 06373 p->t38.jointcapability); 06374 } 06375 snprintf(v, sizeof(v), "v=0\r\n"); 06376 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06377 snprintf(s, sizeof(s), "s=session\r\n"); 06378 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06379 snprintf(t, sizeof(t), "t=0 0\r\n"); 06380 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06381 06382 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06383 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06384 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06385 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06386 if ((x = t38_get_rate(p->t38.jointcapability))) 06387 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06388 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06389 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06390 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06391 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06392 x = ast_udptl_get_local_max_datagram(p->udptl); 06393 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06394 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06395 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06396 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06397 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06398 add_header(resp, "Content-Type", "application/sdp"); 06399 add_header_contentLength(resp, len); 06400 add_line(resp, v); 06401 add_line(resp, o); 06402 add_line(resp, s); 06403 add_line(resp, c); 06404 add_line(resp, t); 06405 add_line(resp, m_modem); 06406 add_line(resp, a_modem); 06407 06408 /* Update lastrtprx when we send our SDP */ 06409 p->lastrtprx = p->lastrtptx = time(NULL); 06410 06411 return 0; 06412 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6197 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06198 { 06199 /* XXX Convert \n's to \r\n's XXX */ 06200 add_header(req, "Content-Type", "text/plain"); 06201 add_header_contentLength(req, strlen(text)); 06202 add_line(req, text); 06203 return 0; 06204 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6221 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06222 { 06223 const char *xml_is_a_huge_waste_of_space = 06224 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06225 " <media_control>\r\n" 06226 " <vc_primitive>\r\n" 06227 " <to_encoder>\r\n" 06228 " <picture_fast_update>\r\n" 06229 " </picture_fast_update>\r\n" 06230 " </to_encoder>\r\n" 06231 " </vc_primitive>\r\n" 06232 " </media_control>\r\n"; 06233 add_header(req, "Content-Type", "application/media_control+xml"); 06234 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06235 add_line(req, xml_is_a_huge_waste_of_space); 06236 return 0; 06237 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6144 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().
06145 { 06146 char tmpdat[256]; 06147 struct tm tm; 06148 time_t t = time(NULL); 06149 06150 gmtime_r(&t, &tm); 06151 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06152 add_header(req, "Date", tmpdat); 06153 }
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
static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
domain | ||||
) | [static] |
The SIP domain list
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 13302 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.
Referenced by attempt_transfer(), and handle_invite_replaces().
13303 { 13304 if (chan && chan->_state == AST_STATE_UP) { 13305 if (ast_test_flag(chan, AST_FLAG_MOH)) 13306 ast_moh_stop(chan); 13307 else if (chan->generatordata) 13308 ast_deactivate_generator(chan); 13309 } 13310 }
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 ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, 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 13314 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(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, and option_debug.
13315 { 13316 int res = 0; 13317 struct ast_channel *peera = NULL, 13318 *peerb = NULL, 13319 *peerc = NULL, 13320 *peerd = NULL; 13321 13322 13323 /* We will try to connect the transferee with the target and hangup 13324 all channels to the transferer */ 13325 if (option_debug > 3) { 13326 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13327 if (transferer->chan1) 13328 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13329 else 13330 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13331 if (target->chan1) 13332 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13333 else 13334 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13335 if (transferer->chan2) 13336 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13337 else 13338 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13339 if (target->chan2) 13340 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)"); 13341 else 13342 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13343 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13344 } 13345 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13346 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13347 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13348 peerc = transferer->chan2; /* Asterisk to Transferee */ 13349 peerd = target->chan2; /* Asterisk to Target */ 13350 if (option_debug > 2) 13351 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13352 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13353 peera = target->chan1; /* Transferer to PBX -> target channel */ 13354 peerb = transferer->chan1; /* Transferer to IVR*/ 13355 peerc = target->chan2; /* Asterisk to Target */ 13356 peerd = transferer->chan2; /* Nothing */ 13357 if (option_debug > 2) 13358 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13359 } 13360 13361 if (peera && peerb && peerc && (peerb != peerc)) { 13362 ast_quiet_chan(peera); /* Stop generators */ 13363 ast_quiet_chan(peerb); 13364 ast_quiet_chan(peerc); 13365 if (peerd) 13366 ast_quiet_chan(peerd); 13367 13368 /* Fix CDRs so they're attached to the remaining channel */ 13369 if (peera->cdr && peerb->cdr) 13370 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13371 else if (peera->cdr) 13372 peerb->cdr = peera->cdr; 13373 peera->cdr = NULL; 13374 13375 if (peerb->cdr && peerc->cdr) 13376 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13377 else if (peerc->cdr) 13378 peerb->cdr = peerc->cdr; 13379 peerc->cdr = NULL; 13380 13381 if (option_debug > 3) 13382 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13383 if (ast_channel_masquerade(peerb, peerc)) { 13384 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13385 res = -1; 13386 } else 13387 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13388 return res; 13389 } else { 13390 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13391 if (transferer->chan1) 13392 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13393 if (target->chan1) 13394 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13395 return -2; 13396 } 13397 return 0; 13398 }
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 6867 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), 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().
06868 { 06869 /* Construct Contact: header */ 06870 if (ourport != STANDARD_SIP_PORT) 06871 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); 06872 else 06873 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06874 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 16640 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, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, 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, sched, 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.
16641 { 16642 struct sip_peer *peer = NULL; 16643 struct ast_ha *oldha = NULL; 16644 int obproxyfound=0; 16645 int found=0; 16646 int firstpass=1; 16647 int format=0; /* Ama flags */ 16648 time_t regseconds = 0; 16649 char *varname = NULL, *varval = NULL; 16650 struct ast_variable *tmpvar = NULL; 16651 struct ast_flags peerflags[2] = {{(0)}}; 16652 struct ast_flags mask[2] = {{(0)}}; 16653 char fullcontact[sizeof(peer->fullcontact)] = ""; 16654 16655 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16656 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16657 /* We also use a case-sensitive comparison (unlike find_peer) so 16658 that case changes made to the peer name will be properly handled 16659 during reload 16660 */ 16661 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16662 16663 if (peer) { 16664 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16665 found = 1; 16666 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16667 firstpass = 0; 16668 } else { 16669 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16670 return NULL; 16671 16672 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16673 rpeerobjs++; 16674 else 16675 speerobjs++; 16676 ASTOBJ_INIT(peer); 16677 } 16678 /* Note that our peer HAS had its reference count incrased */ 16679 if (firstpass) { 16680 peer->lastmsgssent = -1; 16681 oldha = peer->ha; 16682 peer->ha = NULL; 16683 set_peer_defaults(peer); /* Set peer defaults */ 16684 } 16685 if (!found && name) 16686 ast_copy_string(peer->name, name, sizeof(peer->name)); 16687 16688 /* If we have channel variables, remove them (reload) */ 16689 if (peer->chanvars) { 16690 ast_variables_destroy(peer->chanvars); 16691 peer->chanvars = NULL; 16692 /* XXX should unregister ? */ 16693 } 16694 16695 /* If we have realm authentication information, remove them (reload) */ 16696 clear_realm_authentication(peer->auth); 16697 peer->auth = NULL; 16698 16699 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16700 if (handle_common_options(&peerflags[0], &mask[0], v)) 16701 continue; 16702 if (realtime && !strcasecmp(v->name, "regseconds")) { 16703 ast_get_time_t(v->value, ®seconds, 0, NULL); 16704 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16705 inet_aton(v->value, &(peer->addr.sin_addr)); 16706 } else if (realtime && !strcasecmp(v->name, "name")) 16707 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16708 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16709 /* Reconstruct field, because realtime separates our value at the ';' */ 16710 if (!ast_strlen_zero(fullcontact)) { 16711 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 16712 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 16713 } else { 16714 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 16715 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16716 } 16717 } else if (!strcasecmp(v->name, "secret")) 16718 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16719 else if (!strcasecmp(v->name, "md5secret")) 16720 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16721 else if (!strcasecmp(v->name, "auth")) 16722 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16723 else if (!strcasecmp(v->name, "callerid")) { 16724 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16725 } else if (!strcasecmp(v->name, "fullname")) { 16726 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16727 } else if (!strcasecmp(v->name, "cid_number")) { 16728 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16729 } else if (!strcasecmp(v->name, "context")) { 16730 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16731 } else if (!strcasecmp(v->name, "subscribecontext")) { 16732 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16733 } else if (!strcasecmp(v->name, "fromdomain")) { 16734 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16735 } else if (!strcasecmp(v->name, "usereqphone")) { 16736 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16737 } else if (!strcasecmp(v->name, "fromuser")) { 16738 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16739 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16740 if (!strcasecmp(v->value, "dynamic")) { 16741 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16742 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16743 } else { 16744 /* They'll register with us */ 16745 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16746 /* Initialize stuff if this is a new peer, or if it used to be 16747 * non-dynamic before the reload. */ 16748 memset(&peer->addr.sin_addr, 0, 4); 16749 if (peer->addr.sin_port) { 16750 /* If we've already got a port, make it the default rather than absolute */ 16751 peer->defaddr.sin_port = peer->addr.sin_port; 16752 peer->addr.sin_port = 0; 16753 } 16754 } 16755 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16756 } 16757 } else { 16758 /* Non-dynamic. Make sure we become that way if we're not */ 16759 if (!AST_SCHED_DEL(sched, peer->expire)) { 16760 struct sip_peer *peer_ptr = peer; 16761 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16762 } 16763 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16764 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16765 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16766 ASTOBJ_UNREF(peer, sip_destroy_peer); 16767 return NULL; 16768 } 16769 } 16770 if (!strcasecmp(v->name, "outboundproxy")) 16771 obproxyfound=1; 16772 else { 16773 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16774 if (!peer->addr.sin_port) 16775 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16776 } 16777 } 16778 } else if (!strcasecmp(v->name, "defaultip")) { 16779 if (ast_get_ip(&peer->defaddr, v->value)) { 16780 ASTOBJ_UNREF(peer, sip_destroy_peer); 16781 return NULL; 16782 } 16783 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16784 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16785 } else if (!strcasecmp(v->name, "port")) { 16786 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16787 peer->defaddr.sin_port = htons(atoi(v->value)); 16788 else 16789 peer->addr.sin_port = htons(atoi(v->value)); 16790 } else if (!strcasecmp(v->name, "callingpres")) { 16791 peer->callingpres = ast_parse_caller_presentation(v->value); 16792 if (peer->callingpres == -1) 16793 peer->callingpres = atoi(v->value); 16794 } else if (!strcasecmp(v->name, "username")) { 16795 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16796 } else if (!strcasecmp(v->name, "language")) { 16797 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16798 } else if (!strcasecmp(v->name, "regexten")) { 16799 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16800 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16801 peer->call_limit = atoi(v->value); 16802 if (peer->call_limit < 0) 16803 peer->call_limit = 0; 16804 } else if (!strcasecmp(v->name, "amaflags")) { 16805 format = ast_cdr_amaflags2int(v->value); 16806 if (format < 0) { 16807 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16808 } else { 16809 peer->amaflags = format; 16810 } 16811 } else if (!strcasecmp(v->name, "accountcode")) { 16812 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16813 } else if (!strcasecmp(v->name, "mohinterpret") 16814 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16815 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16816 } else if (!strcasecmp(v->name, "mohsuggest")) { 16817 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16818 } else if (!strcasecmp(v->name, "mailbox")) { 16819 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16820 } else if (!strcasecmp(v->name, "subscribemwi")) { 16821 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16822 } else if (!strcasecmp(v->name, "vmexten")) { 16823 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16824 } else if (!strcasecmp(v->name, "callgroup")) { 16825 peer->callgroup = ast_get_group(v->value); 16826 } else if (!strcasecmp(v->name, "allowtransfer")) { 16827 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16828 } else if (!strcasecmp(v->name, "pickupgroup")) { 16829 peer->pickupgroup = ast_get_group(v->value); 16830 } else if (!strcasecmp(v->name, "allow")) { 16831 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16832 } else if (!strcasecmp(v->name, "disallow")) { 16833 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16834 } else if (!strcasecmp(v->name, "autoframing")) { 16835 peer->autoframing = ast_true(v->value); 16836 } else if (!strcasecmp(v->name, "rtptimeout")) { 16837 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16838 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16839 peer->rtptimeout = global_rtptimeout; 16840 } 16841 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16842 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16843 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16844 peer->rtpholdtimeout = global_rtpholdtimeout; 16845 } 16846 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16847 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16848 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16849 peer->rtpkeepalive = global_rtpkeepalive; 16850 } 16851 } else if (!strcasecmp(v->name, "setvar")) { 16852 /* Set peer channel variable */ 16853 varname = ast_strdupa(v->value); 16854 if ((varval = strchr(varname, '='))) { 16855 *varval++ = '\0'; 16856 if ((tmpvar = ast_variable_new(varname, varval))) { 16857 tmpvar->next = peer->chanvars; 16858 peer->chanvars = tmpvar; 16859 } 16860 } 16861 } else if (!strcasecmp(v->name, "qualify")) { 16862 if (!strcasecmp(v->value, "no")) { 16863 peer->maxms = 0; 16864 } else if (!strcasecmp(v->value, "yes")) { 16865 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16866 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16867 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); 16868 peer->maxms = 0; 16869 } 16870 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16871 peer->maxcallbitrate = atoi(v->value); 16872 if (peer->maxcallbitrate < 0) 16873 peer->maxcallbitrate = default_maxcallbitrate; 16874 } 16875 } 16876 if (!ast_strlen_zero(fullcontact)) { 16877 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 16878 } 16879 16880 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16881 time_t nowtime = time(NULL); 16882 16883 if ((nowtime - regseconds) > 0) { 16884 destroy_association(peer); 16885 memset(&peer->addr, 0, sizeof(peer->addr)); 16886 if (option_debug) 16887 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16888 } 16889 } 16890 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16891 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16892 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16893 global_allowsubscribe = TRUE; /* No global ban any more */ 16894 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16895 reg_source_db(peer); 16896 ASTOBJ_UNMARK(peer); 16897 ast_free_ha(oldha); 16898 return peer; 16899 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11602 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, 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().
11603 { 11604 char a1[256]; 11605 char a2[256]; 11606 char a1_hash[256]; 11607 char a2_hash[256]; 11608 char resp[256]; 11609 char resp_hash[256]; 11610 char uri[256]; 11611 char opaque[256] = ""; 11612 char cnonce[80]; 11613 const char *username; 11614 const char *secret; 11615 const char *md5secret; 11616 struct sip_auth *auth = NULL; /* Realm authentication */ 11617 11618 if (!ast_strlen_zero(p->domain)) 11619 ast_copy_string(uri, p->domain, sizeof(uri)); 11620 else if (!ast_strlen_zero(p->uri)) 11621 ast_copy_string(uri, p->uri, sizeof(uri)); 11622 else 11623 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11624 11625 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11626 11627 /* Check if we have separate auth credentials */ 11628 if ((auth = find_realm_authentication(authl, p->realm))) { 11629 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11630 auth->username, p->peername, p->username); 11631 username = auth->username; 11632 secret = auth->secret; 11633 md5secret = auth->md5secret; 11634 if (sipdebug) 11635 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11636 } else { 11637 /* No authentication, use peer or register= config */ 11638 username = p->authname; 11639 secret = p->peersecret; 11640 md5secret = p->peermd5secret; 11641 } 11642 if (ast_strlen_zero(username)) /* We have no authentication */ 11643 return -1; 11644 11645 /* Calculate SIP digest response */ 11646 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11647 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11648 if (!ast_strlen_zero(md5secret)) 11649 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11650 else 11651 ast_md5_hash(a1_hash,a1); 11652 ast_md5_hash(a2_hash,a2); 11653 11654 p->noncecount++; 11655 if (!ast_strlen_zero(p->qop)) 11656 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11657 else 11658 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11659 ast_md5_hash(resp_hash, resp); 11660 11661 /* only include the opaque string if it's set */ 11662 if (!ast_strlen_zero(p->opaque)) { 11663 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11664 } 11665 11666 /* XXX We hard code our qop to "auth" for now. XXX */ 11667 if (!ast_strlen_zero(p->qop)) 11668 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); 11669 else 11670 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); 11671 11672 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11673 11674 return 0; 11675 }
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 8294 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().
08295 { 08296 struct sip_route *thishop, *head, *tail; 08297 int start = 0; 08298 int len; 08299 const char *rr, *contact, *c; 08300 08301 /* Once a persistant route is set, don't fool with it */ 08302 if (p->route && p->route_persistant) { 08303 if (option_debug) 08304 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08305 return; 08306 } 08307 08308 if (p->route) { 08309 free_old_route(p->route); 08310 p->route = NULL; 08311 } 08312 08313 /* We only want to create the route set the first time this is called */ 08314 p->route_persistant = 1; 08315 08316 /* Build a tailq, then assign it to p->route when done. 08317 * If backwards, we add entries from the head so they end up 08318 * in reverse order. However, we do need to maintain a correct 08319 * tail pointer because the contact is always at the end. 08320 */ 08321 head = NULL; 08322 tail = head; 08323 /* 1st we pass through all the hops in any Record-Route headers */ 08324 for (;;) { 08325 /* Each Record-Route header */ 08326 rr = __get_header(req, "Record-Route", &start); 08327 if (*rr == '\0') 08328 break; 08329 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08330 ++rr; 08331 len = strcspn(rr, ">") + 1; 08332 /* Make a struct route */ 08333 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08334 /* ast_calloc is not needed because all fields are initialized in this block */ 08335 ast_copy_string(thishop->hop, rr, len); 08336 if (option_debug > 1) 08337 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08338 /* Link in */ 08339 if (backwards) { 08340 /* Link in at head so they end up in reverse order */ 08341 thishop->next = head; 08342 head = thishop; 08343 /* If this was the first then it'll be the tail */ 08344 if (!tail) 08345 tail = thishop; 08346 } else { 08347 thishop->next = NULL; 08348 /* Link in at the end */ 08349 if (tail) 08350 tail->next = thishop; 08351 else 08352 head = thishop; 08353 tail = thishop; 08354 } 08355 } 08356 } 08357 } 08358 08359 /* Only append the contact if we are dealing with a strict router */ 08360 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08361 /* 2nd append the Contact: if there is one */ 08362 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08363 contact = get_header(req, "Contact"); 08364 if (!ast_strlen_zero(contact)) { 08365 if (option_debug > 1) 08366 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08367 /* Look for <: delimited address */ 08368 c = strchr(contact, '<'); 08369 if (c) { 08370 /* Take to > */ 08371 ++c; 08372 len = strcspn(c, ">") + 1; 08373 } else { 08374 /* No <> - just take the lot */ 08375 c = contact; 08376 len = strlen(contact) + 1; 08377 } 08378 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08379 /* ast_calloc is not needed because all fields are initialized in this block */ 08380 ast_copy_string(thishop->hop, c, len); 08381 thishop->next = NULL; 08382 /* Goes at the end */ 08383 if (tail) 08384 tail->next = thishop; 08385 else 08386 head = thishop; 08387 } 08388 } 08389 } 08390 08391 /* Store as new route */ 08392 p->route = head; 08393 08394 /* For debugging dump what we ended up with */ 08395 if (sip_debug_test_pvt(p)) 08396 list_route(p->route); 08397 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6877 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, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06878 { 06879 int send_pres_tags = TRUE; 06880 const char *privacy=NULL; 06881 const char *screen=NULL; 06882 char buf[256]; 06883 const char *clid = default_callerid; 06884 const char *clin = NULL; 06885 const char *fromdomain; 06886 06887 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06888 return; 06889 06890 if (p->owner && p->owner->cid.cid_num) 06891 clid = p->owner->cid.cid_num; 06892 if (p->owner && p->owner->cid.cid_name) 06893 clin = p->owner->cid.cid_name; 06894 if (ast_strlen_zero(clin)) 06895 clin = clid; 06896 06897 switch (p->callingpres) { 06898 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06899 privacy = "off"; 06900 screen = "no"; 06901 break; 06902 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06903 privacy = "off"; 06904 screen = "yes"; 06905 break; 06906 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06907 privacy = "off"; 06908 screen = "no"; 06909 break; 06910 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06911 privacy = "off"; 06912 screen = "yes"; 06913 break; 06914 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06915 privacy = "full"; 06916 screen = "no"; 06917 break; 06918 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06919 privacy = "full"; 06920 screen = "yes"; 06921 break; 06922 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06923 privacy = "full"; 06924 screen = "no"; 06925 break; 06926 case AST_PRES_PROHIB_NETWORK_NUMBER: 06927 privacy = "full"; 06928 screen = "yes"; 06929 break; 06930 case AST_PRES_NUMBER_NOT_AVAILABLE: 06931 send_pres_tags = FALSE; 06932 break; 06933 default: 06934 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06935 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06936 privacy = "full"; 06937 else 06938 privacy = "off"; 06939 screen = "no"; 06940 break; 06941 } 06942 06943 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06944 06945 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06946 if (send_pres_tags) 06947 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06948 ast_string_field_set(p, rpid, buf); 06949 06950 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06951 S_OR(p->fromuser, clid), 06952 fromdomain, p->tag); 06953 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 16460 of file chan_sip.c.
References 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, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
16461 { 16462 struct sip_user *user; 16463 int format; 16464 struct ast_ha *oldha = NULL; 16465 char *varname = NULL, *varval = NULL; 16466 struct ast_variable *tmpvar = NULL; 16467 struct ast_flags userflags[2] = {{(0)}}; 16468 struct ast_flags mask[2] = {{(0)}}; 16469 16470 16471 if (!(user = ast_calloc(1, sizeof(*user)))) 16472 return NULL; 16473 16474 suserobjs++; 16475 ASTOBJ_INIT(user); 16476 ast_copy_string(user->name, name, sizeof(user->name)); 16477 oldha = user->ha; 16478 user->ha = NULL; 16479 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16480 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16481 user->capability = global_capability; 16482 user->allowtransfer = global_allowtransfer; 16483 user->maxcallbitrate = default_maxcallbitrate; 16484 user->autoframing = global_autoframing; 16485 user->prefs = default_prefs; 16486 /* set default context */ 16487 strcpy(user->context, default_context); 16488 strcpy(user->language, default_language); 16489 strcpy(user->mohinterpret, default_mohinterpret); 16490 strcpy(user->mohsuggest, default_mohsuggest); 16491 /* First we walk through the v parameters list and then the alt parameters list */ 16492 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16493 if (handle_common_options(&userflags[0], &mask[0], v)) 16494 continue; 16495 16496 if (!strcasecmp(v->name, "context")) { 16497 ast_copy_string(user->context, v->value, sizeof(user->context)); 16498 } else if (!strcasecmp(v->name, "subscribecontext")) { 16499 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16500 } else if (!strcasecmp(v->name, "setvar")) { 16501 varname = ast_strdupa(v->value); 16502 if ((varval = strchr(varname,'='))) { 16503 *varval++ = '\0'; 16504 if ((tmpvar = ast_variable_new(varname, varval))) { 16505 tmpvar->next = user->chanvars; 16506 user->chanvars = tmpvar; 16507 } 16508 } 16509 } else if (!strcasecmp(v->name, "permit") || 16510 !strcasecmp(v->name, "deny")) { 16511 user->ha = ast_append_ha(v->name, v->value, user->ha); 16512 } else if (!strcasecmp(v->name, "allowtransfer")) { 16513 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16514 } else if (!strcasecmp(v->name, "secret")) { 16515 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16516 } else if (!strcasecmp(v->name, "md5secret")) { 16517 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16518 } else if (!strcasecmp(v->name, "callerid")) { 16519 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16520 } else if (!strcasecmp(v->name, "fullname")) { 16521 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16522 } else if (!strcasecmp(v->name, "cid_number")) { 16523 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16524 } else if (!strcasecmp(v->name, "callgroup")) { 16525 user->callgroup = ast_get_group(v->value); 16526 } else if (!strcasecmp(v->name, "pickupgroup")) { 16527 user->pickupgroup = ast_get_group(v->value); 16528 } else if (!strcasecmp(v->name, "language")) { 16529 ast_copy_string(user->language, v->value, sizeof(user->language)); 16530 } else if (!strcasecmp(v->name, "mohinterpret") 16531 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16532 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16533 } else if (!strcasecmp(v->name, "mohsuggest")) { 16534 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16535 } else if (!strcasecmp(v->name, "accountcode")) { 16536 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16537 } else if (!strcasecmp(v->name, "call-limit")) { 16538 user->call_limit = atoi(v->value); 16539 if (user->call_limit < 0) 16540 user->call_limit = 0; 16541 } else if (!strcasecmp(v->name, "amaflags")) { 16542 format = ast_cdr_amaflags2int(v->value); 16543 if (format < 0) { 16544 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16545 } else { 16546 user->amaflags = format; 16547 } 16548 } else if (!strcasecmp(v->name, "allow")) { 16549 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16550 } else if (!strcasecmp(v->name, "disallow")) { 16551 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16552 } else if (!strcasecmp(v->name, "autoframing")) { 16553 user->autoframing = ast_true(v->value); 16554 } else if (!strcasecmp(v->name, "callingpres")) { 16555 user->callingpres = ast_parse_caller_presentation(v->value); 16556 if (user->callingpres == -1) 16557 user->callingpres = atoi(v->value); 16558 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16559 user->maxcallbitrate = atoi(v->value); 16560 if (user->maxcallbitrate < 0) 16561 user->maxcallbitrate = default_maxcallbitrate; 16562 } 16563 /* We can't just report unknown options here because this may be a 16564 * type=friend entry. All user options are valid for a peer, but not 16565 * the other way around. */ 16566 } 16567 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16568 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16569 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16570 global_allowsubscribe = TRUE; /* No global ban any more */ 16571 ast_free_ha(oldha); 16572 return user; 16573 }
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 8602 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, 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().
08603 { 08604 struct sip_pvt *p = data; 08605 08606 ast_mutex_lock(&p->lock); 08607 08608 switch(state) { 08609 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08610 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08611 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08612 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08613 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08614 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); 08615 p->stateid = -1; 08616 p->subscribed = NONE; 08617 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08618 break; 08619 default: /* Tell user */ 08620 p->laststate = state; 08621 break; 08622 } 08623 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08624 if (!p->pendinginvite) { 08625 transmit_state_notify(p, state, 1, FALSE); 08626 } else { 08627 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08628 if many state changes happen meanwhile, we will only send a notification of the last one */ 08629 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08630 } 08631 } 08632 if (option_verbose > 1) 08633 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, 08634 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08635 08636 08637 ast_mutex_unlock(&p->lock); 08638 08639 return 0; 08640 }
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 4986 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_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().
04987 { 04988 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04989 sip_peer_hold(dialog, holdstate); 04990 if (global_callevents) 04991 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04992 "Channel: %s\r\n" 04993 "Uniqueid: %s\r\n", 04994 dialog->owner->name, 04995 dialog->owner->uniqueid); 04996 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04997 if (!holdstate) { /* Put off remote hold */ 04998 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04999 return; 05000 } 05001 /* No address for RTP, we're on hold */ 05002 05003 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05004 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05005 else if (sendonly == 2) /* Inactive stream */ 05006 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05007 else 05008 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05009 return; 05010 }
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 8407 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, 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().
08410 { 08411 const char *response = "407 Proxy Authentication Required"; 08412 const char *reqheader = "Proxy-Authorization"; 08413 const char *respheader = "Proxy-Authenticate"; 08414 const char *authtoken; 08415 char a1_hash[256]; 08416 char resp_hash[256]=""; 08417 char *c; 08418 int wrongnonce = FALSE; 08419 int good_response; 08420 const char *usednonce = p->randdata; 08421 struct ast_dynamic_str *buf; 08422 int res; 08423 08424 /* table of recognised keywords, and their value in the digest */ 08425 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08426 struct x { 08427 const char *key; 08428 const char *s; 08429 } *i, keys[] = { 08430 [K_RESP] = { "response=", "" }, 08431 [K_URI] = { "uri=", "" }, 08432 [K_USER] = { "username=", "" }, 08433 [K_NONCE] = { "nonce=", "" }, 08434 [K_LAST] = { NULL, NULL} 08435 }; 08436 08437 /* Always OK if no secret */ 08438 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08439 return AUTH_SUCCESSFUL; 08440 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08441 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08442 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08443 different circumstances! What a surprise. */ 08444 response = "401 Unauthorized"; 08445 reqheader = "Authorization"; 08446 respheader = "WWW-Authenticate"; 08447 } 08448 authtoken = get_header(req, reqheader); 08449 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08450 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08451 information */ 08452 if (!reliable) { 08453 /* Resend message if this was NOT a reliable delivery. Otherwise the 08454 retransmission should get it */ 08455 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08456 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08457 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08458 } 08459 return AUTH_CHALLENGE_SENT; 08460 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08461 /* We have no auth, so issue challenge and request authentication */ 08462 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08463 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08464 /* Schedule auto destroy in 32 seconds */ 08465 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08466 return AUTH_CHALLENGE_SENT; 08467 } 08468 08469 /* --- We have auth, so check it */ 08470 08471 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08472 an example in the spec of just what it is you're doing a hash on. */ 08473 08474 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08475 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08476 08477 /* Make a copy of the response and parse it */ 08478 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08479 08480 if (res == AST_DYNSTR_BUILD_FAILED) 08481 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08482 08483 c = buf->str; 08484 08485 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08486 for (i = keys; i->key != NULL; i++) { 08487 const char *separator = ","; /* default */ 08488 08489 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08490 continue; 08491 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08492 c += strlen(i->key); 08493 if (*c == '"') { /* in quotes. Skip first and look for last */ 08494 c++; 08495 separator = "\""; 08496 } 08497 i->s = c; 08498 strsep(&c, separator); 08499 break; 08500 } 08501 if (i->key == NULL) /* not found, jump after space or comma */ 08502 strsep(&c, " ,"); 08503 } 08504 08505 /* Verify that digest username matches the username we auth as */ 08506 if (strcmp(username, keys[K_USER].s)) { 08507 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08508 username, keys[K_USER].s); 08509 /* Oops, we're trying something here */ 08510 return AUTH_USERNAME_MISMATCH; 08511 } 08512 08513 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08514 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08515 wrongnonce = TRUE; 08516 usednonce = keys[K_NONCE].s; 08517 } 08518 08519 if (!ast_strlen_zero(md5secret)) 08520 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08521 else { 08522 char a1[256]; 08523 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08524 ast_md5_hash(a1_hash, a1); 08525 } 08526 08527 /* compute the expected response to compare with what we received */ 08528 { 08529 char a2[256]; 08530 char a2_hash[256]; 08531 char resp[256]; 08532 08533 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08534 S_OR(keys[K_URI].s, uri)); 08535 ast_md5_hash(a2_hash, a2); 08536 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08537 ast_md5_hash(resp_hash, resp); 08538 } 08539 08540 good_response = keys[K_RESP].s && 08541 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08542 if (wrongnonce) { 08543 if (good_response) { 08544 if (sipdebug) 08545 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08546 /* We got working auth token, based on stale nonce . */ 08547 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08548 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08549 } else { 08550 /* Everything was wrong, so give the device one more try with a new challenge */ 08551 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08552 if (sipdebug) 08553 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08554 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08555 } else { 08556 if (sipdebug) 08557 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08558 } 08559 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08560 } 08561 08562 /* Schedule auto destroy in 32 seconds */ 08563 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08564 return AUTH_CHALLENGE_SENT; 08565 } 08566 if (good_response) { 08567 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08568 return AUTH_SUCCESSFUL; 08569 } 08570 08571 /* Ok, we have a bad username/secret pair */ 08572 /* Tell the UAS not to re-send this authentication data, because 08573 it will continue to fail 08574 */ 08575 08576 return AUTH_SECRET_FAILED; 08577 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12070 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, 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().
12071 { 12072 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12073 /* if we can't BYE, then this is really a pending CANCEL */ 12074 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12075 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12076 /* Actually don't destroy us yet, wait for the 487 on our original 12077 INVITE, but do set an autodestruct just in case we never get it. */ 12078 else { 12079 /* We have a pending outbound invite, don't send someting 12080 new in-transaction */ 12081 if (p->pendinginvite) 12082 return; 12083 12084 /* Perhaps there is an SD change INVITE outstanding */ 12085 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12086 } 12087 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12088 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12089 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12090 /* if we can't REINVITE, hold it for later */ 12091 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12092 if (option_debug) 12093 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12094 } else { 12095 if (option_debug) 12096 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12097 /* Didn't get to reinvite yet, so do it now */ 12098 transmit_reinvite_with_sdp(p); 12099 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12100 } 12101 } 12102 }
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 16339 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().
16340 { 16341 struct domain *d; 16342 int result = 0; 16343 16344 AST_LIST_LOCK(&domain_list); 16345 AST_LIST_TRAVERSE(&domain_list, d, list) { 16346 if (strcasecmp(d->domain, domain)) 16347 continue; 16348 16349 if (len && !ast_strlen_zero(d->context)) 16350 ast_copy_string(context, d->context, len); 16351 16352 result = 1; 16353 break; 16354 } 16355 AST_LIST_UNLOCK(&domain_list); 16356 16357 return result; 16358 }
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 9706 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09707 { 09708 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09709 }
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 9386 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::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, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::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, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::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_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, 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, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
09389 { 09390 struct sip_user *user = NULL; 09391 struct sip_peer *peer; 09392 char from[256], *c; 09393 char *of; 09394 char rpid_num[50]; 09395 const char *rpid; 09396 enum check_auth_result res = AUTH_SUCCESSFUL; 09397 char *t; 09398 char calleridname[50]; 09399 int debug=sip_debug_test_addr(sin); 09400 struct ast_variable *tmpvar = NULL, *v = NULL; 09401 char *uri2 = ast_strdupa(uri); 09402 09403 /* Terminate URI */ 09404 t = uri2; 09405 while (*t && *t > 32 && *t != ';') 09406 t++; 09407 *t = '\0'; 09408 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09409 if (pedanticsipchecking) 09410 ast_uri_decode(from); 09411 /* XXX here tries to map the username for invite things */ 09412 memset(calleridname, 0, sizeof(calleridname)); 09413 get_calleridname(from, calleridname, sizeof(calleridname)); 09414 if (calleridname[0]) 09415 ast_string_field_set(p, cid_name, calleridname); 09416 09417 rpid = get_header(req, "Remote-Party-ID"); 09418 memset(rpid_num, 0, sizeof(rpid_num)); 09419 if (!ast_strlen_zero(rpid)) 09420 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09421 09422 of = get_in_brackets(from); 09423 if (ast_strlen_zero(p->exten)) { 09424 t = uri2; 09425 if (!strncasecmp(t, "sip:", 4)) 09426 t+= 4; 09427 ast_string_field_set(p, exten, t); 09428 t = strchr(p->exten, '@'); 09429 if (t) 09430 *t = '\0'; 09431 if (ast_strlen_zero(p->our_contact)) 09432 build_contact(p); 09433 } 09434 /* save the URI part of the From header */ 09435 ast_string_field_set(p, from, of); 09436 if (strncasecmp(of, "sip:", 4)) { 09437 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09438 } else 09439 of += 4; 09440 /* Get just the username part */ 09441 if ((c = strchr(of, '@'))) { 09442 char *tmp; 09443 *c = '\0'; 09444 if ((c = strchr(of, ':'))) 09445 *c = '\0'; 09446 tmp = ast_strdupa(of); 09447 /* We need to be able to handle auth-headers looking like 09448 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09449 */ 09450 tmp = strsep(&tmp, ";"); 09451 if (ast_is_shrinkable_phonenumber(tmp)) 09452 ast_shrink_phone_number(tmp); 09453 ast_string_field_set(p, cid_num, tmp); 09454 } 09455 09456 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09457 user = find_user(of, 1); 09458 09459 /* Find user based on user name in the from header */ 09460 if (user && ast_apply_ha(user->ha, sin)) { 09461 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09462 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09463 /* copy channel vars */ 09464 for (v = user->chanvars ; v ; v = v->next) { 09465 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09466 tmpvar->next = p->chanvars; 09467 p->chanvars = tmpvar; 09468 } 09469 } 09470 p->prefs = user->prefs; 09471 /* Set Frame packetization */ 09472 if (p->rtp) { 09473 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09474 p->autoframing = user->autoframing; 09475 } 09476 /* replace callerid if rpid found, and not restricted */ 09477 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09478 char *tmp; 09479 if (*calleridname) 09480 ast_string_field_set(p, cid_name, calleridname); 09481 tmp = ast_strdupa(rpid_num); 09482 if (ast_is_shrinkable_phonenumber(tmp)) 09483 ast_shrink_phone_number(tmp); 09484 ast_string_field_set(p, cid_num, tmp); 09485 } 09486 09487 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09488 09489 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09490 if (sip_cancel_destroy(p)) 09491 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09492 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09493 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09494 /* Copy SIP extensions profile from INVITE */ 09495 if (p->sipoptions) 09496 user->sipoptions = p->sipoptions; 09497 09498 /* If we have a call limit, set flag */ 09499 if (user->call_limit) 09500 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09501 if (!ast_strlen_zero(user->context)) 09502 ast_string_field_set(p, context, user->context); 09503 if (!ast_strlen_zero(user->cid_num)) { 09504 char *tmp = ast_strdupa(user->cid_num); 09505 if (ast_is_shrinkable_phonenumber(tmp)) 09506 ast_shrink_phone_number(tmp); 09507 ast_string_field_set(p, cid_num, tmp); 09508 } 09509 if (!ast_strlen_zero(user->cid_name)) 09510 ast_string_field_set(p, cid_name, user->cid_name); 09511 ast_string_field_set(p, username, user->name); 09512 ast_string_field_set(p, peername, user->name); 09513 ast_string_field_set(p, peersecret, user->secret); 09514 ast_string_field_set(p, peermd5secret, user->md5secret); 09515 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09516 ast_string_field_set(p, accountcode, user->accountcode); 09517 ast_string_field_set(p, language, user->language); 09518 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09519 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09520 p->allowtransfer = user->allowtransfer; 09521 p->amaflags = user->amaflags; 09522 p->callgroup = user->callgroup; 09523 p->pickupgroup = user->pickupgroup; 09524 if (user->callingpres) /* User callingpres setting will override RPID header */ 09525 p->callingpres = user->callingpres; 09526 09527 /* Set default codec settings for this call */ 09528 p->capability = user->capability; /* User codec choice */ 09529 p->jointcapability = user->capability; /* Our codecs */ 09530 if (p->peercapability) /* AND with peer's codecs */ 09531 p->jointcapability &= p->peercapability; 09532 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09533 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09534 p->noncodeccapability |= AST_RTP_DTMF; 09535 else 09536 p->noncodeccapability &= ~AST_RTP_DTMF; 09537 p->jointnoncodeccapability = p->noncodeccapability; 09538 if (p->t38.peercapability) 09539 p->t38.jointcapability &= p->t38.peercapability; 09540 p->maxcallbitrate = user->maxcallbitrate; 09541 /* If we do not support video, remove video from call structure */ 09542 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09543 ast_rtp_destroy(p->vrtp); 09544 p->vrtp = NULL; 09545 } 09546 } 09547 if (user && debug) 09548 ast_verbose("Found user '%s'\n", user->name); 09549 } else { 09550 if (user) { 09551 if (!authpeer && debug) 09552 ast_verbose("Found user '%s', but fails host access\n", user->name); 09553 ASTOBJ_UNREF(user,sip_destroy_user); 09554 } 09555 user = NULL; 09556 } 09557 09558 if (!user) { 09559 /* If we didn't find a user match, check for peers */ 09560 if (sipmethod == SIP_SUBSCRIBE) 09561 /* For subscribes, match on peer name only */ 09562 peer = find_peer(of, NULL, 1); 09563 else 09564 /* Look for peer based on the IP address we received data from */ 09565 /* If peer is registered from this IP address or have this as a default 09566 IP address, this call is from the peer 09567 */ 09568 peer = find_peer(NULL, &p->recv, 1); 09569 09570 if (peer) { 09571 /* Set Frame packetization */ 09572 if (p->rtp) { 09573 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09574 p->autoframing = peer->autoframing; 09575 } 09576 if (debug) 09577 ast_verbose("Found peer '%s'\n", peer->name); 09578 09579 /* Take the peer */ 09580 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09581 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09582 09583 /* Copy SIP extensions profile to peer */ 09584 if (p->sipoptions) 09585 peer->sipoptions = p->sipoptions; 09586 09587 /* replace callerid if rpid found, and not restricted */ 09588 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09589 char *tmp = ast_strdupa(rpid_num); 09590 if (*calleridname) 09591 ast_string_field_set(p, cid_name, calleridname); 09592 if (ast_is_shrinkable_phonenumber(tmp)) 09593 ast_shrink_phone_number(tmp); 09594 ast_string_field_set(p, cid_num, tmp); 09595 } 09596 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09597 09598 ast_string_field_set(p, peersecret, peer->secret); 09599 ast_string_field_set(p, peermd5secret, peer->md5secret); 09600 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09601 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09602 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09603 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09604 p->callingpres = peer->callingpres; 09605 if (peer->maxms && peer->lastms) 09606 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09607 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09608 /* Pretend there is no required authentication */ 09609 ast_string_field_free(p, peersecret); 09610 ast_string_field_free(p, peermd5secret); 09611 } 09612 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09613 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09614 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09615 /* If we have a call limit, set flag */ 09616 if (peer->call_limit) 09617 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09618 ast_string_field_set(p, peername, peer->name); 09619 ast_string_field_set(p, authname, peer->name); 09620 09621 /* copy channel vars */ 09622 for (v = peer->chanvars ; v ; v = v->next) { 09623 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09624 tmpvar->next = p->chanvars; 09625 p->chanvars = tmpvar; 09626 } 09627 } 09628 if (authpeer) { 09629 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09630 } 09631 09632 if (!ast_strlen_zero(peer->username)) { 09633 ast_string_field_set(p, username, peer->username); 09634 /* Use the default username for authentication on outbound calls */ 09635 /* XXX this takes the name from the caller... can we override ? */ 09636 ast_string_field_set(p, authname, peer->username); 09637 } 09638 if (!ast_strlen_zero(peer->cid_num)) { 09639 char *tmp = ast_strdupa(peer->cid_num); 09640 if (ast_is_shrinkable_phonenumber(tmp)) 09641 ast_shrink_phone_number(tmp); 09642 ast_string_field_set(p, cid_num, tmp); 09643 } 09644 if (!ast_strlen_zero(peer->cid_name)) 09645 ast_string_field_set(p, cid_name, peer->cid_name); 09646 ast_string_field_set(p, fullcontact, peer->fullcontact); 09647 if (!ast_strlen_zero(peer->context)) 09648 ast_string_field_set(p, context, peer->context); 09649 ast_string_field_set(p, peersecret, peer->secret); 09650 ast_string_field_set(p, peermd5secret, peer->md5secret); 09651 ast_string_field_set(p, language, peer->language); 09652 ast_string_field_set(p, accountcode, peer->accountcode); 09653 p->amaflags = peer->amaflags; 09654 p->callgroup = peer->callgroup; 09655 p->pickupgroup = peer->pickupgroup; 09656 p->capability = peer->capability; 09657 p->prefs = peer->prefs; 09658 p->jointcapability = peer->capability; 09659 if (p->peercapability) 09660 p->jointcapability &= p->peercapability; 09661 p->maxcallbitrate = peer->maxcallbitrate; 09662 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09663 ast_rtp_destroy(p->vrtp); 09664 p->vrtp = NULL; 09665 } 09666 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09667 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09668 p->noncodeccapability |= AST_RTP_DTMF; 09669 else 09670 p->noncodeccapability &= ~AST_RTP_DTMF; 09671 p->jointnoncodeccapability = p->noncodeccapability; 09672 if (p->t38.peercapability) 09673 p->t38.jointcapability &= p->t38.peercapability; 09674 } 09675 ASTOBJ_UNREF(peer, sip_destroy_peer); 09676 } else { 09677 if (debug) 09678 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09679 09680 /* do we allow guests? */ 09681 if (!global_allowguest) { 09682 if (global_alwaysauthreject) 09683 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09684 else 09685 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09686 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09687 char *tmp = ast_strdupa(rpid_num); 09688 if (*calleridname) 09689 ast_string_field_set(p, cid_name, calleridname); 09690 if (ast_is_shrinkable_phonenumber(tmp)) 09691 ast_shrink_phone_number(tmp); 09692 ast_string_field_set(p, cid_num, tmp); 09693 } 09694 } 09695 09696 } 09697 09698 if (user) 09699 ASTOBJ_UNREF(user, sip_destroy_user); 09700 return res; 09701 }
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 9254 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, 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().
09255 { 09256 char via[512]; 09257 char *c, *pt; 09258 struct hostent *hp; 09259 struct ast_hostent ahp; 09260 09261 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09262 09263 /* Work on the leftmost value of the topmost Via header */ 09264 c = strchr(via, ','); 09265 if (c) 09266 *c = '\0'; 09267 09268 /* Check for rport */ 09269 c = strstr(via, ";rport"); 09270 if (c && (c[6] != '=')) /* rport query, not answer */ 09271 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09272 09273 c = strchr(via, ';'); 09274 if (c) 09275 *c = '\0'; 09276 09277 c = strchr(via, ' '); 09278 if (c) { 09279 *c = '\0'; 09280 c = ast_skip_blanks(c+1); 09281 if (strcasecmp(via, "SIP/2.0/UDP")) { 09282 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09283 return; 09284 } 09285 pt = strchr(c, ':'); 09286 if (pt) 09287 *pt++ = '\0'; /* remember port pointer */ 09288 hp = ast_gethostbyname(c, &ahp); 09289 if (!hp) { 09290 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09291 return; 09292 } 09293 memset(&p->sa, 0, sizeof(p->sa)); 09294 p->sa.sin_family = AF_INET; 09295 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09296 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09297 09298 if (sip_debug_test_pvt(p)) { 09299 const struct sockaddr_in *dst = sip_real_dst(p); 09300 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09301 } 09302 } 09303 }
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 10150 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
10151 { 10152 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10153 10154 while ((oldcontext = strsep(&old, "&"))) { 10155 stalecontext = '\0'; 10156 ast_copy_string(newlist, new, sizeof(newlist)); 10157 stringp = newlist; 10158 while ((newcontext = strsep(&stringp, "&"))) { 10159 if (strcmp(newcontext, oldcontext) == 0) { 10160 /* This is not the context you're looking for */ 10161 stalecontext = '\0'; 10162 break; 10163 } else if (strcmp(newcontext, oldcontext)) { 10164 stalecontext = oldcontext; 10165 } 10166 10167 } 10168 if (stalecontext) 10169 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10170 } 10171 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16432 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16433 { 16434 struct sip_auth *a = authlist; 16435 struct sip_auth *b; 16436 16437 while (a) { 16438 b = a; 16439 a = a->next; 16440 free(b); 16441 } 16442 16443 return 1; 16444 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16361 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().
16362 { 16363 struct domain *d; 16364 16365 AST_LIST_LOCK(&domain_list); 16366 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16367 free(d); 16368 AST_LIST_UNLOCK(&domain_list); 16369 }
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 10962 of file chan_sip.c.
References complete_sip_peer().
10963 { 10964 if (pos == 3) 10965 return complete_sip_peer(word, state, 0); 10966 10967 return NULL; 10968 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10936 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().
10937 { 10938 char *result = NULL; 10939 int wordlen = strlen(word); 10940 int which = 0; 10941 10942 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10943 /* locking of the object is not required because only the name and flags are being compared */ 10944 if (!strncasecmp(word, iterator->name, wordlen) && 10945 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10946 ++which > state) 10947 result = ast_strdup(iterator->name); 10948 } while(0) ); 10949 return result; 10950 }
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 11030 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11031 { 11032 if (pos == 4) 11033 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11034 return NULL; 11035 }
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 11038 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11039 { 11040 if (pos == 4) 11041 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11042 11043 return NULL; 11044 }
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 10953 of file chan_sip.c.
References complete_sip_peer().
10954 { 10955 if (pos == 3) 10956 return complete_sip_peer(word, state, 0); 10957 10958 return NULL; 10959 }
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 10991 of file chan_sip.c.
References complete_sip_user().
10992 { 10993 if (pos == 3) 10994 return complete_sip_user(word, state, 0); 10995 10996 return NULL; 10997 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10971 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().
10972 { 10973 char *result = NULL; 10974 int wordlen = strlen(word); 10975 int which = 0; 10976 10977 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10978 /* locking of the object is not required because only the name and flags are being compared */ 10979 if (!strncasecmp(word, iterator->name, wordlen)) { 10980 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10981 continue; 10982 if (++which > state) { 10983 result = ast_strdup(iterator->name); 10984 } 10985 } 10986 } while(0) ); 10987 return result; 10988 }
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 10913 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10914 { 10915 int which=0; 10916 struct sip_pvt *cur; 10917 char *c = NULL; 10918 int wordlen = strlen(word); 10919 10920 if (pos != 3) { 10921 return NULL; 10922 } 10923 10924 ast_mutex_lock(&iflock); 10925 for (cur = iflist; cur; cur = cur->next) { 10926 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10927 c = ast_strdup(cur->callid); 10928 break; 10929 } 10930 } 10931 ast_mutex_unlock(&iflock); 10932 return c; 10933 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11000 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11001 { 11002 char *c = NULL; 11003 11004 if (pos == 2) { 11005 int which = 0; 11006 char *cat = NULL; 11007 int wordlen = strlen(word); 11008 11009 /* do completion for notify type */ 11010 11011 if (!notify_types) 11012 return NULL; 11013 11014 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11015 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11016 c = ast_strdup(cat); 11017 break; 11018 } 11019 } 11020 return c; 11021 } 11022 11023 if (pos > 2) 11024 return complete_sip_peer(word, state, 0); 11025 11026 return NULL; 11027 }
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 5677 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05678 { 05679 int start = 0; 05680 int copied = 0; 05681 for (;;) { 05682 const char *tmp = __get_header(orig, field, &start); 05683 05684 if (ast_strlen_zero(tmp)) 05685 break; 05686 /* Add what we're responding to */ 05687 add_header(req, field, tmp); 05688 copied++; 05689 } 05690 return copied ? 0 : -1; 05691 }
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 5666 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05667 { 05668 const char *tmp = get_header(orig, field); 05669 05670 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05671 return add_header(req, field, tmp); 05672 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05673 return -1; 05674 }
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 6720 of file chan_sip.c.
References offset.
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().
06721 { 06722 long offset; 06723 int x; 06724 offset = ((void *)dst) - ((void *)src); 06725 /* First copy stuff */ 06726 memcpy(dst, src, sizeof(*dst)); 06727 /* Now fix pointer arithmetic */ 06728 for (x=0; x < src->headers; x++) 06729 dst->header[x] += offset; 06730 for (x=0; x < src->lines; x++) 06731 dst->line[x] += offset; 06732 dst->rlPart1 += offset; 06733 dst->rlPart2 += offset; 06734 }
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 5699 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().
05700 { 05701 int copied = 0; 05702 int start = 0; 05703 05704 for (;;) { 05705 char new[512]; 05706 const char *oh = __get_header(orig, field, &start); 05707 05708 if (ast_strlen_zero(oh)) 05709 break; 05710 05711 if (!copied) { /* Only check for empty rport in topmost via header */ 05712 char leftmost[512], *others, *rport; 05713 05714 /* Only work on leftmost value */ 05715 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05716 others = strchr(leftmost, ','); 05717 if (others) 05718 *others++ = '\0'; 05719 05720 /* Find ;rport; (empty request) */ 05721 rport = strstr(leftmost, ";rport"); 05722 if (rport && *(rport+6) == '=') 05723 rport = NULL; /* We already have a parameter to rport */ 05724 05725 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05726 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05727 /* We need to add received port - rport */ 05728 char *end; 05729 05730 rport = strstr(leftmost, ";rport"); 05731 05732 if (rport) { 05733 end = strchr(rport + 1, ';'); 05734 if (end) 05735 memmove(rport, end, strlen(end) + 1); 05736 else 05737 *rport = '\0'; 05738 } 05739 05740 /* Add rport to first VIA header if requested */ 05741 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05742 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05743 ntohs(p->recv.sin_port), 05744 others ? "," : "", others ? others : ""); 05745 } else { 05746 /* We should *always* add a received to the topmost via */ 05747 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05748 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05749 others ? "," : "", others ? others : ""); 05750 } 05751 oh = new; /* the header to copy */ 05752 } /* else add the following via headers untouched */ 05753 add_header(req, field, oh); 05754 copied++; 05755 } 05756 if (!copied) { 05757 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05758 return -1; 05759 } 05760 return 0; 05761 }
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 ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, 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, 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 7900 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07901 { 07902 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07903 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07904 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07905 else 07906 ast_db_del("SIP/Registry", peer->name); 07907 } 07908 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6764 of file chan_sip.c.
References ast_log(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06765 { 06766 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06767 06768 if (!*e) 06769 return -1; 06770 req->rlPart1 = e; /* method or protocol */ 06771 e = ast_skip_nonblanks(e); 06772 if (*e) 06773 *e++ = '\0'; 06774 /* Get URI or status code */ 06775 e = ast_skip_blanks(e); 06776 if ( !*e ) 06777 return -1; 06778 ast_trim_blanks(e); 06779 06780 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06781 if (strlen(e) < 3) /* status code is 3 digits */ 06782 return -1; 06783 req->rlPart2 = e; 06784 } else { /* We have a request */ 06785 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06786 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06787 e++; 06788 if (!*e) 06789 return -1; 06790 } 06791 req->rlPart2 = e; /* URI */ 06792 e = ast_skip_nonblanks(e); 06793 if (*e) 06794 *e++ = '\0'; 06795 e = ast_skip_blanks(e); 06796 if (strcasecmp(e, "SIP/2.0") ) { 06797 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06798 return -1; 06799 } 06800 } 06801 return 1; 06802 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15650 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_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_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
15651 { 15652 int res; 15653 struct sip_pvt *sip; 15654 struct sip_peer *peer = NULL; 15655 time_t t; 15656 int fastrestart = FALSE; 15657 int lastpeernum = -1; 15658 int curpeernum; 15659 int reloading; 15660 15661 /* Add an I/O event to our SIP UDP socket */ 15662 if (sipsock > -1) 15663 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15664 15665 /* From here on out, we die whenever asked */ 15666 for(;;) { 15667 /* Check for a reload request */ 15668 ast_mutex_lock(&sip_reload_lock); 15669 reloading = sip_reloading; 15670 sip_reloading = FALSE; 15671 ast_mutex_unlock(&sip_reload_lock); 15672 if (reloading) { 15673 if (option_verbose > 0) 15674 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15675 sip_do_reload(sip_reloadreason); 15676 15677 /* Change the I/O fd of our UDP socket */ 15678 if (sipsock > -1) { 15679 if (sipsock_read_id) 15680 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15681 else 15682 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15683 } else if (sipsock_read_id) { 15684 ast_io_remove(io, sipsock_read_id); 15685 sipsock_read_id = NULL; 15686 } 15687 } 15688 restartsearch: 15689 /* Check for interfaces needing to be killed */ 15690 ast_mutex_lock(&iflock); 15691 t = time(NULL); 15692 /* don't scan the interface list if it hasn't been a reasonable period 15693 of time since the last time we did it (when MWI is being sent, we can 15694 get back to this point every millisecond or less) 15695 */ 15696 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15697 /*! \note If we can't get a lock on an interface, skip it and come 15698 * back later. Note that there is the possibility of a deadlock with 15699 * sip_hangup otherwise, because sip_hangup is called with the channel 15700 * locked first, and the iface lock is attempted second. 15701 */ 15702 if (ast_mutex_trylock(&sip->lock)) 15703 continue; 15704 15705 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15706 if (sip->rtp && sip->owner && 15707 (sip->owner->_state == AST_STATE_UP) && 15708 !sip->redirip.sin_addr.s_addr && 15709 sip->t38.state != T38_ENABLED) { 15710 if (sip->lastrtptx && 15711 ast_rtp_get_rtpkeepalive(sip->rtp) && 15712 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15713 /* Need to send an empty RTP packet */ 15714 sip->lastrtptx = time(NULL); 15715 ast_rtp_sendcng(sip->rtp, 0); 15716 } 15717 if (sip->lastrtprx && 15718 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15719 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15720 /* Might be a timeout now -- see if we're on hold */ 15721 struct sockaddr_in sin; 15722 ast_rtp_get_peer(sip->rtp, &sin); 15723 if (sin.sin_addr.s_addr || 15724 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15725 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15726 /* Needs a hangup */ 15727 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15728 while (sip->owner && ast_channel_trylock(sip->owner)) { 15729 DEADLOCK_AVOIDANCE(&sip->lock); 15730 } 15731 if (sip->owner) { 15732 ast_log(LOG_NOTICE, 15733 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15734 sip->owner->name, 15735 (long) (t - sip->lastrtprx)); 15736 /* Issue a softhangup */ 15737 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15738 ast_channel_unlock(sip->owner); 15739 /* forget the timeouts for this call, since a hangup 15740 has already been requested and we don't want to 15741 repeatedly request hangups 15742 */ 15743 ast_rtp_set_rtptimeout(sip->rtp, 0); 15744 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15745 if (sip->vrtp) { 15746 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15747 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15748 } 15749 } 15750 } 15751 } 15752 } 15753 } 15754 /* If we have sessions that needs to be destroyed, do it now */ 15755 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15756 !sip->owner) { 15757 ast_mutex_unlock(&sip->lock); 15758 __sip_destroy(sip, 1); 15759 ast_mutex_unlock(&iflock); 15760 usleep(1); 15761 goto restartsearch; 15762 } 15763 ast_mutex_unlock(&sip->lock); 15764 } 15765 ast_mutex_unlock(&iflock); 15766 15767 pthread_testcancel(); 15768 /* Wait for sched or io */ 15769 res = ast_sched_wait(sched); 15770 if ((res < 0) || (res > 1000)) 15771 res = 1000; 15772 /* If we might need to send more mailboxes, don't wait long at all.*/ 15773 if (fastrestart) 15774 res = 1; 15775 res = ast_io_wait(io, res); 15776 if (option_debug && res > 20) 15777 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15778 ast_mutex_lock(&monlock); 15779 if (res >= 0) { 15780 res = ast_sched_runq(sched); 15781 if (option_debug && res >= 20) 15782 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15783 } 15784 15785 /* Send MWI notifications to peers - static and cached realtime peers */ 15786 t = time(NULL); 15787 fastrestart = FALSE; 15788 curpeernum = 0; 15789 peer = NULL; 15790 /* Find next peer that needs mwi */ 15791 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15792 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15793 fastrestart = TRUE; 15794 lastpeernum = curpeernum; 15795 peer = ASTOBJ_REF(iterator); 15796 }; 15797 curpeernum++; 15798 } while (0) 15799 ); 15800 /* Send MWI to the peer */ 15801 if (peer) { 15802 ASTOBJ_WRLOCK(peer); 15803 sip_send_mwi_to_peer(peer); 15804 ASTOBJ_UNLOCK(peer); 15805 ASTOBJ_UNREF(peer,sip_destroy_peer); 15806 } else { 15807 /* Reset where we come from */ 15808 lastpeernum = -1; 15809 } 15810 ast_mutex_unlock(&monlock); 15811 } 15812 /* Never reached */ 15813 return NULL; 15814 15815 }
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 11503 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().
11504 { 11505 char digest[1024]; 11506 11507 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11508 return -2; 11509 11510 p->authtries++; 11511 if (option_debug > 1) 11512 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11513 memset(digest, 0, sizeof(digest)); 11514 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11515 /* No way to authenticate */ 11516 return -1; 11517 } 11518 /* Now we have a reply digest */ 11519 p->options->auth = digest; 11520 p->options->authheader = respheader; 11521 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11522 }
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 11482 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
11483 { 11484 char digest[1024]; 11485 p->authtries++; 11486 memset(digest,0,sizeof(digest)); 11487 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11488 /* There's nothing to use for authentication */ 11489 /* No digest challenge in request */ 11490 if (sip_debug_test_pvt(p) && p->registry) 11491 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11492 /* No old challenge */ 11493 return -1; 11494 } 11495 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11496 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11497 if (sip_debug_test_pvt(p) && p->registry) 11498 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11499 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11500 }
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, 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 15629 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.
15630 { 15631 time_t t = time(NULL); 15632 15633 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15634 !peer->mwipvt) { /* We don't have a subscription */ 15635 peer->lastmsgcheck = t; /* Reset timer */ 15636 return FALSE; 15637 } 15638 15639 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15640 return TRUE; 15641 15642 return FALSE; 15643 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10339 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10340 { 10341 switch (mode) { 10342 case SIP_DOMAIN_AUTO: 10343 return "[Automatic]"; 10344 case SIP_DOMAIN_CONFIG: 10345 return "[Configured]"; 10346 } 10347 10348 return ""; 10349 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10119 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().
10120 { 10121 switch (mode) { 10122 case SIP_DTMF_RFC2833: 10123 return "rfc2833"; 10124 case SIP_DTMF_INFO: 10125 return "info"; 10126 case SIP_DTMF_INBAND: 10127 return "inband"; 10128 case SIP_DTMF_AUTO: 10129 return "auto"; 10130 } 10131 return "<error>"; 10132 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7911 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(), and reg_source_db().
07912 { 07913 struct sip_peer *peer = (struct sip_peer *)data; 07914 07915 if (!peer) /* Hmmm. We have no peer. Weird. */ 07916 return 0; 07917 07918 memset(&peer->addr, 0, sizeof(peer->addr)); 07919 07920 destroy_association(peer); /* remove registration data from storage */ 07921 07922 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07923 register_peer_exten(peer, FALSE); /* Remove regexten */ 07924 peer->expire = -1; 07925 ast_device_state_changed("SIP/%s", peer->name); 07926 07927 /* Do we need to release this peer from memory? 07928 Only for realtime peers and autocreated peers 07929 */ 07930 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07931 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07932 struct sip_peer *peer_ptr = peer_ptr; 07933 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 07934 if (peer_ptr) { 07935 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 07936 } 07937 } 07938 07939 ASTOBJ_UNREF(peer, sip_destroy_peer); 07940 07941 return 0; 07942 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6854 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().
06855 { 06856 char stripped[SIPBUFSIZE]; 06857 char *c; 06858 06859 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06860 c = get_in_brackets(stripped); 06861 c = strsep(&c, ";"); /* trim ; and beyond */ 06862 if (!ast_strlen_zero(c)) 06863 ast_string_field_set(p, uri, c); 06864 }
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] |
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_set_flag, ast_strlen_zero(), FALSE, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.
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 04636 04637 if (found) { 04638 /* Found the call */ 04639 ast_mutex_lock(&p->lock); 04640 ast_mutex_unlock(&iflock); 04641 return p; 04642 } 04643 } 04644 ast_mutex_unlock(&iflock); 04645 04646 /* See if the method is capable of creating a dialog */ 04647 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04648 if (intended_method == SIP_REFER) { 04649 /* We do support REFER, but not outside of a dialog yet */ 04650 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04651 } else if (intended_method == SIP_NOTIFY) { 04652 /* We do not support out-of-dialog NOTIFY either, 04653 like voicemail notification, so cancel that early */ 04654 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04655 } else { 04656 /* Ok, time to create a new SIP dialog object, a pvt */ 04657 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04658 /* Ok, we've created a dialog, let's go and process it */ 04659 ast_mutex_lock(&p->lock); 04660 } else { 04661 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04662 getting a dialog from sip_alloc. 04663 04664 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04665 send an error message. 04666 04667 Sorry, we apologize for the inconvienience 04668 */ 04669 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04670 if (option_debug > 3) 04671 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04672 } 04673 } 04674 return p; 04675 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04676 /* A method we do not support, let's take it on the volley */ 04677 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04678 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04679 /* This is a request outside of a dialog that we don't know about 04680 ...never reply to an ACK! 04681 */ 04682 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04683 } 04684 /* We do not respond to responses for dialogs that we don't know about, we just drop 04685 the session quickly */ 04686 04687 return p; 04688 }
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] |
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] |
Find authentication for a specific realm.
Definition at line 16447 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16448 { 16449 struct sip_auth *a; 16450 16451 for (a = authlist; a; a = a->next) { 16452 if (!strcasecmp(a->realm, realm)) 16453 break; 16454 } 16455 16456 return a; 16457 }
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 4894 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
04895 { 04896 const char *content_type; 04897 const char *content_length; 04898 const char *search; 04899 char *boundary; 04900 unsigned int x; 04901 int boundaryisquoted = FALSE; 04902 int found_application_sdp = FALSE; 04903 int found_end_of_headers = FALSE; 04904 04905 content_length = get_header(req, "Content-Length"); 04906 04907 if (!ast_strlen_zero(content_length)) { 04908 if (sscanf(content_length, "%ud", &x) != 1) { 04909 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04910 return 0; 04911 } 04912 04913 /* Content-Length of zero means there can't possibly be an 04914 SDP here, even if the Content-Type says there is */ 04915 if (x == 0) 04916 return 0; 04917 } 04918 04919 content_type = get_header(req, "Content-Type"); 04920 04921 /* if the body contains only SDP, this is easy */ 04922 if (!strcasecmp(content_type, "application/sdp")) { 04923 req->sdp_start = 0; 04924 req->sdp_end = req->lines; 04925 return req->lines ? 1 : 0; 04926 } 04927 04928 /* if it's not multipart/mixed, there cannot be an SDP */ 04929 if (strncasecmp(content_type, "multipart/mixed", 15)) 04930 return 0; 04931 04932 /* if there is no boundary marker, it's invalid */ 04933 if ((search = strcasestr(content_type, ";boundary="))) 04934 search += 10; 04935 else if ((search = strcasestr(content_type, "; boundary="))) 04936 search += 11; 04937 else 04938 return 0; 04939 04940 if (ast_strlen_zero(search)) 04941 return 0; 04942 04943 /* If the boundary is quoted with ", remove quote */ 04944 if (*search == '\"') { 04945 search++; 04946 boundaryisquoted = TRUE; 04947 } 04948 04949 /* make a duplicate of the string, with two extra characters 04950 at the beginning */ 04951 boundary = ast_strdupa(search - 2); 04952 boundary[0] = boundary[1] = '-'; 04953 /* Remove final quote */ 04954 if (boundaryisquoted) 04955 boundary[strlen(boundary) - 1] = '\0'; 04956 04957 /* search for the boundary marker, the empty line delimiting headers from 04958 sdp part and the end boundry if it exists */ 04959 04960 for (x = 0; x < (req->lines ); x++) { 04961 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04962 if(found_application_sdp && found_end_of_headers){ 04963 req->sdp_end = x-1; 04964 return 1; 04965 } 04966 found_application_sdp = FALSE; 04967 } 04968 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04969 found_application_sdp = TRUE; 04970 04971 if(strlen(req->line[x]) == 0 ){ 04972 if(found_application_sdp && !found_end_of_headers){ 04973 req->sdp_start = x; 04974 found_end_of_headers = TRUE; 04975 } 04976 } 04977 } 04978 if(found_application_sdp && found_end_of_headers) { 04979 req->sdp_end = x; 04980 return TRUE; 04981 } 04982 return FALSE; 04983 }
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] |
Find subscription type in array.
Definition at line 10827 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10828 { 10829 int i; 10830 10831 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10832 if (subscription_types[i].type == subtype) { 10833 return &subscription_types[i]; 10834 } 10835 } 10836 return &subscription_types[0]; 10837 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
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 8271 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08272 { 08273 struct sip_route *next; 08274 08275 while (route) { 08276 next = route->next; 08277 free(route); 08278 route = next; 08279 } 08280 }
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 11836 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), and check_sip_domain().
11837 { 11838 if (ast_strlen_zero(data)) { 11839 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11840 return -1; 11841 } 11842 if (check_sip_domain(data, NULL, 0)) 11843 ast_copy_string(buf, data, len); 11844 else 11845 buf[0] = '\0'; 11846 return 0; 11847 }
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 11772 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, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11773 { 11774 struct sip_pvt *p; 11775 const char *content = NULL; 11776 AST_DECLARE_APP_ARGS(args, 11777 AST_APP_ARG(header); 11778 AST_APP_ARG(number); 11779 ); 11780 int i, number, start = 0; 11781 11782 if (ast_strlen_zero(data)) { 11783 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11784 return -1; 11785 } 11786 11787 ast_channel_lock(chan); 11788 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11789 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11790 ast_channel_unlock(chan); 11791 return -1; 11792 } 11793 11794 AST_STANDARD_APP_ARGS(args, data); 11795 if (!args.number) { 11796 number = 1; 11797 } else { 11798 sscanf(args.number, "%d", &number); 11799 if (number < 1) 11800 number = 1; 11801 } 11802 11803 p = chan->tech_pvt; 11804 11805 /* If there is no private structure, this channel is no longer alive */ 11806 if (!p) { 11807 ast_channel_unlock(chan); 11808 return -1; 11809 } 11810 11811 for (i = 0; i < number; i++) 11812 content = __get_header(&p->initreq, args.header, &start); 11813 11814 if (ast_strlen_zero(content)) { 11815 ast_channel_unlock(chan); 11816 return -1; 11817 } 11818 11819 ast_copy_string(buf, content, len); 11820 ast_channel_unlock(chan); 11821 11822 return 0; 11823 }
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 11951 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), 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.
11952 { 11953 struct sip_pvt *p; 11954 11955 *buf = 0; 11956 11957 if (!data) { 11958 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11959 return -1; 11960 } 11961 11962 ast_channel_lock(chan); 11963 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11964 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11965 ast_channel_unlock(chan); 11966 return -1; 11967 } 11968 11969 p = chan->tech_pvt; 11970 11971 /* If there is no private structure, this channel is no longer alive */ 11972 if (!p) { 11973 ast_channel_unlock(chan); 11974 return -1; 11975 } 11976 11977 if (!strcasecmp(data, "peerip")) { 11978 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11979 } else if (!strcasecmp(data, "recvip")) { 11980 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11981 } else if (!strcasecmp(data, "from")) { 11982 ast_copy_string(buf, p->from, len); 11983 } else if (!strcasecmp(data, "uri")) { 11984 ast_copy_string(buf, p->uri, len); 11985 } else if (!strcasecmp(data, "useragent")) { 11986 ast_copy_string(buf, p->useragent, len); 11987 } else if (!strcasecmp(data, "peername")) { 11988 ast_copy_string(buf, p->peername, len); 11989 } else if (!strcasecmp(data, "t38passthrough")) { 11990 if (p->t38.state == T38_DISABLED) 11991 ast_copy_string(buf, "0", sizeof("0")); 11992 else /* T38 is offered or enabled in this call */ 11993 ast_copy_string(buf, "1", sizeof("1")); 11994 } else { 11995 ast_channel_unlock(chan); 11996 return -1; 11997 } 11998 ast_channel_unlock(chan); 11999 12000 return 0; 12001 }
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 11861 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.
11862 { 11863 struct sip_peer *peer; 11864 char *colname; 11865 11866 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11867 *colname++ = '\0'; 11868 else if ((colname = strchr(data, '|'))) 11869 *colname++ = '\0'; 11870 else 11871 colname = "ip"; 11872 11873 if (!(peer = find_peer(data, NULL, 1))) 11874 return -1; 11875 11876 if (!strcasecmp(colname, "ip")) { 11877 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11878 } else if (!strcasecmp(colname, "status")) { 11879 peer_status(peer, buf, len); 11880 } else if (!strcasecmp(colname, "language")) { 11881 ast_copy_string(buf, peer->language, len); 11882 } else if (!strcasecmp(colname, "regexten")) { 11883 ast_copy_string(buf, peer->regexten, len); 11884 } else if (!strcasecmp(colname, "limit")) { 11885 snprintf(buf, len, "%d", peer->call_limit); 11886 } else if (!strcasecmp(colname, "curcalls")) { 11887 snprintf(buf, len, "%d", peer->inUse); 11888 } else if (!strcasecmp(colname, "accountcode")) { 11889 ast_copy_string(buf, peer->accountcode, len); 11890 } else if (!strcasecmp(colname, "useragent")) { 11891 ast_copy_string(buf, peer->useragent, len); 11892 } else if (!strcasecmp(colname, "mailbox")) { 11893 ast_copy_string(buf, peer->mailbox, len); 11894 } else if (!strcasecmp(colname, "context")) { 11895 ast_copy_string(buf, peer->context, len); 11896 } else if (!strcasecmp(colname, "expire")) { 11897 snprintf(buf, len, "%d", peer->expire); 11898 } else if (!strcasecmp(colname, "dynamic")) { 11899 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11900 } else if (!strcasecmp(colname, "callerid_name")) { 11901 ast_copy_string(buf, peer->cid_name, len); 11902 } else if (!strcasecmp(colname, "callerid_num")) { 11903 ast_copy_string(buf, peer->cid_num, len); 11904 } else if (!strcasecmp(colname, "codecs")) { 11905 ast_getformatname_multiple(buf, len -1, peer->capability); 11906 } else if (!strncasecmp(colname, "codec[", 6)) { 11907 char *codecnum; 11908 int index = 0, codec = 0; 11909 11910 codecnum = colname + 6; /* move past the '[' */ 11911 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11912 index = atoi(codecnum); 11913 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11914 ast_copy_string(buf, ast_getformatname(codec), len); 11915 } 11916 } 11917 11918 ASTOBJ_UNREF(peer, sip_destroy_peer); 11919 11920 return 0; 11921 }
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 9194 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(), context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, 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().
09195 { 09196 char tmp[256] = "", *c, *a; 09197 struct sip_request *req = oreq ? oreq : &p->initreq; 09198 struct sip_refer *referdata = NULL; 09199 const char *transfer_context = NULL; 09200 09201 if (!p->refer && !sip_refer_allocate(p)) 09202 return -1; 09203 09204 referdata = p->refer; 09205 09206 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09207 c = get_in_brackets(tmp); 09208 09209 if (pedanticsipchecking) 09210 ast_uri_decode(c); 09211 09212 if (strncasecmp(c, "sip:", 4)) { 09213 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09214 return -1; 09215 } 09216 c += 4; 09217 if ((a = strchr(c, ';'))) /* Remove arguments */ 09218 *a = '\0'; 09219 09220 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09221 *a++ = '\0'; 09222 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09223 } 09224 09225 if (sip_debug_test_pvt(p)) 09226 ast_verbose("Looking for %s in %s\n", c, p->context); 09227 09228 if (p->owner) /* Mimic behaviour in res_features.c */ 09229 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09230 09231 /* By default, use the context in the channel sending the REFER */ 09232 if (ast_strlen_zero(transfer_context)) { 09233 transfer_context = S_OR(p->owner->macrocontext, 09234 S_OR(p->context, default_context)); 09235 } 09236 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09237 /* This is a blind transfer */ 09238 if (option_debug) 09239 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09240 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09241 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09242 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09243 referdata->refer_call = NULL; 09244 /* Set new context */ 09245 ast_string_field_set(p, context, transfer_context); 09246 return 0; 09247 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09248 return 1; 09249 } 09250 09251 return -1; 09252 }
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 9306 of file chan_sip.c.
Referenced by check_user_full().
09307 { 09308 const char *end = strchr(input,'<'); /* first_bracket */ 09309 const char *tmp = strchr(input,'"'); /* first quote */ 09310 int bytes = 0; 09311 int maxbytes = outputsize - 1; 09312 09313 if (!end || end == input) /* we require a part in brackets */ 09314 return NULL; 09315 09316 end--; /* move just before "<" */ 09317 09318 if (tmp && tmp <= end) { 09319 /* The quote (tmp) precedes the bracket (end+1). 09320 * Find the matching quote and return the content. 09321 */ 09322 end = strchr(tmp+1, '"'); 09323 if (!end) 09324 return NULL; 09325 bytes = (int) (end - tmp); 09326 /* protect the output buffer */ 09327 if (bytes > maxbytes) 09328 bytes = maxbytes; 09329 ast_copy_string(output, tmp + 1, bytes); 09330 } else { 09331 /* No quoted string, or it is inside brackets. */ 09332 /* clear the empty characters in the begining*/ 09333 input = ast_skip_blanks(input); 09334 /* clear the empty characters in the end */ 09335 while(*end && *end < 33 && end > input) 09336 end--; 09337 if (end >= input) { 09338 bytes = (int) (end - input) + 2; 09339 /* protect the output buffer */ 09340 if (bytes > maxbytes) 09341 bytes = maxbytes; 09342 ast_copy_string(output, input, bytes); 09343 } else 09344 return NULL; 09345 } 09346 return output; 09347 }
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 8851 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(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, 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().
08852 { 08853 char tmp[256] = "", *uri, *a; 08854 char tmpf[256] = "", *from; 08855 struct sip_request *req; 08856 char *colon; 08857 08858 req = oreq; 08859 if (!req) 08860 req = &p->initreq; 08861 08862 /* Find the request URI */ 08863 if (req->rlPart2) 08864 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08865 08866 if (pedanticsipchecking) 08867 ast_uri_decode(tmp); 08868 08869 uri = get_in_brackets(tmp); 08870 08871 if (strncasecmp(uri, "sip:", 4)) { 08872 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08873 return -1; 08874 } 08875 uri += 4; 08876 08877 /* Now find the From: caller ID and name */ 08878 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08879 if (!ast_strlen_zero(tmpf)) { 08880 if (pedanticsipchecking) 08881 ast_uri_decode(tmpf); 08882 from = get_in_brackets(tmpf); 08883 } else { 08884 from = NULL; 08885 } 08886 08887 if (!ast_strlen_zero(from)) { 08888 if (strncasecmp(from, "sip:", 4)) { 08889 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08890 return -1; 08891 } 08892 from += 4; 08893 if ((a = strchr(from, '@'))) 08894 *a++ = '\0'; 08895 else 08896 a = from; /* just a domain */ 08897 from = strsep(&from, ";"); /* Remove userinfo options */ 08898 a = strsep(&a, ";"); /* Remove URI options */ 08899 ast_string_field_set(p, fromdomain, a); 08900 } 08901 08902 /* Skip any options and find the domain */ 08903 08904 /* Get the target domain */ 08905 if ((a = strchr(uri, '@'))) { 08906 *a++ = '\0'; 08907 } else { /* No username part */ 08908 a = uri; 08909 uri = "s"; /* Set extension to "s" */ 08910 } 08911 colon = strchr(a, ':'); /* Remove :port */ 08912 if (colon) 08913 *colon = '\0'; 08914 08915 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08916 a = strsep(&a, ";"); /* Remove URI options */ 08917 08918 ast_string_field_set(p, domain, a); 08919 08920 if (!AST_LIST_EMPTY(&domain_list)) { 08921 char domain_context[AST_MAX_EXTENSION]; 08922 08923 domain_context[0] = '\0'; 08924 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08925 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08926 if (option_debug) 08927 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08928 return -2; 08929 } 08930 } 08931 /* If we have a context defined, overwrite the original context */ 08932 if (!ast_strlen_zero(domain_context)) 08933 ast_string_field_set(p, context, domain_context); 08934 } 08935 08936 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 08937 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 08938 ast_string_field_set(p, context, p->subscribecontext); 08939 08940 if (sip_debug_test_pvt(p)) 08941 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08942 08943 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 08944 if (req->method == SIP_SUBSCRIBE) { 08945 char hint[AST_MAX_EXTENSION]; 08946 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 08947 } else { 08948 /* Check the dialplan for the username part of the request URI, 08949 the domain will be stored in the SIPDOMAIN variable 08950 Since extensions.conf can have unescaped characters, try matching a decoded 08951 uri in addition to the non-decoded uri 08952 Return 0 if we have a matching extension */ 08953 char *decoded_uri = ast_strdupa(uri); 08954 ast_uri_decode(decoded_uri); 08955 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)) || 08956 !strcmp(uri, ast_pickup_ext())) { 08957 if (!oreq) 08958 ast_string_field_set(p, exten, uri); 08959 return 0; 08960 } 08961 } 08962 08963 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08964 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08965 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 08966 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08967 return 1; 08968 } 08969 08970 return -1; 08971 }
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 9712 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09713 { 09714 int x; 09715 int y; 09716 09717 buf[0] = '\0'; 09718 y = len - strlen(buf) - 5; 09719 if (y < 0) 09720 y = 0; 09721 for (x=0;x<req->lines;x++) { 09722 strncat(buf, req->line[x], y); /* safe */ 09723 y -= strlen(req->line[x]) + 1; 09724 if (y < 0) 09725 y = 0; 09726 if (y != 0) 09727 strcat(buf, "\n"); /* safe */ 09728 } 09729 return 0; 09730 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8822 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, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08823 { 08824 char tmp[256], *c, *a; 08825 struct sip_request *req; 08826 08827 req = oreq; 08828 if (!req) 08829 req = &p->initreq; 08830 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08831 if (ast_strlen_zero(tmp)) 08832 return 0; 08833 c = get_in_brackets(tmp); 08834 if (strncasecmp(c, "sip:", 4)) { 08835 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08836 return -1; 08837 } 08838 c += 4; 08839 a = c; 08840 strsep(&a, "@;"); /* trim anything after @ or ; */ 08841 if (sip_debug_test_pvt(p)) 08842 ast_verbose("RDNIS is %s\n", c); 08843 ast_string_field_set(p, rdnis, c); 08844 08845 return 0; 08846 }
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 9028 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, 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().
09029 { 09030 09031 const char *p_referred_by = NULL; 09032 char *h_refer_to = NULL; 09033 char *h_referred_by = NULL; 09034 char *refer_to; 09035 const char *p_refer_to; 09036 char *referred_by_uri = NULL; 09037 char *ptr; 09038 struct sip_request *req = NULL; 09039 const char *transfer_context = NULL; 09040 struct sip_refer *referdata; 09041 09042 09043 req = outgoing_req; 09044 referdata = transferer->refer; 09045 09046 if (!req) 09047 req = &transferer->initreq; 09048 09049 p_refer_to = get_header(req, "Refer-To"); 09050 if (ast_strlen_zero(p_refer_to)) { 09051 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09052 return -2; /* Syntax error */ 09053 } 09054 h_refer_to = ast_strdupa(p_refer_to); 09055 refer_to = get_in_brackets(h_refer_to); 09056 if (pedanticsipchecking) 09057 ast_uri_decode(refer_to); 09058 09059 if (strncasecmp(refer_to, "sip:", 4)) { 09060 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09061 return -3; 09062 } 09063 refer_to += 4; /* Skip sip: */ 09064 09065 /* Get referred by header if it exists */ 09066 p_referred_by = get_header(req, "Referred-By"); 09067 if (!ast_strlen_zero(p_referred_by)) { 09068 char *lessthan; 09069 h_referred_by = ast_strdupa(p_referred_by); 09070 if (pedanticsipchecking) 09071 ast_uri_decode(h_referred_by); 09072 09073 /* Store referrer's caller ID name */ 09074 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09075 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09076 *(lessthan - 1) = '\0'; /* Space */ 09077 } 09078 09079 referred_by_uri = get_in_brackets(h_referred_by); 09080 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09081 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09082 referred_by_uri = (char *) NULL; 09083 } else { 09084 referred_by_uri += 4; /* Skip sip: */ 09085 } 09086 } 09087 09088 /* Check for arguments in the refer_to header */ 09089 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09090 *ptr++ = '\0'; 09091 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09092 char *to = NULL, *from = NULL; 09093 09094 /* This is an attended transfer */ 09095 referdata->attendedtransfer = 1; 09096 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09097 ast_uri_decode(referdata->replaces_callid); 09098 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09099 *ptr++ = '\0'; 09100 } 09101 09102 if (ptr) { 09103 /* Find the different tags before we destroy the string */ 09104 to = strcasestr(ptr, "to-tag="); 09105 from = strcasestr(ptr, "from-tag="); 09106 } 09107 09108 /* Grab the to header */ 09109 if (to) { 09110 ptr = to + 7; 09111 if ((to = strchr(ptr, '&'))) 09112 *to = '\0'; 09113 if ((to = strchr(ptr, ';'))) 09114 *to = '\0'; 09115 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09116 } 09117 09118 if (from) { 09119 ptr = from + 9; 09120 if ((to = strchr(ptr, '&'))) 09121 *to = '\0'; 09122 if ((to = strchr(ptr, ';'))) 09123 *to = '\0'; 09124 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09125 } 09126 09127 if (option_debug > 1) { 09128 if (!pedanticsipchecking) 09129 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09130 else 09131 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>" ); 09132 } 09133 } 09134 } 09135 09136 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09137 char *urioption = NULL, *domain; 09138 *ptr++ = '\0'; 09139 09140 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09141 *urioption++ = '\0'; 09142 09143 domain = ptr; 09144 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09145 *ptr = '\0'; 09146 09147 /* Save the domain for the dial plan */ 09148 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09149 if (urioption) 09150 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09151 } 09152 09153 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09154 *ptr = '\0'; 09155 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09156 09157 if (referred_by_uri) { 09158 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09159 *ptr = '\0'; 09160 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09161 } else { 09162 referdata->referred_by[0] = '\0'; 09163 } 09164 09165 /* Determine transfer context */ 09166 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09167 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09168 09169 /* By default, use the context in the channel sending the REFER */ 09170 if (ast_strlen_zero(transfer_context)) { 09171 transfer_context = S_OR(transferer->owner->macrocontext, 09172 S_OR(transferer->context, default_context)); 09173 } 09174 09175 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09176 09177 /* Either an existing extension or the parking extension */ 09178 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09179 if (sip_debug_test_pvt(transferer)) { 09180 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09181 } 09182 /* We are ready to transfer to the extension */ 09183 return 0; 09184 } 09185 if (sip_debug_test_pvt(transferer)) 09186 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09187 09188 /* Failure, we can't find this extension */ 09189 return -1; 09190 }
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 9353 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09354 { 09355 char *start; 09356 char *end; 09357 09358 start = strchr(input,':'); 09359 if (!start) { 09360 output[0] = '\0'; 09361 return 0; 09362 } 09363 start++; 09364 09365 /* we found "number" */ 09366 ast_copy_string(output,start,maxlen); 09367 output[maxlen-1] = '\0'; 09368 09369 end = strchr(output,'@'); 09370 if (end) 09371 *end = '\0'; 09372 else 09373 output[0] = '\0'; 09374 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09375 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09376 09377 return 0; 09378 }
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] |
Lock interface lock and find matching pvt lock
Definition at line 8978 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().
08979 { 08980 struct sip_pvt *sip_pvt_ptr; 08981 08982 ast_mutex_lock(&iflock); 08983 08984 if (option_debug > 3 && totag) 08985 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08986 08987 /* Search interfaces and find the match */ 08988 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08989 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08990 int match = 1; 08991 char *ourtag = sip_pvt_ptr->tag; 08992 08993 /* Go ahead and lock it (and its owner) before returning */ 08994 ast_mutex_lock(&sip_pvt_ptr->lock); 08995 08996 /* Check if tags match. If not, this is not the call we want 08997 (With a forking SIP proxy, several call legs share the 08998 call id, but have different tags) 08999 */ 09000 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 09001 match = 0; 09002 09003 if (!match) { 09004 ast_mutex_unlock(&sip_pvt_ptr->lock); 09005 continue; 09006 } 09007 09008 if (option_debug > 3 && totag) 09009 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09010 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 09011 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09012 09013 /* deadlock avoidance... */ 09014 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09015 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09016 } 09017 break; 09018 } 09019 } 09020 ast_mutex_unlock(&iflock); 09021 if (option_debug > 3 && !sip_pvt_ptr) 09022 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09023 return sip_pvt_ptr; 09024 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13405 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13406 { 13407 const char *thetag; 13408 13409 if (!tagbuf) 13410 return NULL; 13411 tagbuf[0] = '\0'; /* reset the buffer */ 13412 thetag = get_header(req, header); 13413 thetag = strcasestr(thetag, ";tag="); 13414 if (thetag) { 13415 thetag += 5; 13416 ast_copy_string(tagbuf, thetag, tagbufsize); 13417 return strsep(&tagbuf, ";"); 13418 } 13419 return NULL; 13420 }
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 16196 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, 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(), and build_user().
16197 { 16198 int res = 1; 16199 16200 if (!strcasecmp(v->name, "trustrpid")) { 16201 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16202 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16203 } else if (!strcasecmp(v->name, "sendrpid")) { 16204 ast_set_flag(&mask[0], SIP_SENDRPID); 16205 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16206 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16207 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16208 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16209 } else if (!strcasecmp(v->name, "useclientcode")) { 16210 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16211 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16212 } else if (!strcasecmp(v->name, "dtmfmode")) { 16213 ast_set_flag(&mask[0], SIP_DTMF); 16214 ast_clear_flag(&flags[0], SIP_DTMF); 16215 if (!strcasecmp(v->value, "inband")) 16216 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16217 else if (!strcasecmp(v->value, "rfc2833")) 16218 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16219 else if (!strcasecmp(v->value, "info")) 16220 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16221 else if (!strcasecmp(v->value, "auto")) 16222 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16223 else { 16224 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16225 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16226 } 16227 } else if (!strcasecmp(v->name, "nat")) { 16228 ast_set_flag(&mask[0], SIP_NAT); 16229 ast_clear_flag(&flags[0], SIP_NAT); 16230 if (!strcasecmp(v->value, "never")) 16231 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16232 else if (!strcasecmp(v->value, "route")) 16233 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16234 else if (ast_true(v->value)) 16235 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16236 else 16237 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16238 } else if (!strcasecmp(v->name, "canreinvite")) { 16239 ast_set_flag(&mask[0], SIP_REINVITE); 16240 ast_clear_flag(&flags[0], SIP_REINVITE); 16241 if(ast_true(v->value)) { 16242 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16243 } else if (!ast_false(v->value)) { 16244 char buf[64]; 16245 char *word, *next = buf; 16246 16247 ast_copy_string(buf, v->value, sizeof(buf)); 16248 while ((word = strsep(&next, ","))) { 16249 if(!strcasecmp(word, "update")) { 16250 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16251 } else if(!strcasecmp(word, "nonat")) { 16252 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16253 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16254 } else { 16255 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16256 } 16257 } 16258 } 16259 } else if (!strcasecmp(v->name, "insecure")) { 16260 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16261 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16262 set_insecure_flags(flags, v->value, v->lineno); 16263 } else if (!strcasecmp(v->name, "progressinband")) { 16264 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16265 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16266 if (ast_true(v->value)) 16267 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16268 else if (strcasecmp(v->value, "never")) 16269 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16270 } else if (!strcasecmp(v->name, "promiscredir")) { 16271 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16272 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16273 } else if (!strcasecmp(v->name, "videosupport")) { 16274 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16275 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16276 } else if (!strcasecmp(v->name, "allowoverlap")) { 16277 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16278 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16279 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16280 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16281 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16282 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16283 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16284 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16285 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16286 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16287 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16288 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16289 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16290 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16291 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16292 #endif 16293 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16294 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16295 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16296 } else if (!strcasecmp(v->name, "buggymwi")) { 16297 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16298 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16299 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16300 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16301 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16302 } else 16303 res = 0; 16304 16305 return res; 16306 }
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 13584 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, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13585 { 13586 struct ast_frame *f; 13587 int earlyreplace = 0; 13588 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13589 struct ast_channel *c = p->owner; /* Our incoming call */ 13590 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13591 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13592 13593 /* Check if we're in ring state */ 13594 if (replacecall->_state == AST_STATE_RING) 13595 earlyreplace = 1; 13596 13597 /* Check if we have a bridge */ 13598 if (!(targetcall = ast_bridged_channel(replacecall))) { 13599 /* We have no bridge */ 13600 if (!earlyreplace) { 13601 if (option_debug > 1) 13602 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13603 oneleggedreplace = 1; 13604 } 13605 } 13606 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13607 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13608 13609 if (option_debug > 3) { 13610 if (targetcall) 13611 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); 13612 else 13613 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13614 } 13615 13616 if (ignore) { 13617 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13618 /* We should answer something here. If we are here, the 13619 call we are replacing exists, so an accepted 13620 can't harm */ 13621 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13622 /* Do something more clever here */ 13623 ast_channel_unlock(c); 13624 ast_mutex_unlock(&p->refer->refer_call->lock); 13625 return 1; 13626 } 13627 if (!c) { 13628 /* What to do if no channel ??? */ 13629 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13630 transmit_response_reliable(p, "503 Service Unavailable", req); 13631 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13632 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13633 ast_mutex_unlock(&p->refer->refer_call->lock); 13634 return 1; 13635 } 13636 append_history(p, "Xfer", "INVITE/Replace received"); 13637 /* We have three channels to play with 13638 channel c: New incoming call 13639 targetcall: Call from PBX to target 13640 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13641 replacecall: The owner of the previous 13642 We need to masq C into refer_call to connect to 13643 targetcall; 13644 If we are talking to internal audio stream, target call is null. 13645 */ 13646 13647 /* Fake call progress */ 13648 transmit_response(p, "100 Trying", req); 13649 ast_setstate(c, AST_STATE_RING); 13650 13651 /* Masquerade the new call into the referred call to connect to target call 13652 Targetcall is not touched by the masq */ 13653 13654 /* Answer the incoming call and set channel to UP state */ 13655 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13656 13657 ast_setstate(c, AST_STATE_UP); 13658 13659 /* Stop music on hold and other generators */ 13660 ast_quiet_chan(replacecall); 13661 ast_quiet_chan(targetcall); 13662 if (option_debug > 3) 13663 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13664 /* Unlock clone, but not original (replacecall) */ 13665 if (!oneleggedreplace) 13666 ast_channel_unlock(c); 13667 13668 /* Unlock PVT */ 13669 ast_mutex_unlock(&p->refer->refer_call->lock); 13670 13671 /* Make sure that the masq does not free our PVT for the old call */ 13672 if (! earlyreplace && ! oneleggedreplace ) 13673 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13674 13675 /* Prepare the masquerade - if this does not happen, we will be gone */ 13676 if(ast_channel_masquerade(replacecall, c)) 13677 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13678 else if (option_debug > 3) 13679 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13680 13681 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13682 13683 /* C should now be in place of replacecall */ 13684 /* ast_read needs to lock channel */ 13685 ast_channel_unlock(c); 13686 13687 if (earlyreplace || oneleggedreplace ) { 13688 /* Force the masq to happen */ 13689 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13690 ast_frfree(f); 13691 f = NULL; 13692 if (option_debug > 3) 13693 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13694 } else { 13695 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13696 } 13697 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13698 if (!oneleggedreplace) 13699 ast_channel_unlock(replacecall); 13700 } else { /* Bridged call, UP channel */ 13701 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13702 /* Masq ok */ 13703 ast_frfree(f); 13704 f = NULL; 13705 if (option_debug > 2) 13706 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13707 } else { 13708 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13709 } 13710 ast_channel_unlock(replacecall); 13711 } 13712 ast_mutex_unlock(&p->refer->refer_call->lock); 13713 13714 ast_setstate(c, AST_STATE_DOWN); 13715 if (option_debug > 3) { 13716 struct ast_channel *test; 13717 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13718 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13719 if (replacecall) 13720 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13721 if (p->owner) { 13722 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13723 test = ast_bridged_channel(p->owner); 13724 if (test) 13725 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13726 else 13727 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13728 } else 13729 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13730 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13731 } 13732 13733 ast_channel_unlock(p->owner); /* Unlock new owner */ 13734 if (!oneleggedreplace) 13735 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13736 13737 /* The call should be down with no ast_channel, so hang it up */ 13738 c->tech_pvt = NULL; 13739 ast_hangup(c); 13740 return 0; 13741 }
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 15254 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, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, 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.
15255 { 15256 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15257 relatively static */ 15258 const char *cmd; 15259 const char *cseq; 15260 const char *useragent; 15261 int seqno; 15262 int len; 15263 int ignore = FALSE; 15264 int respid; 15265 int res = 0; 15266 int debug = sip_debug_test_pvt(p); 15267 char *e; 15268 int error = 0; 15269 15270 /* Get Method and Cseq */ 15271 cseq = get_header(req, "Cseq"); 15272 cmd = req->header[0]; 15273 15274 /* Must have Cseq */ 15275 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15276 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15277 error = 1; 15278 } 15279 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15280 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15281 error = 1; 15282 } 15283 if (error) { 15284 if (!p->initreq.headers) /* New call */ 15285 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15286 return -1; 15287 } 15288 /* Get the command XXX */ 15289 15290 cmd = req->rlPart1; 15291 e = req->rlPart2; 15292 15293 /* Save useragent of the client */ 15294 useragent = get_header(req, "User-Agent"); 15295 if (!ast_strlen_zero(useragent)) 15296 ast_string_field_set(p, useragent, useragent); 15297 15298 /* Find out SIP method for incoming request */ 15299 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15300 /* Response to our request -- Do some sanity checks */ 15301 if (!p->initreq.headers) { 15302 if (option_debug) 15303 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15304 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15305 return 0; 15306 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15307 if (option_debug) 15308 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15309 return -1; 15310 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15311 /* ignore means "don't do anything with it" but still have to 15312 respond appropriately */ 15313 ignore = TRUE; 15314 ast_set_flag(req, SIP_PKT_IGNORE); 15315 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15316 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15317 } else if (e) { 15318 e = ast_skip_blanks(e); 15319 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15320 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15321 } else { 15322 if (respid <= 0) { 15323 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15324 return 0; 15325 } 15326 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15327 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15328 extract_uri(p, req); 15329 handle_response(p, respid, e + len, req, ignore, seqno); 15330 } 15331 } 15332 return 0; 15333 } 15334 15335 /* New SIP request coming in 15336 (could be new request in existing SIP dialog as well...) 15337 */ 15338 15339 p->method = req->method; /* Find out which SIP method they are using */ 15340 if (option_debug > 3) 15341 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15342 15343 if (p->icseq && (p->icseq > seqno) ) { 15344 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15345 if (option_debug > 2) 15346 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15347 } else { 15348 if (option_debug) 15349 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15350 if (req->method != SIP_ACK) 15351 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15352 return -1; 15353 } 15354 } else if (p->icseq && 15355 p->icseq == seqno && 15356 req->method != SIP_ACK && 15357 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15358 /* ignore means "don't do anything with it" but still have to 15359 respond appropriately. We do this if we receive a repeat of 15360 the last sequence number */ 15361 ignore = 2; 15362 ast_set_flag(req, SIP_PKT_IGNORE); 15363 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15364 if (option_debug > 2) 15365 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15366 } 15367 15368 if (seqno >= p->icseq) 15369 /* Next should follow monotonically (but not necessarily 15370 incrementally -- thanks again to the genius authors of SIP -- 15371 increasing */ 15372 p->icseq = seqno; 15373 15374 /* Find their tag if we haven't got it */ 15375 if (ast_strlen_zero(p->theirtag)) { 15376 char tag[128]; 15377 15378 gettag(req, "From", tag, sizeof(tag)); 15379 ast_string_field_set(p, theirtag, tag); 15380 } 15381 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15382 15383 if (pedanticsipchecking) { 15384 /* If this is a request packet without a from tag, it's not 15385 correct according to RFC 3261 */ 15386 /* Check if this a new request in a new dialog with a totag already attached to it, 15387 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15388 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15389 /* If this is a first request and it got a to-tag, it is not for us */ 15390 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15391 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15392 /* Will cease to exist after ACK */ 15393 } else if (req->method != SIP_ACK) { 15394 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15395 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15396 } 15397 return res; 15398 } 15399 } 15400 15401 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15402 transmit_response(p, "400 Bad request", req); 15403 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15404 return -1; 15405 } 15406 15407 /* Handle various incoming SIP methods in requests */ 15408 switch (p->method) { 15409 case SIP_OPTIONS: 15410 res = handle_request_options(p, req); 15411 break; 15412 case SIP_INVITE: 15413 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15414 break; 15415 case SIP_REFER: 15416 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15417 break; 15418 case SIP_CANCEL: 15419 res = handle_request_cancel(p, req); 15420 break; 15421 case SIP_BYE: 15422 res = handle_request_bye(p, req); 15423 break; 15424 case SIP_MESSAGE: 15425 res = handle_request_message(p, req); 15426 break; 15427 case SIP_SUBSCRIBE: 15428 res = handle_request_subscribe(p, req, sin, seqno, e); 15429 break; 15430 case SIP_REGISTER: 15431 res = handle_request_register(p, req, sin, e); 15432 break; 15433 case SIP_INFO: 15434 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15435 ast_verbose("Receiving INFO!\n"); 15436 if (!ignore) 15437 handle_request_info(p, req); 15438 else /* if ignoring, transmit response */ 15439 transmit_response(p, "200 OK", req); 15440 break; 15441 case SIP_NOTIFY: 15442 res = handle_request_notify(p, req, sin, seqno, e); 15443 break; 15444 case SIP_ACK: 15445 /* Make sure we don't ignore this */ 15446 if (seqno == p->pendinginvite) { 15447 p->invitestate = INV_TERMINATED; 15448 p->pendinginvite = 0; 15449 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15450 if (find_sdp(req)) { 15451 if (process_sdp(p, req)) 15452 return -1; 15453 } 15454 check_pendings(p); 15455 } 15456 /* Got an ACK that we did not match. Ignore silently */ 15457 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15458 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15459 break; 15460 default: 15461 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15462 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15463 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15464 /* If this is some new method, and we don't have a call, destroy it now */ 15465 if (!p->initreq.headers) 15466 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15467 break; 15468 } 15469 return res; 15470 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14819 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, 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().
14820 { 14821 struct ast_channel *c=NULL; 14822 int res; 14823 struct ast_channel *bridged_to; 14824 14825 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14826 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14827 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14828 14829 p->invitestate = INV_TERMINATED; 14830 14831 copy_request(&p->initreq, req); 14832 check_via(p, req); 14833 sip_alreadygone(p); 14834 14835 /* Get RTCP quality before end of call */ 14836 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14837 char *audioqos, *videoqos; 14838 if (p->rtp) { 14839 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14840 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14841 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14842 if (p->owner) 14843 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14844 } 14845 if (p->vrtp) { 14846 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14847 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14848 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14849 if (p->owner) 14850 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14851 } 14852 } 14853 14854 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14855 14856 if (!ast_strlen_zero(get_header(req, "Also"))) { 14857 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14858 ast_inet_ntoa(p->recv.sin_addr)); 14859 if (ast_strlen_zero(p->context)) 14860 ast_string_field_set(p, context, default_context); 14861 res = get_also_info(p, req); 14862 if (!res) { 14863 c = p->owner; 14864 if (c) { 14865 bridged_to = ast_bridged_channel(c); 14866 if (bridged_to) { 14867 /* Don't actually hangup here... */ 14868 ast_queue_control(c, AST_CONTROL_UNHOLD); 14869 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14870 } else 14871 ast_queue_hangup(p->owner); 14872 } 14873 } else { 14874 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14875 if (p->owner) 14876 ast_queue_hangup(p->owner); 14877 } 14878 } else if (p->owner) { 14879 ast_queue_hangup(p->owner); 14880 if (option_debug > 2) 14881 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14882 } else { 14883 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14884 if (option_debug > 2) 14885 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14886 } 14887 transmit_response(p, "200 OK", req); 14888 14889 return 1; 14890 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14713 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, 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().
14714 { 14715 14716 check_via(p, req); 14717 sip_alreadygone(p); 14718 14719 /* At this point, we could have cancelled the invite at the same time 14720 as the other side sends a CANCEL. Our final reply with error code 14721 might not have been received by the other side before the CANCEL 14722 was sent, so let's just give up retransmissions and waiting for 14723 ACK on our error code. The call is hanging up any way. */ 14724 if (p->invitestate == INV_TERMINATED) 14725 __sip_pretend_ack(p); 14726 else 14727 p->invitestate = INV_CANCELLED; 14728 14729 if (p->owner && p->owner->_state == AST_STATE_UP) { 14730 /* This call is up, cancel is ignored, we need a bye */ 14731 transmit_response(p, "200 OK", req); 14732 if (option_debug) 14733 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14734 return 0; 14735 } 14736 14737 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14738 update_call_counter(p, DEC_CALL_LIMIT); 14739 14740 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14741 if (p->owner) 14742 ast_queue_hangup(p->owner); 14743 else 14744 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14745 if (p->initreq.len > 0) { 14746 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14747 transmit_response(p, "200 OK", req); 14748 return 1; 14749 } else { 14750 transmit_response(p, "481 Call Leg Does Not Exist", req); 14751 return 0; 14752 } 14753 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11185 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, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
11186 { 11187 char buf[1024]; 11188 unsigned int event; 11189 const char *c = get_header(req, "Content-Type"); 11190 11191 /* Need to check the media/type */ 11192 if (!strcasecmp(c, "application/dtmf-relay") || 11193 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11194 unsigned int duration = 0; 11195 11196 /* Try getting the "signal=" part */ 11197 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11198 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11199 transmit_response(p, "200 OK", req); /* Should return error */ 11200 return; 11201 } else { 11202 ast_copy_string(buf, c, sizeof(buf)); 11203 } 11204 11205 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11206 duration = atoi(c); 11207 if (!duration) 11208 duration = 100; /* 100 ms */ 11209 11210 if (!p->owner) { /* not a PBX call */ 11211 transmit_response(p, "481 Call leg/transaction does not exist", req); 11212 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11213 return; 11214 } 11215 11216 if (ast_strlen_zero(buf)) { 11217 transmit_response(p, "200 OK", req); 11218 return; 11219 } 11220 11221 if (buf[0] == '*') 11222 event = 10; 11223 else if (buf[0] == '#') 11224 event = 11; 11225 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11226 event = 12 + buf[0] - 'A'; 11227 else 11228 event = atoi(buf); 11229 if (event == 16) { 11230 /* send a FLASH event */ 11231 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11232 ast_queue_frame(p->owner, &f); 11233 if (sipdebug) 11234 ast_verbose("* DTMF-relay event received: FLASH\n"); 11235 } else { 11236 /* send a DTMF event */ 11237 struct ast_frame f = { AST_FRAME_DTMF, }; 11238 if (event < 10) { 11239 f.subclass = '0' + event; 11240 } else if (event < 11) { 11241 f.subclass = '*'; 11242 } else if (event < 12) { 11243 f.subclass = '#'; 11244 } else if (event < 16) { 11245 f.subclass = 'A' + (event - 12); 11246 } 11247 f.len = duration; 11248 ast_queue_frame(p->owner, &f); 11249 if (sipdebug) 11250 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11251 } 11252 transmit_response(p, "200 OK", req); 11253 return; 11254 } else if (!strcasecmp(c, "application/media_control+xml")) { 11255 /* Eh, we'll just assume it's a fast picture update for now */ 11256 if (p->owner) 11257 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11258 transmit_response(p, "200 OK", req); 11259 return; 11260 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11261 /* Client code (from SNOM phone) */ 11262 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11263 if (p->owner && p->owner->cdr) 11264 ast_cdr_setuserfield(p->owner, c); 11265 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11266 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11267 transmit_response(p, "200 OK", req); 11268 } else { 11269 transmit_response(p, "403 Unauthorized", req); 11270 } 11271 return; 11272 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11273 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11274 transmit_response(p, "200 OK", req); 11275 return; 11276 } 11277 11278 /* Other type of INFO message, not really understood by Asterisk */ 11279 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11280 11281 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11282 transmit_response(p, "415 Unsupported media type", req); 11283 return; 11284 }
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 13750 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_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
13751 { 13752 int res = 1; 13753 int gotdest; 13754 const char *p_replaces; 13755 char *replace_id = NULL; 13756 const char *required; 13757 unsigned int required_profile = 0; 13758 struct ast_channel *c = NULL; /* New channel */ 13759 int reinvite = 0; 13760 13761 /* Find out what they support */ 13762 if (!p->sipoptions) { 13763 const char *supported = get_header(req, "Supported"); 13764 if (!ast_strlen_zero(supported)) 13765 parse_sip_options(p, supported); 13766 } 13767 13768 /* Find out what they require */ 13769 required = get_header(req, "Require"); 13770 if (!ast_strlen_zero(required)) { 13771 required_profile = parse_sip_options(NULL, required); 13772 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13773 /* At this point we only support REPLACES */ 13774 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13775 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13776 p->invitestate = INV_COMPLETED; 13777 if (!p->lastinvite) 13778 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13779 return -1; 13780 } 13781 } 13782 13783 /* Check if this is a loop */ 13784 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13785 /* This is a call to ourself. Send ourselves an error code and stop 13786 processing immediately, as SIP really has no good mechanism for 13787 being able to call yourself */ 13788 /* If pedantic is on, we need to check the tags. If they're different, this is 13789 in fact a forked call through a SIP proxy somewhere. */ 13790 transmit_response(p, "482 Loop Detected", req); 13791 p->invitestate = INV_COMPLETED; 13792 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13793 return 0; 13794 } 13795 13796 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13797 /* We already have a pending invite. Sorry. You are on hold. */ 13798 transmit_response(p, "491 Request Pending", req); 13799 if (option_debug) 13800 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13801 /* Don't destroy dialog here */ 13802 return 0; 13803 } 13804 13805 p_replaces = get_header(req, "Replaces"); 13806 if (!ast_strlen_zero(p_replaces)) { 13807 /* We have a replaces header */ 13808 char *ptr; 13809 char *fromtag = NULL; 13810 char *totag = NULL; 13811 char *start, *to; 13812 int error = 0; 13813 13814 if (p->owner) { 13815 if (option_debug > 2) 13816 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13817 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13818 /* Do not destroy existing call */ 13819 return -1; 13820 } 13821 13822 if (sipdebug && option_debug > 2) 13823 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13824 /* Create a buffer we can manipulate */ 13825 replace_id = ast_strdupa(p_replaces); 13826 ast_uri_decode(replace_id); 13827 13828 if (!p->refer && !sip_refer_allocate(p)) { 13829 transmit_response(p, "500 Server Internal Error", req); 13830 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13831 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13832 p->invitestate = INV_COMPLETED; 13833 return -1; 13834 } 13835 13836 /* Todo: (When we find phones that support this) 13837 if the replaces header contains ";early-only" 13838 we can only replace the call in early 13839 stage, not after it's up. 13840 13841 If it's not in early mode, 486 Busy. 13842 */ 13843 13844 /* Skip leading whitespace */ 13845 replace_id = ast_skip_blanks(replace_id); 13846 13847 start = replace_id; 13848 while ( (ptr = strsep(&start, ";")) ) { 13849 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13850 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13851 totag = to + 7; /* skip the keyword */ 13852 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13853 fromtag = to + 9; /* skip the keyword */ 13854 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13855 } 13856 } 13857 13858 if (sipdebug && option_debug > 3) 13859 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>"); 13860 13861 13862 /* Try to find call that we are replacing 13863 If we have a Replaces header, we need to cancel that call if we succeed with this call 13864 */ 13865 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13866 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13867 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13868 error = 1; 13869 } 13870 13871 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13872 13873 /* The matched call is the call from the transferer to Asterisk . 13874 We want to bridge the bridged part of the call to the 13875 incoming invite, thus taking over the refered call */ 13876 13877 if (p->refer->refer_call == p) { 13878 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13879 p->refer->refer_call = NULL; 13880 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13881 error = 1; 13882 } 13883 13884 if (!error && !p->refer->refer_call->owner) { 13885 /* Oops, someting wrong anyway, no owner, no call */ 13886 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13887 /* Check for better return code */ 13888 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13889 error = 1; 13890 } 13891 13892 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 ) { 13893 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13894 transmit_response(p, "603 Declined (Replaces)", req); 13895 error = 1; 13896 } 13897 13898 if (error) { /* Give up this dialog */ 13899 append_history(p, "Xfer", "INVITE/Replace Failed."); 13900 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13901 ast_mutex_unlock(&p->lock); 13902 if (p->refer->refer_call) { 13903 ast_mutex_unlock(&p->refer->refer_call->lock); 13904 ast_channel_unlock(p->refer->refer_call->owner); 13905 } 13906 p->invitestate = INV_COMPLETED; 13907 return -1; 13908 } 13909 } 13910 13911 13912 /* Check if this is an INVITE that sets up a new dialog or 13913 a re-invite in an existing dialog */ 13914 13915 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13916 int newcall = (p->initreq.headers ? TRUE : FALSE); 13917 13918 if (sip_cancel_destroy(p)) 13919 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13920 /* This also counts as a pending invite */ 13921 p->pendinginvite = seqno; 13922 check_via(p, req); 13923 13924 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13925 if (!p->owner) { /* Not a re-invite */ 13926 if (debug) 13927 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13928 if (newcall) 13929 append_history(p, "Invite", "New call: %s", p->callid); 13930 parse_ok_contact(p, req); 13931 } else { /* Re-invite on existing call */ 13932 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13933 /* Handle SDP here if we already have an owner */ 13934 if (find_sdp(req)) { 13935 if (process_sdp(p, req)) { 13936 transmit_response(p, "488 Not acceptable here", req); 13937 if (!p->lastinvite) 13938 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13939 return -1; 13940 } 13941 } else { 13942 p->jointcapability = p->capability; 13943 if (option_debug > 2) 13944 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13945 /* Some devices signal they want to be put off hold by sending a re-invite 13946 *without* an SDP, which is supposed to mean "Go back to your state" 13947 and since they put os on remote hold, we go back to off hold */ 13948 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13949 change_hold_state(p, req, FALSE, 0); 13950 } 13951 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13952 append_history(p, "ReInv", "Re-invite received"); 13953 } 13954 } else if (debug) 13955 ast_verbose("Ignoring this INVITE request\n"); 13956 13957 13958 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13959 /* This is a new invite */ 13960 /* Handle authentication if this is our first invite */ 13961 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13962 if (res == AUTH_CHALLENGE_SENT) { 13963 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13964 return 0; 13965 } 13966 if (res < 0) { /* Something failed in authentication */ 13967 if (res == AUTH_FAKE_AUTH) { 13968 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13969 transmit_fake_auth_response(p, req, 1); 13970 } else { 13971 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13972 transmit_response_reliable(p, "403 Forbidden", req); 13973 } 13974 p->invitestate = INV_COMPLETED; 13975 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13976 ast_string_field_free(p, theirtag); 13977 return 0; 13978 } 13979 13980 /* We have a succesful authentication, process the SDP portion if there is one */ 13981 if (find_sdp(req)) { 13982 if (process_sdp(p, req)) { 13983 /* Unacceptable codecs */ 13984 transmit_response_reliable(p, "488 Not acceptable here", req); 13985 p->invitestate = INV_COMPLETED; 13986 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13987 if (option_debug) 13988 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13989 return -1; 13990 } 13991 } else { /* No SDP in invite, call control session */ 13992 p->jointcapability = p->capability; 13993 if (option_debug > 1) 13994 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13995 } 13996 13997 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13998 /* This seems redundant ... see !p-owner above */ 13999 if (p->owner) 14000 ast_queue_frame(p->owner, &ast_null_frame); 14001 14002 14003 /* Initialize the context if it hasn't been already */ 14004 if (ast_strlen_zero(p->context)) 14005 ast_string_field_set(p, context, default_context); 14006 14007 14008 /* Check number of concurrent calls -vs- incoming limit HERE */ 14009 if (option_debug) 14010 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14011 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14012 if (res < 0) { 14013 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14014 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14015 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14016 p->invitestate = INV_COMPLETED; 14017 } 14018 return 0; 14019 } 14020 gotdest = get_destination(p, NULL); /* Get destination right away */ 14021 get_rdnis(p, NULL); /* Get redirect information */ 14022 extract_uri(p, req); /* Get the Contact URI */ 14023 build_contact(p); /* Build our contact header */ 14024 14025 if (p->rtp) { 14026 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14027 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14028 } 14029 14030 if (!replace_id && gotdest) { /* No matching extension found */ 14031 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14032 transmit_response_reliable(p, "484 Address Incomplete", req); 14033 else { 14034 transmit_response_reliable(p, "404 Not Found", req); 14035 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14036 " '%s' rejected because extension not found.\n", 14037 S_OR(p->username, p->peername), p->exten); 14038 } 14039 p->invitestate = INV_COMPLETED; 14040 update_call_counter(p, DEC_CALL_LIMIT); 14041 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14042 return 0; 14043 } else { 14044 /* If no extension was specified, use the s one */ 14045 /* Basically for calling to IP/Host name only */ 14046 if (ast_strlen_zero(p->exten)) 14047 ast_string_field_set(p, exten, "s"); 14048 /* Initialize our tag */ 14049 14050 make_our_tag(p->tag, sizeof(p->tag)); 14051 /* First invitation - create the channel */ 14052 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14053 *recount = 1; 14054 14055 /* Save Record-Route for any later requests we make on this dialogue */ 14056 build_route(p, req, 0); 14057 14058 if (c) { 14059 /* Pre-lock the call */ 14060 ast_channel_lock(c); 14061 } 14062 } 14063 } else { 14064 if (option_debug > 1 && sipdebug) { 14065 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14066 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14067 else 14068 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14069 } 14070 reinvite = 1; 14071 c = p->owner; 14072 } 14073 14074 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14075 p->lastinvite = seqno; 14076 14077 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14078 /* Go and take over the target call */ 14079 if (sipdebug && option_debug > 3) 14080 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14081 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14082 } 14083 14084 14085 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14086 switch(c->_state) { 14087 case AST_STATE_DOWN: 14088 if (option_debug > 1) 14089 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14090 transmit_response(p, "100 Trying", req); 14091 p->invitestate = INV_PROCEEDING; 14092 ast_setstate(c, AST_STATE_RING); 14093 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14094 enum ast_pbx_result res; 14095 14096 res = ast_pbx_start(c); 14097 14098 switch(res) { 14099 case AST_PBX_FAILED: 14100 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14101 p->invitestate = INV_COMPLETED; 14102 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14103 transmit_response(p, "503 Unavailable", req); 14104 else 14105 transmit_response_reliable(p, "503 Unavailable", req); 14106 break; 14107 case AST_PBX_CALL_LIMIT: 14108 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14109 p->invitestate = INV_COMPLETED; 14110 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14111 transmit_response(p, "480 Temporarily Unavailable", req); 14112 else 14113 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14114 break; 14115 case AST_PBX_SUCCESS: 14116 /* nothing to do */ 14117 break; 14118 } 14119 14120 if (res) { 14121 14122 /* Unlock locks so ast_hangup can do its magic */ 14123 ast_mutex_unlock(&c->lock); 14124 ast_mutex_unlock(&p->lock); 14125 ast_hangup(c); 14126 ast_mutex_lock(&p->lock); 14127 c = NULL; 14128 } 14129 } else { /* Pickup call in call group */ 14130 ast_channel_unlock(c); 14131 *nounlock = 1; 14132 if (ast_pickup_call(c)) { 14133 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14134 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14135 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14136 else 14137 transmit_response_reliable(p, "503 Unavailable", req); 14138 sip_alreadygone(p); 14139 /* Unlock locks so ast_hangup can do its magic */ 14140 ast_mutex_unlock(&p->lock); 14141 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14142 } else { 14143 ast_mutex_unlock(&p->lock); 14144 ast_setstate(c, AST_STATE_DOWN); 14145 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14146 } 14147 p->invitestate = INV_COMPLETED; 14148 ast_hangup(c); 14149 ast_mutex_lock(&p->lock); 14150 c = NULL; 14151 } 14152 break; 14153 case AST_STATE_RING: 14154 transmit_response(p, "100 Trying", req); 14155 p->invitestate = INV_PROCEEDING; 14156 break; 14157 case AST_STATE_RINGING: 14158 transmit_response(p, "180 Ringing", req); 14159 p->invitestate = INV_PROCEEDING; 14160 break; 14161 case AST_STATE_UP: 14162 if (option_debug > 1) 14163 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14164 14165 transmit_response(p, "100 Trying", req); 14166 14167 if (p->t38.state == T38_PEER_REINVITE) { 14168 struct ast_channel *bridgepeer = NULL; 14169 struct sip_pvt *bridgepvt = NULL; 14170 14171 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14172 /* 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*/ 14173 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14174 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14175 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14176 if (bridgepvt->t38.state == T38_DISABLED) { 14177 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14178 /* Send re-invite to the bridged channel */ 14179 sip_handle_t38_reinvite(bridgepeer, p, 1); 14180 } else { /* Something is wrong with peers udptl struct */ 14181 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14182 ast_mutex_lock(&bridgepvt->lock); 14183 bridgepvt->t38.state = T38_DISABLED; 14184 ast_mutex_unlock(&bridgepvt->lock); 14185 if (option_debug > 1) 14186 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14187 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14188 transmit_response(p, "488 Not acceptable here", req); 14189 else 14190 transmit_response_reliable(p, "488 Not acceptable here", req); 14191 14192 } 14193 } else { 14194 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14195 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14196 p->t38.state = T38_ENABLED; 14197 if (option_debug) 14198 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14199 } 14200 } else { 14201 /* Other side is not a SIP channel */ 14202 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14203 transmit_response(p, "488 Not acceptable here", req); 14204 else 14205 transmit_response_reliable(p, "488 Not acceptable here", req); 14206 p->t38.state = T38_DISABLED; 14207 if (option_debug > 1) 14208 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14209 14210 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14211 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14212 } 14213 } else { 14214 /* we are not bridged in a call */ 14215 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14216 p->t38.state = T38_ENABLED; 14217 if (option_debug) 14218 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14219 } 14220 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14221 int sendok = TRUE; 14222 14223 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14224 /* so handle it here (re-invite other party to RTP) */ 14225 struct ast_channel *bridgepeer = NULL; 14226 struct sip_pvt *bridgepvt = NULL; 14227 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14228 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14229 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14230 /* Does the bridged peer have T38 ? */ 14231 if (bridgepvt->t38.state == T38_ENABLED) { 14232 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14233 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14234 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14235 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14236 else 14237 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14238 sendok = FALSE; 14239 } 14240 /* No bridged peer with T38 enabled*/ 14241 } 14242 } 14243 /* Respond to normal re-invite */ 14244 if (sendok) 14245 /* If this is not a re-invite or something to ignore - it's critical */ 14246 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14247 } 14248 p->invitestate = INV_TERMINATED; 14249 break; 14250 default: 14251 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14252 transmit_response(p, "100 Trying", req); 14253 break; 14254 } 14255 } else { 14256 if (p && (p->autokillid == -1)) { 14257 const char *msg; 14258 14259 if (!p->jointcapability) 14260 msg = "488 Not Acceptable Here (codec error)"; 14261 else { 14262 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14263 msg = "503 Unavailable"; 14264 } 14265 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14266 transmit_response(p, msg, req); 14267 else 14268 transmit_response_reliable(p, msg, req); 14269 p->invitestate = INV_COMPLETED; 14270 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14271 } 14272 } 14273 return res; 14274 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14893 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().
14894 { 14895 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14896 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14897 ast_verbose("Receiving message!\n"); 14898 receive_message(p, req); 14899 } else 14900 transmit_response(p, "202 Accepted", req); 14901 return 1; 14902 }
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 13423 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, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13424 { 13425 /* This is mostly a skeleton for future improvements */ 13426 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13427 int res = 0; 13428 const char *event = get_header(req, "Event"); 13429 char *eventid = NULL; 13430 char *sep; 13431 13432 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13433 *sep++ = '\0'; 13434 eventid = sep; 13435 } 13436 13437 if (option_debug > 1 && sipdebug) 13438 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13439 13440 if (strcmp(event, "refer")) { 13441 /* We don't understand this event. */ 13442 /* Here's room to implement incoming voicemail notifications :-) */ 13443 transmit_response(p, "489 Bad event", req); 13444 res = -1; 13445 } else { 13446 /* Save nesting depth for now, since there might be other events we will 13447 support in the future */ 13448 13449 /* Handle REFER notifications */ 13450 13451 char buf[1024]; 13452 char *cmd, *code; 13453 int respcode; 13454 int success = TRUE; 13455 13456 /* EventID for each transfer... EventID is basically the REFER cseq 13457 13458 We are getting notifications on a call that we transfered 13459 We should hangup when we are getting a 200 OK in a sipfrag 13460 Check if we have an owner of this event */ 13461 13462 /* Check the content type */ 13463 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13464 /* We need a sipfrag */ 13465 transmit_response(p, "400 Bad request", req); 13466 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13467 return -1; 13468 } 13469 13470 /* Get the text of the attachment */ 13471 if (get_msg_text(buf, sizeof(buf), req)) { 13472 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13473 transmit_response(p, "400 Bad request", req); 13474 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13475 return -1; 13476 } 13477 13478 /* 13479 From the RFC... 13480 A minimal, but complete, implementation can respond with a single 13481 NOTIFY containing either the body: 13482 SIP/2.0 100 Trying 13483 13484 if the subscription is pending, the body: 13485 SIP/2.0 200 OK 13486 if the reference was successful, the body: 13487 SIP/2.0 503 Service Unavailable 13488 if the reference failed, or the body: 13489 SIP/2.0 603 Declined 13490 13491 if the REFER request was accepted before approval to follow the 13492 reference could be obtained and that approval was subsequently denied 13493 (see Section 2.4.7). 13494 13495 If there are several REFERs in the same dialog, we need to 13496 match the ID of the event header... 13497 */ 13498 if (option_debug > 2) 13499 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13500 cmd = ast_skip_blanks(buf); 13501 code = cmd; 13502 /* We are at SIP/2.0 */ 13503 while(*code && (*code > 32)) { /* Search white space */ 13504 code++; 13505 } 13506 *code++ = '\0'; 13507 code = ast_skip_blanks(code); 13508 sep = code; 13509 sep++; 13510 while(*sep && (*sep > 32)) { /* Search white space */ 13511 sep++; 13512 } 13513 *sep++ = '\0'; /* Response string */ 13514 respcode = atoi(code); 13515 switch (respcode) { 13516 case 100: /* Trying: */ 13517 case 101: /* dialog establishment */ 13518 /* Don't do anything yet */ 13519 break; 13520 case 183: /* Ringing: */ 13521 /* Don't do anything yet */ 13522 break; 13523 case 200: /* OK: The new call is up, hangup this call */ 13524 /* Hangup the call that we are replacing */ 13525 break; 13526 case 301: /* Moved permenantly */ 13527 case 302: /* Moved temporarily */ 13528 /* Do we get the header in the packet in this case? */ 13529 success = FALSE; 13530 break; 13531 case 503: /* Service Unavailable: The new call failed */ 13532 /* Cancel transfer, continue the call */ 13533 success = FALSE; 13534 break; 13535 case 603: /* Declined: Not accepted */ 13536 /* Cancel transfer, continue the current call */ 13537 success = FALSE; 13538 break; 13539 } 13540 if (!success) { 13541 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13542 } 13543 13544 /* Confirm that we received this packet */ 13545 transmit_response(p, "200 OK", req); 13546 }; 13547 13548 if (!p->lastinvite) 13549 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13550 13551 return res; 13552 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13555 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().
13556 { 13557 int res; 13558 13559 res = get_destination(p, req); 13560 build_contact(p); 13561 13562 /* XXX Should we authenticate OPTIONS? XXX */ 13563 13564 if (ast_strlen_zero(p->context)) 13565 ast_string_field_set(p, context, default_context); 13566 13567 if (ast_shutting_down()) 13568 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13569 else if (res < 0) 13570 transmit_response_with_allow(p, "404 Not Found", req, 0); 13571 else 13572 transmit_response_with_allow(p, "200 OK", req, 0); 13573 13574 /* Destroy if this OPTIONS was the opening request, but not if 13575 it's in the middle of a normal call flow. */ 13576 if (!p->lastinvite) 13577 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13578 13579 return res; 13580 }
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 14442 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().
14443 { 14444 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14445 /* Chan2: Call between asterisk and transferee */ 14446 14447 int res = 0; 14448 14449 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14450 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"); 14451 14452 if (!p->owner) { 14453 /* This is a REFER outside of an existing SIP dialog */ 14454 /* We can't handle that, so decline it */ 14455 if (option_debug > 2) 14456 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14457 transmit_response(p, "603 Declined (No dialog)", req); 14458 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14459 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14460 sip_alreadygone(p); 14461 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14462 } 14463 return 0; 14464 } 14465 14466 14467 /* Check if transfer is allowed from this device */ 14468 if (p->allowtransfer == TRANSFER_CLOSED ) { 14469 /* Transfer not allowed, decline */ 14470 transmit_response(p, "603 Declined (policy)", req); 14471 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14472 /* Do not destroy SIP session */ 14473 return 0; 14474 } 14475 14476 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14477 /* Already have a pending REFER */ 14478 transmit_response(p, "491 Request pending", req); 14479 append_history(p, "Xfer", "Refer failed. Request pending."); 14480 return 0; 14481 } 14482 14483 /* Allocate memory for call transfer data */ 14484 if (!p->refer && !sip_refer_allocate(p)) { 14485 transmit_response(p, "500 Internal Server Error", req); 14486 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14487 return -3; 14488 } 14489 14490 res = get_refer_info(p, req); /* Extract headers */ 14491 14492 p->refer->status = REFER_SENT; 14493 14494 if (res != 0) { 14495 switch (res) { 14496 case -2: /* Syntax error */ 14497 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14498 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14499 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14500 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14501 break; 14502 case -3: 14503 transmit_response(p, "603 Declined (Non sip: uri)", req); 14504 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14505 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14506 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14507 break; 14508 default: 14509 /* Refer-to extension not found, fake a failed transfer */ 14510 transmit_response(p, "202 Accepted", req); 14511 append_history(p, "Xfer", "Refer failed. Bad extension."); 14512 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14513 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14514 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14515 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14516 break; 14517 } 14518 return 0; 14519 } 14520 if (ast_strlen_zero(p->context)) 14521 ast_string_field_set(p, context, default_context); 14522 14523 /* If we do not support SIP domains, all transfers are local */ 14524 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14525 p->refer->localtransfer = 1; 14526 if (sipdebug && option_debug > 2) 14527 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14528 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14529 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14530 p->refer->localtransfer = 1; 14531 } else if (sipdebug && option_debug > 2) 14532 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14533 14534 /* Is this a repeat of a current request? Ignore it */ 14535 /* Don't know what else to do right now. */ 14536 if (ignore) 14537 return res; 14538 14539 /* If this is a blind transfer, we have the following 14540 channels to work with: 14541 - chan1, chan2: The current call between transferer and transferee (2 channels) 14542 - target_channel: A new call from the transferee to the target (1 channel) 14543 We need to stay tuned to what happens in order to be able 14544 to bring back the call to the transferer */ 14545 14546 /* If this is a attended transfer, we should have all call legs within reach: 14547 - chan1, chan2: The call between the transferer and transferee (2 channels) 14548 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14549 We want to bridge chan2 with targetcall_pvt! 14550 14551 The replaces call id in the refer message points 14552 to the call leg between Asterisk and the transferer. 14553 So we need to connect the target and the transferee channel 14554 and hangup the two other channels silently 14555 14556 If the target is non-local, the call ID could be on a remote 14557 machine and we need to send an INVITE with replaces to the 14558 target. We basically handle this as a blind transfer 14559 and let the sip_call function catch that we need replaces 14560 header in the INVITE. 14561 */ 14562 14563 14564 /* Get the transferer's channel */ 14565 current.chan1 = p->owner; 14566 14567 /* Find the other part of the bridge (2) - transferee */ 14568 current.chan2 = ast_bridged_channel(current.chan1); 14569 14570 if (sipdebug && option_debug > 2) 14571 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>"); 14572 14573 if (!current.chan2 && !p->refer->attendedtransfer) { 14574 /* No bridged channel, propably IVR or echo or similar... */ 14575 /* Guess we should masquerade or something here */ 14576 /* Until we figure it out, refuse transfer of such calls */ 14577 if (sipdebug && option_debug > 2) 14578 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14579 p->refer->status = REFER_FAILED; 14580 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14581 transmit_response(p, "603 Declined", req); 14582 return -1; 14583 } 14584 14585 if (current.chan2) { 14586 if (sipdebug && option_debug > 3) 14587 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14588 14589 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14590 } 14591 14592 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14593 14594 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14595 if (p->refer->attendedtransfer) { 14596 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14597 return res; /* We're done with the transfer */ 14598 /* Fall through for remote transfers that we did not find locally */ 14599 if (sipdebug && option_debug > 3) 14600 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14601 /* Fallthrough if we can't find the call leg internally */ 14602 } 14603 14604 14605 /* Parking a call */ 14606 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14607 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14608 *nounlock = 1; 14609 ast_channel_unlock(current.chan1); 14610 copy_request(¤t.req, req); 14611 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14612 p->refer->status = REFER_200OK; 14613 append_history(p, "Xfer", "REFER to call parking."); 14614 if (sipdebug && option_debug > 3) 14615 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14616 sip_park(current.chan2, current.chan1, req, seqno); 14617 return res; 14618 } 14619 14620 /* Blind transfers and remote attended xfers */ 14621 transmit_response(p, "202 Accepted", req); 14622 14623 if (current.chan1 && current.chan2) { 14624 if (option_debug > 2) 14625 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14626 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14627 } 14628 if (current.chan2) { 14629 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14630 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14631 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14632 /* One for the new channel */ 14633 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14634 /* Attended transfer to remote host, prepare headers for the INVITE */ 14635 if (p->refer->referred_by) 14636 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14637 } 14638 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14639 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14640 char tempheader[SIPBUFSIZE]; 14641 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14642 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14643 p->refer->replaces_callid_totag, 14644 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14645 p->refer->replaces_callid_fromtag); 14646 if (current.chan2) 14647 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14648 } 14649 /* Must release lock now, because it will not longer 14650 be accessible after the transfer! */ 14651 *nounlock = 1; 14652 ast_channel_unlock(current.chan1); 14653 14654 /* Connect the call */ 14655 14656 /* FAKE ringing if not attended transfer */ 14657 if (!p->refer->attendedtransfer) 14658 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14659 14660 /* For blind transfer, this will lead to a new call */ 14661 /* For attended transfer to remote host, this will lead to 14662 a new SIP call with a replaces header, if the dial plan allows it 14663 */ 14664 if (!current.chan2) { 14665 /* We have no bridge, so we're talking with Asterisk somehow */ 14666 /* We need to masquerade this call */ 14667 /* What to do to fix this situation: 14668 * Set up the new call in a new channel 14669 * Let the new channel masq into this channel 14670 Please add that code here :-) 14671 */ 14672 p->refer->status = REFER_FAILED; 14673 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14674 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14675 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14676 return -1; 14677 } 14678 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14679 14680 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14681 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14682 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14683 14684 if (!res) { 14685 /* Success - we have a new channel */ 14686 if (option_debug > 2) 14687 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14688 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14689 if (p->refer->localtransfer) 14690 p->refer->status = REFER_200OK; 14691 if (p->owner) 14692 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14693 append_history(p, "Xfer", "Refer succeeded."); 14694 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14695 /* Do not hangup call, the other side do that when we say 200 OK */ 14696 /* We could possibly implement a timer here, auto congestion */ 14697 res = 0; 14698 } else { 14699 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14700 if (option_debug > 2) 14701 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14702 append_history(p, "Xfer", "Refer failed."); 14703 /* Failure of some kind */ 14704 p->refer->status = REFER_FAILED; 14705 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14706 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14707 res = -1; 14708 } 14709 return res; 14710 }
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 15201 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().
15202 { 15203 enum check_auth_result res; 15204 15205 /* Use this as the basis */ 15206 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15207 ast_verbose("Using latest REGISTER request as basis request\n"); 15208 copy_request(&p->initreq, req); 15209 check_via(p, req); 15210 if ((res = register_verify(p, sin, req, e)) < 0) { 15211 const char *reason; 15212 15213 switch (res) { 15214 case AUTH_SECRET_FAILED: 15215 reason = "Wrong password"; 15216 break; 15217 case AUTH_USERNAME_MISMATCH: 15218 reason = "Username/auth name mismatch"; 15219 break; 15220 case AUTH_NOT_FOUND: 15221 reason = "No matching peer found"; 15222 break; 15223 case AUTH_UNKNOWN_DOMAIN: 15224 reason = "Not a local domain"; 15225 break; 15226 case AUTH_PEER_NOT_DYNAMIC: 15227 reason = "Peer is not supposed to register"; 15228 break; 15229 case AUTH_ACL_FAILED: 15230 reason = "Device does not match ACL"; 15231 break; 15232 default: 15233 reason = "Unknown failure"; 15234 break; 15235 } 15236 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15237 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15238 reason); 15239 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15240 } else 15241 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15242 15243 if (res < 1) { 15244 /* Destroy the session, but keep us around for just a bit in case they don't 15245 get our 200 OK */ 15246 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15247 } 15248 return res; 15249 }
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 14905 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, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.
Referenced by handle_request().
14906 { 14907 int gotdest; 14908 int res = 0; 14909 int firststate = AST_EXTENSION_REMOVED; 14910 struct sip_peer *authpeer = NULL; 14911 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14912 const char *accept = get_header(req, "Accept"); 14913 int resubscribe = (p->subscribed != NONE); 14914 char *temp, *event; 14915 14916 if (p->initreq.headers) { 14917 /* We already have a dialog */ 14918 if (p->initreq.method != SIP_SUBSCRIBE) { 14919 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14920 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14921 transmit_response(p, "403 Forbidden (within dialog)", req); 14922 /* Do not destroy session, since we will break the call if we do */ 14923 if (option_debug) 14924 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); 14925 return 0; 14926 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14927 if (option_debug) { 14928 if (resubscribe) 14929 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14930 else 14931 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14932 } 14933 } 14934 } 14935 14936 /* Check if we have a global disallow setting on subscriptions. 14937 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14938 */ 14939 if (!global_allowsubscribe) { 14940 transmit_response(p, "403 Forbidden (policy)", req); 14941 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14942 return 0; 14943 } 14944 14945 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14946 const char *to = get_header(req, "To"); 14947 char totag[128]; 14948 14949 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 14950 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 14951 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14952 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 14953 transmit_response(p, "481 Subscription does not exist", req); 14954 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14955 return 0; 14956 } 14957 14958 /* Use this as the basis */ 14959 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14960 ast_verbose("Creating new subscription\n"); 14961 14962 copy_request(&p->initreq, req); 14963 check_via(p, req); 14964 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14965 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14966 14967 /* Find parameters to Event: header value and remove them for now */ 14968 if (ast_strlen_zero(eventheader)) { 14969 transmit_response(p, "489 Bad Event", req); 14970 if (option_debug > 1) 14971 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14972 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14973 return 0; 14974 } 14975 14976 if ( (strchr(eventheader, ';'))) { 14977 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14978 temp = strchr(event, ';'); 14979 *temp = '\0'; /* Remove any options for now */ 14980 /* We might need to use them later :-) */ 14981 } else 14982 event = (char *) eventheader; /* XXX is this legal ? */ 14983 14984 /* Handle authentication */ 14985 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14986 /* if an authentication response was sent, we are done here */ 14987 if (res == AUTH_CHALLENGE_SENT) { 14988 if (authpeer) 14989 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14990 return 0; 14991 } 14992 if (res < 0) { 14993 if (res == AUTH_FAKE_AUTH) { 14994 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14995 transmit_fake_auth_response(p, req, 1); 14996 } else { 14997 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14998 transmit_response_reliable(p, "403 Forbidden", req); 14999 } 15000 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15001 if (authpeer) 15002 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15003 return 0; 15004 } 15005 15006 /* Check if this user/peer is allowed to subscribe at all */ 15007 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15008 transmit_response(p, "403 Forbidden (policy)", req); 15009 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15010 if (authpeer) 15011 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15012 return 0; 15013 } 15014 15015 /* Get destination right away */ 15016 gotdest = get_destination(p, NULL); 15017 15018 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15019 parse_ok_contact(p, req); 15020 15021 build_contact(p); 15022 if (strcmp(event, "message-summary") && gotdest) { 15023 transmit_response(p, "404 Not Found", req); 15024 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15025 if (authpeer) 15026 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15027 return 0; 15028 } 15029 15030 /* Initialize tag for new subscriptions */ 15031 if (ast_strlen_zero(p->tag)) 15032 make_our_tag(p->tag, sizeof(p->tag)); 15033 15034 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15035 if (authpeer) /* No need for authpeer here */ 15036 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15037 15038 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15039 /* Polycom phones only handle xpidf+xml, even if they say they can 15040 handle pidf+xml as well 15041 */ 15042 if (strstr(p->useragent, "Polycom")) { 15043 p->subscribed = XPIDF_XML; 15044 } else if (strstr(accept, "application/pidf+xml")) { 15045 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15046 } else if (strstr(accept, "application/dialog-info+xml")) { 15047 p->subscribed = DIALOG_INFO_XML; 15048 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15049 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15050 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15051 } else if (strstr(accept, "application/xpidf+xml")) { 15052 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15053 } else if (ast_strlen_zero(accept)) { 15054 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15055 transmit_response(p, "489 Bad Event", req); 15056 15057 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15058 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15059 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15060 return 0; 15061 } 15062 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15063 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15064 } else { 15065 /* Can't find a format for events that we know about */ 15066 char mybuf[200]; 15067 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15068 transmit_response(p, mybuf, req); 15069 15070 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15071 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15072 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15073 return 0; 15074 } 15075 } else if (!strcmp(event, "message-summary")) { 15076 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15077 /* Format requested that we do not support */ 15078 transmit_response(p, "406 Not Acceptable", req); 15079 if (option_debug > 1) 15080 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15081 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15082 if (authpeer) /* No need for authpeer here */ 15083 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15084 return 0; 15085 } 15086 /* Looks like they actually want a mailbox status 15087 This version of Asterisk supports mailbox subscriptions 15088 The subscribed URI needs to exist in the dial plan 15089 In most devices, this is configurable to the voicemailmain extension you use 15090 */ 15091 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15092 transmit_response(p, "404 Not found (no mailbox)", req); 15093 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15094 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15095 if (authpeer) /* No need for authpeer here */ 15096 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15097 return 0; 15098 } 15099 15100 p->subscribed = MWI_NOTIFICATION; 15101 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15102 /* We only allow one subscription per peer */ 15103 sip_destroy(authpeer->mwipvt); 15104 authpeer->mwipvt = p; /* Link from peer to pvt */ 15105 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15106 } else { /* At this point, Asterisk does not understand the specified event */ 15107 transmit_response(p, "489 Bad Event", req); 15108 if (option_debug > 1) 15109 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15110 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15111 if (authpeer) /* No need for authpeer here */ 15112 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15113 return 0; 15114 } 15115 15116 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15117 if (p->stateid > -1) 15118 ast_extension_state_del(p->stateid, cb_extensionstate); 15119 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15120 } 15121 15122 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15123 p->lastinvite = seqno; 15124 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15125 p->expiry = atoi(get_header(req, "Expires")); 15126 15127 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15128 if (p->expiry > max_expiry) 15129 p->expiry = max_expiry; 15130 if (p->expiry < min_expiry && p->expiry > 0) 15131 p->expiry = min_expiry; 15132 15133 if (sipdebug || option_debug > 1) { 15134 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15135 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15136 else 15137 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15138 } 15139 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15140 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15141 if (p->expiry > 0) 15142 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15143 15144 if (p->subscribed == MWI_NOTIFICATION) { 15145 transmit_response(p, "200 OK", req); 15146 if (p->relatedpeer) { /* Send first notification */ 15147 ASTOBJ_WRLOCK(p->relatedpeer); 15148 sip_send_mwi_to_peer(p->relatedpeer); 15149 ASTOBJ_UNLOCK(p->relatedpeer); 15150 } 15151 } else { 15152 struct sip_pvt *p_old; 15153 15154 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15155 15156 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)); 15157 transmit_response(p, "404 Not found", req); 15158 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15159 return 0; 15160 } 15161 15162 transmit_response(p, "200 OK", req); 15163 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15164 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15165 /* hide the 'complete' exten/context in the refer_to field for later display */ 15166 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15167 15168 /* remove any old subscription from this peer for the same exten/context, 15169 as the peer has obviously forgotten about it and it's wasteful to wait 15170 for it to expire and send NOTIFY messages to the peer only to have them 15171 ignored (or generate errors) 15172 */ 15173 ast_mutex_lock(&iflock); 15174 for (p_old = iflist; p_old; p_old = p_old->next) { 15175 if (p_old == p) 15176 continue; 15177 if (p_old->initreq.method != SIP_SUBSCRIBE) 15178 continue; 15179 if (p_old->subscribed == NONE) 15180 continue; 15181 ast_mutex_lock(&p_old->lock); 15182 if (!strcmp(p_old->username, p->username)) { 15183 if (!strcmp(p_old->exten, p->exten) && 15184 !strcmp(p_old->context, p->context)) { 15185 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15186 ast_mutex_unlock(&p_old->lock); 15187 break; 15188 } 15189 } 15190 ast_mutex_unlock(&p_old->lock); 15191 } 15192 ast_mutex_unlock(&iflock); 15193 } 15194 if (!p->expiry) 15195 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15196 } 15197 return 1; 15198 }
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 12708 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(), 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::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, 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.
12709 { 12710 struct ast_channel *owner; 12711 int sipmethod; 12712 int res = 1; 12713 const char *c = get_header(req, "Cseq"); 12714 const char *msg = strchr(c, ' '); 12715 12716 if (!msg) 12717 msg = ""; 12718 else 12719 msg++; 12720 sipmethod = find_sip_method(msg); 12721 12722 owner = p->owner; 12723 if (owner) 12724 owner->hangupcause = hangup_sip2cause(resp); 12725 12726 /* Acknowledge whatever it is destined for */ 12727 if ((resp >= 100) && (resp <= 199)) 12728 __sip_semi_ack(p, seqno, 0, sipmethod); 12729 else 12730 __sip_ack(p, seqno, 0, sipmethod); 12731 12732 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12733 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12734 p->pendinginvite = 0; 12735 12736 /* Get their tag if we haven't already */ 12737 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12738 char tag[128]; 12739 12740 gettag(req, "To", tag, sizeof(tag)); 12741 ast_string_field_set(p, theirtag, tag); 12742 } 12743 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12744 /* We don't really care what the response is, just that it replied back. 12745 Well, as long as it's not a 100 response... since we might 12746 need to hang around for something more "definitive" */ 12747 if (resp != 100) 12748 handle_response_peerpoke(p, resp, req); 12749 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12750 switch(resp) { 12751 case 100: /* 100 Trying */ 12752 case 101: /* 101 Dialog establishment */ 12753 if (sipmethod == SIP_INVITE) 12754 handle_response_invite(p, resp, rest, req, seqno); 12755 break; 12756 case 183: /* 183 Session Progress */ 12757 if (sipmethod == SIP_INVITE) 12758 handle_response_invite(p, resp, rest, req, seqno); 12759 break; 12760 case 180: /* 180 Ringing */ 12761 if (sipmethod == SIP_INVITE) 12762 handle_response_invite(p, resp, rest, req, seqno); 12763 break; 12764 case 182: /* 182 Queued */ 12765 if (sipmethod == SIP_INVITE) 12766 handle_response_invite(p, resp, rest, req, seqno); 12767 break; 12768 case 200: /* 200 OK */ 12769 p->authtries = 0; /* Reset authentication counter */ 12770 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12771 /* We successfully transmitted a message 12772 or a video update request in INFO */ 12773 /* Nothing happens here - the message is inside a dialog */ 12774 } else if (sipmethod == SIP_INVITE) { 12775 handle_response_invite(p, resp, rest, req, seqno); 12776 } else if (sipmethod == SIP_NOTIFY) { 12777 /* They got the notify, this is the end */ 12778 if (p->owner) { 12779 if (!p->refer) { 12780 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12781 ast_queue_hangup(p->owner); 12782 } else if (option_debug > 3) 12783 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12784 } else { 12785 if (p->subscribed == NONE) 12786 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12787 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12788 /* Ready to send the next state we have on queue */ 12789 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12790 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 12791 } 12792 } 12793 } else if (sipmethod == SIP_REGISTER) 12794 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12795 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12796 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12797 break; 12798 case 202: /* Transfer accepted */ 12799 if (sipmethod == SIP_REFER) 12800 handle_response_refer(p, resp, rest, req, seqno); 12801 break; 12802 case 401: /* Not www-authorized on SIP method */ 12803 if (sipmethod == SIP_INVITE) 12804 handle_response_invite(p, resp, rest, req, seqno); 12805 else if (sipmethod == SIP_REFER) 12806 handle_response_refer(p, resp, rest, req, seqno); 12807 else if (p->registry && sipmethod == SIP_REGISTER) 12808 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12809 else if (sipmethod == SIP_BYE) { 12810 if (ast_strlen_zero(p->authname)) { 12811 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12812 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12813 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12814 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12815 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12816 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12817 /* We fail to auth bye on our own call, but still needs to tear down the call. 12818 Life, they call it. */ 12819 } 12820 } else { 12821 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12822 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12823 } 12824 break; 12825 case 403: /* Forbidden - we failed authentication */ 12826 if (sipmethod == SIP_INVITE) 12827 handle_response_invite(p, resp, rest, req, seqno); 12828 else if (p->registry && sipmethod == SIP_REGISTER) 12829 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12830 else { 12831 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12832 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12833 } 12834 break; 12835 case 404: /* Not found */ 12836 if (p->registry && sipmethod == SIP_REGISTER) 12837 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12838 else if (sipmethod == SIP_INVITE) 12839 handle_response_invite(p, resp, rest, req, seqno); 12840 else if (owner) 12841 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12842 break; 12843 case 407: /* Proxy auth required */ 12844 if (sipmethod == SIP_INVITE) 12845 handle_response_invite(p, resp, rest, req, seqno); 12846 else if (sipmethod == SIP_REFER) 12847 handle_response_refer(p, resp, rest, req, seqno); 12848 else if (p->registry && sipmethod == SIP_REGISTER) 12849 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12850 else if (sipmethod == SIP_BYE) { 12851 if (ast_strlen_zero(p->authname)) { 12852 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12853 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12854 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12855 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12856 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12857 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12858 } 12859 } else /* We can't handle this, giving up in a bad way */ 12860 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12861 12862 break; 12863 case 408: /* Request timeout - terminate dialog */ 12864 if (sipmethod == SIP_INVITE) 12865 handle_response_invite(p, resp, rest, req, seqno); 12866 else if (sipmethod == SIP_REGISTER) 12867 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12868 else if (sipmethod == SIP_BYE) { 12869 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12870 if (option_debug) 12871 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12872 } else { 12873 if (owner) 12874 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12875 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12876 } 12877 break; 12878 case 481: /* Call leg does not exist */ 12879 if (sipmethod == SIP_INVITE) { 12880 handle_response_invite(p, resp, rest, req, seqno); 12881 } else if (sipmethod == SIP_REFER) { 12882 handle_response_refer(p, resp, rest, req, seqno); 12883 } else if (sipmethod == SIP_BYE) { 12884 /* The other side has no transaction to bye, 12885 just assume it's all right then */ 12886 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12887 } else if (sipmethod == SIP_CANCEL) { 12888 /* The other side has no transaction to cancel, 12889 just assume it's all right then */ 12890 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12891 } else { 12892 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12893 /* Guessing that this is not an important request */ 12894 } 12895 break; 12896 case 487: 12897 if (sipmethod == SIP_INVITE) 12898 handle_response_invite(p, resp, rest, req, seqno); 12899 break; 12900 case 488: /* Not acceptable here - codec error */ 12901 if (sipmethod == SIP_INVITE) 12902 handle_response_invite(p, resp, rest, req, seqno); 12903 break; 12904 case 491: /* Pending */ 12905 if (sipmethod == SIP_INVITE) 12906 handle_response_invite(p, resp, rest, req, seqno); 12907 else { 12908 if (option_debug) 12909 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12910 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12911 } 12912 break; 12913 case 501: /* Not Implemented */ 12914 if (sipmethod == SIP_INVITE) 12915 handle_response_invite(p, resp, rest, req, seqno); 12916 else if (sipmethod == SIP_REFER) 12917 handle_response_refer(p, resp, rest, req, seqno); 12918 else 12919 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12920 break; 12921 case 603: /* Declined transfer */ 12922 if (sipmethod == SIP_REFER) { 12923 handle_response_refer(p, resp, rest, req, seqno); 12924 break; 12925 } 12926 /* Fallthrough */ 12927 default: 12928 if ((resp >= 300) && (resp < 700)) { 12929 /* Fatal response */ 12930 if ((option_verbose > 2) && (resp != 487)) 12931 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12932 12933 if (sipmethod == SIP_INVITE) 12934 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12935 12936 /* XXX Locking issues?? XXX */ 12937 switch(resp) { 12938 case 300: /* Multiple Choices */ 12939 case 301: /* Moved permenantly */ 12940 case 302: /* Moved temporarily */ 12941 case 305: /* Use Proxy */ 12942 parse_moved_contact(p, req); 12943 /* Fall through */ 12944 case 486: /* Busy here */ 12945 case 600: /* Busy everywhere */ 12946 case 603: /* Decline */ 12947 if (p->owner) 12948 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12949 break; 12950 case 482: /* 12951 \note SIP is incapable of performing a hairpin call, which 12952 is yet another failure of not having a layer 2 (again, YAY 12953 IETF for thinking ahead). So we treat this as a call 12954 forward and hope we end up at the right place... */ 12955 if (option_debug) 12956 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12957 if (p->owner) 12958 ast_string_field_build(p->owner, call_forward, 12959 "Local/%s@%s", p->username, p->context); 12960 /* Fall through */ 12961 case 480: /* Temporarily Unavailable */ 12962 case 404: /* Not Found */ 12963 case 410: /* Gone */ 12964 case 400: /* Bad Request */ 12965 case 500: /* Server error */ 12966 if (sipmethod == SIP_REFER) { 12967 handle_response_refer(p, resp, rest, req, seqno); 12968 break; 12969 } 12970 /* Fall through */ 12971 case 502: /* Bad gateway */ 12972 case 503: /* Service Unavailable */ 12973 case 504: /* Server Timeout */ 12974 if (owner) 12975 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12976 break; 12977 default: 12978 /* Send hangup */ 12979 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12980 ast_queue_hangup(p->owner); 12981 break; 12982 } 12983 /* ACK on invite */ 12984 if (sipmethod == SIP_INVITE) 12985 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12986 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12987 sip_alreadygone(p); 12988 if (!p->owner) 12989 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12990 } else if ((resp >= 100) && (resp < 200)) { 12991 if (sipmethod == SIP_INVITE) { 12992 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 12993 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12994 if (find_sdp(req)) 12995 process_sdp(p, req); 12996 if (p->owner) { 12997 /* Queue a progress frame */ 12998 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12999 } 13000 } 13001 } else 13002 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)); 13003 } 13004 } else { 13005 /* Responses to OUTGOING SIP requests on INCOMING calls 13006 get handled here. As well as out-of-call message responses */ 13007 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13008 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13009 13010 if (sipmethod == SIP_INVITE && resp == 200) { 13011 /* Tags in early session is replaced by the tag in 200 OK, which is 13012 the final reply to our INVITE */ 13013 char tag[128]; 13014 13015 gettag(req, "To", tag, sizeof(tag)); 13016 ast_string_field_set(p, theirtag, tag); 13017 } 13018 13019 switch(resp) { 13020 case 200: 13021 if (sipmethod == SIP_INVITE) { 13022 handle_response_invite(p, resp, rest, req, seqno); 13023 } else if (sipmethod == SIP_CANCEL) { 13024 if (option_debug) 13025 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13026 13027 /* Wait for 487, then destroy */ 13028 } else if (sipmethod == SIP_NOTIFY) { 13029 /* They got the notify, this is the end */ 13030 if (p->owner) { 13031 if (p->refer) { 13032 if (option_debug) 13033 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13034 } else 13035 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13036 /* ast_queue_hangup(p->owner); Disabled */ 13037 } else { 13038 if (!p->subscribed && !p->refer) 13039 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13040 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13041 /* Ready to send the next state we have on queue */ 13042 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13043 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p, NULL, NULL); 13044 } 13045 } 13046 } else if (sipmethod == SIP_BYE) 13047 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13048 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13049 /* We successfully transmitted a message or 13050 a video update request in INFO */ 13051 ; 13052 else if (sipmethod == SIP_BYE) 13053 /* Ok, we're ready to go */ 13054 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13055 break; 13056 case 202: /* Transfer accepted */ 13057 if (sipmethod == SIP_REFER) 13058 handle_response_refer(p, resp, rest, req, seqno); 13059 break; 13060 case 401: /* www-auth */ 13061 case 407: 13062 if (sipmethod == SIP_REFER) 13063 handle_response_refer(p, resp, rest, req, seqno); 13064 else if (sipmethod == SIP_INVITE) 13065 handle_response_invite(p, resp, rest, req, seqno); 13066 else if (sipmethod == SIP_BYE) { 13067 char *auth, *auth2; 13068 13069 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13070 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13071 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13072 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13073 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13074 } 13075 } 13076 break; 13077 case 481: /* Call leg does not exist */ 13078 if (sipmethod == SIP_INVITE) { 13079 /* Re-invite failed */ 13080 handle_response_invite(p, resp, rest, req, seqno); 13081 } else if (sipmethod == SIP_BYE) { 13082 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13083 } else if (sipdebug) { 13084 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13085 } 13086 break; 13087 case 501: /* Not Implemented */ 13088 if (sipmethod == SIP_INVITE) 13089 handle_response_invite(p, resp, rest, req, seqno); 13090 else if (sipmethod == SIP_REFER) 13091 handle_response_refer(p, resp, rest, req, seqno); 13092 break; 13093 case 603: /* Declined transfer */ 13094 if (sipmethod == SIP_REFER) { 13095 handle_response_refer(p, resp, rest, req, seqno); 13096 break; 13097 } 13098 /* Fallthrough */ 13099 default: /* Errors without handlers */ 13100 if ((resp >= 100) && (resp < 200)) { 13101 if (sipmethod == SIP_INVITE) { /* re-invite */ 13102 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13103 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13104 } 13105 } 13106 if ((resp >= 300) && (resp < 700)) { 13107 if ((option_verbose > 2) && (resp != 487)) 13108 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)); 13109 switch(resp) { 13110 case 488: /* Not acceptable here - codec error */ 13111 case 603: /* Decline */ 13112 case 500: /* Server error */ 13113 case 502: /* Bad gateway */ 13114 case 503: /* Service Unavailable */ 13115 case 504: /* Server timeout */ 13116 13117 /* re-invite failed */ 13118 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13119 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13120 break; 13121 } 13122 } 13123 break; 13124 } 13125 } 13126 }
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 12119 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, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, 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().
12120 { 12121 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12122 int res = 0; 12123 int xmitres = 0; 12124 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12125 struct ast_channel *bridgepeer = NULL; 12126 12127 if (option_debug > 3) { 12128 if (reinvite) 12129 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12130 else 12131 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12132 } 12133 12134 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12135 if (option_debug) 12136 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12137 return; 12138 } 12139 12140 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12141 /* Don't auto congest anymore since we've gotten something useful back */ 12142 AST_SCHED_DEL(sched, p->initid); 12143 12144 /* RFC3261 says we must treat every 1xx response (but not 100) 12145 that we don't recognize as if it was 183. 12146 */ 12147 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12148 resp = 183; 12149 12150 /* Any response between 100 and 199 is PROCEEDING */ 12151 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12152 p->invitestate = INV_PROCEEDING; 12153 12154 /* Final response, not 200 ? */ 12155 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12156 p->invitestate = INV_COMPLETED; 12157 12158 12159 switch (resp) { 12160 case 100: /* Trying */ 12161 case 101: /* Dialog establishment */ 12162 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12163 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12164 check_pendings(p); 12165 break; 12166 12167 case 180: /* 180 Ringing */ 12168 case 182: /* 182 Queued */ 12169 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12170 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12171 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12172 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12173 if (p->owner->_state != AST_STATE_UP) { 12174 ast_setstate(p->owner, AST_STATE_RINGING); 12175 } 12176 } 12177 if (find_sdp(req)) { 12178 if (p->invitestate != INV_CANCELLED) 12179 p->invitestate = INV_EARLY_MEDIA; 12180 res = process_sdp(p, req); 12181 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12182 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12183 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12184 } 12185 } 12186 check_pendings(p); 12187 break; 12188 12189 case 183: /* Session progress */ 12190 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12191 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12192 /* Ignore 183 Session progress without SDP */ 12193 if (find_sdp(req)) { 12194 if (p->invitestate != INV_CANCELLED) 12195 p->invitestate = INV_EARLY_MEDIA; 12196 res = process_sdp(p, req); 12197 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12198 /* Queue a progress frame */ 12199 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12200 } 12201 } 12202 check_pendings(p); 12203 break; 12204 12205 case 200: /* 200 OK on invite - someone's answering our call */ 12206 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12207 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12208 p->authtries = 0; 12209 if (find_sdp(req)) { 12210 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12211 if (!reinvite) 12212 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12213 /* For re-invites, we try to recover */ 12214 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12215 } 12216 12217 /* Parse contact header for continued conversation */ 12218 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12219 /* This is important when we have a SIP proxy between us and the phone */ 12220 if (outgoing) { 12221 update_call_counter(p, DEC_CALL_RINGING); 12222 parse_ok_contact(p, req); 12223 if(set_address_from_contact(p)) { 12224 /* Bad contact - we don't know how to reach this device */ 12225 /* We need to ACK, but then send a bye */ 12226 /* OEJ: Possible issue that may need a check: 12227 If we have a proxy route between us and the device, 12228 should we care about resolving the contact 12229 or should we just send it? 12230 */ 12231 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12232 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12233 } 12234 12235 /* Save Record-Route for any later requests we make on this dialogue */ 12236 if (!reinvite) 12237 build_route(p, req, 1); 12238 } 12239 12240 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12241 struct sip_pvt *bridgepvt = NULL; 12242 12243 if (!bridgepeer->tech) { 12244 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12245 break; 12246 } 12247 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12248 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12249 if (bridgepvt->udptl) { 12250 if (p->t38.state == T38_PEER_REINVITE) { 12251 sip_handle_t38_reinvite(bridgepeer, p, 0); 12252 ast_rtp_set_rtptimers_onhold(p->rtp); 12253 if (p->vrtp) 12254 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12255 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12256 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12257 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12258 /* XXXX Should we really destroy this session here, without any response at all??? */ 12259 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12260 } 12261 } else { 12262 if (option_debug > 1) 12263 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12264 ast_mutex_lock(&bridgepvt->lock); 12265 bridgepvt->t38.state = T38_DISABLED; 12266 ast_mutex_unlock(&bridgepvt->lock); 12267 if (option_debug) 12268 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12269 p->t38.state = T38_DISABLED; 12270 if (option_debug > 1) 12271 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12272 } 12273 } else { 12274 /* Other side is not a SIP channel */ 12275 if (option_debug > 1) 12276 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12277 p->t38.state = T38_DISABLED; 12278 if (option_debug > 1) 12279 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12280 } 12281 } 12282 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12283 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12284 p->t38.state = T38_ENABLED; 12285 if (option_debug) 12286 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12287 } 12288 12289 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12290 if (!reinvite) { 12291 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12292 } else { /* RE-invite */ 12293 ast_queue_frame(p->owner, &ast_null_frame); 12294 } 12295 } else { 12296 /* It's possible we're getting an 200 OK after we've tried to disconnect 12297 by sending CANCEL */ 12298 /* First send ACK, then send bye */ 12299 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12300 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12301 } 12302 /* If I understand this right, the branch is different for a non-200 ACK only */ 12303 p->invitestate = INV_TERMINATED; 12304 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12305 check_pendings(p); 12306 break; 12307 case 407: /* Proxy authentication */ 12308 case 401: /* Www auth */ 12309 /* First we ACK */ 12310 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12311 if (p->options) 12312 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12313 12314 /* Then we AUTH */ 12315 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12316 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12317 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12318 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12319 if (p->authtries < MAX_AUTHTRIES) 12320 p->invitestate = INV_CALLING; 12321 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12322 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12323 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12324 sip_alreadygone(p); 12325 if (p->owner) 12326 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12327 } 12328 } 12329 break; 12330 12331 case 403: /* Forbidden */ 12332 /* First we ACK */ 12333 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12334 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12335 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12336 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12337 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12338 sip_alreadygone(p); 12339 break; 12340 12341 case 404: /* Not found */ 12342 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12343 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12344 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12345 sip_alreadygone(p); 12346 break; 12347 12348 case 408: /* Request timeout */ 12349 case 481: /* Call leg does not exist */ 12350 /* Could be REFER caused INVITE with replaces */ 12351 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12352 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12353 if (p->owner) 12354 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12355 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12356 break; 12357 case 487: /* Cancelled transaction */ 12358 /* We have sent CANCEL on an outbound INVITE 12359 This transaction is already scheduled to be killed by sip_hangup(). 12360 */ 12361 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12362 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12363 ast_queue_hangup(p->owner); 12364 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12365 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12366 update_call_counter(p, DEC_CALL_LIMIT); 12367 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12368 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12369 sip_alreadygone(p); 12370 } 12371 break; 12372 case 488: /* Not acceptable here */ 12373 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12374 if (reinvite && p->udptl) { 12375 /* If this is a T.38 call, we should go back to 12376 audio. If this is an audio call - something went 12377 terribly wrong since we don't renegotiate codecs, 12378 only IP/port . 12379 */ 12380 p->t38.state = T38_DISABLED; 12381 /* Try to reset RTP timers */ 12382 ast_rtp_set_rtptimers_onhold(p->rtp); 12383 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12384 12385 /*! \bug Is there any way we can go back to the audio call on both 12386 sides here? 12387 */ 12388 /* While figuring that out, hangup the call */ 12389 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12390 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12391 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12392 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12393 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12394 right now we can't fall back to audio so totally abort. 12395 */ 12396 p->t38.state = T38_DISABLED; 12397 /* Try to reset RTP timers */ 12398 ast_rtp_set_rtptimers_onhold(p->rtp); 12399 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12400 12401 /* The dialog is now terminated */ 12402 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12403 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12404 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12405 sip_alreadygone(p); 12406 } else { 12407 /* We can't set up this call, so give up */ 12408 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12409 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12410 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12411 /* If there's no dialog to end, then mark p as already gone */ 12412 if (!reinvite) 12413 sip_alreadygone(p); 12414 } 12415 break; 12416 case 491: /* Pending */ 12417 /* we really should have to wait a while, then retransmit 12418 * We should support the retry-after at some point 12419 * At this point, we treat this as a congestion if the call is not in UP state 12420 */ 12421 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12422 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12423 if (p->owner->_state != AST_STATE_UP) { 12424 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12425 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12426 } else { 12427 /* This is a re-invite that failed. 12428 * Reset the flag after a while 12429 */ 12430 int wait = 3 + ast_random() % 5; 12431 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12432 if (option_debug > 2) 12433 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12434 } 12435 } 12436 break; 12437 12438 case 501: /* Not implemented */ 12439 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12440 if (p->owner) 12441 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12442 break; 12443 } 12444 if (xmitres == XMIT_ERROR) 12445 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12446 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12641 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, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12642 { 12643 struct sip_peer *peer = p->relatedpeer; 12644 int statechanged, is_reachable, was_reachable; 12645 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12646 12647 /* 12648 * Compute the response time to a ping (goes in peer->lastms.) 12649 * -1 means did not respond, 0 means unknown, 12650 * 1..maxms is a valid response, >maxms means late response. 12651 */ 12652 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12653 pingtime = 1; 12654 12655 /* Now determine new state and whether it has changed. 12656 * Use some helper variables to simplify the writing 12657 * of the expressions. 12658 */ 12659 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12660 is_reachable = pingtime <= peer->maxms; 12661 statechanged = peer->lastms == 0 /* yes, unknown before */ 12662 || was_reachable != is_reachable; 12663 12664 peer->lastms = pingtime; 12665 peer->call = NULL; 12666 if (statechanged) { 12667 const char *s = is_reachable ? "Reachable" : "Lagged"; 12668 12669 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12670 peer->name, s, pingtime, peer->maxms); 12671 ast_device_state_changed("SIP/%s", peer->name); 12672 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12673 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12674 peer->name, s, pingtime); 12675 } 12676 12677 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12678 struct sip_peer *peer_ptr = peer; 12679 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12680 } 12681 12682 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12683 12684 /* Try again eventually */ 12685 peer->pokeexpire = ast_sched_add(sched, 12686 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12687 sip_poke_peer_s, ASTOBJ_REF(peer)); 12688 12689 if (peer->pokeexpire == -1) { 12690 ASTOBJ_UNREF(peer, sip_destroy_peer); 12691 } 12692 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12451 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, 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().
12452 { 12453 char *auth = "Proxy-Authenticate"; 12454 char *auth2 = "Proxy-Authorization"; 12455 12456 /* If no refer structure exists, then do nothing */ 12457 if (!p->refer) 12458 return; 12459 12460 switch (resp) { 12461 case 202: /* Transfer accepted */ 12462 /* We need to do something here */ 12463 /* The transferee is now sending INVITE to target */ 12464 p->refer->status = REFER_ACCEPTED; 12465 /* Now wait for next message */ 12466 if (option_debug > 2) 12467 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12468 /* We should hang along, waiting for NOTIFY's here */ 12469 break; 12470 12471 case 401: /* Not www-authorized on SIP method */ 12472 case 407: /* Proxy auth */ 12473 if (ast_strlen_zero(p->authname)) { 12474 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12475 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12476 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12477 } 12478 if (resp == 401) { 12479 auth = "WWW-Authenticate"; 12480 auth2 = "Authorization"; 12481 } 12482 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12483 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12484 p->refer->status = REFER_NOAUTH; 12485 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12486 } 12487 break; 12488 case 481: /* Call leg does not exist */ 12489 12490 /* A transfer with Replaces did not work */ 12491 /* OEJ: We should Set flag, cancel the REFER, go back 12492 to original call - but right now we can't */ 12493 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12494 if (p->owner) 12495 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12496 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12497 break; 12498 12499 case 500: /* Server error */ 12500 case 501: /* Method not implemented */ 12501 /* Return to the current call onhold */ 12502 /* Status flag needed to be reset */ 12503 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12504 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12505 p->refer->status = REFER_FAILED; 12506 break; 12507 case 603: /* Transfer declined */ 12508 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12509 p->refer->status = REFER_FAILED; 12510 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12511 break; 12512 } 12513 }
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 12516 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, 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, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12517 { 12518 int expires, expires_ms; 12519 struct sip_registry *r; 12520 r=p->registry; 12521 12522 switch (resp) { 12523 case 401: /* Unauthorized */ 12524 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12525 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12526 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12527 } 12528 break; 12529 case 403: /* Forbidden */ 12530 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12531 if (global_regattempts_max) 12532 p->registry->regattempts = global_regattempts_max+1; 12533 AST_SCHED_DEL(sched, r->timeout); 12534 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12535 break; 12536 case 404: /* Not found */ 12537 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12538 if (global_regattempts_max) 12539 p->registry->regattempts = global_regattempts_max+1; 12540 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12541 r->call = NULL; 12542 AST_SCHED_DEL(sched, r->timeout); 12543 break; 12544 case 407: /* Proxy auth */ 12545 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12546 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12547 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12548 } 12549 break; 12550 case 408: /* Request timeout */ 12551 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12552 r->call = NULL; 12553 AST_SCHED_DEL(sched, r->timeout); 12554 break; 12555 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12556 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12557 if (global_regattempts_max) 12558 p->registry->regattempts = global_regattempts_max+1; 12559 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12560 r->call = NULL; 12561 AST_SCHED_DEL(sched, r->timeout); 12562 break; 12563 case 200: /* 200 OK */ 12564 if (!r) { 12565 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12566 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12567 return 0; 12568 } 12569 12570 r->regstate = REG_STATE_REGISTERED; 12571 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12572 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12573 r->regattempts = 0; 12574 if (option_debug) 12575 ast_log(LOG_DEBUG, "Registration successful\n"); 12576 if (r->timeout > -1) { 12577 if (option_debug) 12578 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12579 } 12580 AST_SCHED_DEL(sched, r->timeout); 12581 r->call = NULL; 12582 p->registry = NULL; 12583 /* Let this one hang around until we have all the responses */ 12584 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12585 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12586 12587 /* set us up for re-registering */ 12588 /* figure out how long we got registered for */ 12589 AST_SCHED_DEL(sched, r->expire); 12590 /* according to section 6.13 of RFC, contact headers override 12591 expires headers, so check those first */ 12592 expires = 0; 12593 12594 /* XXX todo: try to save the extra call */ 12595 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12596 const char *contact = NULL; 12597 const char *tmptmp = NULL; 12598 int start = 0; 12599 for(;;) { 12600 contact = __get_header(req, "Contact", &start); 12601 /* this loop ensures we get a contact header about our register request */ 12602 if(!ast_strlen_zero(contact)) { 12603 if( (tmptmp=strstr(contact, p->our_contact))) { 12604 contact=tmptmp; 12605 break; 12606 } 12607 } else 12608 break; 12609 } 12610 tmptmp = strcasestr(contact, "expires="); 12611 if (tmptmp) { 12612 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12613 expires = 0; 12614 } 12615 12616 } 12617 if (!expires) 12618 expires=atoi(get_header(req, "expires")); 12619 if (!expires) 12620 expires=default_expiry; 12621 12622 expires_ms = expires * 1000; 12623 if (expires <= EXPIRY_GUARD_LIMIT) 12624 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12625 else 12626 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12627 if (sipdebug) 12628 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12629 12630 r->refresh= (int) expires_ms / 1000; 12631 12632 /* Schedule re-registration before we expire */ 12633 AST_SCHED_DEL(sched, r->expire); 12634 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12635 ASTOBJ_UNREF(r, sip_registry_destroy); 12636 } 12637 return 1; 12638 }
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 5869 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05870 { 05871 /* Initialize a request */ 05872 memset(req, 0, sizeof(*req)); 05873 req->method = sipmethod; 05874 req->header[0] = req->data; 05875 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05876 req->len = strlen(req->header[0]); 05877 req->headers++; 05878 return 0; 05879 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5856 of file chan_sip.c.
References SIP_RESPONSE.
05857 { 05858 /* Initialize a response */ 05859 memset(resp, 0, sizeof(*resp)); 05860 resp->method = SIP_RESPONSE; 05861 resp->header[0] = resp->data; 05862 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05863 resp->len = strlen(resp->header[0]); 05864 resp->headers++; 05865 return 0; 05866 }
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 6956 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().
06957 { 06958 char invite_buf[256] = ""; 06959 char *invite = invite_buf; 06960 size_t invite_max = sizeof(invite_buf); 06961 char from[256]; 06962 char to[256]; 06963 char tmp[SIPBUFSIZE/2]; 06964 char tmp2[SIPBUFSIZE/2]; 06965 const char *l = NULL, *n = NULL; 06966 const char *urioptions = ""; 06967 06968 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06969 const char *s = p->username; /* being a string field, cannot be NULL */ 06970 06971 /* Test p->username against allowed characters in AST_DIGIT_ANY 06972 If it matches the allowed characters list, then sipuser = ";user=phone" 06973 If not, then sipuser = "" 06974 */ 06975 /* + is allowed in first position in a tel: uri */ 06976 if (*s == '+') 06977 s++; 06978 for (; *s; s++) { 06979 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06980 break; 06981 } 06982 /* If we have only digits, add ;user=phone to the uri */ 06983 if (*s) 06984 urioptions = ";user=phone"; 06985 } 06986 06987 06988 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06989 06990 if (p->owner) { 06991 l = p->owner->cid.cid_num; 06992 n = p->owner->cid.cid_name; 06993 } 06994 /* if we are not sending RPID and user wants his callerid restricted */ 06995 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06996 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06997 l = CALLERID_UNKNOWN; 06998 n = l; 06999 } 07000 if (ast_strlen_zero(l)) 07001 l = default_callerid; 07002 if (ast_strlen_zero(n)) 07003 n = l; 07004 /* Allow user to be overridden */ 07005 if (!ast_strlen_zero(p->fromuser)) 07006 l = p->fromuser; 07007 else /* Save for any further attempts */ 07008 ast_string_field_set(p, fromuser, l); 07009 07010 /* Allow user to be overridden */ 07011 if (!ast_strlen_zero(p->fromname)) 07012 n = p->fromname; 07013 else /* Save for any further attempts */ 07014 ast_string_field_set(p, fromname, n); 07015 07016 if (pedanticsipchecking) { 07017 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07018 n = tmp; 07019 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07020 l = tmp2; 07021 } 07022 07023 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07024 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); 07025 else 07026 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07027 07028 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07029 if (!ast_strlen_zero(p->fullcontact)) { 07030 /* If we have full contact, trust it */ 07031 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07032 } else { 07033 /* Otherwise, use the username while waiting for registration */ 07034 ast_build_string(&invite, &invite_max, "sip:"); 07035 if (!ast_strlen_zero(p->username)) { 07036 n = p->username; 07037 if (pedanticsipchecking) { 07038 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07039 n = tmp; 07040 } 07041 ast_build_string(&invite, &invite_max, "%s@", n); 07042 } 07043 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07044 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07045 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07046 ast_build_string(&invite, &invite_max, "%s", urioptions); 07047 } 07048 07049 /* If custom URI options have been provided, append them */ 07050 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07051 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07052 07053 ast_string_field_set(p, uri, invite_buf); 07054 07055 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07056 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07057 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07058 } else if (p->options && p->options->vxml_url) { 07059 /* If there is a VXML URL append it to the SIP URL */ 07060 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07061 } else 07062 snprintf(to, sizeof(to), "<%s>", p->uri); 07063 07064 init_req(req, sipmethod, p->uri); 07065 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07066 07067 add_header(req, "Via", p->via); 07068 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07069 * OTOH, then we won't have anything in p->route anyway */ 07070 /* Build Remote Party-ID and From */ 07071 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07072 build_rpid(p); 07073 add_header(req, "From", p->rpid_from); 07074 } else 07075 add_header(req, "From", from); 07076 add_header(req, "To", to); 07077 ast_string_field_set(p, exten, l); 07078 build_contact(p); 07079 add_header(req, "Contact", p->our_contact); 07080 add_header(req, "Call-ID", p->callid); 07081 add_header(req, "CSeq", tmp); 07082 if (!ast_strlen_zero(global_useragent)) 07083 add_header(req, "User-Agent", global_useragent); 07084 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07085 if (!ast_strlen_zero(p->rpid)) 07086 add_header(req, "Remote-Party-ID", p->rpid); 07087 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10135 of file chan_sip.c.
Referenced by _sip_show_peer().
10136 { 10137 if (port && invite) 10138 return "port,invite"; 10139 else if (port) 10140 return "port"; 10141 else if (invite) 10142 return "invite"; 10143 else 10144 return "no"; 10145 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8283 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08284 { 08285 if (!route) 08286 ast_verbose("list_route: no route\n"); 08287 else { 08288 for (;route; route = route->next) 08289 ast_verbose("list_route: hop: <%s>\n", route->hop); 08290 } 08291 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18135 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, checksipdomain_function, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
18136 { 18137 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18138 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18139 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18140 18141 if (!(sched = sched_context_create())) { 18142 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18143 return AST_MODULE_LOAD_FAILURE; 18144 } 18145 18146 if (!(io = io_context_create())) { 18147 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18148 sched_context_destroy(sched); 18149 return AST_MODULE_LOAD_FAILURE; 18150 } 18151 18152 sip_reloadreason = CHANNEL_MODULE_LOAD; 18153 18154 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18155 return AST_MODULE_LOAD_DECLINE; 18156 18157 /* Make sure we can register our sip channel type */ 18158 if (ast_channel_register(&sip_tech)) { 18159 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18160 io_context_destroy(io); 18161 sched_context_destroy(sched); 18162 return AST_MODULE_LOAD_FAILURE; 18163 } 18164 18165 /* Register all CLI functions for SIP */ 18166 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18167 18168 /* Tell the RTP subdriver that we're here */ 18169 ast_rtp_proto_register(&sip_rtp); 18170 18171 /* Tell the UDPTL subdriver that we're here */ 18172 ast_udptl_proto_register(&sip_udptl); 18173 18174 /* Register dialplan applications */ 18175 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18176 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18177 18178 /* Register dialplan functions */ 18179 ast_custom_function_register(&sip_header_function); 18180 ast_custom_function_register(&sippeer_function); 18181 ast_custom_function_register(&sipchaninfo_function); 18182 ast_custom_function_register(&checksipdomain_function); 18183 18184 /* Register manager commands */ 18185 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18186 "List SIP peers (text format)", mandescr_show_peers); 18187 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18188 "Show SIP peer (text format)", mandescr_show_peer); 18189 18190 sip_poke_all_peers(); 18191 sip_send_all_registers(); 18192 18193 /* And start the monitor for the first time */ 18194 restart_monitor(); 18195 18196 return AST_MODULE_LOAD_SUCCESS; 18197 }
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 14278 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().
14279 { 14280 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14281 /* Chan 2: Call from Asterisk to target */ 14282 int res = 0; 14283 struct sip_pvt *targetcall_pvt; 14284 14285 /* Check if the call ID of the replaces header does exist locally */ 14286 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14287 transferer->refer->replaces_callid_fromtag))) { 14288 if (transferer->refer->localtransfer) { 14289 /* We did not find the refered call. Sorry, can't accept then */ 14290 transmit_response(transferer, "202 Accepted", req); 14291 /* Let's fake a response from someone else in order 14292 to follow the standard */ 14293 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14294 append_history(transferer, "Xfer", "Refer failed"); 14295 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14296 transferer->refer->status = REFER_FAILED; 14297 return -1; 14298 } 14299 /* Fall through for remote transfers that we did not find locally */ 14300 if (option_debug > 2) 14301 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14302 return 0; 14303 } 14304 14305 /* Ok, we can accept this transfer */ 14306 transmit_response(transferer, "202 Accepted", req); 14307 append_history(transferer, "Xfer", "Refer accepted"); 14308 if (!targetcall_pvt->owner) { /* No active channel */ 14309 if (option_debug > 3) 14310 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14311 /* Cancel transfer */ 14312 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14313 append_history(transferer, "Xfer", "Refer failed"); 14314 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14315 transferer->refer->status = REFER_FAILED; 14316 ast_mutex_unlock(&targetcall_pvt->lock); 14317 ast_channel_unlock(current->chan1); 14318 return -1; 14319 } 14320 14321 /* We have a channel, find the bridge */ 14322 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14323 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14324 14325 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14326 /* Wrong state of new channel */ 14327 if (option_debug > 3) { 14328 if (target.chan2) 14329 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14330 else if (target.chan1->_state != AST_STATE_RING) 14331 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14332 else 14333 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14334 } 14335 } 14336 14337 /* Transfer */ 14338 if (option_debug > 3 && sipdebug) { 14339 if (current->chan2) /* We have two bridges */ 14340 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14341 else /* One bridge, propably transfer of IVR/voicemail etc */ 14342 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14343 } 14344 14345 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14346 14347 /* Perform the transfer */ 14348 res = attempt_transfer(current, &target); 14349 ast_mutex_unlock(&targetcall_pvt->lock); 14350 if (res) { 14351 /* Failed transfer */ 14352 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14353 append_history(transferer, "Xfer", "Refer failed"); 14354 transferer->refer->status = REFER_FAILED; 14355 if (targetcall_pvt->owner) 14356 ast_channel_unlock(targetcall_pvt->owner); 14357 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14358 if (res != -2) 14359 ast_hangup(transferer->owner); 14360 else 14361 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14362 } else { 14363 /* Transfer succeeded! */ 14364 14365 /* Tell transferer that we're done. */ 14366 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14367 append_history(transferer, "Xfer", "Refer succeeded"); 14368 transferer->refer->status = REFER_200OK; 14369 if (targetcall_pvt->owner) { 14370 if (option_debug) 14371 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14372 ast_channel_unlock(targetcall_pvt->owner); 14373 } 14374 } 14375 return 1; 14376 }
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 4769 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04770 { 04771 int h = 0, t = 0; 04772 int lws = 0; 04773 04774 for (; h < len;) { 04775 /* Eliminate all CRs */ 04776 if (msgbuf[h] == '\r') { 04777 h++; 04778 continue; 04779 } 04780 /* Check for end-of-line */ 04781 if (msgbuf[h] == '\n') { 04782 /* Check for end-of-message */ 04783 if (h + 1 == len) 04784 break; 04785 /* Check for a continuation line */ 04786 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04787 /* Merge continuation line */ 04788 h++; 04789 continue; 04790 } 04791 /* Propagate LF and start new line */ 04792 msgbuf[t++] = msgbuf[h++]; 04793 lws = 0; 04794 continue; 04795 } 04796 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04797 if (lws) { 04798 h++; 04799 continue; 04800 } 04801 msgbuf[t++] = msgbuf[h++]; 04802 lws = 1; 04803 continue; 04804 } 04805 msgbuf[t++] = msgbuf[h++]; 04806 if (lws) 04807 lws = 0; 04808 } 04809 msgbuf[t] = '\0'; 04810 return t; 04811 }
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 10380 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.
Referenced by load_module().
10381 { 10382 const char *a[4]; 10383 const char *peer; 10384 int ret; 10385 10386 peer = astman_get_header(m,"Peer"); 10387 if (ast_strlen_zero(peer)) { 10388 astman_send_error(s, m, "Peer: <name> missing.\n"); 10389 return 0; 10390 } 10391 a[0] = "sip"; 10392 a[1] = "show"; 10393 a[2] = "peer"; 10394 a[3] = peer; 10395 10396 ret = _sip_show_peer(1, -1, s, m, 4, a); 10397 astman_append(s, "\r\n\r\n" ); 10398 return ret; 10399 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9931 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), s, and total.
Referenced by load_module().
09932 { 09933 const char *id = astman_get_header(m,"ActionID"); 09934 const char *a[] = {"sip", "show", "peers"}; 09935 char idtext[256] = ""; 09936 int total = 0; 09937 09938 if (!ast_strlen_zero(id)) 09939 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09940 09941 astman_send_ack(s, m, "Peer status list will follow"); 09942 /* List the peers in separate manager events */ 09943 _sip_show_peers(-1, &total, s, m, 3, a); 09944 /* Send final confirmation */ 09945 astman_append(s, 09946 "Event: PeerlistComplete\r\n" 09947 "ListItems: %d\r\n" 09948 "%s" 09949 "\r\n", total, idtext); 09950 return 0; 09951 }
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 | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9834 of file chan_sip.c.
References SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, and SIP_NAT_ROUTE.
Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().
09835 { 09836 switch(nat) { 09837 case SIP_NAT_NEVER: 09838 return "No"; 09839 case SIP_NAT_ROUTE: 09840 return "Route"; 09841 case SIP_NAT_ALWAYS: 09842 return "Always"; 09843 case SIP_NAT_RFC3581: 09844 return "RFC3581"; 09845 default: 09846 return "Unknown"; 09847 } 09848 }
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 12020 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().
12021 { 12022 char tmp[SIPBUFSIZE]; 12023 char *s, *e, *uri, *t; 12024 char *domain; 12025 12026 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12027 if ((t = strchr(tmp, ','))) 12028 *t = '\0'; 12029 s = get_in_brackets(tmp); 12030 uri = ast_strdupa(s); 12031 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12032 if (!strncasecmp(s, "sip:", 4)) 12033 s += 4; 12034 e = strchr(s, ';'); 12035 if (e) 12036 *e = '\0'; 12037 if (option_debug) 12038 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12039 if (p->owner) 12040 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12041 } else { 12042 e = strchr(tmp, '@'); 12043 if (e) { 12044 *e++ = '\0'; 12045 domain = e; 12046 } else { 12047 /* No username part */ 12048 domain = tmp; 12049 } 12050 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12051 if (e) 12052 *e = '\0'; 12053 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12054 if (e) 12055 *e = '\0'; 12056 12057 if (!strncasecmp(s, "sip:", 4)) 12058 s += 4; 12059 if (option_debug > 1) 12060 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12061 if (p->owner) { 12062 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12063 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12064 ast_string_field_set(p->owner, call_forward, s); 12065 } 12066 } 12067 }
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 8031 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().
08032 { 08033 char contact[SIPBUFSIZE]; 08034 char *c; 08035 08036 /* Look for brackets */ 08037 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08038 c = get_in_brackets(contact); 08039 08040 /* Save full contact to call pvt for later bye or re-invite */ 08041 ast_string_field_set(pvt, fullcontact, c); 08042 08043 /* Save URI for later ACKs, BYE or RE-invites */ 08044 ast_string_field_set(pvt, okcontacturi, c); 08045 08046 /* We should return false for URI:s we can't handle, 08047 like sips:, tel:, mailto:,ldap: etc */ 08048 return TRUE; 08049 }
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 8115 of file chan_sip.c.
References sip_peer::addr, ahp, 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, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, 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().
08116 { 08117 char contact[SIPBUFSIZE]; 08118 char data[SIPBUFSIZE]; 08119 const char *expires = get_header(req, "Expires"); 08120 int expiry = atoi(expires); 08121 char *curi, *n, *pt; 08122 int port; 08123 const char *useragent; 08124 struct hostent *hp; 08125 struct ast_hostent ahp; 08126 struct sockaddr_in oldsin; 08127 08128 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08129 08130 if (ast_strlen_zero(expires)) { /* No expires header */ 08131 expires = strcasestr(contact, ";expires="); 08132 if (expires) { 08133 /* XXX bug here, we overwrite the string */ 08134 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08135 if (sscanf(expires + 9, "%d", &expiry) != 1) 08136 expiry = default_expiry; 08137 } else { 08138 /* Nothing has been specified */ 08139 expiry = default_expiry; 08140 } 08141 } 08142 08143 /* Look for brackets */ 08144 curi = contact; 08145 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08146 strsep(&curi, ";"); /* This is Header options, not URI options */ 08147 curi = get_in_brackets(contact); 08148 08149 /* if they did not specify Contact: or Expires:, they are querying 08150 what we currently have stored as their contact address, so return 08151 it 08152 */ 08153 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08154 /* If we have an active registration, tell them when the registration is going to expire */ 08155 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08156 pvt->expiry = ast_sched_when(sched, peer->expire); 08157 return PARSE_REGISTER_QUERY; 08158 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08159 /* This means remove all registrations and return OK */ 08160 memset(&peer->addr, 0, sizeof(peer->addr)); 08161 if (!AST_SCHED_DEL(sched, peer->expire)) { 08162 struct sip_peer *peer_ptr = peer; 08163 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08164 } 08165 08166 destroy_association(peer); 08167 08168 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08169 peer->fullcontact[0] = '\0'; 08170 peer->useragent[0] = '\0'; 08171 peer->sipoptions = 0; 08172 peer->lastms = 0; 08173 08174 if (option_verbose > 2) 08175 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08176 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08177 return PARSE_REGISTER_UPDATE; 08178 } 08179 08180 /* Store whatever we got as a contact from the client */ 08181 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08182 08183 /* For the 200 OK, we should use the received contact */ 08184 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08185 08186 /* Make sure it's a SIP URL */ 08187 if (strncasecmp(curi, "sip:", 4)) { 08188 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08189 } else 08190 curi += 4; 08191 /* Ditch q */ 08192 curi = strsep(&curi, ";"); 08193 /* Grab host */ 08194 n = strchr(curi, '@'); 08195 if (!n) { 08196 n = curi; 08197 curi = NULL; 08198 } else 08199 *n++ = '\0'; 08200 pt = strchr(n, ':'); 08201 if (pt) { 08202 *pt++ = '\0'; 08203 port = atoi(pt); 08204 } else 08205 port = STANDARD_SIP_PORT; 08206 oldsin = peer->addr; 08207 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08208 /* XXX This could block for a long time XXX */ 08209 hp = ast_gethostbyname(n, &ahp); 08210 if (!hp) { 08211 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08212 return PARSE_REGISTER_FAILED; 08213 } 08214 peer->addr.sin_family = AF_INET; 08215 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08216 peer->addr.sin_port = htons(port); 08217 } else { 08218 /* Don't trust the contact field. Just use what they came to us 08219 with */ 08220 peer->addr = pvt->recv; 08221 } 08222 08223 /* Save SIP options profile */ 08224 peer->sipoptions = pvt->sipoptions; 08225 08226 if (curi && ast_strlen_zero(peer->username)) 08227 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08228 08229 if (!AST_SCHED_DEL(sched, peer->expire)) { 08230 struct sip_peer *peer_ptr = peer; 08231 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08232 } 08233 if (expiry > max_expiry) 08234 expiry = max_expiry; 08235 if (expiry < min_expiry) 08236 expiry = min_expiry; 08237 if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) { 08238 peer->expire = -1; 08239 } else { 08240 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08241 if (peer->expire == -1) { 08242 struct sip_peer *peer_ptr = peer; 08243 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08244 } 08245 } 08246 pvt->expiry = expiry; 08247 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); 08248 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08249 ast_db_put("SIP/Registry", peer->name, data); 08250 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08251 08252 /* Is this a new IP address for us? */ 08253 if (inaddrcmp(&peer->addr, &oldsin)) { 08254 sip_poke_peer(peer); 08255 if (option_verbose > 2) 08256 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); 08257 register_peer_exten(peer, 1); 08258 } 08259 08260 /* Save User agent */ 08261 useragent = get_header(req, "User-Agent"); 08262 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08263 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08264 if (option_verbose > 3) 08265 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08266 } 08267 return PARSE_REGISTER_UPDATE; 08268 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4816 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, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04817 { 04818 /* Divide fields by NULL's */ 04819 char *c; 04820 int f = 0; 04821 04822 c = req->data; 04823 04824 /* First header starts immediately */ 04825 req->header[f] = c; 04826 while(*c) { 04827 if (*c == '\n') { 04828 /* We've got a new header */ 04829 *c = 0; 04830 04831 if (sipdebug && option_debug > 3) 04832 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04833 if (ast_strlen_zero(req->header[f])) { 04834 /* Line by itself means we're now in content */ 04835 c++; 04836 break; 04837 } 04838 if (f >= SIP_MAX_HEADERS - 1) { 04839 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04840 } else 04841 f++; 04842 req->header[f] = c + 1; 04843 } else if (*c == '\r') { 04844 /* Ignore but eliminate \r's */ 04845 *c = 0; 04846 } 04847 c++; 04848 } 04849 /* Check for last header */ 04850 if (!ast_strlen_zero(req->header[f])) { 04851 if (sipdebug && option_debug > 3) 04852 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04853 f++; 04854 } 04855 req->headers = f; 04856 /* Now we process any mime content */ 04857 f = 0; 04858 req->line[f] = c; 04859 while(*c) { 04860 if (*c == '\n') { 04861 /* We've got a new line */ 04862 *c = 0; 04863 if (sipdebug && option_debug > 3) 04864 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04865 if (f >= SIP_MAX_LINES - 1) { 04866 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04867 } else 04868 f++; 04869 req->line[f] = c + 1; 04870 } else if (*c == '\r') { 04871 /* Ignore and eliminate \r's */ 04872 *c = 0; 04873 } 04874 c++; 04875 } 04876 /* Check for last line */ 04877 if (!ast_strlen_zero(req->line[f])) 04878 f++; 04879 req->lines = f; 04880 if (*c) 04881 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04882 /* Split up the first line parts */ 04883 return determine_firstline_parts(req); 04884 }
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, 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 9853 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09854 { 09855 int res = 0; 09856 if (peer->maxms) { 09857 if (peer->lastms < 0) { 09858 ast_copy_string(status, "UNREACHABLE", statuslen); 09859 } else if (peer->lastms > peer->maxms) { 09860 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09861 res = 1; 09862 } else if (peer->lastms) { 09863 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09864 res = 1; 09865 } else { 09866 ast_copy_string(status, "UNKNOWN", statuslen); 09867 } 09868 } else { 09869 ast_copy_string(status, "Unmonitored", statuslen); 09870 /* Checking if port is 0 */ 09871 res = -1; 09872 } 09873 return res; 09874 }
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 10321 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().
10322 { 10323 int x, codec; 10324 10325 for(x = 0; x < 32 ; x++) { 10326 codec = ast_codec_pref_index(pref, x); 10327 if (!codec) 10328 break; 10329 ast_cli(fd, "%s", ast_getformatname(codec)); 10330 ast_cli(fd, ":%d", pref->framing[x]); 10331 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10332 ast_cli(fd, ","); 10333 } 10334 if (!x) 10335 ast_cli(fd, "none"); 10336 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10112 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10113 { 10114 char buf[256]; 10115 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10116 }
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 5017 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, 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.
05018 { 05019 const char *m; /* SDP media offer */ 05020 const char *c; 05021 const char *a; 05022 char host[258]; 05023 int len = -1; 05024 int portno = -1; /*!< RTP Audio port number */ 05025 int vportno = -1; /*!< RTP Video port number */ 05026 int udptlportno = -1; 05027 int peert38capability = 0; 05028 char s[256]; 05029 int old = 0; 05030 05031 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05032 int peercapability = 0, peernoncodeccapability = 0; 05033 int vpeercapability = 0, vpeernoncodeccapability = 0; 05034 struct sockaddr_in sin; /*!< media socket address */ 05035 struct sockaddr_in vsin; /*!< Video socket address */ 05036 05037 const char *codecs; 05038 struct hostent *hp; /*!< RTP Audio host IP */ 05039 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05040 struct ast_hostent audiohp; 05041 struct ast_hostent videohp; 05042 int codec; 05043 int destiterator = 0; 05044 int iterator; 05045 int sendonly = -1; 05046 int numberofports; 05047 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05048 int newjointcapability; /* Negotiated capability */ 05049 int newpeercapability; 05050 int newnoncodeccapability; 05051 int numberofmediastreams = 0; 05052 int debug = sip_debug_test_pvt(p); 05053 05054 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05055 int last_rtpmap_codec=0; 05056 05057 if (!p->rtp) { 05058 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05059 return -1; 05060 } 05061 05062 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05063 newaudiortp = alloca(ast_rtp_alloc_size()); 05064 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05065 ast_rtp_new_init(newaudiortp); 05066 ast_rtp_pt_clear(newaudiortp); 05067 05068 newvideortp = alloca(ast_rtp_alloc_size()); 05069 memset(newvideortp, 0, ast_rtp_alloc_size()); 05070 ast_rtp_new_init(newvideortp); 05071 ast_rtp_pt_clear(newvideortp); 05072 05073 /* Update our last rtprx when we receive an SDP, too */ 05074 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05075 05076 05077 /* Try to find first media stream */ 05078 m = get_sdp(req, "m"); 05079 destiterator = req->sdp_start; 05080 c = get_sdp_iterate(&destiterator, req, "c"); 05081 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05082 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05083 return -1; 05084 } 05085 05086 /* Check for IPv4 address (not IPv6 yet) */ 05087 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05088 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05089 return -1; 05090 } 05091 05092 /* XXX This could block for a long time, and block the main thread! XXX */ 05093 hp = ast_gethostbyname(host, &audiohp); 05094 if (!hp) { 05095 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05096 return -1; 05097 } 05098 vhp = hp; /* Copy to video address as default too */ 05099 05100 iterator = req->sdp_start; 05101 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05102 05103 05104 /* Find media streams in this SDP offer */ 05105 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05106 int x; 05107 int audio = FALSE; 05108 05109 numberofports = 1; 05110 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05111 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05112 audio = TRUE; 05113 numberofmediastreams++; 05114 /* Found audio stream in this media definition */ 05115 portno = x; 05116 /* Scan through the RTP payload types specified in a "m=" line: */ 05117 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05118 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05119 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05120 return -1; 05121 } 05122 if (debug) 05123 ast_verbose("Found RTP audio format %d\n", codec); 05124 ast_rtp_set_m_type(newaudiortp, codec); 05125 } 05126 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05127 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05128 /* If it is not audio - is it video ? */ 05129 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05130 numberofmediastreams++; 05131 vportno = x; 05132 /* Scan through the RTP payload types specified in a "m=" line: */ 05133 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05134 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05135 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05136 return -1; 05137 } 05138 if (debug) 05139 ast_verbose("Found RTP video format %d\n", codec); 05140 ast_rtp_set_m_type(newvideortp, codec); 05141 } 05142 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05143 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05144 if (debug) 05145 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05146 udptlportno = x; 05147 numberofmediastreams++; 05148 05149 if (p->owner && p->lastinvite) { 05150 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05151 if (option_debug > 1) 05152 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05153 } else { 05154 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05155 if (option_debug > 1) 05156 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05157 } 05158 } else 05159 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05160 if (numberofports > 1) 05161 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05162 05163 05164 /* Check for Media-description-level-address for audio */ 05165 c = get_sdp_iterate(&destiterator, req, "c"); 05166 if (!ast_strlen_zero(c)) { 05167 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05168 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05169 } else { 05170 /* XXX This could block for a long time, and block the main thread! XXX */ 05171 if (audio) { 05172 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05173 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05174 return -2; 05175 } 05176 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05177 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05178 return -2; 05179 } 05180 } 05181 05182 } 05183 } 05184 if (portno == -1 && vportno == -1 && udptlportno == -1) 05185 /* No acceptable offer found in SDP - we have no ports */ 05186 /* Do not change RTP or VRTP if this is a re-invite */ 05187 return -2; 05188 05189 if (numberofmediastreams > 2) 05190 /* We have too many fax, audio and/or video media streams, fail this offer */ 05191 return -3; 05192 05193 /* RTP addresses and ports for audio and video */ 05194 sin.sin_family = AF_INET; 05195 vsin.sin_family = AF_INET; 05196 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05197 if (vhp) 05198 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05199 05200 /* Setup UDPTL port number */ 05201 if (p->udptl) { 05202 if (udptlportno > 0) { 05203 sin.sin_port = htons(udptlportno); 05204 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05205 struct sockaddr_in peer; 05206 ast_rtp_get_peer(p->rtp, &peer); 05207 if (peer.sin_addr.s_addr) { 05208 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(&sin.sin_addr)); 05209 if (debug) { 05210 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)); 05211 } 05212 } 05213 } 05214 ast_udptl_set_peer(p->udptl, &sin); 05215 if (debug) 05216 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05217 } else { 05218 ast_udptl_stop(p->udptl); 05219 if (debug) 05220 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05221 } 05222 } 05223 05224 05225 if (p->rtp) { 05226 if (portno > 0) { 05227 sin.sin_port = htons(portno); 05228 ast_rtp_set_peer(p->rtp, &sin); 05229 if (debug) 05230 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05231 } else { 05232 if (udptlportno > 0) { 05233 if (debug) 05234 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05235 } else { 05236 ast_rtp_stop(p->rtp); 05237 if (debug) 05238 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05239 } 05240 } 05241 } 05242 /* Setup video port number */ 05243 if (vportno != -1) 05244 vsin.sin_port = htons(vportno); 05245 05246 /* Next, scan through each "a=rtpmap:" line, noting each 05247 * specified RTP payload type (with corresponding MIME subtype): 05248 */ 05249 /* XXX This needs to be done per media stream, since it's media stream specific */ 05250 iterator = req->sdp_start; 05251 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05252 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05253 if (option_debug > 1) { 05254 int breakout = FALSE; 05255 05256 /* If we're debugging, check for unsupported sdp options */ 05257 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05258 if (debug) 05259 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05260 breakout = TRUE; 05261 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05262 /* Format parameters: Not supported */ 05263 /* Note: This is used for codec parameters, like bitrate for 05264 G722 and video formats for H263 and H264 05265 See RFC2327 for an example */ 05266 if (debug) 05267 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05268 breakout = TRUE; 05269 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05270 /* Video stuff: Not supported */ 05271 if (debug) 05272 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05273 breakout = TRUE; 05274 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05275 /* Video stuff: Not supported */ 05276 if (debug) 05277 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05278 breakout = TRUE; 05279 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05280 /* SRTP stuff, not yet supported */ 05281 if (debug) 05282 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05283 breakout = TRUE; 05284 } 05285 if (breakout) /* We have a match, skip to next header */ 05286 continue; 05287 } 05288 if (!strcasecmp(a, "sendonly")) { 05289 if (sendonly == -1) 05290 sendonly = 1; 05291 continue; 05292 } else if (!strcasecmp(a, "inactive")) { 05293 if (sendonly == -1) 05294 sendonly = 2; 05295 continue; 05296 } else if (!strcasecmp(a, "sendrecv")) { 05297 if (sendonly == -1) 05298 sendonly = 0; 05299 continue; 05300 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05301 char *tmp = strrchr(a, ':'); 05302 long int framing = 0; 05303 if (tmp) { 05304 tmp++; 05305 framing = strtol(tmp, NULL, 10); 05306 if (framing == LONG_MIN || framing == LONG_MAX) { 05307 framing = 0; 05308 if (option_debug) 05309 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05310 } 05311 } 05312 if (framing && p->autoframing) { 05313 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05314 int codec_n; 05315 int format = 0; 05316 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05317 format = ast_rtp_codec_getformat(codec_n); 05318 if (!format) /* non-codec or not found */ 05319 continue; 05320 if (option_debug) 05321 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05322 ast_codec_pref_setsize(pref, format, framing); 05323 } 05324 ast_rtp_codec_setpref(p->rtp, pref); 05325 } 05326 continue; 05327 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05328 /* We have a rtpmap to handle */ 05329 int found = FALSE; 05330 /* We should propably check if this is an audio or video codec 05331 so we know where to look */ 05332 05333 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05334 /* Note: should really look at the 'freq' and '#chans' params too */ 05335 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05336 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05337 if (debug) 05338 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05339 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05340 last_rtpmap_codec++; 05341 found = TRUE; 05342 05343 } else if (p->vrtp) { 05344 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05345 if (debug) 05346 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05347 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05348 last_rtpmap_codec++; 05349 found = TRUE; 05350 } 05351 } 05352 } else { 05353 if (debug) 05354 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05355 } 05356 05357 if (!found) { 05358 /* Remove this codec since it's an unknown media type for us */ 05359 /* XXX This is buggy since the media line for audio and video can have the 05360 same numbers. We need to check as described above, but for testing this works... */ 05361 ast_rtp_unset_m_type(newaudiortp, codec); 05362 ast_rtp_unset_m_type(newvideortp, codec); 05363 if (debug) 05364 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05365 } 05366 } 05367 } 05368 05369 if (udptlportno != -1) { 05370 int found = 0, x; 05371 05372 old = 0; 05373 05374 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05375 iterator = req->sdp_start; 05376 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05377 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05378 found = 1; 05379 if (option_debug > 2) 05380 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05381 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05382 found = 1; 05383 if (option_debug > 2) 05384 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05385 switch (x) { 05386 case 14400: 05387 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05388 break; 05389 case 12000: 05390 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05391 break; 05392 case 9600: 05393 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05394 break; 05395 case 7200: 05396 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05397 break; 05398 case 4800: 05399 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05400 break; 05401 case 2400: 05402 peert38capability |= T38FAX_RATE_2400; 05403 break; 05404 } 05405 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05406 found = 1; 05407 if (option_debug > 2) 05408 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05409 if (x == 0) 05410 peert38capability |= T38FAX_VERSION_0; 05411 else if (x == 1) 05412 peert38capability |= T38FAX_VERSION_1; 05413 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05414 found = 1; 05415 if (option_debug > 2) 05416 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05417 ast_udptl_set_far_max_datagram(p->udptl, x); 05418 ast_udptl_set_local_max_datagram(p->udptl, x); 05419 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05420 found = 1; 05421 if (option_debug > 2) 05422 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05423 if (x == 1) 05424 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05425 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05426 found = 1; 05427 if (option_debug > 2) 05428 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05429 if (x == 1) 05430 peert38capability |= T38FAX_TRANSCODING_MMR; 05431 } 05432 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05433 found = 1; 05434 if (option_debug > 2) 05435 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05436 if (x == 1) 05437 peert38capability |= T38FAX_TRANSCODING_JBIG; 05438 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05439 found = 1; 05440 if (option_debug > 2) 05441 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05442 if (!strcasecmp(s, "localTCF")) 05443 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05444 else if (!strcasecmp(s, "transferredTCF")) 05445 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05446 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05447 found = 1; 05448 if (option_debug > 2) 05449 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05450 if (!strcasecmp(s, "t38UDPRedundancy")) { 05451 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05452 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05453 } else if (!strcasecmp(s, "t38UDPFEC")) { 05454 peert38capability |= T38FAX_UDP_EC_FEC; 05455 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05456 } else { 05457 peert38capability |= T38FAX_UDP_EC_NONE; 05458 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05459 } 05460 } 05461 } 05462 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05463 p->t38.peercapability = peert38capability; 05464 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05465 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05466 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05467 } 05468 if (debug) 05469 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05470 p->t38.capability, 05471 p->t38.peercapability, 05472 p->t38.jointcapability); 05473 } else { 05474 p->t38.state = T38_DISABLED; 05475 if (option_debug > 2) 05476 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05477 } 05478 05479 /* Now gather all of the codecs that we are asked for: */ 05480 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05481 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05482 05483 newjointcapability = p->capability & (peercapability | vpeercapability); 05484 newpeercapability = (peercapability | vpeercapability); 05485 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05486 05487 05488 if (debug) { 05489 /* shame on whoever coded this.... */ 05490 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05491 05492 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05493 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05494 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05495 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05496 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05497 05498 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05499 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05500 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05501 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05502 } 05503 if (!newjointcapability) { 05504 /* If T.38 was not negotiated either, totally bail out... */ 05505 if (!p->t38.jointcapability || !udptlportno) { 05506 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05507 /* Do NOT Change current setting */ 05508 return -1; 05509 } else { 05510 if (option_debug > 2) 05511 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05512 return 0; 05513 } 05514 } 05515 05516 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05517 they are acceptable */ 05518 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05519 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05520 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05521 05522 ast_rtp_pt_copy(p->rtp, newaudiortp); 05523 if (p->vrtp) 05524 ast_rtp_pt_copy(p->vrtp, newvideortp); 05525 05526 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05527 ast_clear_flag(&p->flags[0], SIP_DTMF); 05528 if (newnoncodeccapability & AST_RTP_DTMF) { 05529 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05530 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05531 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05532 ast_rtp_setdtmf(p->rtp, 1); 05533 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05534 } else { 05535 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05536 } 05537 } 05538 05539 /* Setup audio port number */ 05540 if (p->rtp && sin.sin_port) { 05541 ast_rtp_set_peer(p->rtp, &sin); 05542 if (debug) 05543 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05544 } 05545 05546 /* Setup video port number */ 05547 if (p->vrtp && vsin.sin_port) { 05548 ast_rtp_set_peer(p->vrtp, &vsin); 05549 if (debug) 05550 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05551 } 05552 05553 /* Ok, we're going with this offer */ 05554 if (option_debug > 1) { 05555 char buf[SIPBUFSIZE]; 05556 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05557 } 05558 05559 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05560 return 0; 05561 05562 if (option_debug > 3) 05563 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05564 05565 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05566 if (debug) { 05567 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05568 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05569 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05570 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05571 } 05572 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05573 ast_set_read_format(p->owner, p->owner->readformat); 05574 ast_set_write_format(p->owner, p->owner->writeformat); 05575 } 05576 05577 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05578 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05579 /* Activate a re-invite */ 05580 ast_queue_frame(p->owner, &ast_null_frame); 05581 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05582 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05583 S_OR(p->mohsuggest, NULL), 05584 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05585 if (sendonly) 05586 ast_rtp_stop(p->rtp); 05587 /* RTCP needs to go ahead, even if we're on hold!!! */ 05588 /* Activate a re-invite */ 05589 ast_queue_frame(p->owner, &ast_null_frame); 05590 } 05591 05592 /* Manager Hold and Unhold events must be generated, if necessary */ 05593 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05594 change_hold_state(p, req, FALSE, sendonly); 05595 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05596 change_hold_state(p, req, TRUE, sendonly); 05597 return 0; 05598 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static] |
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 ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ast_flags::flags, hp, ast_variable::name, ast_variable::next, 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(), global_flags, 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] |
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_variables_destroy(), ast_variable::name, ast_variable::next, 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 9736 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
09737 { 09738 char buf[1024]; 09739 struct ast_frame f; 09740 const char *content_type = get_header(req, "Content-Type"); 09741 09742 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09743 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09744 if (!p->owner) 09745 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09746 return; 09747 } 09748 09749 if (get_msg_text(buf, sizeof(buf), req)) { 09750 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09751 transmit_response(p, "202 Accepted", req); 09752 if (!p->owner) 09753 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09754 return; 09755 } 09756 09757 if (p->owner) { 09758 if (sip_debug_test_pvt(p)) 09759 ast_verbose("Message received: '%s'\n", buf); 09760 memset(&f, 0, sizeof(f)); 09761 f.frametype = AST_FRAME_TEXT; 09762 f.subclass = 0; 09763 f.offset = 0; 09764 f.data = buf; 09765 f.datalen = strlen(buf); 09766 ast_queue_frame(p->owner, &f); 09767 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09768 } else { /* Message outside of a call, we do not support that */ 09769 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); 09770 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09771 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09772 } 09773 return; 09774 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1627 of file chan_sip.c.
References referstatusstrings, and 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 7959 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(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07960 { 07961 char data[256]; 07962 struct in_addr in; 07963 int expiry; 07964 int port; 07965 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07966 07967 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07968 return; 07969 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07970 return; 07971 07972 scan = data; 07973 addr = strsep(&scan, ":"); 07974 port_str = strsep(&scan, ":"); 07975 expiry_str = strsep(&scan, ":"); 07976 username = strsep(&scan, ":"); 07977 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07978 07979 if (!inet_aton(addr, &in)) 07980 return; 07981 07982 if (port_str) 07983 port = atoi(port_str); 07984 else 07985 return; 07986 07987 if (expiry_str) 07988 expiry = atoi(expiry_str); 07989 else 07990 return; 07991 07992 if (username) 07993 ast_copy_string(peer->username, username, sizeof(peer->username)); 07994 if (contact) 07995 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07996 07997 if (option_debug > 1) 07998 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07999 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08000 08001 memset(&peer->addr, 0, sizeof(peer->addr)); 08002 peer->addr.sin_family = AF_INET; 08003 peer->addr.sin_addr = in; 08004 peer->addr.sin_port = htons(port); 08005 if (sipsock < 0) { 08006 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08007 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08008 struct sip_peer *peer_ptr = peer; 08009 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08010 } 08011 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08012 if (peer->pokeexpire == -1) { 08013 struct sip_peer *peer_ptr = peer; 08014 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08015 } 08016 } else 08017 sip_poke_peer(peer); 08018 if (!AST_SCHED_DEL(sched, peer->expire)) { 08019 struct sip_peer *peer_ptr = peer; 08020 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08021 } 08022 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08023 if (peer->expire == -1) { 08024 struct sip_peer *peer_ptr = peer; 08025 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08026 } 08027 register_peer_exten(peer, TRUE); 08028 }
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 8656 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, 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, 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.
08658 { 08659 enum check_auth_result res = AUTH_NOT_FOUND; 08660 struct sip_peer *peer; 08661 char tmp[256]; 08662 char *name, *c; 08663 char *t; 08664 char *domain; 08665 08666 /* Terminate URI */ 08667 t = uri; 08668 while(*t && (*t > 32) && (*t != ';')) 08669 t++; 08670 *t = '\0'; 08671 08672 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08673 if (pedanticsipchecking) 08674 ast_uri_decode(tmp); 08675 08676 c = get_in_brackets(tmp); 08677 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08678 08679 if (!strncasecmp(c, "sip:", 4)) { 08680 name = c + 4; 08681 } else { 08682 name = c; 08683 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08684 } 08685 08686 /* Strip off the domain name */ 08687 if ((c = strchr(name, '@'))) { 08688 *c++ = '\0'; 08689 domain = c; 08690 if ((c = strchr(domain, ':'))) /* Remove :port */ 08691 *c = '\0'; 08692 if (!AST_LIST_EMPTY(&domain_list)) { 08693 if (!check_sip_domain(domain, NULL, 0)) { 08694 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08695 return AUTH_UNKNOWN_DOMAIN; 08696 } 08697 } 08698 } 08699 08700 ast_string_field_set(p, exten, name); 08701 build_contact(p); 08702 peer = find_peer(name, NULL, 1); 08703 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08704 /* Peer fails ACL check */ 08705 if (peer) { 08706 ASTOBJ_UNREF(peer, sip_destroy_peer); 08707 res = AUTH_ACL_FAILED; 08708 } else 08709 res = AUTH_NOT_FOUND; 08710 } 08711 if (peer) { 08712 /* Set Frame packetization */ 08713 if (p->rtp) { 08714 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08715 p->autoframing = peer->autoframing; 08716 } 08717 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08718 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08719 res = AUTH_PEER_NOT_DYNAMIC; 08720 } else { 08721 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08722 transmit_response(p, "100 Trying", req); 08723 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08724 if (sip_cancel_destroy(p)) 08725 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08726 08727 /* We have a succesful registration attemp with proper authentication, 08728 now, update the peer */ 08729 switch (parse_register_contact(p, peer, req)) { 08730 case PARSE_REGISTER_FAILED: 08731 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08732 transmit_response_with_date(p, "400 Bad Request", req); 08733 peer->lastmsgssent = -1; 08734 res = 0; 08735 break; 08736 case PARSE_REGISTER_QUERY: 08737 transmit_response_with_date(p, "200 OK", req); 08738 peer->lastmsgssent = -1; 08739 res = 0; 08740 break; 08741 case PARSE_REGISTER_UPDATE: 08742 update_peer(peer, p->expiry); 08743 /* Say OK and ask subsystem to retransmit msg counter */ 08744 transmit_response_with_date(p, "200 OK", req); 08745 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08746 peer->lastmsgssent = -1; 08747 res = 0; 08748 break; 08749 } 08750 } 08751 } 08752 } 08753 if (!peer && autocreatepeer) { 08754 /* Create peer if we have autocreate mode enabled */ 08755 peer = temp_peer(name); 08756 if (peer) { 08757 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08758 if (sip_cancel_destroy(p)) 08759 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08760 switch (parse_register_contact(p, peer, req)) { 08761 case PARSE_REGISTER_FAILED: 08762 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08763 transmit_response_with_date(p, "400 Bad Request", req); 08764 peer->lastmsgssent = -1; 08765 res = 0; 08766 break; 08767 case PARSE_REGISTER_QUERY: 08768 transmit_response_with_date(p, "200 OK", req); 08769 peer->lastmsgssent = -1; 08770 res = 0; 08771 break; 08772 case PARSE_REGISTER_UPDATE: 08773 /* Say OK and ask subsystem to retransmit msg counter */ 08774 transmit_response_with_date(p, "200 OK", req); 08775 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08776 peer->lastmsgssent = -1; 08777 res = 0; 08778 break; 08779 } 08780 } 08781 } 08782 if (!res) { 08783 ast_device_state_changed("SIP/%s", peer->name); 08784 } 08785 if (res < 0) { 08786 switch (res) { 08787 case AUTH_SECRET_FAILED: 08788 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08789 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08790 break; 08791 case AUTH_USERNAME_MISMATCH: 08792 /* Username and digest username does not match. 08793 Asterisk uses the From: username for authentication. We need the 08794 users to use the same authentication user name until we support 08795 proper authentication by digest auth name */ 08796 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08797 break; 08798 case AUTH_NOT_FOUND: 08799 case AUTH_PEER_NOT_DYNAMIC: 08800 case AUTH_ACL_FAILED: 08801 if (global_alwaysauthreject) { 08802 transmit_fake_auth_response(p, &p->initreq, 1); 08803 } else { 08804 /* URI not found */ 08805 if (res == AUTH_PEER_NOT_DYNAMIC) 08806 transmit_response(p, "403 Forbidden", &p->initreq); 08807 else 08808 transmit_response(p, "404 Not found", &p->initreq); 08809 } 08810 break; 08811 default: 08812 break; 08813 } 08814 } 08815 if (peer) 08816 ASTOBJ_UNREF(peer, sip_destroy_peer); 08817 08818 return res; 08819 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7448 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.
07449 { 07450 switch(regstate) { 07451 case REG_STATE_FAILED: 07452 return "Failed"; 07453 case REG_STATE_UNREGISTERED: 07454 return "Unregistered"; 07455 case REG_STATE_REGSENT: 07456 return "Request Sent"; 07457 case REG_STATE_AUTHSENT: 07458 return "Auth. Sent"; 07459 case REG_STATE_REGISTERED: 07460 return "Registered"; 07461 case REG_STATE_REJECTED: 07462 return "Rejected"; 07463 case REG_STATE_TIMEOUT: 07464 return "Timeout"; 07465 case REG_STATE_NOAUTH: 07466 return "No Authentication"; 07467 default: 07468 return "Unknown"; 07469 } 07470 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18021 of file chan_sip.c.
References sip_reload().
18022 { 18023 return sip_reload(0, 0, NULL); 18024 }
static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Default DTMF setting: RFC2833
< NAT support if requested by device with rport
< Allow re-invites
Definition at line 16907 of file chan_sip.c.
References ahp, ast_config_load(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().
16908 { 16909 struct ast_config *cfg, *ucfg; 16910 struct ast_variable *v; 16911 struct sip_peer *peer; 16912 struct sip_user *user; 16913 struct ast_hostent ahp; 16914 char *cat, *stringp, *context, *oldregcontext; 16915 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16916 struct hostent *hp; 16917 int format; 16918 struct ast_flags dummy[2]; 16919 int auto_sip_domains = FALSE; 16920 struct sockaddr_in old_bindaddr = bindaddr; 16921 int registry_count = 0, peer_count = 0, user_count = 0; 16922 unsigned int temp_tos = 0; 16923 struct ast_flags debugflag = {0}; 16924 16925 cfg = ast_config_load(config); 16926 16927 /* We *must* have a config file otherwise stop immediately */ 16928 if (!cfg) { 16929 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16930 return -1; 16931 } 16932 16933 if (option_debug > 3) 16934 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 16935 16936 clear_realm_authentication(authl); 16937 clear_sip_domains(); 16938 authl = NULL; 16939 16940 /* First, destroy all outstanding registry calls */ 16941 /* This is needed, since otherwise active registry entries will not be destroyed */ 16942 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16943 ASTOBJ_RDLOCK(iterator); 16944 if (iterator->call) { 16945 if (option_debug > 2) 16946 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 16947 /* This will also remove references to the registry */ 16948 sip_destroy(iterator->call); 16949 } 16950 ASTOBJ_UNLOCK(iterator); 16951 16952 } while(0)); 16953 16954 /* Then, actually destroy users and registry */ 16955 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 16956 if (option_debug > 3) 16957 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 16958 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 16959 if (option_debug > 3) 16960 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 16961 ASTOBJ_CONTAINER_MARKALL(&peerl); 16962 16963 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16964 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16965 oldregcontext = oldcontexts; 16966 16967 /* Clear all flags before setting default values */ 16968 /* Preserve debugging settings for console */ 16969 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16970 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16971 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16972 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16973 16974 /* Reset IP addresses */ 16975 memset(&bindaddr, 0, sizeof(bindaddr)); 16976 ast_free_ha(localaddr); 16977 memset(&localaddr, 0, sizeof(localaddr)); 16978 memset(&externip, 0, sizeof(externip)); 16979 memset(&default_prefs, 0 , sizeof(default_prefs)); 16980 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16981 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16982 ourport = STANDARD_SIP_PORT; 16983 srvlookup = DEFAULT_SRVLOOKUP; 16984 global_tos_sip = DEFAULT_TOS_SIP; 16985 global_tos_audio = DEFAULT_TOS_AUDIO; 16986 global_tos_video = DEFAULT_TOS_VIDEO; 16987 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16988 externexpire = 0; /* Expiration for DNS re-issuing */ 16989 externrefresh = 10; 16990 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16991 16992 /* Reset channel settings to default before re-configuring */ 16993 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16994 global_regcontext[0] = '\0'; 16995 expiry = DEFAULT_EXPIRY; 16996 global_notifyringing = DEFAULT_NOTIFYRINGING; 16997 global_limitonpeers = FALSE; 16998 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16999 global_notifyhold = FALSE; 17000 global_alwaysauthreject = 0; 17001 global_allowsubscribe = FALSE; 17002 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17003 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17004 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17005 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17006 else 17007 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17008 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17009 compactheaders = DEFAULT_COMPACTHEADERS; 17010 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17011 global_regattempts_max = 0; 17012 pedanticsipchecking = DEFAULT_PEDANTIC; 17013 global_mwitime = DEFAULT_MWITIME; 17014 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17015 global_autoframing = 0; 17016 global_allowguest = DEFAULT_ALLOWGUEST; 17017 global_rtptimeout = 0; 17018 global_rtpholdtimeout = 0; 17019 global_rtpkeepalive = 0; 17020 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17021 global_rtautoclear = 120; 17022 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17023 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17024 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17025 17026 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17027 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17028 default_subscribecontext[0] = '\0'; 17029 default_language[0] = '\0'; 17030 default_fromdomain[0] = '\0'; 17031 default_qualify = DEFAULT_QUALIFY; 17032 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17033 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17034 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17035 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17036 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17037 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17038 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17039 17040 /* Debugging settings, always default to off */ 17041 dumphistory = FALSE; 17042 recordhistory = FALSE; 17043 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17044 17045 /* Misc settings for the channel */ 17046 global_relaxdtmf = FALSE; 17047 global_callevents = FALSE; 17048 global_t1min = DEFAULT_T1MIN; 17049 17050 global_matchexterniplocally = FALSE; 17051 17052 /* Copy the default jb config over global_jbconf */ 17053 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17054 17055 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17056 17057 /* Read the [general] config section of sip.conf (or from realtime config) */ 17058 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17059 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17060 continue; 17061 /* handle jb conf */ 17062 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17063 continue; 17064 17065 /* Create the interface list */ 17066 if (!strcasecmp(v->name, "context")) { 17067 ast_copy_string(default_context, v->value, sizeof(default_context)); 17068 } else if (!strcasecmp(v->name, "subscribecontext")) { 17069 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17070 } else if (!strcasecmp(v->name, "allowguest")) { 17071 global_allowguest = ast_true(v->value) ? 1 : 0; 17072 } else if (!strcasecmp(v->name, "realm")) { 17073 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17074 } else if (!strcasecmp(v->name, "useragent")) { 17075 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17076 if (option_debug) 17077 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17078 } else if (!strcasecmp(v->name, "allowtransfer")) { 17079 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17080 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17081 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17082 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17083 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17084 } else if (!strcasecmp(v->name, "rtupdate")) { 17085 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17086 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17087 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17088 } else if (!strcasecmp(v->name, "t1min")) { 17089 global_t1min = atoi(v->value); 17090 } else if (!strcasecmp(v->name, "rtautoclear")) { 17091 int i = atoi(v->value); 17092 if (i > 0) 17093 global_rtautoclear = i; 17094 else 17095 i = 0; 17096 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17097 } else if (!strcasecmp(v->name, "usereqphone")) { 17098 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17099 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17100 global_relaxdtmf = ast_true(v->value); 17101 } else if (!strcasecmp(v->name, "checkmwi")) { 17102 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17103 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17104 global_mwitime = DEFAULT_MWITIME; 17105 } 17106 } else if (!strcasecmp(v->name, "vmexten")) { 17107 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17108 } else if (!strcasecmp(v->name, "rtptimeout")) { 17109 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17110 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17111 global_rtptimeout = 0; 17112 } 17113 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17114 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17115 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17116 global_rtpholdtimeout = 0; 17117 } 17118 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17119 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17120 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17121 global_rtpkeepalive = 0; 17122 } 17123 } else if (!strcasecmp(v->name, "compactheaders")) { 17124 compactheaders = ast_true(v->value); 17125 } else if (!strcasecmp(v->name, "notifymimetype")) { 17126 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17127 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17128 global_limitonpeers = ast_true(v->value); 17129 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17130 global_directrtpsetup = ast_true(v->value); 17131 } else if (!strcasecmp(v->name, "notifyringing")) { 17132 global_notifyringing = ast_true(v->value); 17133 } else if (!strcasecmp(v->name, "notifyhold")) { 17134 global_notifyhold = ast_true(v->value); 17135 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17136 global_alwaysauthreject = ast_true(v->value); 17137 } else if (!strcasecmp(v->name, "mohinterpret") 17138 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17139 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17140 } else if (!strcasecmp(v->name, "mohsuggest")) { 17141 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17142 } else if (!strcasecmp(v->name, "language")) { 17143 ast_copy_string(default_language, v->value, sizeof(default_language)); 17144 } else if (!strcasecmp(v->name, "regcontext")) { 17145 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17146 stringp = newcontexts; 17147 /* Let's remove any contexts that are no longer defined in regcontext */ 17148 cleanup_stale_contexts(stringp, oldregcontext); 17149 /* Create contexts if they don't exist already */ 17150 while ((context = strsep(&stringp, "&"))) { 17151 if (!ast_context_find(context)) 17152 ast_context_create(NULL, context,"SIP"); 17153 } 17154 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17155 } else if (!strcasecmp(v->name, "callerid")) { 17156 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17157 } else if (!strcasecmp(v->name, "fromdomain")) { 17158 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17159 } else if (!strcasecmp(v->name, "outboundproxy")) { 17160 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17161 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17162 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17163 /* Port needs to be after IP */ 17164 sscanf(v->value, "%d", &format); 17165 outboundproxyip.sin_port = htons(format); 17166 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17167 autocreatepeer = ast_true(v->value); 17168 } else if (!strcasecmp(v->name, "srvlookup")) { 17169 srvlookup = ast_true(v->value); 17170 } else if (!strcasecmp(v->name, "pedantic")) { 17171 pedanticsipchecking = ast_true(v->value); 17172 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17173 max_expiry = atoi(v->value); 17174 if (max_expiry < 1) 17175 max_expiry = DEFAULT_MAX_EXPIRY; 17176 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17177 min_expiry = atoi(v->value); 17178 if (min_expiry < 1) 17179 min_expiry = DEFAULT_MIN_EXPIRY; 17180 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17181 default_expiry = atoi(v->value); 17182 if (default_expiry < 1) 17183 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17184 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17185 if (ast_true(v->value)) 17186 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17187 } else if (!strcasecmp(v->name, "dumphistory")) { 17188 dumphistory = ast_true(v->value); 17189 } else if (!strcasecmp(v->name, "recordhistory")) { 17190 recordhistory = ast_true(v->value); 17191 } else if (!strcasecmp(v->name, "registertimeout")) { 17192 global_reg_timeout = atoi(v->value); 17193 if (global_reg_timeout < 1) 17194 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17195 } else if (!strcasecmp(v->name, "registerattempts")) { 17196 global_regattempts_max = atoi(v->value); 17197 } else if (!strcasecmp(v->name, "bindaddr")) { 17198 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17199 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17200 } else { 17201 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17202 } 17203 } else if (!strcasecmp(v->name, "localnet")) { 17204 struct ast_ha *na; 17205 if (!(na = ast_append_ha("d", v->value, localaddr))) 17206 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17207 else 17208 localaddr = na; 17209 } else if (!strcasecmp(v->name, "localmask")) { 17210 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17211 } else if (!strcasecmp(v->name, "externip")) { 17212 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17213 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17214 else 17215 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17216 externexpire = 0; 17217 } else if (!strcasecmp(v->name, "externhost")) { 17218 ast_copy_string(externhost, v->value, sizeof(externhost)); 17219 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17220 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17221 else 17222 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17223 externexpire = time(NULL); 17224 } else if (!strcasecmp(v->name, "externrefresh")) { 17225 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17226 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17227 externrefresh = 10; 17228 } 17229 } else if (!strcasecmp(v->name, "allow")) { 17230 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17231 } else if (!strcasecmp(v->name, "disallow")) { 17232 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17233 } else if (!strcasecmp(v->name, "autoframing")) { 17234 global_autoframing = ast_true(v->value); 17235 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17236 allow_external_domains = ast_true(v->value); 17237 } else if (!strcasecmp(v->name, "autodomain")) { 17238 auto_sip_domains = ast_true(v->value); 17239 } else if (!strcasecmp(v->name, "domain")) { 17240 char *domain = ast_strdupa(v->value); 17241 char *context = strchr(domain, ','); 17242 17243 if (context) 17244 *context++ = '\0'; 17245 17246 if (option_debug && ast_strlen_zero(context)) 17247 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17248 if (ast_strlen_zero(domain)) 17249 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17250 else 17251 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17252 } else if (!strcasecmp(v->name, "register")) { 17253 if (sip_register(v->value, v->lineno) == 0) 17254 registry_count++; 17255 } else if (!strcasecmp(v->name, "tos")) { 17256 if (!ast_str2tos(v->value, &temp_tos)) { 17257 global_tos_sip = temp_tos; 17258 global_tos_audio = temp_tos; 17259 global_tos_video = temp_tos; 17260 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17261 } else 17262 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17263 } else if (!strcasecmp(v->name, "tos_sip")) { 17264 if (ast_str2tos(v->value, &global_tos_sip)) 17265 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17266 } else if (!strcasecmp(v->name, "tos_audio")) { 17267 if (ast_str2tos(v->value, &global_tos_audio)) 17268 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17269 } else if (!strcasecmp(v->name, "tos_video")) { 17270 if (ast_str2tos(v->value, &global_tos_video)) 17271 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17272 } else if (!strcasecmp(v->name, "bindport")) { 17273 if (sscanf(v->value, "%d", &ourport) == 1) { 17274 bindaddr.sin_port = htons(ourport); 17275 } else { 17276 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17277 } 17278 } else if (!strcasecmp(v->name, "qualify")) { 17279 if (!strcasecmp(v->value, "no")) { 17280 default_qualify = 0; 17281 } else if (!strcasecmp(v->value, "yes")) { 17282 default_qualify = DEFAULT_MAXMS; 17283 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17284 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17285 default_qualify = 0; 17286 } 17287 } else if (!strcasecmp(v->name, "callevents")) { 17288 global_callevents = ast_true(v->value); 17289 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17290 default_maxcallbitrate = atoi(v->value); 17291 if (default_maxcallbitrate < 0) 17292 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17293 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17294 global_matchexterniplocally = ast_true(v->value); 17295 } 17296 } 17297 17298 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17299 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17300 allow_external_domains = 1; 17301 } 17302 17303 /* Build list of authentication to various SIP realms, i.e. service providers */ 17304 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17305 /* Format for authentication is auth = username:password@realm */ 17306 if (!strcasecmp(v->name, "auth")) 17307 authl = add_realm_authentication(authl, v->value, v->lineno); 17308 } 17309 17310 ucfg = ast_config_load("users.conf"); 17311 if (ucfg) { 17312 struct ast_variable *gen; 17313 int genhassip, genregistersip; 17314 const char *hassip, *registersip; 17315 17316 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17317 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17318 gen = ast_variable_browse(ucfg, "general"); 17319 cat = ast_category_browse(ucfg, NULL); 17320 while (cat) { 17321 if (strcasecmp(cat, "general")) { 17322 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17323 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17324 if (ast_true(hassip) || (!hassip && genhassip)) { 17325 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17326 if (user) { 17327 ASTOBJ_CONTAINER_LINK(&userl,user); 17328 ASTOBJ_UNREF(user, sip_destroy_user); 17329 user_count++; 17330 } 17331 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17332 if (peer) { 17333 ast_device_state_changed("SIP/%s", peer->name); 17334 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17335 ASTOBJ_UNREF(peer, sip_destroy_peer); 17336 peer_count++; 17337 } 17338 } 17339 if (ast_true(registersip) || (!registersip && genregistersip)) { 17340 char tmp[256]; 17341 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17342 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17343 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17344 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17345 if (!host) 17346 host = ast_variable_retrieve(ucfg, "general", "host"); 17347 if (!username) 17348 username = ast_variable_retrieve(ucfg, "general", "username"); 17349 if (!secret) 17350 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17351 if (!contact) 17352 contact = "s"; 17353 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17354 if (!ast_strlen_zero(secret)) 17355 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17356 else 17357 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17358 if (sip_register(tmp, 0) == 0) 17359 registry_count++; 17360 } 17361 } 17362 } 17363 cat = ast_category_browse(ucfg, cat); 17364 } 17365 ast_config_destroy(ucfg); 17366 } 17367 17368 17369 /* Load peers, users and friends */ 17370 cat = NULL; 17371 while ( (cat = ast_category_browse(cfg, cat)) ) { 17372 const char *utype; 17373 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17374 continue; 17375 utype = ast_variable_retrieve(cfg, cat, "type"); 17376 if (!utype) { 17377 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17378 continue; 17379 } else { 17380 int is_user = 0, is_peer = 0; 17381 if (!strcasecmp(utype, "user")) 17382 is_user = 1; 17383 else if (!strcasecmp(utype, "friend")) 17384 is_user = is_peer = 1; 17385 else if (!strcasecmp(utype, "peer")) 17386 is_peer = 1; 17387 else { 17388 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17389 continue; 17390 } 17391 if (is_user) { 17392 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17393 if (user) { 17394 ASTOBJ_CONTAINER_LINK(&userl,user); 17395 ASTOBJ_UNREF(user, sip_destroy_user); 17396 user_count++; 17397 } 17398 } 17399 if (is_peer) { 17400 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17401 if (peer) { 17402 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17403 ASTOBJ_UNREF(peer, sip_destroy_peer); 17404 peer_count++; 17405 } 17406 } 17407 } 17408 } 17409 if (ast_find_ourip(&__ourip, bindaddr)) { 17410 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17411 ast_config_destroy(cfg); 17412 return 0; 17413 } 17414 if (!ntohs(bindaddr.sin_port)) 17415 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17416 bindaddr.sin_family = AF_INET; 17417 ast_mutex_lock(&netlock); 17418 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17419 close(sipsock); 17420 sipsock = -1; 17421 } 17422 if (sipsock < 0) { 17423 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17424 if (sipsock < 0) { 17425 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17426 ast_config_destroy(cfg); 17427 return -1; 17428 } else { 17429 /* Allow SIP clients on the same host to access us: */ 17430 const int reuseFlag = 1; 17431 17432 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17433 (const char*)&reuseFlag, 17434 sizeof reuseFlag); 17435 17436 ast_enable_packet_fragmentation(sipsock); 17437 17438 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17439 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17440 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17441 strerror(errno)); 17442 close(sipsock); 17443 sipsock = -1; 17444 } else { 17445 if (option_verbose > 1) { 17446 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17447 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17448 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17449 } 17450 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17451 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17452 } 17453 } 17454 } 17455 ast_mutex_unlock(&netlock); 17456 17457 /* Add default domains - host name, IP address and IP:port */ 17458 /* Only do this if user added any sip domain with "localdomains" */ 17459 /* In order to *not* break backwards compatibility */ 17460 /* Some phones address us at IP only, some with additional port number */ 17461 if (auto_sip_domains) { 17462 char temp[MAXHOSTNAMELEN]; 17463 17464 /* First our default IP address */ 17465 if (bindaddr.sin_addr.s_addr) 17466 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17467 else 17468 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17469 17470 /* Our extern IP address, if configured */ 17471 if (externip.sin_addr.s_addr) 17472 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17473 17474 /* Extern host name (NAT traversal support) */ 17475 if (!ast_strlen_zero(externhost)) 17476 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17477 17478 /* Our host name */ 17479 if (!gethostname(temp, sizeof(temp))) 17480 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17481 } 17482 17483 /* Release configuration from memory */ 17484 ast_config_destroy(cfg); 17485 17486 /* Load the list of manual NOTIFY types to support */ 17487 if (notify_types) 17488 ast_config_destroy(notify_types); 17489 notify_types = ast_config_load(notify_config); 17490 17491 /* Done, tell the manager */ 17492 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); 17493 17494 return 0; 17495 }
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 11528 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, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11529 { 11530 char tmp[512]; 11531 char *c; 11532 char oldnonce[256]; 11533 11534 /* table of recognised keywords, and places where they should be copied */ 11535 const struct x { 11536 const char *key; 11537 int field_index; 11538 } *i, keys[] = { 11539 { "realm=", ast_string_field_index(p, realm) }, 11540 { "nonce=", ast_string_field_index(p, nonce) }, 11541 { "opaque=", ast_string_field_index(p, opaque) }, 11542 { "qop=", ast_string_field_index(p, qop) }, 11543 { "domain=", ast_string_field_index(p, domain) }, 11544 { NULL, 0 }, 11545 }; 11546 11547 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11548 if (ast_strlen_zero(tmp)) 11549 return -1; 11550 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11551 ast_log(LOG_WARNING, "missing Digest.\n"); 11552 return -1; 11553 } 11554 c = tmp + strlen("Digest "); 11555 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11556 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11557 for (i = keys; i->key != NULL; i++) { 11558 char *src, *separator; 11559 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11560 continue; 11561 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11562 c += strlen(i->key); 11563 if (*c == '"') { 11564 src = ++c; 11565 separator = "\""; 11566 } else { 11567 src = c; 11568 separator = ","; 11569 } 11570 strsep(&c, separator); /* clear separator and move ptr */ 11571 ast_string_field_index_set(p, i->field_index, src); 11572 break; 11573 } 11574 if (i->key == NULL) /* not found, try ',' */ 11575 strsep(&c, ","); 11576 } 11577 /* Reset nonce count */ 11578 if (strcmp(p->nonce, oldnonce)) 11579 p->noncecount = 0; 11580 11581 /* Save auth data for following registrations */ 11582 if (p->registry) { 11583 struct sip_registry *r = p->registry; 11584 11585 if (strcmp(r->nonce, p->nonce)) { 11586 ast_string_field_set(r, realm, p->realm); 11587 ast_string_field_set(r, nonce, p->nonce); 11588 ast_string_field_set(r, domain, p->domain); 11589 ast_string_field_set(r, opaque, p->opaque); 11590 ast_string_field_set(r, qop, p->qop); 11591 r->noncecount = 0; 11592 } 11593 } 11594 return build_reply_digest(p, sipmethod, digest, digest_len); 11595 }
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 5931 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.
05932 { 05933 struct sip_request *orig = &p->initreq; 05934 char stripped[80]; 05935 char tmp[80]; 05936 char newto[256]; 05937 const char *c; 05938 const char *ot, *of; 05939 int is_strict = FALSE; /*!< Strict routing flag */ 05940 05941 memset(req, 0, sizeof(struct sip_request)); 05942 05943 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05944 05945 if (!seqno) { 05946 p->ocseq++; 05947 seqno = p->ocseq; 05948 } 05949 05950 if (newbranch) { 05951 p->branch ^= ast_random(); 05952 build_via(p); 05953 } 05954 05955 /* Check for strict or loose router */ 05956 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05957 is_strict = TRUE; 05958 if (sipdebug) 05959 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05960 } 05961 05962 if (sipmethod == SIP_CANCEL) 05963 c = p->initreq.rlPart2; /* Use original URI */ 05964 else if (sipmethod == SIP_ACK) { 05965 /* Use URI from Contact: in 200 OK (if INVITE) 05966 (we only have the contacturi on INVITEs) */ 05967 if (!ast_strlen_zero(p->okcontacturi)) 05968 c = is_strict ? p->route->hop : p->okcontacturi; 05969 else 05970 c = p->initreq.rlPart2; 05971 } else if (!ast_strlen_zero(p->okcontacturi)) 05972 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05973 else if (!ast_strlen_zero(p->uri)) 05974 c = p->uri; 05975 else { 05976 char *n; 05977 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05978 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05979 sizeof(stripped)); 05980 n = get_in_brackets(stripped); 05981 c = strsep(&n, ";"); /* trim ; and beyond */ 05982 } 05983 init_req(req, sipmethod, c); 05984 05985 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05986 05987 add_header(req, "Via", p->via); 05988 if (p->route) { 05989 set_destination(p, p->route->hop); 05990 add_route(req, is_strict ? p->route->next : p->route); 05991 } 05992 05993 ot = get_header(orig, "To"); 05994 of = get_header(orig, "From"); 05995 05996 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05997 as our original request, including tag (or presumably lack thereof) */ 05998 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05999 /* Add the proper tag if we don't have it already. If they have specified 06000 their tag, use it. Otherwise, use our own tag */ 06001 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06002 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06003 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06004 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06005 else 06006 snprintf(newto, sizeof(newto), "%s", ot); 06007 ot = newto; 06008 } 06009 06010 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06011 add_header(req, "From", of); 06012 add_header(req, "To", ot); 06013 } else { 06014 add_header(req, "From", ot); 06015 add_header(req, "To", of); 06016 } 06017 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06018 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06019 add_header(req, "Contact", p->our_contact); 06020 06021 copy_header(req, orig, "Call-ID"); 06022 add_header(req, "CSeq", tmp); 06023 06024 if (!ast_strlen_zero(global_useragent)) 06025 add_header(req, "User-Agent", global_useragent); 06026 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06027 06028 if (!ast_strlen_zero(p->rpid)) 06029 add_header(req, "Remote-Party-ID", p->rpid); 06030 06031 return 0; 06032 }
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 5883 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.
05884 { 05885 char newto[256]; 05886 const char *ot; 05887 05888 init_resp(resp, msg); 05889 copy_via_headers(p, resp, req, "Via"); 05890 if (msg[0] == '1' || msg[0] == '2') 05891 copy_all_header(resp, req, "Record-Route"); 05892 copy_header(resp, req, "From"); 05893 ot = get_header(req, "To"); 05894 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05895 /* Add the proper tag if we don't have it already. If they have specified 05896 their tag, use it. Otherwise, use our own tag */ 05897 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05898 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05899 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05900 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05901 else 05902 ast_copy_string(newto, ot, sizeof(newto)); 05903 ot = newto; 05904 } 05905 add_header(resp, "To", ot); 05906 copy_header(resp, req, "Call-ID"); 05907 copy_header(resp, req, "CSeq"); 05908 if (!ast_strlen_zero(global_useragent)) 05909 add_header(resp, "User-Agent", global_useragent); 05910 add_header(resp, "Allow", ALLOWED_METHODS); 05911 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05912 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05913 /* For registration responses, we also need expiry and 05914 contact info */ 05915 char tmp[256]; 05916 05917 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05918 add_header(resp, "Expires", tmp); 05919 if (p->expiry) { /* Only add contact if we have an expiry time */ 05920 char contact[SIPBUFSIZE]; 05921 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05922 add_header(resp, "Contact", contact); /* Not when we unregister */ 05923 } 05924 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05925 add_header(resp, "Contact", p->our_contact); 05926 } 05927 return 0; 05928 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15818 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(), and LOG_ERROR.
15819 { 15820 /* If we're supposed to be stopped -- stay stopped */ 15821 if (monitor_thread == AST_PTHREADT_STOP) 15822 return 0; 15823 ast_mutex_lock(&monlock); 15824 if (monitor_thread == pthread_self()) { 15825 ast_mutex_unlock(&monlock); 15826 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15827 return -1; 15828 } 15829 if (monitor_thread != AST_PTHREADT_NULL) { 15830 /* Wake up the thread */ 15831 pthread_kill(monitor_thread, SIGURG); 15832 } else { 15833 /* Start a new monitor */ 15834 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15835 ast_mutex_unlock(&monlock); 15836 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15837 return -1; 15838 } 15839 } 15840 ast_mutex_unlock(&monlock); 15841 return 0; 15842 }
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_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 8052 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_log(), ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
08053 { 08054 struct hostent *hp; 08055 struct ast_hostent ahp; 08056 int port; 08057 char *c, *host, *pt; 08058 char contact_buf[256]; 08059 char *contact; 08060 08061 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08062 /* NAT: Don't trust the contact field. Just use what they came to us 08063 with. */ 08064 pvt->sa = pvt->recv; 08065 return 0; 08066 } 08067 08068 /* Work on a copy */ 08069 ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); 08070 contact = contact_buf; 08071 08072 /* Make sure it's a SIP URL */ 08073 if (strncasecmp(contact, "sip:", 4)) { 08074 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08075 } else 08076 contact += 4; 08077 08078 /* Ditch arguments */ 08079 /* XXX this code is replicated also shortly below */ 08080 08081 /* Grab host */ 08082 host = strchr(contact, '@'); 08083 if (!host) { /* No username part */ 08084 host = contact; 08085 c = NULL; 08086 } else { 08087 *host++ = '\0'; 08088 } 08089 pt = strchr(host, ':'); 08090 if (pt) { 08091 *pt++ = '\0'; 08092 port = atoi(pt); 08093 } else 08094 port = STANDARD_SIP_PORT; 08095 08096 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08097 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08098 08099 /* XXX This could block for a long time XXX */ 08100 /* We should only do this if it's a name, not an IP */ 08101 hp = ast_gethostbyname(host, &ahp); 08102 if (!hp) { 08103 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08104 return -1; 08105 } 08106 pvt->sa.sin_family = AF_INET; 08107 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08108 pvt->sa.sin_port = htons(port); 08109 08110 return 0; 08111 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5792 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05793 { 05794 char *h, *maddr, hostname[256]; 05795 int port, hn; 05796 struct hostent *hp; 05797 struct ast_hostent ahp; 05798 int debug=sip_debug_test_pvt(p); 05799 05800 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05801 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05802 05803 if (debug) 05804 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05805 05806 /* Find and parse hostname */ 05807 h = strchr(uri, '@'); 05808 if (h) 05809 ++h; 05810 else { 05811 h = uri; 05812 if (strncasecmp(h, "sip:", 4) == 0) 05813 h += 4; 05814 else if (strncasecmp(h, "sips:", 5) == 0) 05815 h += 5; 05816 } 05817 hn = strcspn(h, ":;>") + 1; 05818 if (hn > sizeof(hostname)) 05819 hn = sizeof(hostname); 05820 ast_copy_string(hostname, h, hn); 05821 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05822 h += hn - 1; 05823 05824 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05825 if (*h == ':') { 05826 /* Parse port */ 05827 ++h; 05828 port = strtol(h, &h, 10); 05829 } 05830 else 05831 port = STANDARD_SIP_PORT; 05832 05833 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05834 maddr = strstr(h, "maddr="); 05835 if (maddr) { 05836 maddr += 6; 05837 hn = strspn(maddr, "0123456789.") + 1; 05838 if (hn > sizeof(hostname)) 05839 hn = sizeof(hostname); 05840 ast_copy_string(hostname, maddr, hn); 05841 } 05842 05843 hp = ast_gethostbyname(hostname, &ahp); 05844 if (hp == NULL) { 05845 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05846 return; 05847 } 05848 p->sa.sin_family = AF_INET; 05849 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05850 p->sa.sin_port = htons(port); 05851 if (debug) 05852 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05853 }
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 16145 of file chan_sip.c.
References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options().
16146 { 16147 static int dep_insecure_very = 0; 16148 static int dep_insecure_yes = 0; 16149 16150 if (ast_strlen_zero(value)) 16151 return; 16152 16153 if (!strcasecmp(value, "very")) { 16154 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16155 if(!dep_insecure_very) { 16156 if(lineno != -1) 16157 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16158 else 16159 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16160 dep_insecure_very = 1; 16161 } 16162 } 16163 else if (ast_true(value)) { 16164 ast_set_flag(flags, SIP_INSECURE_PORT); 16165 if(!dep_insecure_yes) { 16166 if(lineno != -1) 16167 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16168 else 16169 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16170 dep_insecure_yes = 1; 16171 } 16172 } 16173 else if (!ast_false(value)) { 16174 char buf[64]; 16175 char *word, *next; 16176 ast_copy_string(buf, value, sizeof(buf)); 16177 next = buf; 16178 while ((word = strsep(&next, ","))) { 16179 if (!strcasecmp(word, "port")) 16180 ast_set_flag(flags, SIP_INSECURE_PORT); 16181 else if (!strcasecmp(word, "invite")) 16182 ast_set_flag(flags, SIP_INSECURE_INVITE); 16183 else 16184 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16185 } 16186 } 16187 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16576 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, global_flags, 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().
16577 { 16578 if (peer->expire == 0) { 16579 /* Don't reset expire or port time during reload 16580 if we have an active registration 16581 */ 16582 peer->expire = -1; 16583 peer->pokeexpire = -1; 16584 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16585 } 16586 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16587 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16588 strcpy(peer->context, default_context); 16589 strcpy(peer->subscribecontext, default_subscribecontext); 16590 strcpy(peer->language, default_language); 16591 strcpy(peer->mohinterpret, default_mohinterpret); 16592 strcpy(peer->mohsuggest, default_mohsuggest); 16593 peer->addr.sin_family = AF_INET; 16594 peer->defaddr.sin_family = AF_INET; 16595 peer->capability = global_capability; 16596 peer->maxcallbitrate = default_maxcallbitrate; 16597 peer->rtptimeout = global_rtptimeout; 16598 peer->rtpholdtimeout = global_rtpholdtimeout; 16599 peer->rtpkeepalive = global_rtpkeepalive; 16600 peer->allowtransfer = global_allowtransfer; 16601 peer->autoframing = global_autoframing; 16602 strcpy(peer->vmexten, default_vmexten); 16603 peer->secret[0] = '\0'; 16604 peer->md5secret[0] = '\0'; 16605 peer->cid_num[0] = '\0'; 16606 peer->cid_name[0] = '\0'; 16607 peer->fromdomain[0] = '\0'; 16608 peer->fromuser[0] = '\0'; 16609 peer->regexten[0] = '\0'; 16610 peer->mailbox[0] = '\0'; 16611 peer->callgroup = 0; 16612 peer->pickupgroup = 0; 16613 peer->maxms = default_qualify; 16614 peer->prefs = default_prefs; 16615 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17834 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
17835 { 17836 int no = 0; 17837 int ok = FALSE; 17838 char varbuf[30]; 17839 char *inbuf = (char *) data; 17840 17841 if (ast_strlen_zero(inbuf)) { 17842 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17843 return 0; 17844 } 17845 ast_channel_lock(chan); 17846 17847 /* Check for headers */ 17848 while (!ok && no <= 50) { 17849 no++; 17850 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17851 17852 /* Compare without the leading underscore */ 17853 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17854 ok = TRUE; 17855 } 17856 if (ok) { 17857 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17858 if (sipdebug) 17859 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17860 } else { 17861 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17862 } 17863 ast_channel_unlock(chan); 17864 return 0; 17865 }
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] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4444 of file chan_sip.c.
References __ourip, 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(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, 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, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by 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::lock, LOG_DEBUG, option_debug, 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, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, 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(), sip_pvt::autokillid, and sched.
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 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(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), 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(), 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 15987 of file chan_sip.c.
References sip_peer::addr, ahp, 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().
15988 { 15989 char *host; 15990 char *tmp; 15991 15992 struct hostent *hp; 15993 struct ast_hostent ahp; 15994 struct sip_peer *p; 15995 15996 int res = AST_DEVICE_INVALID; 15997 15998 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15999 host = ast_strdupa(data ? data : ""); 16000 if ((tmp = strchr(host, '@'))) 16001 host = tmp + 1; 16002 16003 if (option_debug > 2) 16004 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16005 16006 if ((p = find_peer(host, NULL, 1))) { 16007 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16008 /* we have an address for the peer */ 16009 16010 /* Check status in this order 16011 - Hold 16012 - Ringing 16013 - Busy (enforced only by call limit) 16014 - Inuse (we have a call) 16015 - Unreachable (qualify) 16016 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16017 for registered devices */ 16018 16019 if (p->onHold) 16020 /* First check for hold or ring states */ 16021 res = AST_DEVICE_ONHOLD; 16022 else if (p->inRinging) { 16023 if (p->inRinging == p->inUse) 16024 res = AST_DEVICE_RINGING; 16025 else 16026 res = AST_DEVICE_RINGINUSE; 16027 } else if (p->call_limit && (p->inUse == p->call_limit)) 16028 /* check call limit */ 16029 res = AST_DEVICE_BUSY; 16030 else if (p->call_limit && p->inUse) 16031 /* Not busy, but we do have a call */ 16032 res = AST_DEVICE_INUSE; 16033 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16034 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16035 res = AST_DEVICE_UNAVAILABLE; 16036 else /* Default reply if we're registered and have no other data */ 16037 res = AST_DEVICE_NOT_INUSE; 16038 } else { 16039 /* there is no address, it's unavailable */ 16040 res = AST_DEVICE_UNAVAILABLE; 16041 } 16042 ASTOBJ_UNREF(p,sip_destroy_peer); 16043 } else { 16044 char *port = strchr(host, ':'); 16045 if (port) 16046 *port = '\0'; 16047 hp = ast_gethostbyname(host, &ahp); 16048 if (hp) 16049 res = AST_DEVICE_UNKNOWN; 16050 } 16051 16052 return res; 16053 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11341 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11342 { 11343 int oldsipdebug = sipdebug_console; 11344 if (argc != 3) { 11345 if (argc != 5) 11346 return RESULT_SHOWUSAGE; 11347 else if (strcmp(argv[3], "ip") == 0) 11348 return sip_do_debug_ip(fd, argc, argv); 11349 else if (strcmp(argv[3], "peer") == 0) 11350 return sip_do_debug_peer(fd, argc, argv); 11351 else 11352 return RESULT_SHOWUSAGE; 11353 } 11354 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11355 memset(&debugaddr, 0, sizeof(debugaddr)); 11356 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11357 return RESULT_SUCCESS; 11358 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11360 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11361 { 11362 int oldsipdebug = sipdebug_console; 11363 char *newargv[6] = { "sip", "set", "debug", NULL }; 11364 if (argc != 2) { 11365 if (argc != 4) 11366 return RESULT_SHOWUSAGE; 11367 else if (strcmp(argv[2], "ip") == 0) { 11368 newargv[3] = argv[2]; 11369 newargv[4] = argv[3]; 11370 return sip_do_debug_ip(fd, argc + 1, newargv); 11371 } else if (strcmp(argv[2], "peer") == 0) { 11372 newargv[3] = argv[2]; 11373 newargv[4] = argv[3]; 11374 return sip_do_debug_peer(fd, argc + 1, newargv); 11375 } else 11376 return RESULT_SHOWUSAGE; 11377 } 11378 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11379 memset(&debugaddr, 0, sizeof(debugaddr)); 11380 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11381 return RESULT_SUCCESS; 11382 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11287 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11288 { 11289 struct hostent *hp; 11290 struct ast_hostent ahp; 11291 int port = 0; 11292 char *p, *arg; 11293 11294 /* sip set debug ip <ip> */ 11295 if (argc != 5) 11296 return RESULT_SHOWUSAGE; 11297 p = arg = argv[4]; 11298 strsep(&p, ":"); 11299 if (p) 11300 port = atoi(p); 11301 hp = ast_gethostbyname(arg, &ahp); 11302 if (hp == NULL) 11303 return RESULT_SHOWUSAGE; 11304 11305 debugaddr.sin_family = AF_INET; 11306 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11307 debugaddr.sin_port = htons(port); 11308 if (port == 0) 11309 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11310 else 11311 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11312 11313 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11314 11315 return RESULT_SUCCESS; 11316 }
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 11319 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11320 { 11321 struct sip_peer *peer; 11322 if (argc != 5) 11323 return RESULT_SHOWUSAGE; 11324 peer = find_peer(argv[4], NULL, 1); 11325 if (peer) { 11326 if (peer->addr.sin_addr.s_addr) { 11327 debugaddr.sin_family = AF_INET; 11328 debugaddr.sin_addr = peer->addr.sin_addr; 11329 debugaddr.sin_port = peer->addr.sin_port; 11330 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11331 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11332 } else 11333 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11334 ASTOBJ_UNREF(peer,sip_destroy_peer); 11335 } else 11336 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11337 return RESULT_SUCCESS; 11338 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11460 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11461 { 11462 if (argc != 2) { 11463 return RESULT_SHOWUSAGE; 11464 } 11465 recordhistory = TRUE; 11466 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11467 return RESULT_SUCCESS; 11468 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17980 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
17981 { 17982 reload_config(reason); 17983 17984 /* Prune peers who still are supposed to be deleted */ 17985 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17986 if (option_debug > 3) 17987 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17988 17989 /* Send qualify (OPTIONS) to all peers */ 17990 sip_poke_all_peers(); 17991 17992 /* Register with all services */ 17993 sip_send_all_registers(); 17994 17995 if (option_debug > 3) 17996 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17997 17998 return 0; 17999 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17779 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, 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().
17780 { 17781 struct sip_pvt *p; 17782 char *mode; 17783 if (data) 17784 mode = (char *)data; 17785 else { 17786 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17787 return 0; 17788 } 17789 ast_channel_lock(chan); 17790 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17791 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17792 ast_channel_unlock(chan); 17793 return 0; 17794 } 17795 p = chan->tech_pvt; 17796 if (!p) { 17797 ast_channel_unlock(chan); 17798 return 0; 17799 } 17800 ast_mutex_lock(&p->lock); 17801 if (!strcasecmp(mode,"info")) { 17802 ast_clear_flag(&p->flags[0], SIP_DTMF); 17803 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17804 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17805 } else if (!strcasecmp(mode,"rfc2833")) { 17806 ast_clear_flag(&p->flags[0], SIP_DTMF); 17807 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17808 p->jointnoncodeccapability |= AST_RTP_DTMF; 17809 } else if (!strcasecmp(mode,"inband")) { 17810 ast_clear_flag(&p->flags[0], SIP_DTMF); 17811 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17812 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17813 } else 17814 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17815 if (p->rtp) 17816 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17817 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17818 if (!p->vad) { 17819 p->vad = ast_dsp_new(); 17820 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17821 } 17822 } else { 17823 if (p->vad) { 17824 ast_dsp_free(p->vad); 17825 p->vad = NULL; 17826 } 17827 } 17828 ast_mutex_unlock(&p->lock); 17829 ast_channel_unlock(chan); 17830 return 0; 17831 }
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 11152 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().
11153 { 11154 int x = 0; 11155 struct sip_history *hist; 11156 static int errmsg = 0; 11157 11158 if (!dialog) 11159 return; 11160 11161 if (!option_debug && !sipdebug) { 11162 if (!errmsg) { 11163 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11164 errmsg = 1; 11165 } 11166 return; 11167 } 11168 11169 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11170 if (dialog->subscribed) 11171 ast_log(LOG_DEBUG, " * Subscription\n"); 11172 else 11173 ast_log(LOG_DEBUG, " * SIP Call\n"); 11174 if (dialog->history) 11175 AST_LIST_TRAVERSE(dialog->history, hist, list) 11176 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11177 if (!x) 11178 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11179 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11180 }
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, 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 17924 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17925 { 17926 struct sip_pvt *p = chan->tech_pvt; 17927 return p->peercapability ? p->peercapability : p->capability; 17928 }
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 17632 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.
17633 { 17634 struct sip_pvt *p = NULL; 17635 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17636 17637 if (!(p = chan->tech_pvt)) 17638 return AST_RTP_GET_FAILED; 17639 17640 ast_mutex_lock(&p->lock); 17641 if (!(p->rtp)) { 17642 ast_mutex_unlock(&p->lock); 17643 return AST_RTP_GET_FAILED; 17644 } 17645 17646 *rtp = p->rtp; 17647 17648 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17649 res = AST_RTP_TRY_PARTIAL; 17650 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17651 res = AST_RTP_TRY_NATIVE; 17652 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17653 res = AST_RTP_GET_FAILED; 17654 17655 ast_mutex_unlock(&p->lock); 17656 17657 return res; 17658 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 17497 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.
17498 { 17499 struct sip_pvt *p; 17500 struct ast_udptl *udptl = NULL; 17501 17502 p = chan->tech_pvt; 17503 if (!p) 17504 return NULL; 17505 17506 ast_mutex_lock(&p->lock); 17507 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17508 udptl = p->udptl; 17509 ast_mutex_unlock(&p->lock); 17510 return udptl; 17511 }
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 17661 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_pvt::rtp, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
17662 { 17663 struct sip_pvt *p = NULL; 17664 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17665 17666 if (!(p = chan->tech_pvt)) 17667 return AST_RTP_GET_FAILED; 17668 17669 ast_mutex_lock(&p->lock); 17670 if (!(p->vrtp)) { 17671 ast_mutex_unlock(&p->lock); 17672 return AST_RTP_GET_FAILED; 17673 } 17674 17675 *rtp = p->vrtp; 17676 17677 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17678 res = AST_RTP_TRY_NATIVE; 17679 17680 ast_mutex_unlock(&p->lock); 17681 17682 return res; 17683 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 17549 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, 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().
17550 { 17551 struct sip_pvt *p; 17552 int flag = 0; 17553 17554 p = chan->tech_pvt; 17555 if (!p || !pvt->udptl) 17556 return -1; 17557 17558 /* Setup everything on the other side like offered/responded from first side */ 17559 ast_mutex_lock(&p->lock); 17560 17561 /*! \todo check if this is not set earlier when setting up the PVT. If not 17562 maybe it should move there. */ 17563 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17564 17565 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17566 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17567 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17568 17569 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17570 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17571 not really T38 re-invites which are different. In this 17572 case it's used properly, to see if we can reinvite over 17573 NAT 17574 */ 17575 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17576 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17577 flag =1; 17578 } else { 17579 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17580 } 17581 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17582 if (!p->pendinginvite) { 17583 if (option_debug > 2) { 17584 if (flag) 17585 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)); 17586 else 17587 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)); 17588 } 17589 transmit_reinvite_with_t38_sdp(p); 17590 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17591 if (option_debug > 2) { 17592 if (flag) 17593 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)); 17594 else 17595 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)); 17596 } 17597 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17598 } 17599 } 17600 /* Reset lastrtprx timer */ 17601 p->lastrtprx = p->lastrtptx = time(NULL); 17602 ast_mutex_unlock(&p->lock); 17603 return 0; 17604 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17605 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17606 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17607 flag = 1; 17608 } else { 17609 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17610 } 17611 if (option_debug > 2) { 17612 if (flag) 17613 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)); 17614 else 17615 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)); 17616 } 17617 pvt->t38.state = T38_ENABLED; 17618 p->t38.state = T38_ENABLED; 17619 if (option_debug > 1) { 17620 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17621 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17622 } 17623 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17624 p->lastrtprx = p->lastrtptx = time(NULL); 17625 ast_mutex_unlock(&p->lock); 17626 return 0; 17627 } 17628 }
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, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, 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, 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, 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] |
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, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, 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 11441 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11442 { 11443 if (argc != 4) 11444 return RESULT_SHOWUSAGE; 11445 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11446 ast_cli(fd, "SIP Debugging Disabled\n"); 11447 return RESULT_SUCCESS; 11448 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11450 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11451 { 11452 if (argc != 3) 11453 return RESULT_SHOWUSAGE; 11454 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11455 ast_cli(fd, "SIP Debugging Disabled\n"); 11456 return RESULT_SUCCESS; 11457 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11471 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11472 { 11473 if (argc != 3) { 11474 return RESULT_SHOWUSAGE; 11475 } 11476 recordhistory = FALSE; 11477 ast_cli(fd, "SIP History Recording Disabled\n"); 11478 return RESULT_SUCCESS; 11479 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11385 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(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
11386 { 11387 struct ast_variable *varlist; 11388 int i; 11389 11390 if (argc < 4) 11391 return RESULT_SHOWUSAGE; 11392 11393 if (!notify_types) { 11394 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11395 return RESULT_FAILURE; 11396 } 11397 11398 varlist = ast_variable_browse(notify_types, argv[2]); 11399 11400 if (!varlist) { 11401 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11402 return RESULT_FAILURE; 11403 } 11404 11405 for (i = 3; i < argc; i++) { 11406 struct sip_pvt *p; 11407 struct sip_request req; 11408 struct ast_variable *var; 11409 11410 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11411 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11412 return RESULT_FAILURE; 11413 } 11414 11415 if (create_addr(p, argv[i])) { 11416 /* Maybe they're not registered, etc. */ 11417 sip_destroy(p); 11418 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11419 continue; 11420 } 11421 11422 initreqprep(&req, p, SIP_NOTIFY); 11423 11424 for (var = varlist; var; var = var->next) 11425 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11426 11427 /* Recalculate our side, and recalculate Call ID */ 11428 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11429 p->ourip = __ourip; 11430 build_via(p); 11431 build_callid_pvt(p); 11432 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11433 transmit_sip_request(p, &req); 11434 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11435 } 11436 11437 return RESULT_SUCCESS; 11438 }
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 13201 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, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
13202 { 13203 struct sip_dual *d; 13204 struct ast_channel *transferee, *transferer; 13205 /* Chan2m: The transferer, chan1m: The transferee */ 13206 pthread_t th; 13207 13208 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13209 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13210 if ((!transferer) || (!transferee)) { 13211 if (transferee) { 13212 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13213 ast_hangup(transferee); 13214 } 13215 if (transferer) { 13216 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13217 ast_hangup(transferer); 13218 } 13219 return -1; 13220 } 13221 13222 /* Make formats okay */ 13223 transferee->readformat = chan1->readformat; 13224 transferee->writeformat = chan1->writeformat; 13225 13226 /* Prepare for taking over the channel */ 13227 ast_channel_masquerade(transferee, chan1); 13228 13229 /* Setup the extensions and such */ 13230 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13231 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13232 transferee->priority = chan1->priority; 13233 13234 /* We make a clone of the peer channel too, so we can play 13235 back the announcement */ 13236 13237 /* Make formats okay */ 13238 transferer->readformat = chan2->readformat; 13239 transferer->writeformat = chan2->writeformat; 13240 13241 /* Prepare for taking over the channel. Go ahead and grab this channel 13242 * lock here to avoid a deadlock with callbacks into the channel driver 13243 * that hold the channel lock and want the pvt lock. */ 13244 while (ast_channel_trylock(chan2)) { 13245 struct sip_pvt *pvt = chan2->tech_pvt; 13246 DEADLOCK_AVOIDANCE(&pvt->lock); 13247 } 13248 ast_channel_masquerade(transferer, chan2); 13249 ast_channel_unlock(chan2); 13250 13251 /* Setup the extensions and such */ 13252 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13253 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13254 transferer->priority = chan2->priority; 13255 13256 ast_channel_lock(transferer); 13257 if (ast_do_masquerade(transferer)) { 13258 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13259 ast_channel_unlock(transferer); 13260 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13261 ast_hangup(transferer); 13262 return -1; 13263 } 13264 ast_channel_unlock(transferer); 13265 if (!transferer || !transferee) { 13266 if (!transferer) { 13267 if (option_debug) 13268 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13269 } 13270 if (!transferee) { 13271 if (option_debug) 13272 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13273 } 13274 return -1; 13275 } 13276 if ((d = ast_calloc(1, sizeof(*d)))) { 13277 pthread_attr_t attr; 13278 13279 pthread_attr_init(&attr); 13280 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13281 13282 /* Save original request for followup */ 13283 copy_request(&d->req, req); 13284 d->chan1 = transferee; /* Transferee */ 13285 d->chan2 = transferer; /* Transferer */ 13286 d->seqno = seqno; 13287 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13288 /* Could not start thread */ 13289 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13290 by sip_park_thread() */ 13291 pthread_attr_destroy(&attr); 13292 return 0; 13293 } 13294 pthread_attr_destroy(&attr); 13295 } 13296 return -1; 13297 }
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 13134 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, 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().
13135 { 13136 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13137 struct sip_dual *d; 13138 struct sip_request req; 13139 int ext; 13140 int res; 13141 13142 d = stuff; 13143 transferee = d->chan1; 13144 transferer = d->chan2; 13145 copy_request(&req, &d->req); 13146 free(d); 13147 13148 if (!transferee || !transferer) { 13149 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13150 return NULL; 13151 } 13152 if (option_debug > 3) 13153 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13154 13155 ast_channel_lock(transferee); 13156 if (ast_do_masquerade(transferee)) { 13157 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13158 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13159 ast_channel_unlock(transferee); 13160 return NULL; 13161 } 13162 ast_channel_unlock(transferee); 13163 13164 res = ast_park_call(transferee, transferer, 0, &ext); 13165 13166 13167 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13168 if (!res) { 13169 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13170 } else { 13171 /* Then tell the transferer what happened */ 13172 sprintf(buf, "Call parked on extension '%d'", ext); 13173 transmit_message_with_text(transferer->tech_pvt, buf); 13174 } 13175 #endif 13176 13177 /* Any way back to the current call??? */ 13178 /* Transmit response to the REFER request */ 13179 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13180 if (!res) { 13181 /* Transfer succeeded */ 13182 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13183 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13184 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13185 ast_hangup(transferer); /* This will cause a BYE */ 13186 if (option_debug) 13187 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13188 } else { 13189 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13190 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13191 if (option_debug) 13192 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13193 /* Do not hangup call */ 13194 } 13195 return NULL; 13196 }
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 8580 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().
08581 { 08582 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08583 08584 if (!peer) 08585 return; 08586 08587 /* If they put someone on hold, increment the value... otherwise decrement it */ 08588 if (hold) 08589 peer->onHold++; 08590 else 08591 peer->onHold--; 08592 08593 /* Request device state update */ 08594 ast_device_state_changed("SIP/%s", peer->name); 08595 08596 return; 08597 }
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 17934 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sched, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
17935 { 17936 int ms = 0; 17937 17938 if (!speerobjs) /* No peers, just give up */ 17939 return; 17940 17941 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17942 ASTOBJ_WRLOCK(iterator); 17943 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 17944 struct sip_peer *peer_ptr = iterator; 17945 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17946 } 17947 ms += 100; 17948 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 17949 if (iterator->pokeexpire == -1) { 17950 struct sip_peer *peer_ptr = iterator; 17951 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17952 } 17953 ASTOBJ_UNLOCK(iterator); 17954 } while (0) 17955 ); 17956 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15845 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, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15846 { 15847 struct sip_peer *peer = (struct sip_peer *)data; 15848 15849 peer->pokeexpire = -1; 15850 if (peer->lastms > -1) { 15851 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15852 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15853 } 15854 if (peer->call) 15855 sip_destroy(peer->call); 15856 peer->call = NULL; 15857 peer->lastms = -1; 15858 ast_device_state_changed("SIP/%s", peer->name); 15859 15860 /* This function gets called one place outside of the scheduler ... */ 15861 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15862 struct sip_peer *peer_ptr = peer; 15863 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15864 } 15865 15866 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 15867 * inherit the reference that the current callback already has. */ 15868 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15869 if (peer->pokeexpire == -1) { 15870 ASTOBJ_UNREF(peer, sip_destroy_peer); 15871 } 15872 15873 return 0; 15874 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15879 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, sched, 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().
15880 { 15881 struct sip_pvt *p; 15882 int xmitres = 0; 15883 15884 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15885 /* IF we have no IP, or this isn't to be monitored, return 15886 imeediately after clearing things out */ 15887 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15888 struct sip_peer *peer_ptr = peer; 15889 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15890 } 15891 peer->lastms = 0; 15892 peer->call = NULL; 15893 return 0; 15894 } 15895 if (peer->call) { 15896 if (sipdebug) 15897 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15898 sip_destroy(peer->call); 15899 } 15900 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15901 return -1; 15902 15903 p->sa = peer->addr; 15904 p->recv = peer->addr; 15905 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15906 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15907 15908 /* Send OPTIONs to peer's fullcontact */ 15909 if (!ast_strlen_zero(peer->fullcontact)) 15910 ast_string_field_set(p, fullcontact, peer->fullcontact); 15911 15912 if (!ast_strlen_zero(peer->tohost)) 15913 ast_string_field_set(p, tohost, peer->tohost); 15914 else 15915 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15916 15917 /* Recalculate our side, and recalculate Call ID */ 15918 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15919 p->ourip = __ourip; 15920 build_via(p); 15921 build_callid_pvt(p); 15922 15923 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15924 struct sip_peer *peer_ptr = peer; 15925 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15926 } 15927 15928 p->relatedpeer = ASTOBJ_REF(peer); 15929 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15930 #ifdef VOCAL_DATA_HACK 15931 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15932 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15933 #else 15934 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15935 #endif 15936 gettimeofday(&peer->ps, NULL); 15937 if (xmitres == XMIT_ERROR) { 15938 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 15939 } else { 15940 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15941 struct sip_peer *peer_ptr = peer; 15942 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15943 } 15944 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 15945 if (peer->pokeexpire == -1) { 15946 struct sip_peer *peer_ptr = peer; 15947 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15948 } 15949 } 15950 15951 return 0; 15952 }
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 7945 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().
07946 { 07947 struct sip_peer *peer = (struct sip_peer *) data; 07948 07949 peer->pokeexpire = -1; 07950 07951 sip_poke_peer(peer); 07952 07953 ASTOBJ_UNREF(peer, sip_destroy_peer); 07954 07955 return 0; 07956 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10174 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and TRUE.
10175 { 10176 struct sip_peer *peer; 10177 struct sip_user *user; 10178 int pruneuser = FALSE; 10179 int prunepeer = FALSE; 10180 int multi = FALSE; 10181 char *name = NULL; 10182 regex_t regexbuf; 10183 10184 switch (argc) { 10185 case 4: 10186 if (!strcasecmp(argv[3], "user")) 10187 return RESULT_SHOWUSAGE; 10188 if (!strcasecmp(argv[3], "peer")) 10189 return RESULT_SHOWUSAGE; 10190 if (!strcasecmp(argv[3], "like")) 10191 return RESULT_SHOWUSAGE; 10192 if (!strcasecmp(argv[3], "all")) { 10193 multi = TRUE; 10194 pruneuser = prunepeer = TRUE; 10195 } else { 10196 pruneuser = prunepeer = TRUE; 10197 name = argv[3]; 10198 } 10199 break; 10200 case 5: 10201 if (!strcasecmp(argv[4], "like")) 10202 return RESULT_SHOWUSAGE; 10203 if (!strcasecmp(argv[3], "all")) 10204 return RESULT_SHOWUSAGE; 10205 if (!strcasecmp(argv[3], "like")) { 10206 multi = TRUE; 10207 name = argv[4]; 10208 pruneuser = prunepeer = TRUE; 10209 } else if (!strcasecmp(argv[3], "user")) { 10210 pruneuser = TRUE; 10211 if (!strcasecmp(argv[4], "all")) 10212 multi = TRUE; 10213 else 10214 name = argv[4]; 10215 } else if (!strcasecmp(argv[3], "peer")) { 10216 prunepeer = TRUE; 10217 if (!strcasecmp(argv[4], "all")) 10218 multi = TRUE; 10219 else 10220 name = argv[4]; 10221 } else 10222 return RESULT_SHOWUSAGE; 10223 break; 10224 case 6: 10225 if (strcasecmp(argv[4], "like")) 10226 return RESULT_SHOWUSAGE; 10227 if (!strcasecmp(argv[3], "user")) { 10228 pruneuser = TRUE; 10229 name = argv[5]; 10230 } else if (!strcasecmp(argv[3], "peer")) { 10231 prunepeer = TRUE; 10232 name = argv[5]; 10233 } else 10234 return RESULT_SHOWUSAGE; 10235 break; 10236 default: 10237 return RESULT_SHOWUSAGE; 10238 } 10239 10240 if (multi && name) { 10241 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10242 return RESULT_SHOWUSAGE; 10243 } 10244 10245 if (multi) { 10246 if (prunepeer) { 10247 int pruned = 0; 10248 10249 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10250 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10251 ASTOBJ_RDLOCK(iterator); 10252 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10253 ASTOBJ_UNLOCK(iterator); 10254 continue; 10255 }; 10256 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10257 ASTOBJ_MARK(iterator); 10258 pruned++; 10259 } 10260 ASTOBJ_UNLOCK(iterator); 10261 } while (0) ); 10262 if (pruned) { 10263 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10264 ast_cli(fd, "%d peers pruned.\n", pruned); 10265 } else 10266 ast_cli(fd, "No peers found to prune.\n"); 10267 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10268 } 10269 if (pruneuser) { 10270 int pruned = 0; 10271 10272 ASTOBJ_CONTAINER_WRLOCK(&userl); 10273 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10274 ASTOBJ_RDLOCK(iterator); 10275 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10276 ASTOBJ_UNLOCK(iterator); 10277 continue; 10278 }; 10279 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10280 ASTOBJ_MARK(iterator); 10281 pruned++; 10282 } 10283 ASTOBJ_UNLOCK(iterator); 10284 } while (0) ); 10285 if (pruned) { 10286 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10287 ast_cli(fd, "%d users pruned.\n", pruned); 10288 } else 10289 ast_cli(fd, "No users found to prune.\n"); 10290 ASTOBJ_CONTAINER_UNLOCK(&userl); 10291 } 10292 } else { 10293 if (prunepeer) { 10294 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10295 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10296 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10297 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10298 } else 10299 ast_cli(fd, "Peer '%s' pruned.\n", name); 10300 ASTOBJ_UNREF(peer, sip_destroy_peer); 10301 } else 10302 ast_cli(fd, "Peer '%s' not found.\n", name); 10303 } 10304 if (pruneuser) { 10305 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10306 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10307 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10308 ASTOBJ_CONTAINER_LINK(&userl, user); 10309 } else 10310 ast_cli(fd, "User '%s' pruned.\n", name); 10311 ASTOBJ_UNREF(user, sip_destroy_user); 10312 } else 10313 ast_cli(fd, "User '%s' not found.\n", name); 10314 } 10315 } 10316 10317 return RESULT_SUCCESS; 10318 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
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] |
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 7750 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().
07751 { 07752 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07753 return p->refer ? 1 : 0; 07754 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7505 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().
07506 { 07507 07508 /* if we are here, our registration timed out, so we'll just do it over */ 07509 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07510 struct sip_pvt *p; 07511 int res; 07512 07513 /* if we couldn't get a reference to the registry object, punt */ 07514 if (!r) 07515 return 0; 07516 07517 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07518 if (r->call) { 07519 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07520 in the single SIP manager thread. */ 07521 p = r->call; 07522 ast_mutex_lock(&p->lock); 07523 if (p->registry) 07524 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07525 r->call = NULL; 07526 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07527 /* Pretend to ACK anything just in case */ 07528 __sip_pretend_ack(p); 07529 ast_mutex_unlock(&p->lock); 07530 } 07531 /* If we have a limit, stop registration and give up */ 07532 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07533 /* Ok, enough is enough. Don't try any more */ 07534 /* We could add an external notification here... 07535 steal it from app_voicemail :-) */ 07536 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07537 r->regstate = REG_STATE_FAILED; 07538 } else { 07539 r->regstate = REG_STATE_UNREGISTERED; 07540 r->timeout = -1; 07541 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07542 } 07543 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)); 07544 ASTOBJ_UNREF(r, sip_registry_destroy); 07545 return 0; 07546 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4691 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, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.
04692 { 04693 struct sip_registry *reg; 04694 int portnum = 0; 04695 char username[256] = ""; 04696 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04697 char *porta=NULL; 04698 char *contact=NULL; 04699 04700 if (!value) 04701 return -1; 04702 ast_copy_string(username, value, sizeof(username)); 04703 /* First split around the last '@' then parse the two components. */ 04704 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04705 if (hostname) 04706 *hostname++ = '\0'; 04707 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04708 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04709 return -1; 04710 } 04711 /* split user[:secret[:authuser]] */ 04712 secret = strchr(username, ':'); 04713 if (secret) { 04714 *secret++ = '\0'; 04715 authuser = strchr(secret, ':'); 04716 if (authuser) 04717 *authuser++ = '\0'; 04718 } 04719 /* split host[:port][/contact] */ 04720 contact = strchr(hostname, '/'); 04721 if (contact) 04722 *contact++ = '\0'; 04723 if (ast_strlen_zero(contact)) 04724 contact = "s"; 04725 porta = strchr(hostname, ':'); 04726 if (porta) { 04727 *porta++ = '\0'; 04728 portnum = atoi(porta); 04729 if (portnum == 0) { 04730 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04731 return -1; 04732 } 04733 } 04734 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04735 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04736 return -1; 04737 } 04738 04739 if (ast_string_field_init(reg, 256)) { 04740 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04741 free(reg); 04742 return -1; 04743 } 04744 04745 regobjs++; 04746 ASTOBJ_INIT(reg); 04747 ast_string_field_set(reg, contact, contact); 04748 if (!ast_strlen_zero(username)) 04749 ast_string_field_set(reg, username, username); 04750 if (hostname) 04751 ast_string_field_set(reg, hostname, hostname); 04752 if (authuser) 04753 ast_string_field_set(reg, authuser, authuser); 04754 if (secret) 04755 ast_string_field_set(reg, secret, secret); 04756 reg->expire = -1; 04757 reg->timeout = -1; 04758 reg->refresh = default_expiry; 04759 reg->portno = portnum; 04760 reg->callid_valid = FALSE; 04761 reg->ocseq = INITIAL_CSEQ; 04762 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04763 ASTOBJ_UNREF(reg,sip_registry_destroy); 04764 return 0; 04765 }
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, sched, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), 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 12108 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12109 { 12110 struct sip_pvt *p = (struct sip_pvt *) data; 12111 12112 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12113 p->waitid = -1; 12114 return 0; 12115 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18002 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().
18003 { 18004 ast_mutex_lock(&sip_reload_lock); 18005 if (sip_reloading) 18006 ast_verbose("Previous SIP reload not yet done\n"); 18007 else { 18008 sip_reloading = TRUE; 18009 if (fd) 18010 sip_reloadreason = CHANNEL_CLI_RELOAD; 18011 else 18012 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18013 } 18014 ast_mutex_unlock(&sip_reload_lock); 18015 restart_monitor(); 18016 18017 return 0; 18018 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 16057 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, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
16058 { 16059 int oldformat; 16060 struct sip_pvt *p; 16061 struct ast_channel *tmpc = NULL; 16062 char *ext, *host; 16063 char tmp[256]; 16064 char *dest = data; 16065 16066 oldformat = format; 16067 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16068 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)); 16069 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16070 return NULL; 16071 } 16072 if (option_debug) 16073 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16074 16075 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16076 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16077 *cause = AST_CAUSE_SWITCH_CONGESTION; 16078 return NULL; 16079 } 16080 16081 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16082 16083 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16084 sip_destroy(p); 16085 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16086 *cause = AST_CAUSE_SWITCH_CONGESTION; 16087 return NULL; 16088 } 16089 16090 ast_copy_string(tmp, dest, sizeof(tmp)); 16091 host = strchr(tmp, '@'); 16092 if (host) { 16093 *host++ = '\0'; 16094 ext = tmp; 16095 } else { 16096 ext = strchr(tmp, '/'); 16097 if (ext) 16098 *ext++ = '\0'; 16099 host = tmp; 16100 } 16101 16102 if (create_addr(p, host)) { 16103 *cause = AST_CAUSE_UNREGISTERED; 16104 if (option_debug > 2) 16105 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16106 sip_destroy(p); 16107 return NULL; 16108 } 16109 if (ast_strlen_zero(p->peername) && ext) 16110 ast_string_field_set(p, peername, ext); 16111 /* Recalculate our side, and recalculate Call ID */ 16112 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16113 p->ourip = __ourip; 16114 build_via(p); 16115 build_callid_pvt(p); 16116 16117 /* We have an extension to call, don't use the full contact here */ 16118 /* This to enable dialing registered peers with extension dialling, 16119 like SIP/peername/extension 16120 SIP/peername will still use the full contact */ 16121 if (ext) { 16122 ast_string_field_set(p, username, ext); 16123 ast_string_field_free(p, fullcontact); 16124 } 16125 #if 0 16126 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16127 #endif 16128 p->prefcodec = oldformat; /* Format for this call */ 16129 ast_mutex_lock(&p->lock); 16130 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16131 ast_mutex_unlock(&p->lock); 16132 if (!tmpc) 16133 sip_destroy(p); 16134 ast_update_use_count(); 16135 restart_monitor(); 16136 return tmpc; 16137 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7473 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().
07474 { 07475 /* if we are here, we know that we need to reregister. */ 07476 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07477 07478 /* if we couldn't get a reference to the registry object, punt */ 07479 if (!r) 07480 return 0; 07481 07482 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07483 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07484 /* Since registry's are only added/removed by the the monitor thread, this 07485 may be overkill to reference/dereference at all here */ 07486 if (sipdebug) 07487 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07488 07489 r->expire = -1; 07490 __sip_do_register(r); 07491 ASTOBJ_UNREF(r, sip_registry_destroy); 07492 return 0; 07493 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static] |
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, 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, 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::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02113 { 02114 if (ms < 0) { 02115 if (p->timer_t1 == 0) 02116 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02117 ms = p->timer_t1 * 64; 02118 } 02119 if (sip_debug_test_pvt(p)) 02120 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02121 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02122 append_history(p, "SchedDestroy", "%d ms", ms); 02123 02124 AST_SCHED_DEL(sched, p->autokillid); 02125 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02126 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17959 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
17960 { 17961 int ms; 17962 int regspacing; 17963 if (!regobjs) 17964 return; 17965 regspacing = default_expiry * 1000/regobjs; 17966 if (regspacing > 100) 17967 regspacing = 100; 17968 ms = regspacing; 17969 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17970 ASTOBJ_WRLOCK(iterator); 17971 AST_SCHED_DEL(sched, iterator->expire); 17972 ms += regspacing; 17973 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17974 ASTOBJ_UNLOCK(iterator); 17975 } while (0) 17976 ); 17977 }
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 15579 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 handle_request_subscribe().
15580 { 15581 /* Called with peerl lock, but releases it */ 15582 struct sip_pvt *p; 15583 int newmsgs, oldmsgs; 15584 15585 /* Do we have an IP address? If not, skip this peer */ 15586 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15587 return 0; 15588 15589 /* Check for messages */ 15590 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15591 15592 peer->lastmsgcheck = time(NULL); 15593 15594 /* Return now if it's the same thing we told them last time */ 15595 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15596 return 0; 15597 } 15598 15599 15600 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15601 15602 if (peer->mwipvt) { 15603 /* Base message on subscription */ 15604 p = peer->mwipvt; 15605 } else { 15606 /* Build temporary dialog for this message */ 15607 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15608 return -1; 15609 if (create_addr_from_peer(p, peer)) { 15610 /* Maybe they're not registered, etc. */ 15611 sip_destroy(p); 15612 return 0; 15613 } 15614 /* Recalculate our side, and recalculate Call ID */ 15615 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15616 p->ourip = __ourip; 15617 build_via(p); 15618 build_callid_pvt(p); 15619 /* Destroy this session after 32 secs */ 15620 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15621 } 15622 /* Send MWI */ 15623 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15624 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15625 return 0; 15626 }
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_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 17686 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, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, 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(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
17687 { 17688 struct sip_pvt *p; 17689 int changed = 0; 17690 17691 p = chan->tech_pvt; 17692 if (!p) 17693 return -1; 17694 17695 /* Disable early RTP bridge */ 17696 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17697 return 0; 17698 17699 ast_mutex_lock(&p->lock); 17700 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17701 /* If we're destroyed, don't bother */ 17702 ast_mutex_unlock(&p->lock); 17703 return 0; 17704 } 17705 17706 /* if this peer cannot handle reinvites of the media stream to devices 17707 that are known to be behind a NAT, then stop the process now 17708 */ 17709 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17710 ast_mutex_unlock(&p->lock); 17711 return 0; 17712 } 17713 17714 if (rtp) { 17715 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17716 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17717 memset(&p->redirip, 0, sizeof(p->redirip)); 17718 changed = 1; 17719 } 17720 if (vrtp) { 17721 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17722 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17723 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17724 changed = 1; 17725 } 17726 if (codecs) { 17727 if ((p->redircodecs != codecs)) { 17728 p->redircodecs = codecs; 17729 changed = 1; 17730 } 17731 if ((p->capability & codecs) != p->capability) { 17732 p->jointcapability &= codecs; 17733 p->capability &= codecs; 17734 changed = 1; 17735 } 17736 } 17737 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17738 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17739 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17740 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17741 if (option_debug) 17742 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)); 17743 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17744 if (option_debug > 2) { 17745 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)); 17746 } 17747 transmit_reinvite_with_sdp(p); 17748 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17749 if (option_debug > 2) { 17750 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)); 17751 } 17752 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17753 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17754 } 17755 } 17756 /* Reset lastrtprx timer */ 17757 p->lastrtprx = p->lastrtptx = time(NULL); 17758 ast_mutex_unlock(&p->lock); 17759 return 0; 17760 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17513 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, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
17514 { 17515 struct sip_pvt *p; 17516 17517 p = chan->tech_pvt; 17518 if (!p) 17519 return -1; 17520 ast_mutex_lock(&p->lock); 17521 if (udptl) 17522 ast_udptl_get_peer(udptl, &p->udptlredirip); 17523 else 17524 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17525 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17526 if (!p->pendinginvite) { 17527 if (option_debug > 2) { 17528 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); 17529 } 17530 transmit_reinvite_with_t38_sdp(p); 17531 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17532 if (option_debug > 2) { 17533 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); 17534 } 17535 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17536 } 17537 } 17538 /* Reset lastrtprx timer */ 17539 p->lastrtprx = p->lastrtptx = time(NULL); 17540 ast_mutex_unlock(&p->lock); 17541 return 0; 17542 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11047 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, 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, 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().
11048 { 11049 struct sip_pvt *cur; 11050 size_t len; 11051 int found = 0; 11052 11053 if (argc != 4) 11054 return RESULT_SHOWUSAGE; 11055 len = strlen(argv[3]); 11056 ast_mutex_lock(&iflock); 11057 for (cur = iflist; cur; cur = cur->next) { 11058 if (!strncasecmp(cur->callid, argv[3], len)) { 11059 char formatbuf[SIPBUFSIZE/2]; 11060 ast_cli(fd,"\n"); 11061 if (cur->subscribed != NONE) 11062 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11063 else 11064 ast_cli(fd, " * SIP Call\n"); 11065 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11066 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11067 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11068 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11069 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11070 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11071 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11072 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11073 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11074 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11075 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11076 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11077 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11078 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)" ); 11079 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11080 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11081 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11082 if (!ast_strlen_zero(cur->username)) 11083 ast_cli(fd, " Username: %s\n", cur->username); 11084 if (!ast_strlen_zero(cur->peername)) 11085 ast_cli(fd, " Peername: %s\n", cur->peername); 11086 if (!ast_strlen_zero(cur->uri)) 11087 ast_cli(fd, " Original uri: %s\n", cur->uri); 11088 if (!ast_strlen_zero(cur->cid_num)) 11089 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11090 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11091 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11092 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11093 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11094 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11095 ast_cli(fd, " SIP Options: "); 11096 if (cur->sipoptions) { 11097 int x; 11098 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11099 if (cur->sipoptions & sip_options[x].id) 11100 ast_cli(fd, "%s ", sip_options[x].text); 11101 } 11102 } else 11103 ast_cli(fd, "(none)\n"); 11104 ast_cli(fd, "\n\n"); 11105 found++; 11106 } 11107 } 11108 ast_mutex_unlock(&iflock); 11109 if (!found) 11110 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11111 return RESULT_SUCCESS; 11112 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10840 of file chan_sip.c.
References __sip_show_channels().
10841 { 10842 return __sip_show_channels(fd, argc, argv, 0); 10843 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10352 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.
10353 { 10354 struct domain *d; 10355 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10356 10357 if (AST_LIST_EMPTY(&domain_list)) { 10358 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10359 return RESULT_SUCCESS; 10360 } else { 10361 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10362 AST_LIST_LOCK(&domain_list); 10363 AST_LIST_TRAVERSE(&domain_list, d, list) 10364 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10365 domain_mode_to_text(d->mode)); 10366 AST_LIST_UNLOCK(&domain_list); 10367 ast_cli(fd, "\n"); 10368 return RESULT_SUCCESS; 10369 } 10370 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11115 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
11116 { 11117 struct sip_pvt *cur; 11118 size_t len; 11119 int found = 0; 11120 11121 if (argc != 4) 11122 return RESULT_SHOWUSAGE; 11123 if (!recordhistory) 11124 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11125 len = strlen(argv[3]); 11126 ast_mutex_lock(&iflock); 11127 for (cur = iflist; cur; cur = cur->next) { 11128 if (!strncasecmp(cur->callid, argv[3], len)) { 11129 struct sip_history *hist; 11130 int x = 0; 11131 11132 ast_cli(fd,"\n"); 11133 if (cur->subscribed != NONE) 11134 ast_cli(fd, " * Subscription\n"); 11135 else 11136 ast_cli(fd, " * SIP Call\n"); 11137 if (cur->history) 11138 AST_LIST_TRAVERSE(cur->history, hist, list) 11139 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11140 if (x == 0) 11141 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11142 found++; 11143 } 11144 } 11145 ast_mutex_unlock(&iflock); 11146 if (!found) 11147 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11148 return RESULT_SUCCESS; 11149 }
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 9777 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.
09778 { 09779 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09780 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09781 char ilimits[40]; 09782 char iused[40]; 09783 int showall = FALSE; 09784 09785 if (argc < 3) 09786 return RESULT_SHOWUSAGE; 09787 09788 if (argc == 4 && !strcmp(argv[3],"all")) 09789 showall = TRUE; 09790 09791 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09792 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09793 ASTOBJ_RDLOCK(iterator); 09794 if (iterator->call_limit) 09795 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09796 else 09797 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09798 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09799 if (showall || iterator->call_limit) 09800 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09801 ASTOBJ_UNLOCK(iterator); 09802 } while (0) ); 09803 09804 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09805 09806 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09807 ASTOBJ_RDLOCK(iterator); 09808 if (iterator->call_limit) 09809 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09810 else 09811 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09812 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09813 if (showall || iterator->call_limit) 09814 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09815 ASTOBJ_UNLOCK(iterator); 09816 } while (0) ); 09817 09818 return RESULT_SUCCESS; 09819 #undef FORMAT 09820 #undef FORMAT2 09821 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10098 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10099 { 10100 char tmp[256]; 10101 if (argc != 3) 10102 return RESULT_SHOWUSAGE; 10103 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10104 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10105 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10106 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10107 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10108 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10109 return RESULT_SUCCESS; 10110 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10404 of file chan_sip.c.
References _sip_show_peer().
10405 { 10406 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10407 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9954 of file chan_sip.c.
References _sip_show_peers().
09955 { 09956 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09957 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10677 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.
10678 { 10679 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10680 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10681 char host[80]; 10682 char tmpdat[256]; 10683 struct tm tm; 10684 10685 10686 if (argc != 3) 10687 return RESULT_SHOWUSAGE; 10688 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10689 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10690 ASTOBJ_RDLOCK(iterator); 10691 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10692 if (iterator->regtime) { 10693 ast_localtime(&iterator->regtime, &tm, NULL); 10694 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10695 } else { 10696 tmpdat[0] = 0; 10697 } 10698 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10699 ASTOBJ_UNLOCK(iterator); 10700 } while(0)); 10701 return RESULT_SUCCESS; 10702 #undef FORMAT 10703 #undef FORMAT2 10704 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10707 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(), global_flags, 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().
10708 { 10709 int realtimepeers; 10710 int realtimeusers; 10711 char codec_buf[SIPBUFSIZE]; 10712 10713 realtimepeers = ast_check_realtime("sippeers"); 10714 realtimeusers = ast_check_realtime("sipusers"); 10715 10716 if (argc != 3) 10717 return RESULT_SHOWUSAGE; 10718 ast_cli(fd, "\n\nGlobal Settings:\n"); 10719 ast_cli(fd, "----------------\n"); 10720 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10721 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10722 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10723 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10724 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10725 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10726 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10727 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10728 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10729 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10730 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10731 ast_cli(fd, " Our auth realm %s\n", global_realm); 10732 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10733 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10734 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10735 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10736 ast_cli(fd, " User Agent: %s\n", global_useragent); 10737 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10738 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10739 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10740 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10741 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10742 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10743 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10744 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10745 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10746 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10747 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10748 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10749 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10750 #endif 10751 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10752 if (!realtimepeers && !realtimeusers) 10753 ast_cli(fd, " SIP realtime: Disabled\n" ); 10754 else 10755 ast_cli(fd, " SIP realtime: Enabled\n" ); 10756 10757 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10758 ast_cli(fd, "---------------------------\n"); 10759 ast_cli(fd, " Codecs: "); 10760 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10761 ast_cli(fd, "%s\n", codec_buf); 10762 ast_cli(fd, " Codec Order: "); 10763 print_codec_to_cli(fd, &default_prefs); 10764 ast_cli(fd, "\n"); 10765 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10766 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10767 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10768 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10769 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10770 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10771 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10772 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10773 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10774 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10775 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10776 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10777 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10778 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10779 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10780 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10781 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10782 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10783 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10784 ast_cli(fd, "\nDefault Settings:\n"); 10785 ast_cli(fd, "-----------------\n"); 10786 ast_cli(fd, " Context: %s\n", default_context); 10787 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10788 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10789 ast_cli(fd, " Qualify: %d\n", default_qualify); 10790 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10791 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" ); 10792 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10793 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10794 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10795 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10796 10797 10798 if (realtimepeers || realtimeusers) { 10799 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10800 ast_cli(fd, "----------------------\n"); 10801 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10802 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10803 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10804 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10805 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10806 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10807 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10808 } 10809 ast_cli(fd, "\n----\n"); 10810 return RESULT_SUCCESS; 10811 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10846 of file chan_sip.c.
References __sip_show_channels().
10847 { 10848 return __sip_show_channels(fd, argc, argv, 1); 10849 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10622 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.
10623 { 10624 char cbuf[256]; 10625 struct sip_user *user; 10626 struct ast_variable *v; 10627 int load_realtime; 10628 10629 if (argc < 4) 10630 return RESULT_SHOWUSAGE; 10631 10632 /* Load from realtime storage? */ 10633 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10634 10635 user = find_user(argv[3], load_realtime); 10636 if (user) { 10637 ast_cli(fd,"\n\n"); 10638 ast_cli(fd, " * Name : %s\n", user->name); 10639 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10640 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10641 ast_cli(fd, " Context : %s\n", user->context); 10642 ast_cli(fd, " Language : %s\n", user->language); 10643 if (!ast_strlen_zero(user->accountcode)) 10644 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10645 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10646 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10647 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10648 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10649 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10650 ast_cli(fd, " Callgroup : "); 10651 print_group(fd, user->callgroup, 0); 10652 ast_cli(fd, " Pickupgroup : "); 10653 print_group(fd, user->pickupgroup, 0); 10654 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10655 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10656 ast_cli(fd, " Codec Order : ("); 10657 print_codec_to_cli(fd, &user->prefs); 10658 ast_cli(fd, ")\n"); 10659 10660 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10661 if (user->chanvars) { 10662 ast_cli(fd, " Variables :\n"); 10663 for (v = user->chanvars ; v ; v = v->next) 10664 ast_cli(fd, " %s = %s\n", v->name, v->value); 10665 } 10666 ast_cli(fd,"\n"); 10667 ASTOBJ_UNREF(user,sip_destroy_user); 10668 } else { 10669 ast_cli(fd,"User %s not found.\n", argv[3]); 10670 ast_cli(fd,"\n"); 10671 } 10672 10673 return RESULT_SUCCESS; 10674 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9877 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, TRUE, and userl.
09878 { 09879 regex_t regexbuf; 09880 int havepattern = FALSE; 09881 09882 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09883 09884 switch (argc) { 09885 case 5: 09886 if (!strcasecmp(argv[3], "like")) { 09887 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09888 return RESULT_SHOWUSAGE; 09889 havepattern = TRUE; 09890 } else 09891 return RESULT_SHOWUSAGE; 09892 case 3: 09893 break; 09894 default: 09895 return RESULT_SHOWUSAGE; 09896 } 09897 09898 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09899 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09900 ASTOBJ_RDLOCK(iterator); 09901 09902 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09903 ASTOBJ_UNLOCK(iterator); 09904 continue; 09905 } 09906 09907 ast_cli(fd, FORMAT, iterator->name, 09908 iterator->secret, 09909 iterator->accountcode, 09910 iterator->context, 09911 iterator->ha ? "Yes" : "No", 09912 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09913 ASTOBJ_UNLOCK(iterator); 09914 } while (0) 09915 ); 09916 09917 if (havepattern) 09918 regfree(®exbuf); 09919 09920 return RESULT_SUCCESS; 09921 #undef FORMAT 09922 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17873 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().
17874 { 17875 char *cdest; 17876 char *extension, *host, *port; 17877 char tmp[80]; 17878 17879 cdest = ast_strdupa(dest); 17880 17881 extension = strsep(&cdest, "@"); 17882 host = strsep(&cdest, ":"); 17883 port = strsep(&cdest, ":"); 17884 if (ast_strlen_zero(extension)) { 17885 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17886 return 0; 17887 } 17888 17889 /* we'll issue the redirect message here */ 17890 if (!host) { 17891 char *localtmp; 17892 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17893 if (ast_strlen_zero(tmp)) { 17894 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17895 return 0; 17896 } 17897 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17898 char lhost[80], lport[80]; 17899 memset(lhost, 0, sizeof(lhost)); 17900 memset(lport, 0, sizeof(lport)); 17901 localtmp++; 17902 /* This is okey because lhost and lport are as big as tmp */ 17903 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17904 if (ast_strlen_zero(lhost)) { 17905 ast_log(LOG_ERROR, "Can't find the host address\n"); 17906 return 0; 17907 } 17908 host = ast_strdupa(lhost); 17909 if (!ast_strlen_zero(lport)) { 17910 port = ast_strdupa(lport); 17911 } 17912 } 17913 } 17914 17915 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17916 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17917 17918 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17919 sip_alreadygone(p); 17920 return 0; 17921 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3871 of file chan_sip.c.
References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RING, sip_pvt::lock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().
03872 { 03873 struct sip_pvt *p = ast->tech_pvt; 03874 int res; 03875 03876 if (dest == NULL) /* functions below do not take a NULL */ 03877 dest = ""; 03878 ast_mutex_lock(&p->lock); 03879 if (ast->_state == AST_STATE_RING) 03880 res = sip_sipredirect(p, dest); 03881 else 03882 res = transmit_refer(p, dest); 03883 ast_mutex_unlock(&p->lock); 03884 return res; 03885 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3698 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_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, 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 15477 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(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15478 { 15479 struct sip_request req; 15480 struct sockaddr_in sin = { 0, }; 15481 struct sip_pvt *p; 15482 int res; 15483 socklen_t len = sizeof(sin); 15484 int nounlock; 15485 int recount = 0; 15486 int lockretry; 15487 15488 memset(&req, 0, sizeof(req)); 15489 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15490 if (res < 0) { 15491 #if !defined(__FreeBSD__) 15492 if (errno == EAGAIN) 15493 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15494 else 15495 #endif 15496 if (errno != ECONNREFUSED) 15497 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15498 return 1; 15499 } 15500 if (option_debug && res == sizeof(req.data) - 1) 15501 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15502 15503 req.data[res] = '\0'; 15504 req.len = res; 15505 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15506 ast_set_flag(&req, SIP_PKT_DEBUG); 15507 if (pedanticsipchecking) 15508 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15509 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15510 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15511 15512 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 15513 return 1; 15514 15515 req.method = find_sip_method(req.rlPart1); 15516 15517 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15518 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15519 15520 if (req.headers < 2) /* Must have at least two headers */ 15521 return 1; 15522 15523 /* Process request, with netlock held, and with usual deadlock avoidance */ 15524 for (lockretry = 100; lockretry > 0; lockretry--) { 15525 ast_mutex_lock(&netlock); 15526 15527 /* Find the active SIP dialog or create a new one */ 15528 p = find_call(&req, &sin, req.method); /* returns p locked */ 15529 if (p == NULL) { 15530 if (option_debug) 15531 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15532 ast_mutex_unlock(&netlock); 15533 return 1; 15534 } 15535 /* Go ahead and lock the owner if it has one -- we may need it */ 15536 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15537 if (!p->owner || !ast_channel_trylock(p->owner)) 15538 break; /* locking succeeded */ 15539 if (option_debug) 15540 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15541 ast_mutex_unlock(&p->lock); 15542 ast_mutex_unlock(&netlock); 15543 /* Sleep for a very short amount of time */ 15544 usleep(1); 15545 } 15546 p->recv = sin; 15547 15548 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15549 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15550 15551 if (!lockretry) { 15552 if (p->owner) 15553 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15554 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15555 if (req.method != SIP_ACK) 15556 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15557 /* XXX We could add retry-after to make sure they come back */ 15558 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15559 return 1; 15560 } 15561 nounlock = 0; 15562 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15563 /* Request failed */ 15564 if (option_debug) 15565 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15566 } 15567 15568 if (p->owner && !nounlock) 15569 ast_channel_unlock(p->owner); 15570 ast_mutex_unlock(&p->lock); 15571 ast_mutex_unlock(&netlock); 15572 if (recount) 15573 ast_update_use_count(); 15574 15575 return 1; 15576 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12695 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().
12696 { 12697 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12698 if (p->rtp) 12699 ast_rtp_stop(p->rtp); 12700 if (p->vrtp) 12701 ast_rtp_stop(p->vrtp); 12702 if (p->udptl) 12703 ast_udptl_stop(p->udptl); 12704 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10814 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10815 { 10816 int i; 10817 10818 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10819 if (subscription_types[i].type == subtype) { 10820 return subscription_types[i].text; 10821 } 10822 } 10823 return subscription_types[0].text; 10824 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6283 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().
06284 { 06285 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06286 06287 if (maxrate & T38FAX_RATE_14400) { 06288 if (option_debug > 1) 06289 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06290 return 14400; 06291 } else if (maxrate & T38FAX_RATE_12000) { 06292 if (option_debug > 1) 06293 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06294 return 12000; 06295 } else if (maxrate & T38FAX_RATE_9600) { 06296 if (option_debug > 1) 06297 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06298 return 9600; 06299 } else if (maxrate & T38FAX_RATE_7200) { 06300 if (option_debug > 1) 06301 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06302 return 7200; 06303 } else if (maxrate & T38FAX_RATE_4800) { 06304 if (option_debug > 1) 06305 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06306 return 4800; 06307 } else if (maxrate & T38FAX_RATE_2400) { 06308 if (option_debug > 1) 06309 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06310 return 2400; 06311 } else { 06312 if (option_debug > 1) 06313 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06314 return 0; 06315 } 06316 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16618 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
16619 { 16620 struct sip_peer *peer; 16621 16622 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16623 return NULL; 16624 16625 apeerobjs++; 16626 ASTOBJ_INIT(peer); 16627 set_peer_defaults(peer); 16628 16629 ast_copy_string(peer->name, name, sizeof(peer->name)); 16630 16631 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16632 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16633 peer->prefs = default_prefs; 16634 reg_source_db(peer); 16635 16636 return peer; 16637 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6058 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06059 { 06060 struct sip_pvt *p = data; 06061 06062 ast_string_field_free_memory(p); 06063 06064 free(data); 06065 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9824 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().
09825 { 09826 if (mode == TRANSFER_OPENFORALL) 09827 return "open"; 09828 else if (mode == TRANSFER_CLOSED) 09829 return "closed"; 09830 return "strict"; 09831 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8645 of file chan_sip.c.
References ast_random(), ast_string_field_build, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08646 { 08647 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08648 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08649 }
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 7831 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07832 { 07833 struct sip_request req; 07834 07835 reqprep(&req, p, SIP_INFO, 0, 1); 07836 add_digit(&req, digit, duration); 07837 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07838 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7841 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07842 { 07843 struct sip_request req; 07844 07845 reqprep(&req, p, SIP_INFO, 0, 1); 07846 add_vidupdate(&req); 07847 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07848 }
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 7090 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, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07091 { 07092 struct sip_request req; 07093 07094 req.method = sipmethod; 07095 if (init) { /* Seems like init always is 2 */ 07096 /* Bump branch even on initial requests */ 07097 p->branch ^= ast_random(); 07098 build_via(p); 07099 if (init > 1) 07100 initreqprep(&req, p, sipmethod); 07101 else 07102 reqprep(&req, p, sipmethod, 0, 1); 07103 } else 07104 reqprep(&req, p, sipmethod, 0, 1); 07105 07106 if (p->options && p->options->auth) 07107 add_header(&req, p->options->authheader, p->options->auth); 07108 append_date(&req); 07109 if (sipmethod == SIP_REFER) { /* Call transfer */ 07110 if (p->refer) { 07111 char buf[SIPBUFSIZE]; 07112 if (!ast_strlen_zero(p->refer->refer_to)) 07113 add_header(&req, "Refer-To", p->refer->refer_to); 07114 if (!ast_strlen_zero(p->refer->referred_by)) { 07115 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07116 add_header(&req, "Referred-By", buf); 07117 } 07118 } 07119 } 07120 /* This new INVITE is part of an attended transfer. Make sure that the 07121 other end knows and replace the current call with this new call */ 07122 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07123 add_header(&req, "Replaces", p->options->replaces); 07124 add_header(&req, "Require", "replaces"); 07125 } 07126 07127 add_header(&req, "Allow", ALLOWED_METHODS); 07128 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07129 if (p->options && p->options->addsipheaders && p->owner) { 07130 struct ast_channel *chan = p->owner; /* The owner channel */ 07131 struct varshead *headp; 07132 07133 ast_channel_lock(chan); 07134 07135 headp = &chan->varshead; 07136 07137 if (!headp) 07138 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07139 else { 07140 const struct ast_var_t *current; 07141 AST_LIST_TRAVERSE(headp, current, entries) { 07142 /* SIPADDHEADER: Add SIP header to outgoing call */ 07143 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07144 char *content, *end; 07145 const char *header = ast_var_value(current); 07146 char *headdup = ast_strdupa(header); 07147 07148 /* Strip of the starting " (if it's there) */ 07149 if (*headdup == '"') 07150 headdup++; 07151 if ((content = strchr(headdup, ':'))) { 07152 *content++ = '\0'; 07153 content = ast_skip_blanks(content); /* Skip white space */ 07154 /* Strip the ending " (if it's there) */ 07155 end = content + strlen(content) -1; 07156 if (*end == '"') 07157 *end = '\0'; 07158 07159 add_header(&req, headdup, content); 07160 if (sipdebug) 07161 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07162 } 07163 } 07164 } 07165 } 07166 07167 ast_channel_unlock(chan); 07168 } 07169 if (sdp) { 07170 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07171 ast_udptl_offered_from_local(p->udptl, 1); 07172 if (option_debug) 07173 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07174 add_t38_sdp(&req, p); 07175 } else if (p->rtp) 07176 add_sdp(&req, p); 07177 } else { 07178 add_header_contentLength(&req, 0); 07179 } 07180 07181 if (!p->initreq.headers) 07182 initialize_initreq(p, &req); 07183 p->lastinvite = p->ocseq; 07184 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07185 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7740 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().
07741 { 07742 struct sip_request req; 07743 07744 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07745 add_text(&req, text); 07746 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07747 }
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 7376 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(), 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().
07377 { 07378 struct sip_request req; 07379 char tmp[500]; 07380 char *t = tmp; 07381 size_t maxbytes = sizeof(tmp); 07382 07383 initreqprep(&req, p, SIP_NOTIFY); 07384 add_header(&req, "Event", "message-summary"); 07385 add_header(&req, "Content-Type", default_notifymime); 07386 07387 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07388 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07389 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07390 /* Cisco has a bug in the SIP stack where it can't accept the 07391 (0/0) notification. This can temporarily be disabled in 07392 sip.conf with the "buggymwi" option */ 07393 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)")); 07394 07395 if (p->subscribed) { 07396 if (p->expiry) 07397 add_header(&req, "Subscription-State", "active"); 07398 else /* Expired */ 07399 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07400 } 07401 07402 if (t > tmp + sizeof(tmp)) 07403 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07404 07405 add_header_contentLength(&req, strlen(tmp)); 07406 add_line(&req, tmp); 07407 07408 if (!p->initreq.headers) 07409 initialize_initreq(p, &req); 07410 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07411 }
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 7422 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().
07423 { 07424 struct sip_request req; 07425 char tmp[SIPBUFSIZE/2]; 07426 07427 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07428 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07429 add_header(&req, "Event", tmp); 07430 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07431 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07432 add_header(&req, "Allow", ALLOWED_METHODS); 07433 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07434 07435 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07436 add_header_contentLength(&req, strlen(tmp)); 07437 add_line(&req, tmp); 07438 07439 if (!p->initreq.headers) 07440 initialize_initreq(p, &req); 07441 07442 p->lastnoninvite = p->ocseq; 07443 07444 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07445 }
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 7761 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().
07762 { 07763 struct sip_request req = { 07764 .headers = 0, 07765 }; 07766 char from[256]; 07767 const char *of; 07768 char *c; 07769 char referto[256]; 07770 char *ttag, *ftag; 07771 char *theirtag = ast_strdupa(p->theirtag); 07772 07773 if (option_debug || sipdebug) 07774 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07775 07776 /* Are we transfering an inbound or outbound call ? */ 07777 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07778 of = get_header(&p->initreq, "To"); 07779 ttag = theirtag; 07780 ftag = p->tag; 07781 } else { 07782 of = get_header(&p->initreq, "From"); 07783 ftag = theirtag; 07784 ttag = p->tag; 07785 } 07786 07787 ast_copy_string(from, of, sizeof(from)); 07788 of = get_in_brackets(from); 07789 ast_string_field_set(p, from, of); 07790 if (strncasecmp(of, "sip:", 4)) 07791 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07792 else 07793 of += 4; 07794 /* Get just the username part */ 07795 if ((c = strchr(dest, '@'))) 07796 c = NULL; 07797 else if ((c = strchr(of, '@'))) 07798 *c++ = '\0'; 07799 if (c) 07800 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07801 else 07802 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07803 07804 /* save in case we get 407 challenge */ 07805 sip_refer_allocate(p); 07806 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07807 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07808 p->refer->status = REFER_SENT; /* Set refer status */ 07809 07810 reqprep(&req, p, SIP_REFER, 0, 1); 07811 07812 add_header(&req, "Refer-To", referto); 07813 add_header(&req, "Allow", ALLOWED_METHODS); 07814 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07815 if (!ast_strlen_zero(p->our_contact)) 07816 add_header(&req, "Referred-By", p->our_contact); 07817 07818 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07819 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07820 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07821 07822 /*! \todo In theory, we should hang around and wait for a reply, before 07823 returning to the dial plan here. Don't know really how that would 07824 affect the transfer() app or the pbx, but, well, to make this 07825 useful we should have a STATUS code on transfer(). 07826 */ 07827 }
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 7549 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, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, 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().
07550 { 07551 struct sip_request req; 07552 char from[256]; 07553 char to[256]; 07554 char tmp[80]; 07555 char addr[80]; 07556 struct sip_pvt *p; 07557 07558 /* exit if we are already in process with this registrar ?*/ 07559 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07560 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07561 return 0; 07562 } 07563 07564 if (r->call) { /* We have a registration */ 07565 if (!auth) { 07566 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07567 return 0; 07568 } else { 07569 p = r->call; 07570 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07571 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07572 } 07573 } else { 07574 /* Build callid for registration if we haven't registered before */ 07575 if (!r->callid_valid) { 07576 build_callid_registry(r, __ourip, default_fromdomain); 07577 r->callid_valid = TRUE; 07578 } 07579 /* Allocate SIP packet for registration */ 07580 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07581 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07582 return 0; 07583 } 07584 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07585 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07586 /* Find address to hostname */ 07587 if (create_addr(p, r->hostname)) { 07588 /* we have what we hope is a temporary network error, 07589 * probably DNS. We need to reschedule a registration try */ 07590 sip_destroy(p); 07591 07592 if (r->timeout > -1) 07593 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07594 else 07595 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); 07596 07597 AST_SCHED_DEL(sched, r->timeout); 07598 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07599 r->regattempts++; 07600 return 0; 07601 } 07602 /* Copy back Call-ID in case create_addr changed it */ 07603 ast_string_field_set(r, callid, p->callid); 07604 if (r->portno) { 07605 p->sa.sin_port = htons(r->portno); 07606 p->recv.sin_port = htons(r->portno); 07607 } else /* Set registry port to the port set from the peer definition/srv or default */ 07608 r->portno = ntohs(p->sa.sin_port); 07609 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07610 r->call=p; /* Save pointer to SIP packet */ 07611 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07612 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07613 ast_string_field_set(p, peersecret, r->secret); 07614 if (!ast_strlen_zero(r->md5secret)) 07615 ast_string_field_set(p, peermd5secret, r->md5secret); 07616 /* User name in this realm 07617 - if authuser is set, use that, otherwise use username */ 07618 if (!ast_strlen_zero(r->authuser)) { 07619 ast_string_field_set(p, peername, r->authuser); 07620 ast_string_field_set(p, authname, r->authuser); 07621 } else if (!ast_strlen_zero(r->username)) { 07622 ast_string_field_set(p, peername, r->username); 07623 ast_string_field_set(p, authname, r->username); 07624 ast_string_field_set(p, fromuser, r->username); 07625 } 07626 if (!ast_strlen_zero(r->username)) 07627 ast_string_field_set(p, username, r->username); 07628 /* Save extension in packet */ 07629 ast_string_field_set(p, exten, r->contact); 07630 07631 /* 07632 check which address we should use in our contact header 07633 based on whether the remote host is on the external or 07634 internal network so we can register through nat 07635 */ 07636 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07637 p->ourip = bindaddr.sin_addr; 07638 build_contact(p); 07639 } 07640 07641 /* set up a timeout */ 07642 if (auth == NULL) { 07643 if (r->timeout > -1) 07644 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07645 AST_SCHED_DEL(sched, r->timeout); 07646 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07647 if (option_debug) 07648 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07649 } 07650 07651 if (strchr(r->username, '@')) { 07652 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07653 if (!ast_strlen_zero(p->theirtag)) 07654 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07655 else 07656 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07657 } else { 07658 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07659 if (!ast_strlen_zero(p->theirtag)) 07660 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07661 else 07662 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07663 } 07664 07665 /* Fromdomain is what we are registering to, regardless of actual 07666 host name from SRV */ 07667 if (!ast_strlen_zero(p->fromdomain)) { 07668 if (r->portno && r->portno != STANDARD_SIP_PORT) 07669 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07670 else 07671 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07672 } else { 07673 if (r->portno && r->portno != STANDARD_SIP_PORT) 07674 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07675 else 07676 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07677 } 07678 ast_string_field_set(p, uri, addr); 07679 07680 p->branch ^= ast_random(); 07681 07682 init_req(&req, sipmethod, addr); 07683 07684 /* Add to CSEQ */ 07685 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07686 p->ocseq = r->ocseq; 07687 07688 build_via(p); 07689 add_header(&req, "Via", p->via); 07690 add_header(&req, "From", from); 07691 add_header(&req, "To", to); 07692 add_header(&req, "Call-ID", p->callid); 07693 add_header(&req, "CSeq", tmp); 07694 if (!ast_strlen_zero(global_useragent)) 07695 add_header(&req, "User-Agent", global_useragent); 07696 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07697 07698 07699 if (auth) /* Add auth header */ 07700 add_header(&req, authheader, auth); 07701 else if (!ast_strlen_zero(r->nonce)) { 07702 char digest[1024]; 07703 07704 /* We have auth data to reuse, build a digest header! */ 07705 if (sipdebug) 07706 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07707 ast_string_field_set(p, realm, r->realm); 07708 ast_string_field_set(p, nonce, r->nonce); 07709 ast_string_field_set(p, domain, r->domain); 07710 ast_string_field_set(p, opaque, r->opaque); 07711 ast_string_field_set(p, qop, r->qop); 07712 r->noncecount++; 07713 p->noncecount = r->noncecount; 07714 07715 memset(digest,0,sizeof(digest)); 07716 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07717 add_header(&req, "Authorization", digest); 07718 else 07719 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07720 07721 } 07722 07723 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07724 add_header(&req, "Expires", tmp); 07725 add_header(&req, "Contact", p->our_contact); 07726 add_header(&req, "Event", "registration"); 07727 add_header_contentLength(&req, 0); 07728 07729 initialize_initreq(p, &req); 07730 if (sip_debug_test_pvt(p)) 07731 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07732 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07733 r->regattempts++; /* Another attempt */ 07734 if (option_debug > 3) 07735 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07736 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07737 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6810 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(), 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().
06811 { 06812 struct sip_request req; 06813 06814 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06815 06816 add_header(&req, "Allow", ALLOWED_METHODS); 06817 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06818 if (sipdebug) 06819 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06820 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06821 append_history(p, "ReInv", "Re-invite sent"); 06822 add_sdp(&req, p); 06823 /* Use this as the basis */ 06824 initialize_initreq(p, &req); 06825 p->lastinvite = p->ocseq; 06826 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06827 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06828 }
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 6834 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().
06835 { 06836 struct sip_request req; 06837 06838 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06839 06840 add_header(&req, "Allow", ALLOWED_METHODS); 06841 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06842 if (sipdebug) 06843 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06844 ast_udptl_offered_from_local(p->udptl, 1); 06845 add_t38_sdp(&req, p); 06846 /* Use this as the basis */ 06847 initialize_initreq(p, &req); 06848 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06849 p->lastinvite = p->ocseq; 06850 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06851 }
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 7853 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().
07854 { 07855 struct sip_request resp; 07856 07857 if (sipmethod == SIP_ACK) 07858 p->invitestate = INV_CONFIRMED; 07859 07860 reqprep(&resp, p, sipmethod, seqno, newbranch); 07861 add_header_contentLength(&resp, 0); 07862 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07863 }
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 7866 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, 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().
07867 { 07868 struct sip_request resp; 07869 07870 reqprep(&resp, p, sipmethod, seqno, newbranch); 07871 if (!ast_strlen_zero(p->realm)) { 07872 char digest[1024]; 07873 07874 memset(digest, 0, sizeof(digest)); 07875 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07876 if (p->options && p->options->auth_type == PROXY_AUTH) 07877 add_header(&resp, "Proxy-Authorization", digest); 07878 else if (p->options && p->options->auth_type == WWW_AUTH) 07879 add_header(&resp, "Authorization", digest); 07880 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07881 add_header(&resp, "Proxy-Authorization", digest); 07882 } else 07883 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07884 } 07885 /* If we are hanging up and know a cause for that, send it in clear text to make 07886 debugging easier. */ 07887 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07888 char buf[10]; 07889 07890 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07891 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07892 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07893 } 07894 07895 add_header_contentLength(&resp, 0); 07896 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07897 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6119 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06120 { 06121 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06122 }
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 6138 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().
06139 { 06140 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06141 }
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 6068 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, build_via(), check_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.
06069 { 06070 struct sip_pvt *p = NULL; 06071 06072 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06073 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06074 return -1; 06075 } 06076 06077 /* if the structure was just allocated, initialize it */ 06078 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06079 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06080 if (ast_string_field_init(p, 512)) 06081 return -1; 06082 } 06083 06084 /* Initialize the bare minimum */ 06085 p->method = intended_method; 06086 06087 if (sin) { 06088 p->sa = *sin; 06089 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06090 p->ourip = __ourip; 06091 } else 06092 p->ourip = __ourip; 06093 06094 p->branch = ast_random(); 06095 make_our_tag(p->tag, sizeof(p->tag)); 06096 p->ocseq = INITIAL_CSEQ; 06097 06098 if (useglobal_nat && sin) { 06099 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06100 p->recv = *sin; 06101 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06102 } 06103 check_via(p, req); 06104 06105 ast_string_field_set(p, fromdomain, default_fromdomain); 06106 build_via(p); 06107 ast_string_field_set(p, callid, callid); 06108 06109 /* Use this temporary pvt structure to send the message */ 06110 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06111 06112 /* Free the string fields, but not the pool space */ 06113 ast_string_field_reset_all(p); 06114 06115 return 0; 06116 }
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 6166 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06167 { 06168 struct sip_request resp; 06169 respprep(&resp, p, msg, req); 06170 add_header(&resp, "Accept", "application/sdp"); 06171 add_header_contentLength(&resp, 0); 06172 return send_response(p, &resp, reliable, 0); 06173 }
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 6176 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
06177 { 06178 struct sip_request resp; 06179 char tmp[512]; 06180 int seqno = 0; 06181 06182 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06183 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06184 return -1; 06185 } 06186 /* Stale means that they sent us correct authentication, but 06187 based it on an old challenge (nonce) */ 06188 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06189 respprep(&resp, p, msg, req); 06190 add_header(&resp, header, tmp); 06191 add_header_contentLength(&resp, 0); 06192 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06193 return send_response(p, &resp, reliable, seqno); 06194 }
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 6156 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06157 { 06158 struct sip_request resp; 06159 respprep(&resp, p, msg, req); 06160 append_date(&resp); 06161 add_header_contentLength(&resp, 0); 06162 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06163 }
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 6739 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, 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().
06740 { 06741 struct sip_request resp; 06742 int seqno; 06743 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06744 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06745 return -1; 06746 } 06747 respprep(&resp, p, msg, req); 06748 if (p->rtp) { 06749 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06750 if (option_debug) 06751 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06752 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06753 } 06754 try_suggested_sip_codec(p); 06755 add_sdp(&resp, p); 06756 } else 06757 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06758 if (reliable && !p->pendinginvite) 06759 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06760 return send_response(p, &resp, reliable, seqno); 06761 }
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 6699 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06700 { 06701 struct sip_request resp; 06702 int seqno; 06703 06704 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06705 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06706 return -1; 06707 } 06708 respprep(&resp, p, msg, req); 06709 if (p->udptl) { 06710 ast_udptl_offered_from_local(p->udptl, 0); 06711 add_t38_sdp(&resp, p); 06712 } else 06713 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06714 if (retrans && !p->pendinginvite) 06715 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06716 return send_response(p, &resp, retrans, seqno); 06717 }
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 6125 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06126 { 06127 struct sip_request resp; 06128 respprep(&resp, p, msg, req); 06129 append_date(&resp); 06130 add_header(&resp, "Unsupported", unsupported); 06131 add_header_contentLength(&resp, 0); 06132 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06133 }
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 7414 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().
07415 { 07416 if (!p->initreq.headers) /* Initialize first request before sending */ 07417 initialize_initreq(p, req); 07418 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07419 }
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 7188 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, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, 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().
07189 { 07190 char tmp[4000], from[256], to[256]; 07191 char *t = tmp, *c, *mfrom, *mto; 07192 size_t maxbytes = sizeof(tmp); 07193 struct sip_request req; 07194 char hint[AST_MAX_EXTENSION]; 07195 char *statestring = "terminated"; 07196 const struct cfsubscription_types *subscriptiontype; 07197 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07198 char *pidfstate = "--"; 07199 char *pidfnote= "Ready"; 07200 07201 memset(from, 0, sizeof(from)); 07202 memset(to, 0, sizeof(to)); 07203 memset(tmp, 0, sizeof(tmp)); 07204 07205 switch (state) { 07206 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07207 statestring = (global_notifyringing) ? "early" : "confirmed"; 07208 local_state = NOTIFY_INUSE; 07209 pidfstate = "busy"; 07210 pidfnote = "Ringing"; 07211 break; 07212 case AST_EXTENSION_RINGING: 07213 statestring = "early"; 07214 local_state = NOTIFY_INUSE; 07215 pidfstate = "busy"; 07216 pidfnote = "Ringing"; 07217 break; 07218 case AST_EXTENSION_INUSE: 07219 statestring = "confirmed"; 07220 local_state = NOTIFY_INUSE; 07221 pidfstate = "busy"; 07222 pidfnote = "On the phone"; 07223 break; 07224 case AST_EXTENSION_BUSY: 07225 statestring = "confirmed"; 07226 local_state = NOTIFY_CLOSED; 07227 pidfstate = "busy"; 07228 pidfnote = "On the phone"; 07229 break; 07230 case AST_EXTENSION_UNAVAILABLE: 07231 statestring = "terminated"; 07232 local_state = NOTIFY_CLOSED; 07233 pidfstate = "away"; 07234 pidfnote = "Unavailable"; 07235 break; 07236 case AST_EXTENSION_ONHOLD: 07237 statestring = "confirmed"; 07238 local_state = NOTIFY_CLOSED; 07239 pidfstate = "busy"; 07240 pidfnote = "On Hold"; 07241 break; 07242 case AST_EXTENSION_NOT_INUSE: 07243 default: 07244 /* Default setting */ 07245 break; 07246 } 07247 07248 subscriptiontype = find_subscription_type(p->subscribed); 07249 07250 /* Check which device/devices we are watching and if they are registered */ 07251 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07252 char *hint2 = hint, *individual_hint = NULL; 07253 int hint_count = 0, unavailable_count = 0; 07254 07255 while ((individual_hint = strsep(&hint2, "&"))) { 07256 hint_count++; 07257 07258 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07259 unavailable_count++; 07260 } 07261 07262 /* If none of the hinted devices are registered, we will 07263 * override notification and show no availability. 07264 */ 07265 if (hint_count > 0 && hint_count == unavailable_count) { 07266 local_state = NOTIFY_CLOSED; 07267 pidfstate = "away"; 07268 pidfnote = "Not online"; 07269 } 07270 } 07271 07272 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07273 c = get_in_brackets(from); 07274 if (strncasecmp(c, "sip:", 4)) { 07275 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07276 return -1; 07277 } 07278 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07279 07280 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07281 c = get_in_brackets(to); 07282 if (strncasecmp(c, "sip:", 4)) { 07283 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07284 return -1; 07285 } 07286 mto = strsep(&c, ";"); /* trim ; and beyond */ 07287 07288 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07289 07290 07291 add_header(&req, "Event", subscriptiontype->event); 07292 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07293 switch(state) { 07294 case AST_EXTENSION_DEACTIVATED: 07295 if (timeout) 07296 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07297 else { 07298 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07299 add_header(&req, "Retry-After", "60"); 07300 } 07301 break; 07302 case AST_EXTENSION_REMOVED: 07303 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07304 break; 07305 default: 07306 if (p->expiry) 07307 add_header(&req, "Subscription-State", "active"); 07308 else /* Expired */ 07309 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07310 } 07311 switch (p->subscribed) { 07312 case XPIDF_XML: 07313 case CPIM_PIDF_XML: 07314 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07315 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07316 ast_build_string(&t, &maxbytes, "<presence>\n"); 07317 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07318 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07319 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07320 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07321 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07322 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07323 break; 07324 case PIDF_XML: /* Eyebeam supports this format */ 07325 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07326 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); 07327 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07328 if (pidfstate[0] != '-') 07329 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07330 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07331 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07332 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07333 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07334 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07335 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07336 else 07337 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07338 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07339 break; 07340 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07341 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07342 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); 07343 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07344 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07345 else 07346 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07347 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07348 if (state == AST_EXTENSION_ONHOLD) { 07349 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07350 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07351 "</target>\n</local>\n", mto); 07352 } 07353 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07354 break; 07355 case NONE: 07356 default: 07357 break; 07358 } 07359 07360 if (t > tmp + sizeof(tmp)) 07361 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07362 07363 add_header_contentLength(&req, strlen(tmp)); 07364 add_line(&req, tmp); 07365 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07366 07367 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07368 }
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 18200 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, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
18201 { 18202 struct sip_pvt *p, *pl; 18203 18204 /* First, take us out of the channel type list */ 18205 ast_channel_unregister(&sip_tech); 18206 18207 /* Unregister dial plan functions */ 18208 ast_custom_function_unregister(&sipchaninfo_function); 18209 ast_custom_function_unregister(&sippeer_function); 18210 ast_custom_function_unregister(&sip_header_function); 18211 ast_custom_function_unregister(&checksipdomain_function); 18212 18213 /* Unregister dial plan applications */ 18214 ast_unregister_application(app_dtmfmode); 18215 ast_unregister_application(app_sipaddheader); 18216 18217 /* Unregister CLI commands */ 18218 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18219 18220 /* Disconnect from the RTP subsystem */ 18221 ast_rtp_proto_unregister(&sip_rtp); 18222 18223 /* Disconnect from UDPTL */ 18224 ast_udptl_proto_unregister(&sip_udptl); 18225 18226 /* Unregister AMI actions */ 18227 ast_manager_unregister("SIPpeers"); 18228 ast_manager_unregister("SIPshowpeer"); 18229 18230 ast_mutex_lock(&iflock); 18231 /* Hangup all interfaces if they have an owner */ 18232 for (p = iflist; p ; p = p->next) { 18233 if (p->owner) 18234 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18235 } 18236 ast_mutex_unlock(&iflock); 18237 18238 ast_mutex_lock(&monlock); 18239 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18240 pthread_cancel(monitor_thread); 18241 pthread_kill(monitor_thread, SIGURG); 18242 pthread_join(monitor_thread, NULL); 18243 } 18244 monitor_thread = AST_PTHREADT_STOP; 18245 ast_mutex_unlock(&monlock); 18246 18247 restartdestroy: 18248 ast_mutex_lock(&iflock); 18249 /* Destroy all the interfaces and free their memory */ 18250 p = iflist; 18251 while (p) { 18252 pl = p; 18253 p = p->next; 18254 if (__sip_destroy(pl, TRUE) < 0) { 18255 /* Something is still bridged, let it react to getting a hangup */ 18256 iflist = p; 18257 ast_mutex_unlock(&iflock); 18258 usleep(1); 18259 goto restartdestroy; 18260 } 18261 } 18262 iflist = NULL; 18263 ast_mutex_unlock(&iflock); 18264 18265 /* Free memory for local network address mask */ 18266 ast_free_ha(localaddr); 18267 18268 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18269 ASTOBJ_CONTAINER_DESTROY(&userl); 18270 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18271 ASTOBJ_CONTAINER_DESTROY(&peerl); 18272 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18273 ASTOBJ_CONTAINER_DESTROY(®l); 18274 18275 clear_realm_authentication(authl); 18276 clear_sip_domains(); 18277 close(sipsock); 18278 sched_context_destroy(sched); 18279 18280 return 0; 18281 }
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, 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, global_flags, 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 17764 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17766 of file chan_sip.c.
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] |
struct ast_cli_entry cli_sip[] [static] |
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 18026 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 18031 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 11733 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1212 of file chan_sip.c.
Referenced by 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 17763 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17769 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().
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().
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] |
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.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
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 11750 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(), 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 10373 of file chan_sip.c.
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 9924 of file chan_sip.c.
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 11742 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 11746 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(), 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 11682 of file chan_sip.c.
int ourport [static] |
Definition at line 1211 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1210 of file chan_sip.c.
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 11724 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 11706 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 11702 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 11677 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 11710 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 11697 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 11763 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 11719 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 11714 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 11729 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 11767 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 11759 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 11692 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 11687 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
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_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 11755 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] |
Structure to declare a dialplan function: SIPCHANINFO.
Definition at line 12004 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 11924 of file chan_sip.c.
Referenced by load_module(), and unload_module().
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(), 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 17762 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17767 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.