#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\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_TCP (1 << 29) |
#define | SIP_PAGE2_TCP_CONNECTED (1 << 30) |
#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) |
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 int | siptcpsock_accept (int *id, int fd, short events, void *ignore) |
Accept incoming TCP connections. | |
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 | siptcpsock = -1 |
static int * | siptcpsock_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. |
Better support of forking
VIA branch tag transaction checking
Transaction support
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 475 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 1861 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 368 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 369 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 367 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 507 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 498 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 494 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 171 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 188 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 203 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 202 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 514 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 175 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 201 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 495 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 205 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 502 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 513 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 505 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 504 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 506 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 210 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 516 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 497 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 180 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 182 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 186 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 179 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 153 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1030 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 FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#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 219 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 166 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 196 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 211 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 1028 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 206 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 235 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 408 of file chan_sip.c.
#define RTP 1 |
Definition at line 234 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 217 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6499 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 213 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 214 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 215 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 411 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 412 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 802 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_TCP (1 << 29) |
29: Should we use TCP with this peer
Definition at line 799 of file chan_sip.c.
Referenced by __sip_xmit(), _sip_show_peer(), build_via(), create_addr_from_peer(), parse_register_contact(), sip_poke_peer(), and sipsock_read().
#define SIP_PAGE2_TCP_CONNECTED (1 << 30) |
30: Is this TCP peer connected
Definition at line 800 of file chan_sip.c.
Referenced by __sip_xmit(), create_addr_from_peer(), expire_register(), parse_register_contact(), and sip_poke_peer().
#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 807 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 809 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 808 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 207 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 160 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 839 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 840 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 841 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 481 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 407 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 478 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 814 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 833 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 834 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 829 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 830 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 831 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 832 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 819 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 818 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 816 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 815 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 822 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 821 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 823 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 825 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 826 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 827 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 157 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1608 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 164 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 162 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 343 of file chan_sip.c.
00343 { 00344 AUTH_SUCCESSFUL = 0, 00345 AUTH_CHALLENGE_SENT = 1, 00346 AUTH_SECRET_FAILED = -1, 00347 AUTH_USERNAME_MISMATCH = -2, 00348 AUTH_NOT_FOUND = -3, 00349 AUTH_FAKE_AUTH = -4, 00350 AUTH_UNKNOWN_DOMAIN = -5, 00351 AUTH_PEER_NOT_DYNAMIC = -6, 00352 AUTH_ACL_FAILED = -7, 00353 };
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 254 of file chan_sip.c.
00254 { 00255 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00256 INV_CALLING = 1, /*!< Invite sent, no answer */ 00257 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00258 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00259 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00260 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00261 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00262 The only way out of this is a BYE from one side */ 00263 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00264 };
Definition at line 281 of file chan_sip.c.
00281 { 00282 PARSE_REGISTER_FAILED, 00283 PARSE_REGISTER_UPDATE, 00284 PARSE_REGISTER_QUERY, 00285 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 863 of file chan_sip.c.
00863 { 00864 REFER_IDLE, /*!< No REFER is in progress */ 00865 REFER_SENT, /*!< Sent REFER to transferee */ 00866 REFER_RECEIVED, /*!< Received REFER from transferer */ 00867 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00868 REFER_ACCEPTED, /*!< Accepted by transferee */ 00869 REFER_RINGING, /*!< Target Ringing */ 00870 REFER_200OK, /*!< Answered by transfer target */ 00871 REFER_FAILED, /*!< REFER declined - go on */ 00872 REFER_NOAUTH /*!< We had no auth for REFER */ 00873 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 337 of file chan_sip.c.
00337 { 00338 PROXY_AUTH, 00339 WWW_AUTH, 00340 };
enum sip_result |
Definition at line 246 of file chan_sip.c.
00246 { 00247 AST_SUCCESS = 0, 00248 AST_FAILURE = -1, 00249 };
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 312 of file chan_sip.c.
00312 { 00313 SIP_UNKNOWN, /* Unknown response */ 00314 SIP_RESPONSE, /* Not request, response to outbound request */ 00315 SIP_REGISTER, 00316 SIP_OPTIONS, 00317 SIP_NOTIFY, 00318 SIP_INVITE, 00319 SIP_ACK, 00320 SIP_PRACK, /* Not supported at all */ 00321 SIP_BYE, 00322 SIP_REFER, 00323 SIP_SUBSCRIBE, 00324 SIP_MESSAGE, 00325 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00326 SIP_INFO, 00327 SIP_CANCEL, 00328 SIP_PUBLISH, /* Not supported at all */ 00329 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00330 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 356 of file chan_sip.c.
00356 { 00357 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00358 REG_STATE_REGSENT, /*!< Registration request sent */ 00359 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00360 REG_STATE_REGISTERED, /*!< Registred and done */ 00361 REG_STATE_REJECTED, /*!< Registration rejected */ 00362 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00363 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00364 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00365 };
enum subscriptiontype |
Definition at line 287 of file chan_sip.c.
00287 { 00288 NONE = 0, 00289 XPIDF_XML, 00290 DIALOG_INFO_XML, 00291 CPIM_PIDF_XML, 00292 PIDF_XML, 00293 MWI_NOTIFICATION 00294 };
enum t38state |
T38 States for a call.
Definition at line 844 of file chan_sip.c.
00844 { 00845 T38_DISABLED = 0, /*!< Not enabled */ 00846 T38_LOCAL_DIRECT, /*!< Offered from local */ 00847 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00848 T38_PEER_DIRECT, /*!< Offered from peer */ 00849 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00850 T38_ENABLED /*!< Negotiated (enabled) */ 00851 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 240 of file chan_sip.c.
00240 { 00241 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00242 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00243 };
enum xmittype |
Definition at line 274 of file chan_sip.c.
00274 { 00275 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00276 If it fails, it's critical and will cause a teardown of the session */ 00277 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00278 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00279 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4308 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04309 { 04310 int pass; 04311 04312 /* 04313 * Technically you can place arbitrary whitespace both before and after the ':' in 04314 * a header, although RFC3261 clearly says you shouldn't before, and place just 04315 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04316 * a good idea to say you can do it, and if you can do it, why in the hell would. 04317 * you say you shouldn't. 04318 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04319 * and we always allow spaces after that for compatibility. 04320 */ 04321 for (pass = 0; name && pass < 2;pass++) { 04322 int x, len = strlen(name); 04323 for (x=*start; x<req->headers; x++) { 04324 if (!strncasecmp(req->header[x], name, len)) { 04325 char *r = req->header[x] + len; /* skip name */ 04326 if (pedanticsipchecking) 04327 r = ast_skip_blanks(r); 04328 04329 if (*r == ':') { 04330 *start = x+1; 04331 return ast_skip_blanks(r+1); 04332 } 04333 } 04334 } 04335 if (pass == 0) /* Try aliases */ 04336 name = find_alias(name, NULL); 04337 } 04338 04339 /* Don't return NULL, so get_header is always a valid pointer */ 04340 return ""; 04341 }
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 2161 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().
02162 { 02163 struct sip_pkt *cur, *prev = NULL; 02164 02165 /* Just in case... */ 02166 char *msg; 02167 int res = FALSE; 02168 02169 msg = sip_methods[sipmethod].text; 02170 02171 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02172 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02173 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02174 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02175 if (!resp && (seqno == p->pendinginvite)) { 02176 if (option_debug) 02177 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02178 p->pendinginvite = 0; 02179 } 02180 /* this is our baby */ 02181 res = TRUE; 02182 UNLINK(cur, p->packets, prev); 02183 if (cur->retransid > -1) { 02184 if (sipdebug && option_debug > 3) 02185 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02186 } 02187 /* This odd section is designed to thwart a 02188 * race condition in the packet scheduler. There are 02189 * two conditions under which deleting the packet from the 02190 * scheduler can fail. 02191 * 02192 * 1. The packet has been removed from the scheduler because retransmission 02193 * is being attempted. The problem is that if the packet is currently attempting 02194 * retransmission and we are at this point in the code, then that MUST mean 02195 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02196 * lock temporarily to allow retransmission. 02197 * 02198 * 2. The packet has reached its maximum number of retransmissions and has 02199 * been permanently removed from the packet scheduler. If this is the case, then 02200 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02201 * of the retransid to -1 is ensured since in both cases p's lock is held. 02202 */ 02203 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02204 DEADLOCK_AVOIDANCE(&p->lock); 02205 } 02206 free(cur); 02207 break; 02208 } 02209 } 02210 if (option_debug) 02211 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"); 02212 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2084 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, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02085 { 02086 struct sip_pvt *p = (struct sip_pvt *)data; 02087 02088 /* If this is a subscription, tell the phone that we got a timeout */ 02089 if (p->subscribed) { 02090 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02091 p->subscribed = NONE; 02092 append_history(p, "Subscribestatus", "timeout"); 02093 if (option_debug > 2) 02094 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02095 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02096 } 02097 02098 /* If there are packets still waiting for delivery, delay the destruction */ 02099 if (p->packets) { 02100 if (option_debug > 2) 02101 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02102 append_history(p, "ReliableXmit", "timeout"); 02103 return 10000; 02104 } 02105 02106 /* If we're destroying a subscription, dereference peer object too */ 02107 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02108 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02109 02110 /* Reset schedule ID */ 02111 p->autokillid = -1; 02112 02113 if (option_debug) 02114 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02115 append_history(p, "AutoDestroy", "%s", p->callid); 02116 if (p->owner) { 02117 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02118 ast_queue_hangup(p->owner); 02119 } else if (p->refer) { 02120 if (option_debug > 2) 02121 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02122 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02123 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02124 } else 02125 sip_destroy(p); 02126 return 0; 02127 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3089 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, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03090 { 03091 struct sip_pvt *cur, *prev = NULL; 03092 struct sip_pkt *cp; 03093 03094 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03095 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03096 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03097 return -1; 03098 } 03099 03100 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03101 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03102 return -1; 03103 } 03104 03105 if (sip_debug_test_pvt(p) || option_debug > 2) 03106 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03107 03108 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03109 update_call_counter(p, DEC_CALL_LIMIT); 03110 if (option_debug > 1) 03111 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03112 } 03113 03114 /* Unlink us from the owner if we have one */ 03115 if (p->owner) { 03116 if (lockowner) 03117 ast_channel_lock(p->owner); 03118 if (option_debug) 03119 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03120 p->owner->tech_pvt = NULL; 03121 /* Make sure that the channel knows its backend is going away */ 03122 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03123 if (lockowner) 03124 ast_channel_unlock(p->owner); 03125 /* Give the channel a chance to react before deallocation */ 03126 usleep(1); 03127 } 03128 03129 /* Remove link from peer to subscription of MWI */ 03130 if (p->relatedpeer) { 03131 p->relatedpeer->mwipvt = NULL; 03132 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03133 } 03134 03135 if (dumphistory) 03136 sip_dump_history(p); 03137 03138 if (p->options) 03139 free(p->options); 03140 03141 if (p->stateid > -1) 03142 ast_extension_state_del(p->stateid, NULL); 03143 AST_SCHED_DEL(sched, p->initid); 03144 AST_SCHED_DEL(sched, p->waitid); 03145 AST_SCHED_DEL(sched, p->autokillid); 03146 03147 if (p->rtp) { 03148 ast_rtp_destroy(p->rtp); 03149 } 03150 if (p->vrtp) { 03151 ast_rtp_destroy(p->vrtp); 03152 } 03153 if (p->udptl) 03154 ast_udptl_destroy(p->udptl); 03155 if (p->refer) 03156 free(p->refer); 03157 if (p->route) { 03158 free_old_route(p->route); 03159 p->route = NULL; 03160 } 03161 if (p->registry) { 03162 if (p->registry->call == p) 03163 p->registry->call = NULL; 03164 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03165 } 03166 03167 /* Clear history */ 03168 if (p->history) { 03169 struct sip_history *hist; 03170 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03171 free(hist); 03172 p->history_entries--; 03173 } 03174 free(p->history); 03175 p->history = NULL; 03176 } 03177 03178 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03179 if (cur == p) { 03180 UNLINK(cur, iflist, prev); 03181 break; 03182 } 03183 } 03184 if (!cur) { 03185 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03186 return 0; 03187 } 03188 03189 /* remove all current packets in this dialog */ 03190 while((cp = p->packets)) { 03191 p->packets = p->packets->next; 03192 AST_SCHED_DEL(sched, cp->retransid); 03193 free(cp); 03194 } 03195 if (p->chanvars) { 03196 ast_variables_destroy(p->chanvars); 03197 p->chanvars = NULL; 03198 } 03199 ast_mutex_destroy(&p->lock); 03200 03201 ast_string_field_free_memory(p); 03202 03203 free(p); 03204 return 0; 03205 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7554 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07555 { 07556 int res; 07557 07558 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07559 return res; 07560 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2216 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, and sip_methods.
Referenced by handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02217 { 02218 struct sip_pkt *cur = NULL; 02219 02220 while (p->packets) { 02221 int method; 02222 if (cur == p->packets) { 02223 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02224 return; 02225 } 02226 cur = p->packets; 02227 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02228 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02229 } 02230 }
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 2037 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().
02038 { 02039 struct sip_pkt *pkt; 02040 int siptimer_a = DEFAULT_RETRANS; 02041 int xmitres = 0; 02042 02043 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02044 return AST_FAILURE; 02045 memcpy(pkt->data, data, len); 02046 pkt->method = sipmethod; 02047 pkt->packetlen = len; 02048 pkt->next = p->packets; 02049 pkt->owner = p; 02050 pkt->seqno = seqno; 02051 if (resp) 02052 ast_set_flag(pkt, FLAG_RESPONSE); 02053 pkt->data[len] = '\0'; 02054 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02055 pkt->retransid = -1; 02056 if (fatal) 02057 ast_set_flag(pkt, FLAG_FATAL); 02058 if (pkt->timer_t1) 02059 siptimer_a = pkt->timer_t1 * 2; 02060 02061 if (option_debug > 3 && sipdebug) 02062 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02063 pkt->retransid = -1; 02064 pkt->next = p->packets; 02065 p->packets = pkt; 02066 if (sipmethod == SIP_INVITE) { 02067 /* Note this is a pending invite */ 02068 p->pendinginvite = seqno; 02069 } 02070 02071 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02072 02073 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02074 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02075 return AST_FAILURE; 02076 } else { 02077 /* Schedule retransmission */ 02078 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02079 return AST_SUCCESS; 02080 } 02081 }
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 2233 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().
02234 { 02235 struct sip_pkt *cur; 02236 int res = -1; 02237 02238 for (cur = p->packets; cur; cur = cur->next) { 02239 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02240 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02241 /* this is our baby */ 02242 if (cur->retransid > -1) { 02243 if (option_debug > 3 && sipdebug) 02244 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02245 } 02246 AST_SCHED_DEL(sched, cur->retransid); 02247 res = 0; 02248 break; 02249 } 02250 } 02251 if (option_debug) 02252 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"); 02253 return res; 02254 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10922 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, FORMAT3H, 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().
10923 { 10924 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 10925 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 10926 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10927 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10928 struct sip_pvt *cur; 10929 int numchans = 0; 10930 char *referstatus = NULL; 10931 10932 if (argc != 3) 10933 return RESULT_SHOWUSAGE; 10934 ast_mutex_lock(&iflock); 10935 cur = iflist; 10936 if (!subscriptions) 10937 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10938 else 10939 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 10940 for (; cur; cur = cur->next) { 10941 referstatus = ""; 10942 if (cur->refer) { /* SIP transfer in progress */ 10943 referstatus = referstatus2str(cur->refer->status); 10944 } 10945 if (cur->subscribed == NONE && !subscriptions) { 10946 char formatbuf[SIPBUFSIZE/2]; 10947 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10948 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10949 cur->callid, 10950 cur->ocseq, cur->icseq, 10951 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10952 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10953 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10954 cur->lastmsg , 10955 referstatus 10956 ); 10957 numchans++; 10958 } 10959 if (cur->subscribed != NONE && subscriptions) { 10960 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 10961 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10962 cur->callid, 10963 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10964 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10965 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10966 subscription_type2str(cur->subscribed), 10967 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 10968 cur->expiry 10969 ); 10970 numchans++; 10971 } 10972 } 10973 ast_mutex_unlock(&iflock); 10974 if (!subscriptions) 10975 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10976 else 10977 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10978 return RESULT_SUCCESS; 10979 #undef FORMAT 10980 #undef FORMAT2 10981 #undef FORMAT3 10982 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1775 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, errno, sip_pvt::flags, LOG_ERROR, LOG_WARNING, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_real_dst(), sipsock, sip_pvt::sockfd, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01776 { 01777 int res; 01778 const struct sockaddr_in *dst = sip_real_dst(p); 01779 /* This is a TCP connection*/ 01780 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TCP)) { 01781 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED)) { 01782 if (connect(p->sockfd, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)) == 0) { 01783 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01784 } else if (errno == EISCONN) { 01785 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01786 } else { 01787 ast_log(LOG_ERROR, "Connect Failed Sock: %i %s:%d %s\n",p->sockfd,ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), strerror(errno)); 01788 } 01789 } 01790 res = write(p->sockfd, data, len); 01791 } else 01792 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01793 01794 if (res == -1) { 01795 switch (errno) { 01796 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01797 case EHOSTUNREACH: /* Host can't be reached */ 01798 case ENETDOWN: /* Inteface down */ 01799 case ENETUNREACH: /* Network failure */ 01800 case ECONNREFUSED: /* ICMP port unreachable */ 01801 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01802 } 01803 } 01804 if (res != len) 01805 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)); 01806 return res; 01807 }
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 6093 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().
06094 { 06095 struct sip_request resp; 06096 int seqno = 0; 06097 06098 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06099 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06100 return -1; 06101 } 06102 respprep(&resp, p, msg, req); 06103 add_header_contentLength(&resp, 0); 06104 /* If we are cancelling an incoming invite for some reason, add information 06105 about the reason why we are doing this in clear text */ 06106 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06107 char buf[10]; 06108 06109 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06110 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06111 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06112 } 06113 return send_response(p, &resp, reliable, seqno); 06114 }
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 10479 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_TCP, 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().
10480 { 10481 char status[30] = ""; 10482 char cbuf[256]; 10483 struct sip_peer *peer; 10484 char codec_buf[512]; 10485 struct ast_codec_pref *pref; 10486 struct ast_variable *v; 10487 struct sip_auth *auth; 10488 int x = 0, codec = 0, load_realtime; 10489 int realtimepeers; 10490 10491 realtimepeers = ast_check_realtime("sippeers"); 10492 10493 if (argc < 4) 10494 return RESULT_SHOWUSAGE; 10495 10496 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10497 peer = find_peer(argv[3], NULL, load_realtime); 10498 if (s) { /* Manager */ 10499 if (peer) { 10500 const char *id = astman_get_header(m,"ActionID"); 10501 10502 astman_append(s, "Response: Success\r\n"); 10503 if (!ast_strlen_zero(id)) 10504 astman_append(s, "ActionID: %s\r\n",id); 10505 } else { 10506 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10507 astman_send_error(s, m, cbuf); 10508 return 0; 10509 } 10510 } 10511 if (peer && type==0 ) { /* Normal listing */ 10512 ast_cli(fd,"\n\n"); 10513 ast_cli(fd, " * Name : %s\n", peer->name); 10514 if (realtimepeers) { /* Realtime is enabled */ 10515 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10516 } 10517 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10518 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10519 for (auth = peer->auth; auth; auth = auth->next) { 10520 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10521 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10522 } 10523 ast_cli(fd, " Context : %s\n", peer->context); 10524 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10525 ast_cli(fd, " Language : %s\n", peer->language); 10526 if (!ast_strlen_zero(peer->accountcode)) 10527 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10528 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10529 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10530 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10531 if (!ast_strlen_zero(peer->fromuser)) 10532 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10533 if (!ast_strlen_zero(peer->fromdomain)) 10534 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10535 ast_cli(fd, " Callgroup : "); 10536 print_group(fd, peer->callgroup, 0); 10537 ast_cli(fd, " Pickupgroup : "); 10538 print_group(fd, peer->pickupgroup, 0); 10539 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10540 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10541 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10542 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10543 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10544 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10545 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10546 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10547 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))); 10548 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10549 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10550 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10551 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10552 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10553 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10554 #endif 10555 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10556 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10557 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10558 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10559 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10560 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10561 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10562 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10563 10564 /* - is enumerated */ 10565 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10566 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10567 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10568 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)); 10569 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10570 ast_cli(fd, " Transport : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP"); 10571 if (!ast_strlen_zero(global_regcontext)) 10572 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10573 ast_cli(fd, " Def. Username: %s\n", peer->username); 10574 ast_cli(fd, " SIP Options : "); 10575 if (peer->sipoptions) { 10576 int lastoption = -1; 10577 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10578 if (sip_options[x].id != lastoption) { 10579 if (peer->sipoptions & sip_options[x].id) 10580 ast_cli(fd, "%s ", sip_options[x].text); 10581 lastoption = x; 10582 } 10583 } 10584 } else 10585 ast_cli(fd, "(none)"); 10586 10587 ast_cli(fd, "\n"); 10588 ast_cli(fd, " Codecs : "); 10589 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10590 ast_cli(fd, "%s\n", codec_buf); 10591 ast_cli(fd, " Codec Order : ("); 10592 print_codec_to_cli(fd, &peer->prefs); 10593 ast_cli(fd, ")\n"); 10594 10595 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10596 ast_cli(fd, " Status : "); 10597 peer_status(peer, status, sizeof(status)); 10598 ast_cli(fd, "%s\n",status); 10599 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10600 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10601 if (peer->chanvars) { 10602 ast_cli(fd, " Variables :\n"); 10603 for (v = peer->chanvars ; v ; v = v->next) 10604 ast_cli(fd, " %s = %s\n", v->name, v->value); 10605 } 10606 ast_cli(fd,"\n"); 10607 ASTOBJ_UNREF(peer,sip_destroy_peer); 10608 } else if (peer && type == 1) { /* manager listing */ 10609 char buf[256]; 10610 astman_append(s, "Channeltype: SIP\r\n"); 10611 astman_append(s, "ObjectName: %s\r\n", peer->name); 10612 astman_append(s, "ChanObjectType: peer\r\n"); 10613 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10614 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10615 astman_append(s, "Context: %s\r\n", peer->context); 10616 astman_append(s, "Language: %s\r\n", peer->language); 10617 if (!ast_strlen_zero(peer->accountcode)) 10618 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10619 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10620 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10621 if (!ast_strlen_zero(peer->fromuser)) 10622 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10623 if (!ast_strlen_zero(peer->fromdomain)) 10624 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10625 astman_append(s, "Callgroup: "); 10626 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10627 astman_append(s, "Pickupgroup: "); 10628 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10629 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10630 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10631 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10632 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10633 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10634 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10635 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10636 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10637 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))); 10638 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10639 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10640 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10641 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10642 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10643 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10644 10645 /* - is enumerated */ 10646 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10647 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10648 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10649 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)); 10650 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)); 10651 astman_append(s, "Default-Username: %s\r\n", peer->username); 10652 if (!ast_strlen_zero(global_regcontext)) 10653 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10654 astman_append(s, "Codecs: "); 10655 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10656 astman_append(s, "%s\r\n", codec_buf); 10657 astman_append(s, "CodecOrder: "); 10658 pref = &peer->prefs; 10659 for(x = 0; x < 32 ; x++) { 10660 codec = ast_codec_pref_index(pref,x); 10661 if (!codec) 10662 break; 10663 astman_append(s, "%s", ast_getformatname(codec)); 10664 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10665 astman_append(s, ","); 10666 } 10667 10668 astman_append(s, "\r\n"); 10669 astman_append(s, "Status: "); 10670 peer_status(peer, status, sizeof(status)); 10671 astman_append(s, "%s\r\n", status); 10672 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10673 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10674 if (peer->chanvars) { 10675 for (v = peer->chanvars ; v ; v = v->next) { 10676 astman_append(s, "ChanVariable:\n"); 10677 astman_append(s, " %s,%s\r\n", v->name, v->value); 10678 } 10679 } 10680 10681 ASTOBJ_UNREF(peer,sip_destroy_peer); 10682 10683 } else { 10684 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10685 ast_cli(fd,"\n"); 10686 } 10687 10688 return RESULT_SUCCESS; 10689 }
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 10029 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().
10030 { 10031 regex_t regexbuf; 10032 int havepattern = FALSE; 10033 10034 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10035 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10036 10037 char name[256]; 10038 int total_peers = 0; 10039 int peers_mon_online = 0; 10040 int peers_mon_offline = 0; 10041 int peers_unmon_offline = 0; 10042 int peers_unmon_online = 0; 10043 const char *id; 10044 char idtext[256] = ""; 10045 int realtimepeers; 10046 10047 realtimepeers = ast_check_realtime("sippeers"); 10048 10049 if (s) { /* Manager - get ActionID */ 10050 id = astman_get_header(m,"ActionID"); 10051 if (!ast_strlen_zero(id)) 10052 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10053 } 10054 10055 switch (argc) { 10056 case 5: 10057 if (!strcasecmp(argv[3], "like")) { 10058 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10059 return RESULT_SHOWUSAGE; 10060 havepattern = TRUE; 10061 } else 10062 return RESULT_SHOWUSAGE; 10063 case 3: 10064 break; 10065 default: 10066 return RESULT_SHOWUSAGE; 10067 } 10068 10069 if (!s) /* Normal list */ 10070 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10071 10072 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10073 char status[20] = ""; 10074 char srch[2000]; 10075 char pstatus; 10076 10077 ASTOBJ_RDLOCK(iterator); 10078 10079 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10080 ASTOBJ_UNLOCK(iterator); 10081 continue; 10082 } 10083 10084 if (!ast_strlen_zero(iterator->username) && !s) 10085 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10086 else 10087 ast_copy_string(name, iterator->name, sizeof(name)); 10088 10089 pstatus = peer_status(iterator, status, sizeof(status)); 10090 if (pstatus == 1) 10091 peers_mon_online++; 10092 else if (pstatus == 0) 10093 peers_mon_offline++; 10094 else { 10095 if (iterator->addr.sin_port == 0) 10096 peers_unmon_offline++; 10097 else 10098 peers_unmon_online++; 10099 } 10100 10101 snprintf(srch, sizeof(srch), FORMAT, name, 10102 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10103 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10104 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10105 iterator->ha ? " A " : " ", /* permit/deny */ 10106 ntohs(iterator->addr.sin_port), status, 10107 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10108 10109 if (!s) {/* Normal CLI list */ 10110 ast_cli(fd, FORMAT, name, 10111 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10112 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10113 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10114 iterator->ha ? " A " : " ", /* permit/deny */ 10115 10116 ntohs(iterator->addr.sin_port), status, 10117 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10118 } else { /* Manager format */ 10119 /* The names here need to be the same as other channels */ 10120 astman_append(s, 10121 "Event: PeerEntry\r\n%s" 10122 "Channeltype: SIP\r\n" 10123 "ObjectName: %s\r\n" 10124 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10125 "IPaddress: %s\r\n" 10126 "IPport: %d\r\n" 10127 "Dynamic: %s\r\n" 10128 "Natsupport: %s\r\n" 10129 "VideoSupport: %s\r\n" 10130 "ACL: %s\r\n" 10131 "Status: %s\r\n" 10132 "RealtimeDevice: %s\r\n\r\n", 10133 idtext, 10134 iterator->name, 10135 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10136 ntohs(iterator->addr.sin_port), 10137 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10138 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10139 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10140 iterator->ha ? "yes" : "no", /* permit/deny */ 10141 status, 10142 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10143 } 10144 10145 ASTOBJ_UNLOCK(iterator); 10146 10147 total_peers++; 10148 } while(0) ); 10149 10150 if (!s) 10151 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10152 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10153 10154 if (havepattern) 10155 regfree(®exbuf); 10156 10157 if (total) 10158 *total = total_peers; 10159 10160 10161 return RESULT_SUCCESS; 10162 #undef FORMAT 10163 #undef FORMAT2 10164 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14834 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.
14835 { 14836 struct ast_rtp_quality qos; 14837 struct sip_pvt *p = chan->tech_pvt; 14838 char *all = "", *parse = ast_strdupa(preparse); 14839 AST_DECLARE_APP_ARGS(args, 14840 AST_APP_ARG(param); 14841 AST_APP_ARG(type); 14842 AST_APP_ARG(field); 14843 ); 14844 AST_STANDARD_APP_ARGS(args, parse); 14845 14846 /* Sanity check */ 14847 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14848 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14849 return 0; 14850 } 14851 14852 if (strcasecmp(args.param, "rtpqos")) 14853 return 0; 14854 14855 /* Default arguments of audio,all */ 14856 if (ast_strlen_zero(args.type)) 14857 args.type = "audio"; 14858 if (ast_strlen_zero(args.field)) 14859 args.field = "all"; 14860 14861 memset(buf, 0, buflen); 14862 memset(&qos, 0, sizeof(qos)); 14863 14864 if (strcasecmp(args.type, "AUDIO") == 0) { 14865 all = ast_rtp_get_quality(p->rtp, &qos); 14866 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14867 all = ast_rtp_get_quality(p->vrtp, &qos); 14868 } 14869 14870 if (strcasecmp(args.field, "local_ssrc") == 0) 14871 snprintf(buf, buflen, "%u", qos.local_ssrc); 14872 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14873 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14874 else if (strcasecmp(args.field, "local_jitter") == 0) 14875 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14876 else if (strcasecmp(args.field, "local_count") == 0) 14877 snprintf(buf, buflen, "%u", qos.local_count); 14878 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14879 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14880 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14881 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14882 else if (strcasecmp(args.field, "remote_jitter") == 0) 14883 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14884 else if (strcasecmp(args.field, "remote_count") == 0) 14885 snprintf(buf, buflen, "%u", qos.remote_count); 14886 else if (strcasecmp(args.field, "rtt") == 0) 14887 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14888 else if (strcasecmp(args.field, "all") == 0) 14889 ast_copy_string(buf, all, buflen); 14890 else { 14891 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14892 return -1; 14893 } 14894 return 0; 14895 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2267 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02268 { 02269 if (!req->lines) { 02270 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02271 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02272 req->len += strlen(req->data + req->len); 02273 } 02274 }
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 6298 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().
06301 { 06302 int rtp_code; 06303 struct ast_format_list fmt; 06304 06305 06306 if (debug) 06307 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06308 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06309 return; 06310 06311 if (p->rtp) { 06312 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06313 fmt = ast_codec_pref_getsize(pref, codec); 06314 } 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 */ 06315 return; 06316 ast_build_string(m_buf, m_size, " %d", rtp_code); 06317 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06318 ast_rtp_lookup_mime_subtype(1, codec, 06319 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06320 sample_rate); 06321 if (codec == AST_FORMAT_G729A) { 06322 /* Indicate that we don't support VAD (G.729 annex B) */ 06323 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06324 } else if (codec == AST_FORMAT_G723_1) { 06325 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06326 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06327 } else if (codec == AST_FORMAT_ILBC) { 06328 /* Add information about us using only 20/30 ms packetization */ 06329 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06330 } 06331 06332 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06333 *min_packet_size = fmt.cur_ms; 06334 06335 /* Our first codec packetization processed cannot be less than zero */ 06336 if ((*min_packet_size) == 0 && fmt.cur_ms) 06337 *min_packet_size = fmt.cur_ms; 06338 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6266 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06267 { 06268 char tmp[256]; 06269 06270 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06271 add_header(req, "Content-Type", "application/dtmf-relay"); 06272 add_header_contentLength(req, strlen(tmp)); 06273 add_line(req, tmp); 06274 return 0; 06275 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5660 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.
05661 { 05662 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05663 05664 if (req->headers == SIP_MAX_HEADERS) { 05665 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05666 return -1; 05667 } 05668 05669 if (req->lines) { 05670 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05671 return -1; 05672 } 05673 05674 if (maxlen <= 0) { 05675 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05676 return -1; 05677 } 05678 05679 req->header[req->headers] = req->data + req->len; 05680 05681 if (compactheaders) 05682 var = find_alias(var, var); 05683 05684 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05685 req->len += strlen(req->header[req->headers]); 05686 req->headers++; 05687 05688 return 0; 05689 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5692 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().
05693 { 05694 char clen[10]; 05695 05696 snprintf(clen, sizeof(clen), "%d", len); 05697 return add_header(req, "Content-Length", clen); 05698 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5701 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05702 { 05703 if (req->lines == SIP_MAX_LINES) { 05704 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05705 return -1; 05706 } 05707 if (!req->lines) { 05708 /* Add extra empty return */ 05709 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05710 req->len += strlen(req->data + req->len); 05711 } 05712 if (req->len >= sizeof(req->data) - 4) { 05713 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05714 return -1; 05715 } 05716 req->line[req->lines] = req->data + req->len; 05717 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05718 req->len += strlen(req->line[req->lines]); 05719 req->lines++; 05720 return 0; 05721 }
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 6474 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().
06477 { 06478 int rtp_code; 06479 06480 if (debug) 06481 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06482 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06483 return; 06484 06485 ast_build_string(m_buf, m_size, " %d", rtp_code); 06486 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06487 ast_rtp_lookup_mime_subtype(0, format, 0), 06488 sample_rate); 06489 if (format == AST_RTP_DTMF) 06490 /* Indicate we support DTMF and FLASH... */ 06491 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06492 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 16494 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().
16495 { 16496 char authcopy[256]; 16497 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16498 char *stringp; 16499 struct sip_auth *a, *b, *auth; 16500 16501 if (ast_strlen_zero(configuration)) 16502 return authlist; 16503 16504 if (option_debug) 16505 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16506 16507 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16508 stringp = authcopy; 16509 16510 username = stringp; 16511 realm = strrchr(stringp, '@'); 16512 if (realm) 16513 *realm++ = '\0'; 16514 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16515 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16516 return authlist; 16517 } 16518 stringp = username; 16519 username = strsep(&stringp, ":"); 16520 if (username) { 16521 secret = strsep(&stringp, ":"); 16522 if (!secret) { 16523 stringp = username; 16524 md5secret = strsep(&stringp,"#"); 16525 } 16526 } 16527 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16528 return authlist; 16529 16530 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16531 ast_copy_string(auth->username, username, sizeof(auth->username)); 16532 if (secret) 16533 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16534 if (md5secret) 16535 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16536 16537 /* find the end of the list */ 16538 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16539 ; 16540 if (b) 16541 b->next = auth; /* Add structure add end of list */ 16542 else 16543 authlist = auth; 16544 16545 if (option_verbose > 2) 16546 ast_verbose("Added authentication for realm %s\n", realm); 16547 16548 return authlist; 16549 16550 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5822 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05823 { 05824 char r[SIPBUFSIZE*2], *p; 05825 int n, rem = sizeof(r); 05826 05827 if (!route) 05828 return; 05829 05830 p = r; 05831 for (;route ; route = route->next) { 05832 n = strlen(route->hop); 05833 if (rem < n+3) /* we need room for ",<route>" */ 05834 break; 05835 if (p != r) { /* add a separator after fist route */ 05836 *p++ = ','; 05837 --rem; 05838 } 05839 *p++ = '<'; 05840 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05841 p += n; 05842 *p++ = '>'; 05843 rem -= (n+2); 05844 } 05845 *p = '\0'; 05846 add_header(req, "Route", r); 05847 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6502 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.
06503 { 06504 int len = 0; 06505 int alreadysent = 0; 06506 06507 struct sockaddr_in sin; 06508 struct sockaddr_in vsin; 06509 struct sockaddr_in dest; 06510 struct sockaddr_in vdest = { 0, }; 06511 06512 /* SDP fields */ 06513 char *version = "v=0\r\n"; /* Protocol version */ 06514 char *subject = "s=session\r\n"; /* Subject of the session */ 06515 char owner[256]; /* Session owner/creator */ 06516 char connection[256]; /* Connection data */ 06517 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06518 char bandwidth[256] = ""; /* Max bitrate */ 06519 char *hold; 06520 char m_audio[256]; /* Media declaration line for audio */ 06521 char m_video[256]; /* Media declaration line for video */ 06522 char a_audio[1024]; /* Attributes for audio */ 06523 char a_video[1024]; /* Attributes for video */ 06524 char *m_audio_next = m_audio; 06525 char *m_video_next = m_video; 06526 size_t m_audio_left = sizeof(m_audio); 06527 size_t m_video_left = sizeof(m_video); 06528 char *a_audio_next = a_audio; 06529 char *a_video_next = a_video; 06530 size_t a_audio_left = sizeof(a_audio); 06531 size_t a_video_left = sizeof(a_video); 06532 06533 int x; 06534 int capability; 06535 int needvideo = FALSE; 06536 int debug = sip_debug_test_pvt(p); 06537 int min_audio_packet_size = 0; 06538 int min_video_packet_size = 0; 06539 06540 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06541 06542 if (!p->rtp) { 06543 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06544 return AST_FAILURE; 06545 } 06546 06547 /* Set RTP Session ID and version */ 06548 if (!p->sessionid) { 06549 p->sessionid = getpid(); 06550 p->sessionversion = p->sessionid; 06551 } else 06552 p->sessionversion++; 06553 06554 /* Get our addresses */ 06555 ast_rtp_get_us(p->rtp, &sin); 06556 if (p->vrtp) 06557 ast_rtp_get_us(p->vrtp, &vsin); 06558 06559 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06560 if (p->redirip.sin_addr.s_addr) { 06561 dest.sin_port = p->redirip.sin_port; 06562 dest.sin_addr = p->redirip.sin_addr; 06563 } else { 06564 dest.sin_addr = p->ourip; 06565 dest.sin_port = sin.sin_port; 06566 } 06567 06568 capability = p->jointcapability; 06569 06570 06571 if (option_debug > 1) { 06572 char codecbuf[SIPBUFSIZE]; 06573 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"); 06574 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06575 } 06576 06577 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06578 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06579 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06580 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06581 } 06582 #endif 06583 06584 /* Check if we need video in this call */ 06585 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06586 if (p->vrtp) { 06587 needvideo = TRUE; 06588 if (option_debug > 1) 06589 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06590 } else if (option_debug > 1) 06591 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06592 } 06593 06594 06595 /* Ok, we need video. Let's add what we need for video and set codecs. 06596 Video is handled differently than audio since we can not transcode. */ 06597 if (needvideo) { 06598 /* Determine video destination */ 06599 if (p->vredirip.sin_addr.s_addr) { 06600 vdest.sin_addr = p->vredirip.sin_addr; 06601 vdest.sin_port = p->vredirip.sin_port; 06602 } else { 06603 vdest.sin_addr = p->ourip; 06604 vdest.sin_port = vsin.sin_port; 06605 } 06606 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06607 06608 /* Build max bitrate string */ 06609 if (p->maxcallbitrate) 06610 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06611 if (debug) 06612 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06613 } 06614 06615 if (debug) 06616 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06617 06618 /* Start building generic SDP headers */ 06619 06620 /* We break with the "recommendation" and send our IP, in order that our 06621 peer doesn't have to ast_gethostbyname() us */ 06622 06623 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06624 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06625 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06626 06627 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06628 hold = "a=recvonly\r\n"; 06629 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06630 hold = "a=inactive\r\n"; 06631 else 06632 hold = "a=sendrecv\r\n"; 06633 06634 /* Now, start adding audio codecs. These are added in this order: 06635 - First what was requested by the calling channel 06636 - Then preferences in order from sip.conf device config for this peer/user 06637 - Then other codecs in capabilities, including video 06638 */ 06639 06640 /* Prefer the audio codec we were requested to use, first, no matter what 06641 Note that p->prefcodec can include video codecs, so mask them out 06642 */ 06643 if (capability & p->prefcodec) { 06644 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06645 06646 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06647 &m_audio_next, &m_audio_left, 06648 &a_audio_next, &a_audio_left, 06649 debug, &min_audio_packet_size); 06650 alreadysent |= codec; 06651 } 06652 06653 /* Start by sending our preferred audio codecs */ 06654 for (x = 0; x < 32; x++) { 06655 int codec; 06656 06657 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06658 break; 06659 06660 if (!(capability & codec)) 06661 continue; 06662 06663 if (alreadysent & codec) 06664 continue; 06665 06666 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06667 &m_audio_next, &m_audio_left, 06668 &a_audio_next, &a_audio_left, 06669 debug, &min_audio_packet_size); 06670 alreadysent |= codec; 06671 } 06672 06673 /* Now send any other common audio and video codecs, and non-codec formats: */ 06674 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06675 if (!(capability & x)) /* Codec not requested */ 06676 continue; 06677 06678 if (alreadysent & x) /* Already added to SDP */ 06679 continue; 06680 06681 if (x <= AST_FORMAT_MAX_AUDIO) 06682 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06683 &m_audio_next, &m_audio_left, 06684 &a_audio_next, &a_audio_left, 06685 debug, &min_audio_packet_size); 06686 else 06687 add_codec_to_sdp(p, x, 90000, 06688 &m_video_next, &m_video_left, 06689 &a_video_next, &a_video_left, 06690 debug, &min_video_packet_size); 06691 } 06692 06693 /* Now add DTMF RFC2833 telephony-event as a codec */ 06694 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06695 if (!(p->jointnoncodeccapability & x)) 06696 continue; 06697 06698 add_noncodec_to_sdp(p, x, 8000, 06699 &m_audio_next, &m_audio_left, 06700 &a_audio_next, &a_audio_left, 06701 debug); 06702 } 06703 06704 if (option_debug > 2) 06705 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06706 06707 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06708 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06709 06710 if (min_audio_packet_size) 06711 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06712 06713 if (min_video_packet_size) 06714 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06715 06716 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06717 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06718 06719 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06720 if (needvideo) 06721 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06722 06723 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06724 if (needvideo) /* only if video response is appropriate */ 06725 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06726 06727 add_header(resp, "Content-Type", "application/sdp"); 06728 add_header_contentLength(resp, len); 06729 add_line(resp, version); 06730 add_line(resp, owner); 06731 add_line(resp, subject); 06732 add_line(resp, connection); 06733 if (needvideo) /* only if video response is appropriate */ 06734 add_line(resp, bandwidth); 06735 add_line(resp, stime); 06736 add_line(resp, m_audio); 06737 add_line(resp, a_audio); 06738 add_line(resp, hold); 06739 if (needvideo) { /* only if video response is appropriate */ 06740 add_line(resp, m_video); 06741 add_line(resp, a_video); 06742 add_line(resp, hold); /* Repeat hold for the video stream */ 06743 } 06744 06745 /* Update lastrtprx when we send our SDP */ 06746 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06747 06748 if (option_debug > 2) { 06749 char buf[SIPBUFSIZE]; 06750 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06751 } 06752 06753 return AST_SUCCESS; 06754 }
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 16430 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.
16431 { 16432 struct domain *d; 16433 16434 if (ast_strlen_zero(domain)) { 16435 ast_log(LOG_WARNING, "Zero length domain.\n"); 16436 return 1; 16437 } 16438 16439 if (!(d = ast_calloc(1, sizeof(*d)))) 16440 return 0; 16441 16442 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16443 16444 if (!ast_strlen_zero(context)) 16445 ast_copy_string(d->context, context, sizeof(d->context)); 16446 16447 d->mode = mode; 16448 16449 AST_LIST_LOCK(&domain_list); 16450 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16451 AST_LIST_UNLOCK(&domain_list); 16452 16453 if (sipdebug) 16454 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16455 16456 return 1; 16457 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6377 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().
06378 { 06379 int len = 0; 06380 int x = 0; 06381 struct sockaddr_in udptlsin; 06382 char v[256] = ""; 06383 char s[256] = ""; 06384 char o[256] = ""; 06385 char c[256] = ""; 06386 char t[256] = ""; 06387 char m_modem[256]; 06388 char a_modem[1024]; 06389 char *m_modem_next = m_modem; 06390 size_t m_modem_left = sizeof(m_modem); 06391 char *a_modem_next = a_modem; 06392 size_t a_modem_left = sizeof(a_modem); 06393 struct sockaddr_in udptldest = { 0, }; 06394 int debug; 06395 06396 debug = sip_debug_test_pvt(p); 06397 len = 0; 06398 if (!p->udptl) { 06399 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06400 return -1; 06401 } 06402 06403 if (!p->sessionid) { 06404 p->sessionid = getpid(); 06405 p->sessionversion = p->sessionid; 06406 } else 06407 p->sessionversion++; 06408 06409 /* Our T.38 end is */ 06410 ast_udptl_get_us(p->udptl, &udptlsin); 06411 06412 /* Determine T.38 UDPTL destination */ 06413 if (p->udptlredirip.sin_addr.s_addr) { 06414 udptldest.sin_port = p->udptlredirip.sin_port; 06415 udptldest.sin_addr = p->udptlredirip.sin_addr; 06416 } else { 06417 udptldest.sin_addr = p->ourip; 06418 udptldest.sin_port = udptlsin.sin_port; 06419 } 06420 06421 if (debug) 06422 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06423 06424 /* We break with the "recommendation" and send our IP, in order that our 06425 peer doesn't have to ast_gethostbyname() us */ 06426 06427 if (debug) { 06428 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06429 p->t38.capability, 06430 p->t38.peercapability, 06431 p->t38.jointcapability); 06432 } 06433 snprintf(v, sizeof(v), "v=0\r\n"); 06434 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06435 snprintf(s, sizeof(s), "s=session\r\n"); 06436 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06437 snprintf(t, sizeof(t), "t=0 0\r\n"); 06438 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06439 06440 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06441 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06442 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06443 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06444 if ((x = t38_get_rate(p->t38.jointcapability))) 06445 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06446 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06447 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06448 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06449 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06450 x = ast_udptl_get_local_max_datagram(p->udptl); 06451 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06452 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06453 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06454 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06455 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06456 add_header(resp, "Content-Type", "application/sdp"); 06457 add_header_contentLength(resp, len); 06458 add_line(resp, v); 06459 add_line(resp, o); 06460 add_line(resp, s); 06461 add_line(resp, c); 06462 add_line(resp, t); 06463 add_line(resp, m_modem); 06464 add_line(resp, a_modem); 06465 06466 /* Update lastrtprx when we send our SDP */ 06467 p->lastrtprx = p->lastrtptx = time(NULL); 06468 06469 return 0; 06470 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6255 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06256 { 06257 /* XXX Convert \n's to \r\n's XXX */ 06258 add_header(req, "Content-Type", "text/plain"); 06259 add_header_contentLength(req, strlen(text)); 06260 add_line(req, text); 06261 return 0; 06262 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6279 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06280 { 06281 const char *xml_is_a_huge_waste_of_space = 06282 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06283 " <media_control>\r\n" 06284 " <vc_primitive>\r\n" 06285 " <to_encoder>\r\n" 06286 " <picture_fast_update>\r\n" 06287 " </picture_fast_update>\r\n" 06288 " </to_encoder>\r\n" 06289 " </vc_primitive>\r\n" 06290 " </media_control>\r\n"; 06291 add_header(req, "Content-Type", "application/media_control+xml"); 06292 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06293 add_line(req, xml_is_a_huge_waste_of_space); 06294 return 0; 06295 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6202 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().
06203 { 06204 char tmpdat[256]; 06205 struct tm tm; 06206 time_t t = time(NULL); 06207 06208 gmtime_r(&t, &tm); 06209 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06210 add_header(req, "Date", tmpdat); 06211 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1894 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01895 { 01896 va_list ap; 01897 01898 if (!p) 01899 return; 01900 01901 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01902 && !recordhistory && !dumphistory) { 01903 return; 01904 } 01905 01906 va_start(ap, fmt); 01907 append_history_va(p, fmt, ap); 01908 va_end(ap); 01909 01910 return; 01911 }
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 1867 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().
01868 { 01869 char buf[80], *c = buf; /* max history length */ 01870 struct sip_history *hist; 01871 int l; 01872 01873 vsnprintf(buf, sizeof(buf), fmt, ap); 01874 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01875 l = strlen(buf) + 1; 01876 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01877 return; 01878 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01879 free(hist); 01880 return; 01881 } 01882 memcpy(hist->event, buf, l); 01883 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01884 struct sip_history *oldest; 01885 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01886 p->history_entries--; 01887 free(oldest); 01888 } 01889 AST_LIST_INSERT_TAIL(p->history, hist, list); 01890 p->history_entries++; 01891 }
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 13381 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().
13382 { 13383 if (chan && chan->_state == AST_STATE_UP) { 13384 if (ast_test_flag(chan, AST_FLAG_MOH)) 13385 ast_moh_stop(chan); 13386 else if (chan->generatordata) 13387 ast_deactivate_generator(chan); 13388 } 13389 }
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 1827 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().
01828 { 01829 struct sockaddr_in theirs, ours; 01830 01831 /* Get our local information */ 01832 ast_ouraddrfor(them, us); 01833 theirs.sin_addr = *them; 01834 ours.sin_addr = *us; 01835 01836 if (localaddr && externip.sin_addr.s_addr && 01837 (ast_apply_ha(localaddr, &theirs)) && 01838 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01839 if (externexpire && time(NULL) >= externexpire) { 01840 struct ast_hostent ahp; 01841 struct hostent *hp; 01842 01843 externexpire = time(NULL) + externrefresh; 01844 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01845 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01846 } else 01847 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01848 } 01849 *us = externip.sin_addr; 01850 if (option_debug) { 01851 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01852 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01853 } 01854 } else if (bindaddr.sin_addr.s_addr) 01855 *us = bindaddr.sin_addr; 01856 return AST_SUCCESS; 01857 }
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 13393 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.
13394 { 13395 int res = 0; 13396 struct ast_channel *peera = NULL, 13397 *peerb = NULL, 13398 *peerc = NULL, 13399 *peerd = NULL; 13400 13401 13402 /* We will try to connect the transferee with the target and hangup 13403 all channels to the transferer */ 13404 if (option_debug > 3) { 13405 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13406 if (transferer->chan1) 13407 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13408 else 13409 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13410 if (target->chan1) 13411 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13412 else 13413 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13414 if (transferer->chan2) 13415 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13416 else 13417 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13418 if (target->chan2) 13419 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)"); 13420 else 13421 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13422 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13423 } 13424 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13425 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13426 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13427 peerc = transferer->chan2; /* Asterisk to Transferee */ 13428 peerd = target->chan2; /* Asterisk to Target */ 13429 if (option_debug > 2) 13430 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13431 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13432 peera = target->chan1; /* Transferer to PBX -> target channel */ 13433 peerb = transferer->chan1; /* Transferer to IVR*/ 13434 peerc = target->chan2; /* Asterisk to Target */ 13435 peerd = transferer->chan2; /* Nothing */ 13436 if (option_debug > 2) 13437 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13438 } 13439 13440 if (peera && peerb && peerc && (peerb != peerc)) { 13441 ast_quiet_chan(peera); /* Stop generators */ 13442 ast_quiet_chan(peerb); 13443 ast_quiet_chan(peerc); 13444 if (peerd) 13445 ast_quiet_chan(peerd); 13446 13447 /* Fix CDRs so they're attached to the remaining channel */ 13448 if (peera->cdr && peerb->cdr) 13449 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13450 else if (peera->cdr) 13451 peerb->cdr = peera->cdr; 13452 peera->cdr = NULL; 13453 13454 if (peerb->cdr && peerc->cdr) 13455 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13456 else if (peerc->cdr) 13457 peerb->cdr = peerc->cdr; 13458 peerc->cdr = NULL; 13459 13460 if (option_debug > 3) 13461 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13462 if (ast_channel_masquerade(peerb, peerc)) { 13463 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13464 res = -1; 13465 } else 13466 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13467 return res; 13468 } else { 13469 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13470 if (transferer->chan1) 13471 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13472 if (target->chan1) 13473 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13474 return -2; 13475 } 13476 return 0; 13477 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2952 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.
02953 { 02954 struct sip_pvt *p = (struct sip_pvt *)nothing; 02955 02956 ast_mutex_lock(&p->lock); 02957 p->initid = -1; 02958 if (p->owner) { 02959 /* XXX fails on possible deadlock */ 02960 if (!ast_channel_trylock(p->owner)) { 02961 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02962 append_history(p, "Cong", "Auto-congesting (timer)"); 02963 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02964 ast_channel_unlock(p->owner); 02965 } 02966 } 02967 ast_mutex_unlock(&p->lock); 02968 return 0; 02969 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4474 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().
04475 { 04476 char buf[33]; 04477 04478 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04479 04480 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04481 04482 }
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 4485 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04486 { 04487 char buf[33]; 04488 04489 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04490 04491 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04492 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6925 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().
06926 { 06927 /* Construct Contact: header */ 06928 if (ourport != STANDARD_SIP_PORT) 06929 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); 06930 else 06931 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06932 }
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 16761 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, sip_peer::sockfd, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
16762 { 16763 struct sip_peer *peer = NULL; 16764 struct ast_ha *oldha = NULL; 16765 int obproxyfound=0; 16766 int found=0; 16767 int firstpass=1; 16768 int format=0; /* Ama flags */ 16769 time_t regseconds = 0; 16770 char *varname = NULL, *varval = NULL; 16771 struct ast_variable *tmpvar = NULL; 16772 struct ast_flags peerflags[2] = {{(0)}}; 16773 struct ast_flags mask[2] = {{(0)}}; 16774 char fullcontact[sizeof(peer->fullcontact)] = ""; 16775 16776 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16777 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16778 /* We also use a case-sensitive comparison (unlike find_peer) so 16779 that case changes made to the peer name will be properly handled 16780 during reload 16781 */ 16782 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16783 16784 if (peer) { 16785 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16786 found = 1; 16787 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16788 firstpass = 0; 16789 } else { 16790 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16791 return NULL; 16792 16793 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 16794 rpeerobjs++; 16795 else 16796 speerobjs++; 16797 ASTOBJ_INIT(peer); 16798 } 16799 /* Note that our peer HAS had its reference count incrased */ 16800 if (firstpass) { 16801 peer->lastmsgssent = -1; 16802 oldha = peer->ha; 16803 peer->ha = NULL; 16804 set_peer_defaults(peer); /* Set peer defaults */ 16805 } 16806 if (!found && name) 16807 ast_copy_string(peer->name, name, sizeof(peer->name)); 16808 16809 /* If we have channel variables, remove them (reload) */ 16810 if (peer->chanvars) { 16811 ast_variables_destroy(peer->chanvars); 16812 peer->chanvars = NULL; 16813 /* XXX should unregister ? */ 16814 } 16815 16816 /* If we have realm authentication information, remove them (reload) */ 16817 clear_realm_authentication(peer->auth); 16818 peer->auth = NULL; 16819 peer->sockfd = -1; 16820 16821 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16822 if (handle_common_options(&peerflags[0], &mask[0], v)) 16823 continue; 16824 if (realtime && !strcasecmp(v->name, "regseconds")) { 16825 ast_get_time_t(v->value, ®seconds, 0, NULL); 16826 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16827 inet_aton(v->value, &(peer->addr.sin_addr)); 16828 } else if (realtime && !strcasecmp(v->name, "name")) 16829 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16830 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16831 /* Reconstruct field, because realtime separates our value at the ';' */ 16832 if (!ast_strlen_zero(fullcontact)) { 16833 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 16834 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 16835 } else { 16836 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 16837 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16838 } 16839 } else if (!strcasecmp(v->name, "secret")) 16840 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16841 else if (!strcasecmp(v->name, "md5secret")) 16842 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16843 else if (!strcasecmp(v->name, "auth")) 16844 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16845 else if (!strcasecmp(v->name, "callerid")) { 16846 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16847 } else if (!strcasecmp(v->name, "fullname")) { 16848 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16849 } else if (!strcasecmp(v->name, "cid_number")) { 16850 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16851 } else if (!strcasecmp(v->name, "context")) { 16852 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16853 } else if (!strcasecmp(v->name, "subscribecontext")) { 16854 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16855 } else if (!strcasecmp(v->name, "fromdomain")) { 16856 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16857 } else if (!strcasecmp(v->name, "usereqphone")) { 16858 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16859 } else if (!strcasecmp(v->name, "fromuser")) { 16860 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16861 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16862 if (!strcasecmp(v->value, "dynamic")) { 16863 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16864 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16865 } else { 16866 /* They'll register with us */ 16867 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16868 /* Initialize stuff if this is a new peer, or if it used to be 16869 * non-dynamic before the reload. */ 16870 memset(&peer->addr.sin_addr, 0, 4); 16871 if (peer->addr.sin_port) { 16872 /* If we've already got a port, make it the default rather than absolute */ 16873 peer->defaddr.sin_port = peer->addr.sin_port; 16874 peer->addr.sin_port = 0; 16875 } 16876 } 16877 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16878 } 16879 } else { 16880 /* Non-dynamic. Make sure we become that way if we're not */ 16881 if (!AST_SCHED_DEL(sched, peer->expire)) { 16882 struct sip_peer *peer_ptr = peer; 16883 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16884 } 16885 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16886 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16887 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16888 ASTOBJ_UNREF(peer, sip_destroy_peer); 16889 return NULL; 16890 } 16891 } 16892 if (!strcasecmp(v->name, "outboundproxy")) 16893 obproxyfound=1; 16894 else { 16895 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16896 if (!peer->addr.sin_port) 16897 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16898 } 16899 } 16900 } else if (!strcasecmp(v->name, "defaultip")) { 16901 if (ast_get_ip(&peer->defaddr, v->value)) { 16902 ASTOBJ_UNREF(peer, sip_destroy_peer); 16903 return NULL; 16904 } 16905 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16906 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16907 } else if (!strcasecmp(v->name, "port")) { 16908 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16909 peer->defaddr.sin_port = htons(atoi(v->value)); 16910 else 16911 peer->addr.sin_port = htons(atoi(v->value)); 16912 } else if (!strcasecmp(v->name, "callingpres")) { 16913 peer->callingpres = ast_parse_caller_presentation(v->value); 16914 if (peer->callingpres == -1) 16915 peer->callingpres = atoi(v->value); 16916 } else if (!strcasecmp(v->name, "username")) { 16917 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16918 } else if (!strcasecmp(v->name, "language")) { 16919 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16920 } else if (!strcasecmp(v->name, "regexten")) { 16921 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16922 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16923 peer->call_limit = atoi(v->value); 16924 if (peer->call_limit < 0) 16925 peer->call_limit = 0; 16926 } else if (!strcasecmp(v->name, "amaflags")) { 16927 format = ast_cdr_amaflags2int(v->value); 16928 if (format < 0) { 16929 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16930 } else { 16931 peer->amaflags = format; 16932 } 16933 } else if (!strcasecmp(v->name, "accountcode")) { 16934 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16935 } else if (!strcasecmp(v->name, "mohinterpret") 16936 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16937 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16938 } else if (!strcasecmp(v->name, "mohsuggest")) { 16939 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16940 } else if (!strcasecmp(v->name, "mailbox")) { 16941 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16942 } else if (!strcasecmp(v->name, "subscribemwi")) { 16943 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16944 } else if (!strcasecmp(v->name, "vmexten")) { 16945 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16946 } else if (!strcasecmp(v->name, "callgroup")) { 16947 peer->callgroup = ast_get_group(v->value); 16948 } else if (!strcasecmp(v->name, "allowtransfer")) { 16949 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16950 } else if (!strcasecmp(v->name, "pickupgroup")) { 16951 peer->pickupgroup = ast_get_group(v->value); 16952 } else if (!strcasecmp(v->name, "allow")) { 16953 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16954 } else if (!strcasecmp(v->name, "disallow")) { 16955 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16956 } else if (!strcasecmp(v->name, "autoframing")) { 16957 peer->autoframing = ast_true(v->value); 16958 } else if (!strcasecmp(v->name, "rtptimeout")) { 16959 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16960 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16961 peer->rtptimeout = global_rtptimeout; 16962 } 16963 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16964 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16965 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16966 peer->rtpholdtimeout = global_rtpholdtimeout; 16967 } 16968 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16969 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16970 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16971 peer->rtpkeepalive = global_rtpkeepalive; 16972 } 16973 } else if (!strcasecmp(v->name, "setvar")) { 16974 /* Set peer channel variable */ 16975 varname = ast_strdupa(v->value); 16976 if ((varval = strchr(varname, '='))) { 16977 *varval++ = '\0'; 16978 if ((tmpvar = ast_variable_new(varname, varval))) { 16979 tmpvar->next = peer->chanvars; 16980 peer->chanvars = tmpvar; 16981 } 16982 } 16983 } else if (!strcasecmp(v->name, "qualify")) { 16984 if (!strcasecmp(v->value, "no")) { 16985 peer->maxms = 0; 16986 } else if (!strcasecmp(v->value, "yes")) { 16987 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16988 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16989 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); 16990 peer->maxms = 0; 16991 } 16992 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16993 peer->maxcallbitrate = atoi(v->value); 16994 if (peer->maxcallbitrate < 0) 16995 peer->maxcallbitrate = default_maxcallbitrate; 16996 } 16997 } 16998 if (!ast_strlen_zero(fullcontact)) { 16999 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17000 } 17001 17002 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17003 time_t nowtime = time(NULL); 17004 17005 if ((nowtime - regseconds) > 0) { 17006 destroy_association(peer); 17007 memset(&peer->addr, 0, sizeof(peer->addr)); 17008 if (option_debug) 17009 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17010 } 17011 } 17012 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17013 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17014 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17015 global_allowsubscribe = TRUE; /* No global ban any more */ 17016 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17017 reg_source_db(peer); 17018 ASTOBJ_UNMARK(peer); 17019 ast_free_ha(oldha); 17020 return peer; 17021 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11681 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().
11682 { 11683 char a1[256]; 11684 char a2[256]; 11685 char a1_hash[256]; 11686 char a2_hash[256]; 11687 char resp[256]; 11688 char resp_hash[256]; 11689 char uri[256]; 11690 char opaque[256] = ""; 11691 char cnonce[80]; 11692 const char *username; 11693 const char *secret; 11694 const char *md5secret; 11695 struct sip_auth *auth = NULL; /* Realm authentication */ 11696 11697 if (!ast_strlen_zero(p->domain)) 11698 ast_copy_string(uri, p->domain, sizeof(uri)); 11699 else if (!ast_strlen_zero(p->uri)) 11700 ast_copy_string(uri, p->uri, sizeof(uri)); 11701 else 11702 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11703 11704 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11705 11706 /* Check if we have separate auth credentials */ 11707 if ((auth = find_realm_authentication(authl, p->realm))) { 11708 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11709 auth->username, p->peername, p->username); 11710 username = auth->username; 11711 secret = auth->secret; 11712 md5secret = auth->md5secret; 11713 if (sipdebug) 11714 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11715 } else { 11716 /* No authentication, use peer or register= config */ 11717 username = p->authname; 11718 secret = p->peersecret; 11719 md5secret = p->peermd5secret; 11720 } 11721 if (ast_strlen_zero(username)) /* We have no authentication */ 11722 return -1; 11723 11724 /* Calculate SIP digest response */ 11725 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11726 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11727 if (!ast_strlen_zero(md5secret)) 11728 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11729 else 11730 ast_md5_hash(a1_hash,a1); 11731 ast_md5_hash(a2_hash,a2); 11732 11733 p->noncecount++; 11734 if (!ast_strlen_zero(p->qop)) 11735 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11736 else 11737 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11738 ast_md5_hash(resp_hash, resp); 11739 11740 /* only include the opaque string if it's set */ 11741 if (!ast_strlen_zero(p->opaque)) { 11742 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11743 } 11744 11745 /* XXX We hard code our qop to "auth" for now. XXX */ 11746 if (!ast_strlen_zero(p->qop)) 11747 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); 11748 else 11749 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); 11750 11751 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11752 11753 return 0; 11754 }
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 8363 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().
08364 { 08365 struct sip_route *thishop, *head, *tail; 08366 int start = 0; 08367 int len; 08368 const char *rr, *contact, *c; 08369 08370 /* Once a persistant route is set, don't fool with it */ 08371 if (p->route && p->route_persistant) { 08372 if (option_debug) 08373 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08374 return; 08375 } 08376 08377 if (p->route) { 08378 free_old_route(p->route); 08379 p->route = NULL; 08380 } 08381 08382 /* We only want to create the route set the first time this is called */ 08383 p->route_persistant = 1; 08384 08385 /* Build a tailq, then assign it to p->route when done. 08386 * If backwards, we add entries from the head so they end up 08387 * in reverse order. However, we do need to maintain a correct 08388 * tail pointer because the contact is always at the end. 08389 */ 08390 head = NULL; 08391 tail = head; 08392 /* 1st we pass through all the hops in any Record-Route headers */ 08393 for (;;) { 08394 /* Each Record-Route header */ 08395 rr = __get_header(req, "Record-Route", &start); 08396 if (*rr == '\0') 08397 break; 08398 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08399 ++rr; 08400 len = strcspn(rr, ">") + 1; 08401 /* Make a struct route */ 08402 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08403 /* ast_calloc is not needed because all fields are initialized in this block */ 08404 ast_copy_string(thishop->hop, rr, len); 08405 if (option_debug > 1) 08406 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08407 /* Link in */ 08408 if (backwards) { 08409 /* Link in at head so they end up in reverse order */ 08410 thishop->next = head; 08411 head = thishop; 08412 /* If this was the first then it'll be the tail */ 08413 if (!tail) 08414 tail = thishop; 08415 } else { 08416 thishop->next = NULL; 08417 /* Link in at the end */ 08418 if (tail) 08419 tail->next = thishop; 08420 else 08421 head = thishop; 08422 tail = thishop; 08423 } 08424 } 08425 } 08426 } 08427 08428 /* Only append the contact if we are dealing with a strict router */ 08429 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08430 /* 2nd append the Contact: if there is one */ 08431 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08432 contact = get_header(req, "Contact"); 08433 if (!ast_strlen_zero(contact)) { 08434 if (option_debug > 1) 08435 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08436 /* Look for <: delimited address */ 08437 c = strchr(contact, '<'); 08438 if (c) { 08439 /* Take to > */ 08440 ++c; 08441 len = strcspn(c, ">") + 1; 08442 } else { 08443 /* No <> - just take the lot */ 08444 c = contact; 08445 len = strlen(contact) + 1; 08446 } 08447 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08448 /* ast_calloc is not needed because all fields are initialized in this block */ 08449 ast_copy_string(thishop->hop, c, len); 08450 thishop->next = NULL; 08451 /* Goes at the end */ 08452 if (tail) 08453 tail->next = thishop; 08454 else 08455 head = thishop; 08456 } 08457 } 08458 } 08459 08460 /* Store as new route */ 08461 p->route = head; 08462 08463 /* For debugging dump what we ended up with */ 08464 if (sip_debug_test_pvt(p)) 08465 list_route(p->route); 08466 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6935 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().
06936 { 06937 int send_pres_tags = TRUE; 06938 const char *privacy=NULL; 06939 const char *screen=NULL; 06940 char buf[256]; 06941 const char *clid = default_callerid; 06942 const char *clin = NULL; 06943 const char *fromdomain; 06944 06945 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06946 return; 06947 06948 if (p->owner && p->owner->cid.cid_num) 06949 clid = p->owner->cid.cid_num; 06950 if (p->owner && p->owner->cid.cid_name) 06951 clin = p->owner->cid.cid_name; 06952 if (ast_strlen_zero(clin)) 06953 clin = clid; 06954 06955 switch (p->callingpres) { 06956 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06957 privacy = "off"; 06958 screen = "no"; 06959 break; 06960 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06961 privacy = "off"; 06962 screen = "yes"; 06963 break; 06964 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06965 privacy = "off"; 06966 screen = "no"; 06967 break; 06968 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06969 privacy = "off"; 06970 screen = "yes"; 06971 break; 06972 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06973 privacy = "full"; 06974 screen = "no"; 06975 break; 06976 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06977 privacy = "full"; 06978 screen = "yes"; 06979 break; 06980 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06981 privacy = "full"; 06982 screen = "no"; 06983 break; 06984 case AST_PRES_PROHIB_NETWORK_NUMBER: 06985 privacy = "full"; 06986 screen = "yes"; 06987 break; 06988 case AST_PRES_NUMBER_NOT_AVAILABLE: 06989 send_pres_tags = FALSE; 06990 break; 06991 default: 06992 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06993 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06994 privacy = "full"; 06995 else 06996 privacy = "off"; 06997 screen = "no"; 06998 break; 06999 } 07000 07001 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07002 07003 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07004 if (send_pres_tags) 07005 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07006 ast_string_field_set(p, rpid, buf); 07007 07008 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07009 S_OR(p->fromuser, clid), 07010 fromdomain, p->tag); 07011 }
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 16581 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.
16582 { 16583 struct sip_user *user; 16584 int format; 16585 struct ast_ha *oldha = NULL; 16586 char *varname = NULL, *varval = NULL; 16587 struct ast_variable *tmpvar = NULL; 16588 struct ast_flags userflags[2] = {{(0)}}; 16589 struct ast_flags mask[2] = {{(0)}}; 16590 16591 16592 if (!(user = ast_calloc(1, sizeof(*user)))) 16593 return NULL; 16594 16595 suserobjs++; 16596 ASTOBJ_INIT(user); 16597 ast_copy_string(user->name, name, sizeof(user->name)); 16598 oldha = user->ha; 16599 user->ha = NULL; 16600 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16601 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16602 user->capability = global_capability; 16603 user->allowtransfer = global_allowtransfer; 16604 user->maxcallbitrate = default_maxcallbitrate; 16605 user->autoframing = global_autoframing; 16606 user->prefs = default_prefs; 16607 /* set default context */ 16608 strcpy(user->context, default_context); 16609 strcpy(user->language, default_language); 16610 strcpy(user->mohinterpret, default_mohinterpret); 16611 strcpy(user->mohsuggest, default_mohsuggest); 16612 /* First we walk through the v parameters list and then the alt parameters list */ 16613 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16614 if (handle_common_options(&userflags[0], &mask[0], v)) 16615 continue; 16616 16617 if (!strcasecmp(v->name, "context")) { 16618 ast_copy_string(user->context, v->value, sizeof(user->context)); 16619 } else if (!strcasecmp(v->name, "subscribecontext")) { 16620 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16621 } else if (!strcasecmp(v->name, "setvar")) { 16622 varname = ast_strdupa(v->value); 16623 if ((varval = strchr(varname,'='))) { 16624 *varval++ = '\0'; 16625 if ((tmpvar = ast_variable_new(varname, varval))) { 16626 tmpvar->next = user->chanvars; 16627 user->chanvars = tmpvar; 16628 } 16629 } 16630 } else if (!strcasecmp(v->name, "permit") || 16631 !strcasecmp(v->name, "deny")) { 16632 user->ha = ast_append_ha(v->name, v->value, user->ha); 16633 } else if (!strcasecmp(v->name, "allowtransfer")) { 16634 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16635 } else if (!strcasecmp(v->name, "secret")) { 16636 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16637 } else if (!strcasecmp(v->name, "md5secret")) { 16638 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16639 } else if (!strcasecmp(v->name, "callerid")) { 16640 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16641 } else if (!strcasecmp(v->name, "fullname")) { 16642 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16643 } else if (!strcasecmp(v->name, "cid_number")) { 16644 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16645 } else if (!strcasecmp(v->name, "callgroup")) { 16646 user->callgroup = ast_get_group(v->value); 16647 } else if (!strcasecmp(v->name, "pickupgroup")) { 16648 user->pickupgroup = ast_get_group(v->value); 16649 } else if (!strcasecmp(v->name, "language")) { 16650 ast_copy_string(user->language, v->value, sizeof(user->language)); 16651 } else if (!strcasecmp(v->name, "mohinterpret") 16652 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16653 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16654 } else if (!strcasecmp(v->name, "mohsuggest")) { 16655 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16656 } else if (!strcasecmp(v->name, "accountcode")) { 16657 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16658 } else if (!strcasecmp(v->name, "call-limit")) { 16659 user->call_limit = atoi(v->value); 16660 if (user->call_limit < 0) 16661 user->call_limit = 0; 16662 } else if (!strcasecmp(v->name, "amaflags")) { 16663 format = ast_cdr_amaflags2int(v->value); 16664 if (format < 0) { 16665 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16666 } else { 16667 user->amaflags = format; 16668 } 16669 } else if (!strcasecmp(v->name, "allow")) { 16670 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16671 } else if (!strcasecmp(v->name, "disallow")) { 16672 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16673 } else if (!strcasecmp(v->name, "autoframing")) { 16674 user->autoframing = ast_true(v->value); 16675 } else if (!strcasecmp(v->name, "callingpres")) { 16676 user->callingpres = ast_parse_caller_presentation(v->value); 16677 if (user->callingpres == -1) 16678 user->callingpres = atoi(v->value); 16679 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16680 user->maxcallbitrate = atoi(v->value); 16681 if (user->maxcallbitrate < 0) 16682 user->maxcallbitrate = default_maxcallbitrate; 16683 } 16684 /* We can't just report unknown options here because this may be a 16685 * type=friend entry. All user options are valid for a peer, but not 16686 * the other way around. */ 16687 } 16688 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16689 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16690 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16691 global_allowsubscribe = TRUE; /* No global ban any more */ 16692 ast_free_ha(oldha); 16693 return user; 16694 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1811 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, SIP_NAT_RFC3581, and SIP_PAGE2_TCP.
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().
01812 { 01813 /* Work around buggy UNIDEN UIP200 firmware */ 01814 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01815 01816 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01817 ast_string_field_build(p, via, "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s", 01818 ast_test_flag(&p->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP", ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01819 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8671 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().
08672 { 08673 struct sip_pvt *p = data; 08674 08675 ast_mutex_lock(&p->lock); 08676 08677 switch(state) { 08678 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08679 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08680 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08681 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08682 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08683 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); 08684 p->stateid = -1; 08685 p->subscribed = NONE; 08686 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08687 break; 08688 default: /* Tell user */ 08689 p->laststate = state; 08690 break; 08691 } 08692 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08693 if (!p->pendinginvite) { 08694 transmit_state_notify(p, state, 1, FALSE); 08695 } else { 08696 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08697 if many state changes happen meanwhile, we will only send a notification of the last one */ 08698 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08699 } 08700 } 08701 if (option_verbose > 1) 08702 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, 08703 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08704 08705 08706 ast_mutex_unlock(&p->lock); 08707 08708 return 0; 08709 }
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 5044 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().
05045 { 05046 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05047 sip_peer_hold(dialog, holdstate); 05048 if (global_callevents) 05049 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05050 "Channel: %s\r\n" 05051 "Uniqueid: %s\r\n", 05052 dialog->owner->name, 05053 dialog->owner->uniqueid); 05054 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05055 if (!holdstate) { /* Put off remote hold */ 05056 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05057 return; 05058 } 05059 /* No address for RTP, we're on hold */ 05060 05061 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05062 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05063 else if (sendonly == 2) /* Inactive stream */ 05064 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05065 else 05066 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05067 return; 05068 }
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 8476 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().
08479 { 08480 const char *response = "407 Proxy Authentication Required"; 08481 const char *reqheader = "Proxy-Authorization"; 08482 const char *respheader = "Proxy-Authenticate"; 08483 const char *authtoken; 08484 char a1_hash[256]; 08485 char resp_hash[256]=""; 08486 char *c; 08487 int wrongnonce = FALSE; 08488 int good_response; 08489 const char *usednonce = p->randdata; 08490 struct ast_dynamic_str *buf; 08491 int res; 08492 08493 /* table of recognised keywords, and their value in the digest */ 08494 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08495 struct x { 08496 const char *key; 08497 const char *s; 08498 } *i, keys[] = { 08499 [K_RESP] = { "response=", "" }, 08500 [K_URI] = { "uri=", "" }, 08501 [K_USER] = { "username=", "" }, 08502 [K_NONCE] = { "nonce=", "" }, 08503 [K_LAST] = { NULL, NULL} 08504 }; 08505 08506 /* Always OK if no secret */ 08507 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08508 return AUTH_SUCCESSFUL; 08509 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08510 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08511 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08512 different circumstances! What a surprise. */ 08513 response = "401 Unauthorized"; 08514 reqheader = "Authorization"; 08515 respheader = "WWW-Authenticate"; 08516 } 08517 authtoken = get_header(req, reqheader); 08518 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08519 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08520 information */ 08521 if (!reliable) { 08522 /* Resend message if this was NOT a reliable delivery. Otherwise the 08523 retransmission should get it */ 08524 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08525 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08526 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08527 } 08528 return AUTH_CHALLENGE_SENT; 08529 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08530 /* We have no auth, so issue challenge and request authentication */ 08531 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08532 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08533 /* Schedule auto destroy in 32 seconds */ 08534 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08535 return AUTH_CHALLENGE_SENT; 08536 } 08537 08538 /* --- We have auth, so check it */ 08539 08540 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08541 an example in the spec of just what it is you're doing a hash on. */ 08542 08543 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08544 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08545 08546 /* Make a copy of the response and parse it */ 08547 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08548 08549 if (res == AST_DYNSTR_BUILD_FAILED) 08550 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08551 08552 c = buf->str; 08553 08554 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08555 for (i = keys; i->key != NULL; i++) { 08556 const char *separator = ","; /* default */ 08557 08558 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08559 continue; 08560 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08561 c += strlen(i->key); 08562 if (*c == '"') { /* in quotes. Skip first and look for last */ 08563 c++; 08564 separator = "\""; 08565 } 08566 i->s = c; 08567 strsep(&c, separator); 08568 break; 08569 } 08570 if (i->key == NULL) /* not found, jump after space or comma */ 08571 strsep(&c, " ,"); 08572 } 08573 08574 /* Verify that digest username matches the username we auth as */ 08575 if (strcmp(username, keys[K_USER].s)) { 08576 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08577 username, keys[K_USER].s); 08578 /* Oops, we're trying something here */ 08579 return AUTH_USERNAME_MISMATCH; 08580 } 08581 08582 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08583 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08584 wrongnonce = TRUE; 08585 usednonce = keys[K_NONCE].s; 08586 } 08587 08588 if (!ast_strlen_zero(md5secret)) 08589 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08590 else { 08591 char a1[256]; 08592 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08593 ast_md5_hash(a1_hash, a1); 08594 } 08595 08596 /* compute the expected response to compare with what we received */ 08597 { 08598 char a2[256]; 08599 char a2_hash[256]; 08600 char resp[256]; 08601 08602 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08603 S_OR(keys[K_URI].s, uri)); 08604 ast_md5_hash(a2_hash, a2); 08605 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08606 ast_md5_hash(resp_hash, resp); 08607 } 08608 08609 good_response = keys[K_RESP].s && 08610 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08611 if (wrongnonce) { 08612 if (good_response) { 08613 if (sipdebug) 08614 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08615 /* We got working auth token, based on stale nonce . */ 08616 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08617 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08618 } else { 08619 /* Everything was wrong, so give the device one more try with a new challenge */ 08620 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08621 if (sipdebug) 08622 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08623 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08624 } else { 08625 if (sipdebug) 08626 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08627 } 08628 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08629 } 08630 08631 /* Schedule auto destroy in 32 seconds */ 08632 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08633 return AUTH_CHALLENGE_SENT; 08634 } 08635 if (good_response) { 08636 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08637 return AUTH_SUCCESSFUL; 08638 } 08639 08640 /* Ok, we have a bad username/secret pair */ 08641 /* Tell the UAS not to re-send this authentication data, because 08642 it will continue to fail 08643 */ 08644 08645 return AUTH_SECRET_FAILED; 08646 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12149 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().
12150 { 12151 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12152 /* if we can't BYE, then this is really a pending CANCEL */ 12153 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12154 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12155 /* Actually don't destroy us yet, wait for the 487 on our original 12156 INVITE, but do set an autodestruct just in case we never get it. */ 12157 else { 12158 /* We have a pending outbound invite, don't send someting 12159 new in-transaction */ 12160 if (p->pendinginvite) 12161 return; 12162 12163 /* Perhaps there is an SD change INVITE outstanding */ 12164 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12165 } 12166 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12167 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12168 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12169 /* if we can't REINVITE, hold it for later */ 12170 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12171 if (option_debug) 12172 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12173 } else { 12174 if (option_debug) 12175 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12176 /* Didn't get to reinvite yet, so do it now */ 12177 transmit_reinvite_with_sdp(p); 12178 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12179 } 12180 } 12181 }
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 16460 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().
16461 { 16462 struct domain *d; 16463 int result = 0; 16464 16465 AST_LIST_LOCK(&domain_list); 16466 AST_LIST_TRAVERSE(&domain_list, d, list) { 16467 if (strcasecmp(d->domain, domain)) 16468 continue; 16469 16470 if (len && !ast_strlen_zero(d->context)) 16471 ast_copy_string(context, d->context, len); 16472 16473 result = 1; 16474 break; 16475 } 16476 AST_LIST_UNLOCK(&domain_list); 16477 16478 return result; 16479 }
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 9775 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09776 { 09777 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09778 }
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 9455 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().
09458 { 09459 struct sip_user *user = NULL; 09460 struct sip_peer *peer; 09461 char from[256], *c; 09462 char *of; 09463 char rpid_num[50]; 09464 const char *rpid; 09465 enum check_auth_result res = AUTH_SUCCESSFUL; 09466 char *t; 09467 char calleridname[50]; 09468 int debug=sip_debug_test_addr(sin); 09469 struct ast_variable *tmpvar = NULL, *v = NULL; 09470 char *uri2 = ast_strdupa(uri); 09471 09472 /* Terminate URI */ 09473 t = uri2; 09474 while (*t && *t > 32 && *t != ';') 09475 t++; 09476 *t = '\0'; 09477 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09478 if (pedanticsipchecking) 09479 ast_uri_decode(from); 09480 /* XXX here tries to map the username for invite things */ 09481 memset(calleridname, 0, sizeof(calleridname)); 09482 get_calleridname(from, calleridname, sizeof(calleridname)); 09483 if (calleridname[0]) 09484 ast_string_field_set(p, cid_name, calleridname); 09485 09486 rpid = get_header(req, "Remote-Party-ID"); 09487 memset(rpid_num, 0, sizeof(rpid_num)); 09488 if (!ast_strlen_zero(rpid)) 09489 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09490 09491 of = get_in_brackets(from); 09492 if (ast_strlen_zero(p->exten)) { 09493 t = uri2; 09494 if (!strncasecmp(t, "sip:", 4)) 09495 t+= 4; 09496 ast_string_field_set(p, exten, t); 09497 t = strchr(p->exten, '@'); 09498 if (t) 09499 *t = '\0'; 09500 if (ast_strlen_zero(p->our_contact)) 09501 build_contact(p); 09502 } 09503 /* save the URI part of the From header */ 09504 ast_string_field_set(p, from, of); 09505 if (strncasecmp(of, "sip:", 4)) { 09506 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09507 } else 09508 of += 4; 09509 /* Get just the username part */ 09510 if ((c = strchr(of, '@'))) { 09511 char *tmp; 09512 *c = '\0'; 09513 if ((c = strchr(of, ':'))) 09514 *c = '\0'; 09515 tmp = ast_strdupa(of); 09516 /* We need to be able to handle auth-headers looking like 09517 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09518 */ 09519 tmp = strsep(&tmp, ";"); 09520 if (ast_is_shrinkable_phonenumber(tmp)) 09521 ast_shrink_phone_number(tmp); 09522 ast_string_field_set(p, cid_num, tmp); 09523 } 09524 09525 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09526 user = find_user(of, 1); 09527 09528 /* Find user based on user name in the from header */ 09529 if (user && ast_apply_ha(user->ha, sin)) { 09530 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09531 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09532 /* copy channel vars */ 09533 for (v = user->chanvars ; v ; v = v->next) { 09534 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09535 tmpvar->next = p->chanvars; 09536 p->chanvars = tmpvar; 09537 } 09538 } 09539 p->prefs = user->prefs; 09540 /* Set Frame packetization */ 09541 if (p->rtp) { 09542 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09543 p->autoframing = user->autoframing; 09544 } 09545 /* replace callerid if rpid found, and not restricted */ 09546 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09547 char *tmp; 09548 if (*calleridname) 09549 ast_string_field_set(p, cid_name, calleridname); 09550 tmp = ast_strdupa(rpid_num); 09551 if (ast_is_shrinkable_phonenumber(tmp)) 09552 ast_shrink_phone_number(tmp); 09553 ast_string_field_set(p, cid_num, tmp); 09554 } 09555 09556 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09557 09558 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09559 if (sip_cancel_destroy(p)) 09560 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09561 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09562 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09563 /* Copy SIP extensions profile from INVITE */ 09564 if (p->sipoptions) 09565 user->sipoptions = p->sipoptions; 09566 09567 /* If we have a call limit, set flag */ 09568 if (user->call_limit) 09569 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09570 if (!ast_strlen_zero(user->context)) 09571 ast_string_field_set(p, context, user->context); 09572 if (!ast_strlen_zero(user->cid_num)) { 09573 char *tmp = ast_strdupa(user->cid_num); 09574 if (ast_is_shrinkable_phonenumber(tmp)) 09575 ast_shrink_phone_number(tmp); 09576 ast_string_field_set(p, cid_num, tmp); 09577 } 09578 if (!ast_strlen_zero(user->cid_name)) 09579 ast_string_field_set(p, cid_name, user->cid_name); 09580 ast_string_field_set(p, username, user->name); 09581 ast_string_field_set(p, peername, user->name); 09582 ast_string_field_set(p, peersecret, user->secret); 09583 ast_string_field_set(p, peermd5secret, user->md5secret); 09584 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09585 ast_string_field_set(p, accountcode, user->accountcode); 09586 ast_string_field_set(p, language, user->language); 09587 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09588 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09589 p->allowtransfer = user->allowtransfer; 09590 p->amaflags = user->amaflags; 09591 p->callgroup = user->callgroup; 09592 p->pickupgroup = user->pickupgroup; 09593 if (user->callingpres) /* User callingpres setting will override RPID header */ 09594 p->callingpres = user->callingpres; 09595 09596 /* Set default codec settings for this call */ 09597 p->capability = user->capability; /* User codec choice */ 09598 p->jointcapability = user->capability; /* Our codecs */ 09599 if (p->peercapability) /* AND with peer's codecs */ 09600 p->jointcapability &= p->peercapability; 09601 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09602 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09603 p->noncodeccapability |= AST_RTP_DTMF; 09604 else 09605 p->noncodeccapability &= ~AST_RTP_DTMF; 09606 p->jointnoncodeccapability = p->noncodeccapability; 09607 if (p->t38.peercapability) 09608 p->t38.jointcapability &= p->t38.peercapability; 09609 p->maxcallbitrate = user->maxcallbitrate; 09610 /* If we do not support video, remove video from call structure */ 09611 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09612 ast_rtp_destroy(p->vrtp); 09613 p->vrtp = NULL; 09614 } 09615 } 09616 if (user && debug) 09617 ast_verbose("Found user '%s'\n", user->name); 09618 } else { 09619 if (user) { 09620 if (!authpeer && debug) 09621 ast_verbose("Found user '%s', but fails host access\n", user->name); 09622 ASTOBJ_UNREF(user,sip_destroy_user); 09623 } 09624 user = NULL; 09625 } 09626 09627 if (!user) { 09628 /* If we didn't find a user match, check for peers */ 09629 if (sipmethod == SIP_SUBSCRIBE) 09630 /* For subscribes, match on peer name only */ 09631 peer = find_peer(of, NULL, 1); 09632 else 09633 /* Look for peer based on the IP address we received data from */ 09634 /* If peer is registered from this IP address or have this as a default 09635 IP address, this call is from the peer 09636 */ 09637 peer = find_peer(NULL, &p->recv, 1); 09638 09639 if (peer) { 09640 /* Set Frame packetization */ 09641 if (p->rtp) { 09642 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09643 p->autoframing = peer->autoframing; 09644 } 09645 if (debug) 09646 ast_verbose("Found peer '%s'\n", peer->name); 09647 09648 /* Take the peer */ 09649 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09650 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09651 09652 /* Copy SIP extensions profile to peer */ 09653 if (p->sipoptions) 09654 peer->sipoptions = p->sipoptions; 09655 09656 /* replace callerid if rpid found, and not restricted */ 09657 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09658 char *tmp = ast_strdupa(rpid_num); 09659 if (*calleridname) 09660 ast_string_field_set(p, cid_name, calleridname); 09661 if (ast_is_shrinkable_phonenumber(tmp)) 09662 ast_shrink_phone_number(tmp); 09663 ast_string_field_set(p, cid_num, tmp); 09664 } 09665 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09666 09667 ast_string_field_set(p, peersecret, peer->secret); 09668 ast_string_field_set(p, peermd5secret, peer->md5secret); 09669 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09670 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09671 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09672 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09673 p->callingpres = peer->callingpres; 09674 if (peer->maxms && peer->lastms) 09675 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09676 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09677 /* Pretend there is no required authentication */ 09678 ast_string_field_free(p, peersecret); 09679 ast_string_field_free(p, peermd5secret); 09680 } 09681 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09682 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09683 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09684 /* If we have a call limit, set flag */ 09685 if (peer->call_limit) 09686 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09687 ast_string_field_set(p, peername, peer->name); 09688 ast_string_field_set(p, authname, peer->name); 09689 09690 /* copy channel vars */ 09691 for (v = peer->chanvars ; v ; v = v->next) { 09692 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09693 tmpvar->next = p->chanvars; 09694 p->chanvars = tmpvar; 09695 } 09696 } 09697 if (authpeer) { 09698 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09699 } 09700 09701 if (!ast_strlen_zero(peer->username)) { 09702 ast_string_field_set(p, username, peer->username); 09703 /* Use the default username for authentication on outbound calls */ 09704 /* XXX this takes the name from the caller... can we override ? */ 09705 ast_string_field_set(p, authname, peer->username); 09706 } 09707 if (!ast_strlen_zero(peer->cid_num)) { 09708 char *tmp = ast_strdupa(peer->cid_num); 09709 if (ast_is_shrinkable_phonenumber(tmp)) 09710 ast_shrink_phone_number(tmp); 09711 ast_string_field_set(p, cid_num, tmp); 09712 } 09713 if (!ast_strlen_zero(peer->cid_name)) 09714 ast_string_field_set(p, cid_name, peer->cid_name); 09715 ast_string_field_set(p, fullcontact, peer->fullcontact); 09716 if (!ast_strlen_zero(peer->context)) 09717 ast_string_field_set(p, context, peer->context); 09718 ast_string_field_set(p, peersecret, peer->secret); 09719 ast_string_field_set(p, peermd5secret, peer->md5secret); 09720 ast_string_field_set(p, language, peer->language); 09721 ast_string_field_set(p, accountcode, peer->accountcode); 09722 p->amaflags = peer->amaflags; 09723 p->callgroup = peer->callgroup; 09724 p->pickupgroup = peer->pickupgroup; 09725 p->capability = peer->capability; 09726 p->prefs = peer->prefs; 09727 p->jointcapability = peer->capability; 09728 if (p->peercapability) 09729 p->jointcapability &= p->peercapability; 09730 p->maxcallbitrate = peer->maxcallbitrate; 09731 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09732 ast_rtp_destroy(p->vrtp); 09733 p->vrtp = NULL; 09734 } 09735 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09736 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09737 p->noncodeccapability |= AST_RTP_DTMF; 09738 else 09739 p->noncodeccapability &= ~AST_RTP_DTMF; 09740 p->jointnoncodeccapability = p->noncodeccapability; 09741 if (p->t38.peercapability) 09742 p->t38.jointcapability &= p->t38.peercapability; 09743 } 09744 ASTOBJ_UNREF(peer, sip_destroy_peer); 09745 } else { 09746 if (debug) 09747 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09748 09749 /* do we allow guests? */ 09750 if (!global_allowguest) { 09751 if (global_alwaysauthreject) 09752 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09753 else 09754 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09755 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09756 char *tmp = ast_strdupa(rpid_num); 09757 if (*calleridname) 09758 ast_string_field_set(p, cid_name, calleridname); 09759 if (ast_is_shrinkable_phonenumber(tmp)) 09760 ast_shrink_phone_number(tmp); 09761 ast_string_field_set(p, cid_num, tmp); 09762 } 09763 } 09764 09765 } 09766 09767 if (user) 09768 ASTOBJ_UNREF(user, sip_destroy_user); 09769 return res; 09770 }
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 9323 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().
09324 { 09325 char via[512]; 09326 char *c, *pt; 09327 struct hostent *hp; 09328 struct ast_hostent ahp; 09329 09330 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09331 09332 /* Work on the leftmost value of the topmost Via header */ 09333 c = strchr(via, ','); 09334 if (c) 09335 *c = '\0'; 09336 09337 /* Check for rport */ 09338 c = strstr(via, ";rport"); 09339 if (c && (c[6] != '=')) /* rport query, not answer */ 09340 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09341 09342 c = strchr(via, ';'); 09343 if (c) 09344 *c = '\0'; 09345 09346 c = strchr(via, ' '); 09347 if (c) { 09348 *c = '\0'; 09349 c = ast_skip_blanks(c+1); 09350 if ((strcasecmp(via, "SIP/2.0/UDP")) && (strcasecmp(via, "SIP/2.0/TCP"))) { 09351 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09352 return; 09353 } 09354 pt = strchr(c, ':'); 09355 if (pt) 09356 *pt++ = '\0'; /* remember port pointer */ 09357 hp = ast_gethostbyname(c, &ahp); 09358 if (!hp) { 09359 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09360 return; 09361 } 09362 memset(&p->sa, 0, sizeof(p->sa)); 09363 p->sa.sin_family = AF_INET; 09364 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09365 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09366 09367 if (sip_debug_test_pvt(p)) { 09368 const struct sockaddr_in *dst = sip_real_dst(p); 09369 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09370 } 09371 } 09372 }
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 10219 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
10220 { 10221 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10222 10223 while ((oldcontext = strsep(&old, "&"))) { 10224 stalecontext = '\0'; 10225 ast_copy_string(newlist, new, sizeof(newlist)); 10226 stringp = newlist; 10227 while ((newcontext = strsep(&stringp, "&"))) { 10228 if (strcmp(newcontext, oldcontext) == 0) { 10229 /* This is not the context you're looking for */ 10230 stalecontext = '\0'; 10231 break; 10232 } else if (strcmp(newcontext, oldcontext)) { 10233 stalecontext = oldcontext; 10234 } 10235 10236 } 10237 if (stalecontext) 10238 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10239 } 10240 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16553 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16554 { 16555 struct sip_auth *a = authlist; 16556 struct sip_auth *b; 16557 16558 while (a) { 16559 b = a; 16560 a = a->next; 16561 free(b); 16562 } 16563 16564 return 1; 16565 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16482 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().
16483 { 16484 struct domain *d; 16485 16486 AST_LIST_LOCK(&domain_list); 16487 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16488 free(d); 16489 AST_LIST_UNLOCK(&domain_list); 16490 }
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 11034 of file chan_sip.c.
References complete_sip_peer().
11035 { 11036 if (pos == 3) 11037 return complete_sip_peer(word, state, 0); 11038 11039 return NULL; 11040 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11008 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().
11009 { 11010 char *result = NULL; 11011 int wordlen = strlen(word); 11012 int which = 0; 11013 11014 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11015 /* locking of the object is not required because only the name and flags are being compared */ 11016 if (!strncasecmp(word, iterator->name, wordlen) && 11017 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11018 ++which > state) 11019 result = ast_strdup(iterator->name); 11020 } while(0) ); 11021 return result; 11022 }
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 11102 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11103 { 11104 if (pos == 4) 11105 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11106 return NULL; 11107 }
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 11110 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11111 { 11112 if (pos == 4) 11113 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11114 11115 return NULL; 11116 }
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 11025 of file chan_sip.c.
References complete_sip_peer().
11026 { 11027 if (pos == 3) 11028 return complete_sip_peer(word, state, 0); 11029 11030 return NULL; 11031 }
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 11063 of file chan_sip.c.
References complete_sip_user().
11064 { 11065 if (pos == 3) 11066 return complete_sip_user(word, state, 0); 11067 11068 return NULL; 11069 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11043 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().
11044 { 11045 char *result = NULL; 11046 int wordlen = strlen(word); 11047 int which = 0; 11048 11049 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11050 /* locking of the object is not required because only the name and flags are being compared */ 11051 if (!strncasecmp(word, iterator->name, wordlen)) { 11052 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11053 continue; 11054 if (++which > state) { 11055 result = ast_strdup(iterator->name); 11056 } 11057 } 11058 } while(0) ); 11059 return result; 11060 }
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 10985 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10986 { 10987 int which=0; 10988 struct sip_pvt *cur; 10989 char *c = NULL; 10990 int wordlen = strlen(word); 10991 10992 if (pos != 3) { 10993 return NULL; 10994 } 10995 10996 ast_mutex_lock(&iflock); 10997 for (cur = iflist; cur; cur = cur->next) { 10998 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10999 c = ast_strdup(cur->callid); 11000 break; 11001 } 11002 } 11003 ast_mutex_unlock(&iflock); 11004 return c; 11005 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11072 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11073 { 11074 char *c = NULL; 11075 11076 if (pos == 2) { 11077 int which = 0; 11078 char *cat = NULL; 11079 int wordlen = strlen(word); 11080 11081 /* do completion for notify type */ 11082 11083 if (!notify_types) 11084 return NULL; 11085 11086 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11087 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11088 c = ast_strdup(cat); 11089 break; 11090 } 11091 } 11092 return c; 11093 } 11094 11095 if (pos > 2) 11096 return complete_sip_peer(word, state, 0); 11097 11098 return NULL; 11099 }
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 5735 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05736 { 05737 int start = 0; 05738 int copied = 0; 05739 for (;;) { 05740 const char *tmp = __get_header(orig, field, &start); 05741 05742 if (ast_strlen_zero(tmp)) 05743 break; 05744 /* Add what we're responding to */ 05745 add_header(req, field, tmp); 05746 copied++; 05747 } 05748 return copied ? 0 : -1; 05749 }
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 5724 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05725 { 05726 const char *tmp = get_header(orig, field); 05727 05728 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05729 return add_header(req, field, tmp); 05730 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05731 return -1; 05732 }
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 6778 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().
06779 { 06780 long offset; 06781 int x; 06782 offset = ((void *)dst) - ((void *)src); 06783 /* First copy stuff */ 06784 memcpy(dst, src, sizeof(*dst)); 06785 /* Now fix pointer arithmetic */ 06786 for (x=0; x < src->headers; x++) 06787 dst->header[x] += offset; 06788 for (x=0; x < src->lines; x++) 06789 dst->line[x] += offset; 06790 dst->rlPart1 += offset; 06791 dst->rlPart2 += offset; 06792 }
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 5757 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().
05758 { 05759 int copied = 0; 05760 int start = 0; 05761 05762 for (;;) { 05763 char new[512]; 05764 const char *oh = __get_header(orig, field, &start); 05765 05766 if (ast_strlen_zero(oh)) 05767 break; 05768 05769 if (!copied) { /* Only check for empty rport in topmost via header */ 05770 char leftmost[512], *others, *rport; 05771 05772 /* Only work on leftmost value */ 05773 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05774 others = strchr(leftmost, ','); 05775 if (others) 05776 *others++ = '\0'; 05777 05778 /* Find ;rport; (empty request) */ 05779 rport = strstr(leftmost, ";rport"); 05780 if (rport && *(rport+6) == '=') 05781 rport = NULL; /* We already have a parameter to rport */ 05782 05783 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05784 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05785 /* We need to add received port - rport */ 05786 char *end; 05787 05788 rport = strstr(leftmost, ";rport"); 05789 05790 if (rport) { 05791 end = strchr(rport + 1, ';'); 05792 if (end) 05793 memmove(rport, end, strlen(end) + 1); 05794 else 05795 *rport = '\0'; 05796 } 05797 05798 /* Add rport to first VIA header if requested */ 05799 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05800 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05801 ntohs(p->recv.sin_port), 05802 others ? "," : "", others ? others : ""); 05803 } else { 05804 /* We should *always* add a received to the topmost via */ 05805 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05806 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05807 others ? "," : "", others ? others : ""); 05808 } 05809 oh = new; /* the header to copy */ 05810 } /* else add the following via headers untouched */ 05811 add_header(req, field, oh); 05812 copied++; 05813 } 05814 if (!copied) { 05815 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05816 return -1; 05817 } 05818 return 0; 05819 }
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 2902 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.
02903 { 02904 struct hostent *hp; 02905 struct ast_hostent ahp; 02906 struct sip_peer *p; 02907 char *port; 02908 int portno; 02909 char host[MAXHOSTNAMELEN], *hostn; 02910 char peer[256]; 02911 02912 ast_copy_string(peer, opeer, sizeof(peer)); 02913 port = strchr(peer, ':'); 02914 if (port) 02915 *port++ = '\0'; 02916 dialog->sa.sin_family = AF_INET; 02917 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02918 p = find_peer(peer, NULL, 1); 02919 02920 if (p) { 02921 int res = create_addr_from_peer(dialog, p); 02922 ASTOBJ_UNREF(p, sip_destroy_peer); 02923 return res; 02924 } 02925 hostn = peer; 02926 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02927 if (srvlookup) { 02928 char service[MAXHOSTNAMELEN]; 02929 int tportno; 02930 int ret; 02931 02932 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02933 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02934 if (ret > 0) { 02935 hostn = host; 02936 portno = tportno; 02937 } 02938 } 02939 hp = ast_gethostbyname(hostn, &ahp); 02940 if (!hp) { 02941 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02942 return -1; 02943 } 02944 ast_string_field_set(dialog, tohost, peer); 02945 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02946 dialog->sa.sin_port = htons(portno); 02947 dialog->recv = dialog->sa; 02948 return 0; 02949 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2792 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_TCP, SIP_PAGE2_TCP_CONNECTED, SIP_PAGE2_VIDEOSUPPORT, sip_peer::sockfd, sip_pvt::sockfd, 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().
02793 { 02794 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02795 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02796 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02797 dialog->recv = dialog->sa; 02798 } else 02799 return -1; 02800 02801 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02802 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02803 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 02804 dialog->sockfd = peer->sockfd; 02805 dialog->capability = peer->capability; 02806 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02807 ast_rtp_destroy(dialog->vrtp); 02808 dialog->vrtp = NULL; 02809 } 02810 dialog->prefs = peer->prefs; 02811 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02812 dialog->t38.capability = global_t38_capability; 02813 if (dialog->udptl) { 02814 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02815 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02816 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02817 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02818 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02819 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02820 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02821 if (option_debug > 1) 02822 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02823 } 02824 dialog->t38.jointcapability = dialog->t38.capability; 02825 } else if (dialog->udptl) { 02826 ast_udptl_destroy(dialog->udptl); 02827 dialog->udptl = NULL; 02828 } 02829 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02830 02831 if (dialog->rtp) { 02832 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02833 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02834 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02835 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02836 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02837 /* Set Frame packetization */ 02838 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02839 dialog->autoframing = peer->autoframing; 02840 } 02841 if (dialog->vrtp) { 02842 ast_rtp_setdtmf(dialog->vrtp, 0); 02843 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02844 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02845 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02846 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02847 } 02848 02849 ast_string_field_set(dialog, peername, peer->name); 02850 ast_string_field_set(dialog, authname, peer->username); 02851 ast_string_field_set(dialog, username, peer->username); 02852 ast_string_field_set(dialog, peersecret, peer->secret); 02853 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02854 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02855 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02856 ast_string_field_set(dialog, tohost, peer->tohost); 02857 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02858 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02859 char *tmpcall; 02860 char *c; 02861 tmpcall = ast_strdupa(dialog->callid); 02862 c = strchr(tmpcall, '@'); 02863 if (c) { 02864 *c = '\0'; 02865 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02866 } 02867 } 02868 if (ast_strlen_zero(dialog->tohost)) 02869 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02870 if (!ast_strlen_zero(peer->fromdomain)) 02871 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02872 if (!ast_strlen_zero(peer->fromuser)) 02873 ast_string_field_set(dialog, fromuser, peer->fromuser); 02874 if (!ast_strlen_zero(peer->language)) 02875 ast_string_field_set(dialog, language, peer->language); 02876 dialog->maxtime = peer->maxms; 02877 dialog->callgroup = peer->callgroup; 02878 dialog->pickupgroup = peer->pickupgroup; 02879 dialog->allowtransfer = peer->allowtransfer; 02880 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02881 /* Minimum is settable or default to 100 ms */ 02882 if (peer->maxms && peer->lastms) 02883 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02884 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02885 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02886 dialog->noncodeccapability |= AST_RTP_DTMF; 02887 else 02888 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02889 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02890 ast_string_field_set(dialog, context, peer->context); 02891 dialog->rtptimeout = peer->rtptimeout; 02892 if (peer->call_limit) 02893 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02894 dialog->maxcallbitrate = peer->maxcallbitrate; 02895 02896 return 0; 02897 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7958 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().
07959 { 07960 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07961 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07962 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07963 else 07964 ast_db_del("SIP/Registry", peer->name); 07965 } 07966 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6822 of file chan_sip.c.
References ast_log(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06823 { 06824 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06825 06826 if (!*e) 06827 return -1; 06828 req->rlPart1 = e; /* method or protocol */ 06829 e = ast_skip_nonblanks(e); 06830 if (*e) 06831 *e++ = '\0'; 06832 /* Get URI or status code */ 06833 e = ast_skip_blanks(e); 06834 if ( !*e ) 06835 return -1; 06836 ast_trim_blanks(e); 06837 06838 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06839 if (strlen(e) < 3) /* status code is 3 digits */ 06840 return -1; 06841 req->rlPart2 = e; 06842 } else { /* We have a request */ 06843 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06844 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06845 e++; 06846 if (!*e) 06847 return -1; 06848 } 06849 req->rlPart2 = e; /* URI */ 06850 e = ast_skip_nonblanks(e); 06851 if (*e) 06852 *e++ = '\0'; 06853 e = ast_skip_blanks(e); 06854 if (strcasecmp(e, "SIP/2.0") ) { 06855 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06856 return -1; 06857 } 06858 } 06859 return 1; 06860 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15760 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(), siptcpsock, siptcpsock_accept(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
15761 { 15762 int res; 15763 struct sip_pvt *sip; 15764 struct sip_peer *peer = NULL; 15765 time_t t; 15766 int fastrestart = FALSE; 15767 int lastpeernum = -1; 15768 int curpeernum; 15769 int reloading; 15770 15771 /* Add an I/O event to our SIP UDP socket */ 15772 if (sipsock > -1) 15773 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15774 if (siptcpsock > -1) 15775 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 15776 15777 /* From here on out, we die whenever asked */ 15778 for(;;) { 15779 /* Check for a reload request */ 15780 ast_mutex_lock(&sip_reload_lock); 15781 reloading = sip_reloading; 15782 sip_reloading = FALSE; 15783 ast_mutex_unlock(&sip_reload_lock); 15784 if (reloading) { 15785 if (option_verbose > 0) 15786 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15787 sip_do_reload(sip_reloadreason); 15788 15789 /* Change the I/O fd of our UDP socket */ 15790 if (sipsock > -1) { 15791 if (sipsock_read_id) 15792 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15793 else 15794 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15795 } else if (sipsock_read_id) { 15796 ast_io_remove(io, sipsock_read_id); 15797 sipsock_read_id = NULL; 15798 } 15799 15800 if (siptcpsock > -1) { 15801 if (siptcpsock_read_id) 15802 siptcpsock_read_id = ast_io_change(io, siptcpsock_read_id, siptcpsock, NULL, 0, NULL); 15803 else 15804 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 15805 } 15806 } 15807 restartsearch: 15808 /* Check for interfaces needing to be killed */ 15809 ast_mutex_lock(&iflock); 15810 t = time(NULL); 15811 /* don't scan the interface list if it hasn't been a reasonable period 15812 of time since the last time we did it (when MWI is being sent, we can 15813 get back to this point every millisecond or less) 15814 */ 15815 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15816 /*! \note If we can't get a lock on an interface, skip it and come 15817 * back later. Note that there is the possibility of a deadlock with 15818 * sip_hangup otherwise, because sip_hangup is called with the channel 15819 * locked first, and the iface lock is attempted second. 15820 */ 15821 if (ast_mutex_trylock(&sip->lock)) 15822 continue; 15823 15824 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15825 if (sip->rtp && sip->owner && 15826 (sip->owner->_state == AST_STATE_UP) && 15827 !sip->redirip.sin_addr.s_addr && 15828 sip->t38.state != T38_ENABLED) { 15829 if (sip->lastrtptx && 15830 ast_rtp_get_rtpkeepalive(sip->rtp) && 15831 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15832 /* Need to send an empty RTP packet */ 15833 sip->lastrtptx = time(NULL); 15834 ast_rtp_sendcng(sip->rtp, 0); 15835 } 15836 if (sip->lastrtprx && 15837 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15838 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15839 /* Might be a timeout now -- see if we're on hold */ 15840 struct sockaddr_in sin; 15841 ast_rtp_get_peer(sip->rtp, &sin); 15842 if (sin.sin_addr.s_addr || 15843 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15844 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15845 /* Needs a hangup */ 15846 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15847 while (sip->owner && ast_channel_trylock(sip->owner)) { 15848 DEADLOCK_AVOIDANCE(&sip->lock); 15849 } 15850 if (sip->owner) { 15851 ast_log(LOG_NOTICE, 15852 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15853 sip->owner->name, 15854 (long) (t - sip->lastrtprx)); 15855 /* Issue a softhangup */ 15856 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15857 ast_channel_unlock(sip->owner); 15858 /* forget the timeouts for this call, since a hangup 15859 has already been requested and we don't want to 15860 repeatedly request hangups 15861 */ 15862 ast_rtp_set_rtptimeout(sip->rtp, 0); 15863 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15864 if (sip->vrtp) { 15865 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15866 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15867 } 15868 } 15869 } 15870 } 15871 } 15872 } 15873 /* If we have sessions that needs to be destroyed, do it now */ 15874 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15875 !sip->owner) { 15876 ast_mutex_unlock(&sip->lock); 15877 __sip_destroy(sip, 1); 15878 ast_mutex_unlock(&iflock); 15879 usleep(1); 15880 goto restartsearch; 15881 } 15882 ast_mutex_unlock(&sip->lock); 15883 } 15884 ast_mutex_unlock(&iflock); 15885 15886 pthread_testcancel(); 15887 /* Wait for sched or io */ 15888 res = ast_sched_wait(sched); 15889 if ((res < 0) || (res > 1000)) 15890 res = 1000; 15891 /* If we might need to send more mailboxes, don't wait long at all.*/ 15892 if (fastrestart) 15893 res = 1; 15894 res = ast_io_wait(io, res); 15895 if (option_debug && res > 20) 15896 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15897 ast_mutex_lock(&monlock); 15898 if (res >= 0) { 15899 res = ast_sched_runq(sched); 15900 if (option_debug && res >= 20) 15901 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15902 } 15903 15904 /* Send MWI notifications to peers - static and cached realtime peers */ 15905 t = time(NULL); 15906 fastrestart = FALSE; 15907 curpeernum = 0; 15908 peer = NULL; 15909 /* Find next peer that needs mwi */ 15910 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15911 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15912 fastrestart = TRUE; 15913 lastpeernum = curpeernum; 15914 peer = ASTOBJ_REF(iterator); 15915 }; 15916 curpeernum++; 15917 } while (0) 15918 ); 15919 /* Send MWI to the peer */ 15920 if (peer) { 15921 ASTOBJ_WRLOCK(peer); 15922 sip_send_mwi_to_peer(peer); 15923 ASTOBJ_UNLOCK(peer); 15924 ASTOBJ_UNREF(peer,sip_destroy_peer); 15925 } else { 15926 /* Reset where we come from */ 15927 lastpeernum = -1; 15928 } 15929 ast_mutex_unlock(&monlock); 15930 } 15931 /* Never reached */ 15932 return NULL; 15933 15934 }
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 11582 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().
11583 { 11584 char digest[1024]; 11585 11586 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11587 return -2; 11588 11589 p->authtries++; 11590 if (option_debug > 1) 11591 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11592 memset(digest, 0, sizeof(digest)); 11593 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11594 /* No way to authenticate */ 11595 return -1; 11596 } 11597 /* Now we have a reply digest */ 11598 p->options->auth = digest; 11599 p->options->authheader = respheader; 11600 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11601 }
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 11561 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().
11562 { 11563 char digest[1024]; 11564 p->authtries++; 11565 memset(digest,0,sizeof(digest)); 11566 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11567 /* There's nothing to use for authentication */ 11568 /* No digest challenge in request */ 11569 if (sip_debug_test_pvt(p) && p->registry) 11570 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11571 /* No old challenge */ 11572 return -1; 11573 } 11574 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11575 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11576 if (sip_debug_test_pvt(p) && p->registry) 11577 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11578 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11579 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2768 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().
02769 { 02770 const char *mode = natflags ? "On" : "Off"; 02771 02772 if (p->rtp) { 02773 if (option_debug) 02774 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02775 ast_rtp_setnat(p->rtp, natflags); 02776 } 02777 if (p->vrtp) { 02778 if (option_debug) 02779 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02780 ast_rtp_setnat(p->vrtp, natflags); 02781 } 02782 if (p->udptl) { 02783 if (option_debug) 02784 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02785 ast_udptl_setnat(p->udptl, natflags); 02786 } 02787 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15739 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.
15740 { 15741 time_t t = time(NULL); 15742 15743 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15744 !peer->mwipvt) { /* We don't have a subscription */ 15745 peer->lastmsgcheck = t; /* Reset timer */ 15746 return FALSE; 15747 } 15748 15749 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15750 return TRUE; 15751 15752 return FALSE; 15753 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10408 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10409 { 10410 switch (mode) { 10411 case SIP_DOMAIN_AUTO: 10412 return "[Automatic]"; 10413 case SIP_DOMAIN_CONFIG: 10414 return "[Configured]"; 10415 } 10416 10417 return ""; 10418 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10188 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().
10189 { 10190 switch (mode) { 10191 case SIP_DTMF_RFC2833: 10192 return "rfc2833"; 10193 case SIP_DTMF_INFO: 10194 return "info"; 10195 case SIP_DTMF_INBAND: 10196 return "inband"; 10197 case SIP_DTMF_AUTO: 10198 return "auto"; 10199 } 10200 return "<error>"; 10201 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7969 of file chan_sip.c.
References sip_peer::addr, ast_clear_flag, 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, SIP_PAGE2_SELFDESTRUCT, SIP_PAGE2_TCP_CONNECTED, and sip_peer::sockfd.
Referenced by parse_register_contact(), and reg_source_db().
07970 { 07971 struct sip_peer *peer = (struct sip_peer *)data; 07972 07973 if (!peer) /* Hmmm. We have no peer. Weird. */ 07974 return 0; 07975 07976 memset(&peer->addr, 0, sizeof(peer->addr)); 07977 if (peer->sockfd > 0) { 07978 close(peer->sockfd); 07979 ast_clear_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 07980 } 07981 07982 destroy_association(peer); /* remove registration data from storage */ 07983 07984 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07985 register_peer_exten(peer, FALSE); /* Remove regexten */ 07986 peer->expire = -1; 07987 ast_device_state_changed("SIP/%s", peer->name); 07988 07989 /* Do we need to release this peer from memory? 07990 Only for realtime peers and autocreated peers 07991 */ 07992 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07993 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07994 struct sip_peer *peer_ptr = peer_ptr; 07995 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 07996 if (peer_ptr) { 07997 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 07998 } 07999 } 08000 08001 ASTOBJ_UNREF(peer, sip_destroy_peer); 08002 08003 return 0; 08004 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6912 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().
06913 { 06914 char stripped[SIPBUFSIZE]; 06915 char *c; 06916 06917 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06918 c = get_in_brackets(stripped); 06919 c = strsep(&c, ";"); /* trim ; and beyond */ 06920 if (!ast_strlen_zero(c)) 06921 ast_string_field_set(p, uri, c); 06922 }
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 4271 of file chan_sip.c.
References aliases.
04272 { 04273 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04274 static const struct cfalias { 04275 char * const fullname; 04276 char * const shortname; 04277 } aliases[] = { 04278 { "Content-Type", "c" }, 04279 { "Content-Encoding", "e" }, 04280 { "From", "f" }, 04281 { "Call-ID", "i" }, 04282 { "Contact", "m" }, 04283 { "Content-Length", "l" }, 04284 { "Subject", "s" }, 04285 { "To", "t" }, 04286 { "Supported", "k" }, 04287 { "Refer-To", "r" }, 04288 { "Referred-By", "b" }, 04289 { "Allow-Events", "u" }, 04290 { "Event", "o" }, 04291 { "Via", "v" }, 04292 { "Accept-Contact", "a" }, 04293 { "Reject-Contact", "j" }, 04294 { "Request-Disposition", "d" }, 04295 { "Session-Expires", "x" }, 04296 { "Identity", "y" }, 04297 { "Identity-Info", "n" }, 04298 }; 04299 int x; 04300 04301 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04302 if (!strcasecmp(aliases[x].fullname, name)) 04303 return aliases[x].shortname; 04304 04305 return _default; 04306 }
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 4631 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().
04632 { 04633 struct sip_pvt *p = NULL; 04634 char *tag = ""; /* note, tag is never NULL */ 04635 char totag[128]; 04636 char fromtag[128]; 04637 const char *callid = get_header(req, "Call-ID"); 04638 const char *from = get_header(req, "From"); 04639 const char *to = get_header(req, "To"); 04640 const char *cseq = get_header(req, "Cseq"); 04641 04642 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04643 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04644 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04645 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04646 return NULL; /* Invalid packet */ 04647 04648 if (pedanticsipchecking) { 04649 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04650 we need more to identify a branch - so we have to check branch, from 04651 and to tags to identify a call leg. 04652 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04653 in sip.conf 04654 */ 04655 if (gettag(req, "To", totag, sizeof(totag))) 04656 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04657 gettag(req, "From", fromtag, sizeof(fromtag)); 04658 04659 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04660 04661 if (option_debug > 4 ) 04662 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); 04663 } 04664 04665 ast_mutex_lock(&iflock); 04666 for (p = iflist; p; p = p->next) { 04667 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04668 int found = FALSE; 04669 if (ast_strlen_zero(p->callid)) 04670 continue; 04671 if (req->method == SIP_REGISTER) 04672 found = (!strcmp(p->callid, callid)); 04673 else 04674 found = (!strcmp(p->callid, callid) && 04675 (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04676 04677 if (option_debug > 4) 04678 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); 04679 04680 /* If we get a new request within an existing to-tag - check the to tag as well */ 04681 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04682 if (p->tag[0] == '\0' && totag[0]) { 04683 /* We have no to tag, but they have. Wrong dialog */ 04684 found = FALSE; 04685 } else if (totag[0]) { /* Both have tags, compare them */ 04686 if (strcmp(totag, p->tag)) { 04687 found = FALSE; /* This is not our packet */ 04688 } 04689 } 04690 if (!found && option_debug > 4) 04691 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); 04692 } 04693 04694 04695 if (found) { 04696 /* Found the call */ 04697 ast_mutex_lock(&p->lock); 04698 ast_mutex_unlock(&iflock); 04699 return p; 04700 } 04701 } 04702 ast_mutex_unlock(&iflock); 04703 04704 /* See if the method is capable of creating a dialog */ 04705 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04706 if (intended_method == SIP_REFER) { 04707 /* We do support REFER, but not outside of a dialog yet */ 04708 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04709 } else if (intended_method == SIP_NOTIFY) { 04710 /* We do not support out-of-dialog NOTIFY either, 04711 like voicemail notification, so cancel that early */ 04712 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04713 } else { 04714 /* Ok, time to create a new SIP dialog object, a pvt */ 04715 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04716 /* Ok, we've created a dialog, let's go and process it */ 04717 ast_mutex_lock(&p->lock); 04718 } else { 04719 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04720 getting a dialog from sip_alloc. 04721 04722 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04723 send an error message. 04724 04725 Sorry, we apologize for the inconvienience 04726 */ 04727 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04728 if (option_debug > 3) 04729 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04730 } 04731 } 04732 return p; 04733 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04734 /* A method we do not support, let's take it on the volley */ 04735 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04736 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04737 /* This is a request outside of a dialog that we don't know about 04738 ...never reply to an ACK! 04739 */ 04740 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04741 } 04742 /* We do not respond to responses for dialogs that we don't know about, we just drop 04743 the session quickly */ 04744 04745 return p; 04746 }
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 2331 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02332 { 02333 char last_char = '\0'; 02334 const char *s; 02335 for (s = start; *s && s != lim; last_char = *s++) { 02336 if (*s == '"' && last_char != '\\') 02337 break; 02338 } 02339 return s; 02340 }
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 2680 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02681 { 02682 struct sip_peer *p = NULL; 02683 02684 if (peer) 02685 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02686 else 02687 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02688 02689 if (!p && realtime) 02690 p = realtime_peer(peer, sin); 02691 02692 return p; 02693 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 16568 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16569 { 16570 struct sip_auth *a; 16571 16572 for (a = authlist; a; a = a->next) { 16573 if (!strcasecmp(a->realm, realm)) 16574 break; 16575 } 16576 16577 return a; 16578 }
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 4952 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().
04953 { 04954 const char *content_type; 04955 const char *content_length; 04956 const char *search; 04957 char *boundary; 04958 unsigned int x; 04959 int boundaryisquoted = FALSE; 04960 int found_application_sdp = FALSE; 04961 int found_end_of_headers = FALSE; 04962 04963 content_length = get_header(req, "Content-Length"); 04964 04965 if (!ast_strlen_zero(content_length)) { 04966 if (sscanf(content_length, "%ud", &x) != 1) { 04967 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04968 return 0; 04969 } 04970 04971 /* Content-Length of zero means there can't possibly be an 04972 SDP here, even if the Content-Type says there is */ 04973 if (x == 0) 04974 return 0; 04975 } 04976 04977 content_type = get_header(req, "Content-Type"); 04978 04979 /* if the body contains only SDP, this is easy */ 04980 if (!strcasecmp(content_type, "application/sdp")) { 04981 req->sdp_start = 0; 04982 req->sdp_end = req->lines; 04983 return req->lines ? 1 : 0; 04984 } 04985 04986 /* if it's not multipart/mixed, there cannot be an SDP */ 04987 if (strncasecmp(content_type, "multipart/mixed", 15)) 04988 return 0; 04989 04990 /* if there is no boundary marker, it's invalid */ 04991 if ((search = strcasestr(content_type, ";boundary="))) 04992 search += 10; 04993 else if ((search = strcasestr(content_type, "; boundary="))) 04994 search += 11; 04995 else 04996 return 0; 04997 04998 if (ast_strlen_zero(search)) 04999 return 0; 05000 05001 /* If the boundary is quoted with ", remove quote */ 05002 if (*search == '\"') { 05003 search++; 05004 boundaryisquoted = TRUE; 05005 } 05006 05007 /* make a duplicate of the string, with two extra characters 05008 at the beginning */ 05009 boundary = ast_strdupa(search - 2); 05010 boundary[0] = boundary[1] = '-'; 05011 /* Remove final quote */ 05012 if (boundaryisquoted) 05013 boundary[strlen(boundary) - 1] = '\0'; 05014 05015 /* search for the boundary marker, the empty line delimiting headers from 05016 sdp part and the end boundry if it exists */ 05017 05018 for (x = 0; x < (req->lines ); x++) { 05019 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05020 if(found_application_sdp && found_end_of_headers){ 05021 req->sdp_end = x-1; 05022 return 1; 05023 } 05024 found_application_sdp = FALSE; 05025 } 05026 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05027 found_application_sdp = TRUE; 05028 05029 if(strlen(req->line[x]) == 0 ){ 05030 if(found_application_sdp && !found_end_of_headers){ 05031 req->sdp_start = x; 05032 found_end_of_headers = TRUE; 05033 } 05034 } 05035 } 05036 if(found_application_sdp && found_end_of_headers) { 05037 req->sdp_end = x; 05038 return TRUE; 05039 } 05040 return FALSE; 05041 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1683 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01684 { 01685 int i, res = 0; 01686 01687 if (ast_strlen_zero(msg)) 01688 return 0; 01689 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01690 if (method_match(i, msg)) 01691 res = sip_methods[i].id; 01692 } 01693 return res; 01694 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10897 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10898 { 10899 int i; 10900 10901 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10902 if (subscription_types[i].type == subtype) { 10903 return &subscription_types[i]; 10904 } 10905 } 10906 return &subscription_types[0]; 10907 }
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 2759 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02760 { 02761 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02762 if (!u && realtime) 02763 u = realtime_user(name); 02764 return u; 02765 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8340 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08341 { 08342 struct sip_route *next; 08343 08344 while (route) { 08345 next = route->next; 08346 free(route); 08347 route = next; 08348 } 08349 }
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 11915 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), and check_sip_domain().
11916 { 11917 if (ast_strlen_zero(data)) { 11918 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11919 return -1; 11920 } 11921 if (check_sip_domain(data, NULL, 0)) 11922 ast_copy_string(buf, data, len); 11923 else 11924 buf[0] = '\0'; 11925 return 0; 11926 }
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 11851 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.
11852 { 11853 struct sip_pvt *p; 11854 const char *content = NULL; 11855 AST_DECLARE_APP_ARGS(args, 11856 AST_APP_ARG(header); 11857 AST_APP_ARG(number); 11858 ); 11859 int i, number, start = 0; 11860 11861 if (ast_strlen_zero(data)) { 11862 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11863 return -1; 11864 } 11865 11866 ast_channel_lock(chan); 11867 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11868 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11869 ast_channel_unlock(chan); 11870 return -1; 11871 } 11872 11873 AST_STANDARD_APP_ARGS(args, data); 11874 if (!args.number) { 11875 number = 1; 11876 } else { 11877 sscanf(args.number, "%d", &number); 11878 if (number < 1) 11879 number = 1; 11880 } 11881 11882 p = chan->tech_pvt; 11883 11884 /* If there is no private structure, this channel is no longer alive */ 11885 if (!p) { 11886 ast_channel_unlock(chan); 11887 return -1; 11888 } 11889 11890 for (i = 0; i < number; i++) 11891 content = __get_header(&p->initreq, args.header, &start); 11892 11893 if (ast_strlen_zero(content)) { 11894 ast_channel_unlock(chan); 11895 return -1; 11896 } 11897 11898 ast_copy_string(buf, content, len); 11899 ast_channel_unlock(chan); 11900 11901 return 0; 11902 }
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 12030 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.
12031 { 12032 struct sip_pvt *p; 12033 12034 *buf = 0; 12035 12036 if (!data) { 12037 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12038 return -1; 12039 } 12040 12041 ast_channel_lock(chan); 12042 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12043 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12044 ast_channel_unlock(chan); 12045 return -1; 12046 } 12047 12048 p = chan->tech_pvt; 12049 12050 /* If there is no private structure, this channel is no longer alive */ 12051 if (!p) { 12052 ast_channel_unlock(chan); 12053 return -1; 12054 } 12055 12056 if (!strcasecmp(data, "peerip")) { 12057 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12058 } else if (!strcasecmp(data, "recvip")) { 12059 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12060 } else if (!strcasecmp(data, "from")) { 12061 ast_copy_string(buf, p->from, len); 12062 } else if (!strcasecmp(data, "uri")) { 12063 ast_copy_string(buf, p->uri, len); 12064 } else if (!strcasecmp(data, "useragent")) { 12065 ast_copy_string(buf, p->useragent, len); 12066 } else if (!strcasecmp(data, "peername")) { 12067 ast_copy_string(buf, p->peername, len); 12068 } else if (!strcasecmp(data, "t38passthrough")) { 12069 if (p->t38.state == T38_DISABLED) 12070 ast_copy_string(buf, "0", sizeof("0")); 12071 else /* T38 is offered or enabled in this call */ 12072 ast_copy_string(buf, "1", sizeof("1")); 12073 } else { 12074 ast_channel_unlock(chan); 12075 return -1; 12076 } 12077 ast_channel_unlock(chan); 12078 12079 return 0; 12080 }
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 11940 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.
11941 { 11942 struct sip_peer *peer; 11943 char *colname; 11944 11945 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11946 *colname++ = '\0'; 11947 else if ((colname = strchr(data, '|'))) 11948 *colname++ = '\0'; 11949 else 11950 colname = "ip"; 11951 11952 if (!(peer = find_peer(data, NULL, 1))) 11953 return -1; 11954 11955 if (!strcasecmp(colname, "ip")) { 11956 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11957 } else if (!strcasecmp(colname, "status")) { 11958 peer_status(peer, buf, len); 11959 } else if (!strcasecmp(colname, "language")) { 11960 ast_copy_string(buf, peer->language, len); 11961 } else if (!strcasecmp(colname, "regexten")) { 11962 ast_copy_string(buf, peer->regexten, len); 11963 } else if (!strcasecmp(colname, "limit")) { 11964 snprintf(buf, len, "%d", peer->call_limit); 11965 } else if (!strcasecmp(colname, "curcalls")) { 11966 snprintf(buf, len, "%d", peer->inUse); 11967 } else if (!strcasecmp(colname, "accountcode")) { 11968 ast_copy_string(buf, peer->accountcode, len); 11969 } else if (!strcasecmp(colname, "useragent")) { 11970 ast_copy_string(buf, peer->useragent, len); 11971 } else if (!strcasecmp(colname, "mailbox")) { 11972 ast_copy_string(buf, peer->mailbox, len); 11973 } else if (!strcasecmp(colname, "context")) { 11974 ast_copy_string(buf, peer->context, len); 11975 } else if (!strcasecmp(colname, "expire")) { 11976 snprintf(buf, len, "%d", peer->expire); 11977 } else if (!strcasecmp(colname, "dynamic")) { 11978 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11979 } else if (!strcasecmp(colname, "callerid_name")) { 11980 ast_copy_string(buf, peer->cid_name, len); 11981 } else if (!strcasecmp(colname, "callerid_num")) { 11982 ast_copy_string(buf, peer->cid_num, len); 11983 } else if (!strcasecmp(colname, "codecs")) { 11984 ast_getformatname_multiple(buf, len -1, peer->capability); 11985 } else if (!strncasecmp(colname, "codec[", 6)) { 11986 char *codecnum; 11987 int index = 0, codec = 0; 11988 11989 codecnum = colname + 6; /* move past the '[' */ 11990 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11991 index = atoi(codecnum); 11992 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11993 ast_copy_string(buf, ast_getformatname(codec), len); 11994 } 11995 } 11996 11997 ASTOBJ_UNREF(peer, sip_destroy_peer); 11998 11999 return 0; 12000 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4461 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04462 { 04463 long val[4]; 04464 int x; 04465 04466 for (x=0; x<4; x++) 04467 val[x] = ast_random(); 04468 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04469 04470 return buf; 04471 }
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 9263 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().
09264 { 09265 char tmp[256] = "", *c, *a; 09266 struct sip_request *req = oreq ? oreq : &p->initreq; 09267 struct sip_refer *referdata = NULL; 09268 const char *transfer_context = NULL; 09269 09270 if (!p->refer && !sip_refer_allocate(p)) 09271 return -1; 09272 09273 referdata = p->refer; 09274 09275 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09276 c = get_in_brackets(tmp); 09277 09278 if (pedanticsipchecking) 09279 ast_uri_decode(c); 09280 09281 if (strncasecmp(c, "sip:", 4)) { 09282 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09283 return -1; 09284 } 09285 c += 4; 09286 if ((a = strchr(c, ';'))) /* Remove arguments */ 09287 *a = '\0'; 09288 09289 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09290 *a++ = '\0'; 09291 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09292 } 09293 09294 if (sip_debug_test_pvt(p)) 09295 ast_verbose("Looking for %s in %s\n", c, p->context); 09296 09297 if (p->owner) /* Mimic behaviour in res_features.c */ 09298 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09299 09300 /* By default, use the context in the channel sending the REFER */ 09301 if (ast_strlen_zero(transfer_context)) { 09302 transfer_context = S_OR(p->owner->macrocontext, 09303 S_OR(p->context, default_context)); 09304 } 09305 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09306 /* This is a blind transfer */ 09307 if (option_debug) 09308 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09309 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09310 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09311 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09312 referdata->refer_call = NULL; 09313 /* Set new context */ 09314 ast_string_field_set(p, context, transfer_context); 09315 return 0; 09316 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09317 return 1; 09318 } 09319 09320 return -1; 09321 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4255 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04256 { 04257 int x; 04258 int len = strlen(name); 04259 char *r; 04260 04261 for (x = 0; x < req->lines; x++) { 04262 r = get_body_by_line(req->line[x], name, len); 04263 if (r[0] != '\0') 04264 return r; 04265 } 04266 04267 return ""; 04268 }
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 4221 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04222 { 04223 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04224 return ast_skip_blanks(line + nameLen + 1); 04225 04226 return ""; 04227 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9375 of file chan_sip.c.
Referenced by check_user_full().
09376 { 09377 const char *end = strchr(input,'<'); /* first_bracket */ 09378 const char *tmp = strchr(input,'"'); /* first quote */ 09379 int bytes = 0; 09380 int maxbytes = outputsize - 1; 09381 09382 if (!end || end == input) /* we require a part in brackets */ 09383 return NULL; 09384 09385 end--; /* move just before "<" */ 09386 09387 if (tmp && tmp <= end) { 09388 /* The quote (tmp) precedes the bracket (end+1). 09389 * Find the matching quote and return the content. 09390 */ 09391 end = strchr(tmp+1, '"'); 09392 if (!end) 09393 return NULL; 09394 bytes = (int) (end - tmp); 09395 /* protect the output buffer */ 09396 if (bytes > maxbytes) 09397 bytes = maxbytes; 09398 ast_copy_string(output, tmp + 1, bytes); 09399 } else { 09400 /* No quoted string, or it is inside brackets. */ 09401 /* clear the empty characters in the begining*/ 09402 input = ast_skip_blanks(input); 09403 /* clear the empty characters in the end */ 09404 while(*end && *end < 33 && end > input) 09405 end--; 09406 if (end >= input) { 09407 bytes = (int) (end - input) + 2; 09408 /* protect the output buffer */ 09409 if (bytes > maxbytes) 09410 bytes = maxbytes; 09411 ast_copy_string(output, input, bytes); 09412 } else 09413 return NULL; 09414 } 09415 return output; 09416 }
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 8920 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, and strsep().
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08921 { 08922 char tmp[256] = "", *uri, *a; 08923 char tmpf[256] = "", *from; 08924 struct sip_request *req; 08925 char *colon; 08926 08927 req = oreq; 08928 if (!req) 08929 req = &p->initreq; 08930 08931 /* Find the request URI */ 08932 if (req->rlPart2) 08933 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08934 08935 if (pedanticsipchecking) 08936 ast_uri_decode(tmp); 08937 08938 uri = get_in_brackets(tmp); 08939 08940 if (strncasecmp(uri, "sip:", 4)) { 08941 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08942 return -1; 08943 } 08944 uri += 4; 08945 08946 /* Now find the From: caller ID and name */ 08947 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08948 if (!ast_strlen_zero(tmpf)) { 08949 if (pedanticsipchecking) 08950 ast_uri_decode(tmpf); 08951 from = get_in_brackets(tmpf); 08952 } else { 08953 from = NULL; 08954 } 08955 08956 if (!ast_strlen_zero(from)) { 08957 if (strncasecmp(from, "sip:", 4)) { 08958 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08959 return -1; 08960 } 08961 from += 4; 08962 if ((a = strchr(from, '@'))) 08963 *a++ = '\0'; 08964 else 08965 a = from; /* just a domain */ 08966 from = strsep(&from, ";"); /* Remove userinfo options */ 08967 a = strsep(&a, ";"); /* Remove URI options */ 08968 ast_string_field_set(p, fromdomain, a); 08969 } 08970 08971 /* Skip any options and find the domain */ 08972 08973 /* Get the target domain */ 08974 if ((a = strchr(uri, '@'))) { 08975 *a++ = '\0'; 08976 } else { /* No username part */ 08977 a = uri; 08978 uri = "s"; /* Set extension to "s" */ 08979 } 08980 colon = strchr(a, ':'); /* Remove :port */ 08981 if (colon) 08982 *colon = '\0'; 08983 08984 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08985 a = strsep(&a, ";"); /* Remove URI options */ 08986 08987 ast_string_field_set(p, domain, a); 08988 08989 if (!AST_LIST_EMPTY(&domain_list)) { 08990 char domain_context[AST_MAX_EXTENSION]; 08991 08992 domain_context[0] = '\0'; 08993 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08994 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08995 if (option_debug) 08996 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08997 return -2; 08998 } 08999 } 09000 /* If we have a context defined, overwrite the original context */ 09001 if (!ast_strlen_zero(domain_context)) 09002 ast_string_field_set(p, context, domain_context); 09003 } 09004 09005 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09006 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09007 ast_string_field_set(p, context, p->subscribecontext); 09008 09009 if (sip_debug_test_pvt(p)) 09010 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09011 09012 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09013 if (req->method == SIP_SUBSCRIBE) { 09014 char hint[AST_MAX_EXTENSION]; 09015 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09016 } else { 09017 /* Check the dialplan for the username part of the request URI, 09018 the domain will be stored in the SIPDOMAIN variable 09019 Since extensions.conf can have unescaped characters, try matching a decoded 09020 uri in addition to the non-decoded uri 09021 Return 0 if we have a matching extension */ 09022 char *decoded_uri = ast_strdupa(uri); 09023 ast_uri_decode(decoded_uri); 09024 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)) || 09025 !strcmp(uri, ast_pickup_ext())) { 09026 if (!oreq) 09027 ast_string_field_set(p, exten, uri); 09028 return 0; 09029 } 09030 } 09031 09032 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09033 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09034 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 09035 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 09036 return 1; 09037 } 09038 09039 return -1; 09040 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4344 of file chan_sip.c.
References __get_header().
04345 { 04346 int start = 0; 04347 return __get_header(req, name, &start); 04348 }
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 2353 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().
02354 { 02355 const char *parse = tmp; 02356 char *first_bracket; 02357 02358 /* 02359 * Skip any quoted text until we find the part in brackets. 02360 * On any error give up and return the full string. 02361 */ 02362 while ( (first_bracket = strchr(parse, '<')) ) { 02363 char *first_quote = strchr(parse, '"'); 02364 02365 if (!first_quote || first_quote > first_bracket) 02366 break; /* no need to look at quoted part */ 02367 /* the bracket is within quotes, so ignore it */ 02368 parse = find_closing_quote(first_quote + 1, NULL); 02369 if (!*parse) { /* not found, return full string ? */ 02370 /* XXX or be robust and return in-bracket part ? */ 02371 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02372 break; 02373 } 02374 parse++; 02375 } 02376 if (first_bracket) { 02377 char *second_bracket = strchr(first_bracket + 1, '>'); 02378 if (second_bracket) { 02379 *second_bracket = '\0'; 02380 tmp = first_bracket + 1; 02381 } else { 02382 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02383 } 02384 } 02385 return tmp; 02386 }
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 9781 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09782 { 09783 int x; 09784 int y; 09785 09786 buf[0] = '\0'; 09787 y = len - strlen(buf) - 5; 09788 if (y < 0) 09789 y = 0; 09790 for (x=0;x<req->lines;x++) { 09791 strncat(buf, req->line[x], y); /* safe */ 09792 y -= strlen(req->line[x]) + 1; 09793 if (y < 0) 09794 y = 0; 09795 if (y != 0) 09796 strcat(buf, "\n"); /* safe */ 09797 } 09798 return 0; 09799 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8891 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().
08892 { 08893 char tmp[256], *c, *a; 08894 struct sip_request *req; 08895 08896 req = oreq; 08897 if (!req) 08898 req = &p->initreq; 08899 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08900 if (ast_strlen_zero(tmp)) 08901 return 0; 08902 c = get_in_brackets(tmp); 08903 if (strncasecmp(c, "sip:", 4)) { 08904 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08905 return -1; 08906 } 08907 c += 4; 08908 a = c; 08909 strsep(&a, "@;"); /* trim anything after @ or ; */ 08910 if (sip_debug_test_pvt(p)) 08911 ast_verbose("RDNIS is %s\n", c); 08912 ast_string_field_set(p, rdnis, c); 08913 08914 return 0; 08915 }
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 9097 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().
09098 { 09099 09100 const char *p_referred_by = NULL; 09101 char *h_refer_to = NULL; 09102 char *h_referred_by = NULL; 09103 char *refer_to; 09104 const char *p_refer_to; 09105 char *referred_by_uri = NULL; 09106 char *ptr; 09107 struct sip_request *req = NULL; 09108 const char *transfer_context = NULL; 09109 struct sip_refer *referdata; 09110 09111 09112 req = outgoing_req; 09113 referdata = transferer->refer; 09114 09115 if (!req) 09116 req = &transferer->initreq; 09117 09118 p_refer_to = get_header(req, "Refer-To"); 09119 if (ast_strlen_zero(p_refer_to)) { 09120 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09121 return -2; /* Syntax error */ 09122 } 09123 h_refer_to = ast_strdupa(p_refer_to); 09124 refer_to = get_in_brackets(h_refer_to); 09125 if (pedanticsipchecking) 09126 ast_uri_decode(refer_to); 09127 09128 if (strncasecmp(refer_to, "sip:", 4)) { 09129 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09130 return -3; 09131 } 09132 refer_to += 4; /* Skip sip: */ 09133 09134 /* Get referred by header if it exists */ 09135 p_referred_by = get_header(req, "Referred-By"); 09136 if (!ast_strlen_zero(p_referred_by)) { 09137 char *lessthan; 09138 h_referred_by = ast_strdupa(p_referred_by); 09139 if (pedanticsipchecking) 09140 ast_uri_decode(h_referred_by); 09141 09142 /* Store referrer's caller ID name */ 09143 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09144 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09145 *(lessthan - 1) = '\0'; /* Space */ 09146 } 09147 09148 referred_by_uri = get_in_brackets(h_referred_by); 09149 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09150 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09151 referred_by_uri = (char *) NULL; 09152 } else { 09153 referred_by_uri += 4; /* Skip sip: */ 09154 } 09155 } 09156 09157 /* Check for arguments in the refer_to header */ 09158 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09159 *ptr++ = '\0'; 09160 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09161 char *to = NULL, *from = NULL; 09162 09163 /* This is an attended transfer */ 09164 referdata->attendedtransfer = 1; 09165 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09166 ast_uri_decode(referdata->replaces_callid); 09167 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09168 *ptr++ = '\0'; 09169 } 09170 09171 if (ptr) { 09172 /* Find the different tags before we destroy the string */ 09173 to = strcasestr(ptr, "to-tag="); 09174 from = strcasestr(ptr, "from-tag="); 09175 } 09176 09177 /* Grab the to header */ 09178 if (to) { 09179 ptr = to + 7; 09180 if ((to = strchr(ptr, '&'))) 09181 *to = '\0'; 09182 if ((to = strchr(ptr, ';'))) 09183 *to = '\0'; 09184 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09185 } 09186 09187 if (from) { 09188 ptr = from + 9; 09189 if ((to = strchr(ptr, '&'))) 09190 *to = '\0'; 09191 if ((to = strchr(ptr, ';'))) 09192 *to = '\0'; 09193 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09194 } 09195 09196 if (option_debug > 1) { 09197 if (!pedanticsipchecking) 09198 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09199 else 09200 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>" ); 09201 } 09202 } 09203 } 09204 09205 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09206 char *urioption = NULL, *domain; 09207 *ptr++ = '\0'; 09208 09209 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09210 *urioption++ = '\0'; 09211 09212 domain = ptr; 09213 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09214 *ptr = '\0'; 09215 09216 /* Save the domain for the dial plan */ 09217 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09218 if (urioption) 09219 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09220 } 09221 09222 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09223 *ptr = '\0'; 09224 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09225 09226 if (referred_by_uri) { 09227 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09228 *ptr = '\0'; 09229 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09230 } else { 09231 referdata->referred_by[0] = '\0'; 09232 } 09233 09234 /* Determine transfer context */ 09235 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09236 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09237 09238 /* By default, use the context in the channel sending the REFER */ 09239 if (ast_strlen_zero(transfer_context)) { 09240 transfer_context = S_OR(transferer->owner->macrocontext, 09241 S_OR(transferer->context, default_context)); 09242 } 09243 09244 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09245 09246 /* Either an existing extension or the parking extension */ 09247 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09248 if (sip_debug_test_pvt(transferer)) { 09249 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09250 } 09251 /* We are ready to transfer to the extension */ 09252 return 0; 09253 } 09254 if (sip_debug_test_pvt(transferer)) 09255 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09256 09257 /* Failure, we can't find this extension */ 09258 return -1; 09259 }
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 9422 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09423 { 09424 char *start; 09425 char *end; 09426 09427 start = strchr(input,':'); 09428 if (!start) { 09429 output[0] = '\0'; 09430 return 0; 09431 } 09432 start++; 09433 09434 /* we found "number" */ 09435 ast_copy_string(output,start,maxlen); 09436 output[maxlen-1] = '\0'; 09437 09438 end = strchr(output,'@'); 09439 if (end) 09440 *end = '\0'; 09441 else 09442 output[0] = '\0'; 09443 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09444 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09445 09446 return 0; 09447 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4247 of file chan_sip.c.
References get_sdp_iterate().
04248 { 04249 int dummy = 0; 04250 04251 return get_sdp_iterate(&dummy, req, name); 04252 }
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 4233 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04234 { 04235 int len = strlen(name); 04236 04237 while (*start < req->sdp_end) { 04238 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04239 if (r[0] != '\0') 04240 return r; 04241 } 04242 04243 return ""; 04244 }
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 9047 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().
09048 { 09049 struct sip_pvt *sip_pvt_ptr; 09050 09051 ast_mutex_lock(&iflock); 09052 09053 if (option_debug > 3 && totag) 09054 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09055 09056 /* Search interfaces and find the match */ 09057 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09058 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09059 int match = 1; 09060 char *ourtag = sip_pvt_ptr->tag; 09061 09062 /* Go ahead and lock it (and its owner) before returning */ 09063 ast_mutex_lock(&sip_pvt_ptr->lock); 09064 09065 /* Check if tags match. If not, this is not the call we want 09066 (With a forking SIP proxy, several call legs share the 09067 call id, but have different tags) 09068 */ 09069 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 09070 match = 0; 09071 09072 if (!match) { 09073 ast_mutex_unlock(&sip_pvt_ptr->lock); 09074 continue; 09075 } 09076 09077 if (option_debug > 3 && totag) 09078 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09079 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 09080 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09081 09082 /* deadlock avoidance... */ 09083 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09084 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09085 } 09086 break; 09087 } 09088 } 09089 ast_mutex_unlock(&iflock); 09090 if (option_debug > 3 && !sip_pvt_ptr) 09091 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09092 return sip_pvt_ptr; 09093 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13484 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13485 { 13486 const char *thetag; 13487 13488 if (!tagbuf) 13489 return NULL; 13490 tagbuf[0] = '\0'; /* reset the buffer */ 13491 thetag = get_header(req, header); 13492 thetag = strcasestr(thetag, ";tag="); 13493 if (thetag) { 13494 thetag += 5; 13495 ast_copy_string(tagbuf, thetag, tagbufsize); 13496 return strsep(&tagbuf, ";"); 13497 } 13498 return NULL; 13499 }
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 16317 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().
16318 { 16319 int res = 1; 16320 16321 if (!strcasecmp(v->name, "trustrpid")) { 16322 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16323 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16324 } else if (!strcasecmp(v->name, "sendrpid")) { 16325 ast_set_flag(&mask[0], SIP_SENDRPID); 16326 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16327 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16328 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16329 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16330 } else if (!strcasecmp(v->name, "useclientcode")) { 16331 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16332 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16333 } else if (!strcasecmp(v->name, "dtmfmode")) { 16334 ast_set_flag(&mask[0], SIP_DTMF); 16335 ast_clear_flag(&flags[0], SIP_DTMF); 16336 if (!strcasecmp(v->value, "inband")) 16337 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16338 else if (!strcasecmp(v->value, "rfc2833")) 16339 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16340 else if (!strcasecmp(v->value, "info")) 16341 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16342 else if (!strcasecmp(v->value, "auto")) 16343 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16344 else { 16345 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16346 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16347 } 16348 } else if (!strcasecmp(v->name, "nat")) { 16349 ast_set_flag(&mask[0], SIP_NAT); 16350 ast_clear_flag(&flags[0], SIP_NAT); 16351 if (!strcasecmp(v->value, "never")) 16352 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16353 else if (!strcasecmp(v->value, "route")) 16354 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16355 else if (ast_true(v->value)) 16356 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16357 else 16358 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16359 } else if (!strcasecmp(v->name, "canreinvite")) { 16360 ast_set_flag(&mask[0], SIP_REINVITE); 16361 ast_clear_flag(&flags[0], SIP_REINVITE); 16362 if(ast_true(v->value)) { 16363 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16364 } else if (!ast_false(v->value)) { 16365 char buf[64]; 16366 char *word, *next = buf; 16367 16368 ast_copy_string(buf, v->value, sizeof(buf)); 16369 while ((word = strsep(&next, ","))) { 16370 if(!strcasecmp(word, "update")) { 16371 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16372 } else if(!strcasecmp(word, "nonat")) { 16373 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16374 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16375 } else { 16376 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16377 } 16378 } 16379 } 16380 } else if (!strcasecmp(v->name, "insecure")) { 16381 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16382 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16383 set_insecure_flags(flags, v->value, v->lineno); 16384 } else if (!strcasecmp(v->name, "progressinband")) { 16385 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16386 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16387 if (ast_true(v->value)) 16388 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16389 else if (strcasecmp(v->value, "never")) 16390 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16391 } else if (!strcasecmp(v->name, "promiscredir")) { 16392 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16393 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16394 } else if (!strcasecmp(v->name, "videosupport")) { 16395 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16396 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16397 } else if (!strcasecmp(v->name, "allowoverlap")) { 16398 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16399 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16400 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16401 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16402 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16403 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16404 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16405 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16406 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16407 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16408 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16409 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16410 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16411 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16412 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16413 #endif 16414 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16415 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16416 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16417 } else if (!strcasecmp(v->name, "buggymwi")) { 16418 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16419 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16420 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16421 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16422 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16423 } else 16424 res = 0; 16425 16426 return res; 16427 }
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 13663 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().
13664 { 13665 struct ast_frame *f; 13666 int earlyreplace = 0; 13667 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13668 struct ast_channel *c = p->owner; /* Our incoming call */ 13669 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13670 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13671 13672 /* Check if we're in ring state */ 13673 if (replacecall->_state == AST_STATE_RING) 13674 earlyreplace = 1; 13675 13676 /* Check if we have a bridge */ 13677 if (!(targetcall = ast_bridged_channel(replacecall))) { 13678 /* We have no bridge */ 13679 if (!earlyreplace) { 13680 if (option_debug > 1) 13681 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13682 oneleggedreplace = 1; 13683 } 13684 } 13685 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13686 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13687 13688 if (option_debug > 3) { 13689 if (targetcall) 13690 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); 13691 else 13692 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13693 } 13694 13695 if (ignore) { 13696 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13697 /* We should answer something here. If we are here, the 13698 call we are replacing exists, so an accepted 13699 can't harm */ 13700 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13701 /* Do something more clever here */ 13702 ast_channel_unlock(c); 13703 ast_mutex_unlock(&p->refer->refer_call->lock); 13704 return 1; 13705 } 13706 if (!c) { 13707 /* What to do if no channel ??? */ 13708 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13709 transmit_response_reliable(p, "503 Service Unavailable", req); 13710 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13711 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13712 ast_mutex_unlock(&p->refer->refer_call->lock); 13713 return 1; 13714 } 13715 append_history(p, "Xfer", "INVITE/Replace received"); 13716 /* We have three channels to play with 13717 channel c: New incoming call 13718 targetcall: Call from PBX to target 13719 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13720 replacecall: The owner of the previous 13721 We need to masq C into refer_call to connect to 13722 targetcall; 13723 If we are talking to internal audio stream, target call is null. 13724 */ 13725 13726 /* Fake call progress */ 13727 transmit_response(p, "100 Trying", req); 13728 ast_setstate(c, AST_STATE_RING); 13729 13730 /* Masquerade the new call into the referred call to connect to target call 13731 Targetcall is not touched by the masq */ 13732 13733 /* Answer the incoming call and set channel to UP state */ 13734 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13735 13736 ast_setstate(c, AST_STATE_UP); 13737 13738 /* Stop music on hold and other generators */ 13739 ast_quiet_chan(replacecall); 13740 ast_quiet_chan(targetcall); 13741 if (option_debug > 3) 13742 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13743 /* Unlock clone, but not original (replacecall) */ 13744 if (!oneleggedreplace) 13745 ast_channel_unlock(c); 13746 13747 /* Unlock PVT */ 13748 ast_mutex_unlock(&p->refer->refer_call->lock); 13749 13750 /* Make sure that the masq does not free our PVT for the old call */ 13751 if (! earlyreplace && ! oneleggedreplace ) 13752 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13753 13754 /* Prepare the masquerade - if this does not happen, we will be gone */ 13755 if(ast_channel_masquerade(replacecall, c)) 13756 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13757 else if (option_debug > 3) 13758 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13759 13760 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13761 13762 /* C should now be in place of replacecall */ 13763 /* ast_read needs to lock channel */ 13764 ast_channel_unlock(c); 13765 13766 if (earlyreplace || oneleggedreplace ) { 13767 /* Force the masq to happen */ 13768 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13769 ast_frfree(f); 13770 f = NULL; 13771 if (option_debug > 3) 13772 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13773 } else { 13774 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13775 } 13776 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13777 if (!oneleggedreplace) 13778 ast_channel_unlock(replacecall); 13779 } else { /* Bridged call, UP channel */ 13780 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13781 /* Masq ok */ 13782 ast_frfree(f); 13783 f = NULL; 13784 if (option_debug > 2) 13785 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13786 } else { 13787 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13788 } 13789 ast_channel_unlock(replacecall); 13790 } 13791 ast_mutex_unlock(&p->refer->refer_call->lock); 13792 13793 ast_setstate(c, AST_STATE_DOWN); 13794 if (option_debug > 3) { 13795 struct ast_channel *test; 13796 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13797 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13798 if (replacecall) 13799 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13800 if (p->owner) { 13801 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13802 test = ast_bridged_channel(p->owner); 13803 if (test) 13804 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13805 else 13806 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13807 } else 13808 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13809 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13810 } 13811 13812 ast_channel_unlock(p->owner); /* Unlock new owner */ 13813 if (!oneleggedreplace) 13814 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13815 13816 /* The call should be down with no ast_channel, so hang it up */ 13817 c->tech_pvt = NULL; 13818 ast_hangup(c); 13819 return 0; 13820 }
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 15333 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.
15334 { 15335 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15336 relatively static */ 15337 const char *cmd; 15338 const char *cseq; 15339 const char *useragent; 15340 int seqno; 15341 int len; 15342 int ignore = FALSE; 15343 int respid; 15344 int res = 0; 15345 int debug = sip_debug_test_pvt(p); 15346 char *e; 15347 int error = 0; 15348 15349 /* Get Method and Cseq */ 15350 cseq = get_header(req, "Cseq"); 15351 cmd = req->header[0]; 15352 15353 /* Must have Cseq */ 15354 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15355 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15356 error = 1; 15357 } 15358 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15359 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15360 error = 1; 15361 } 15362 if (error) { 15363 if (!p->initreq.headers) /* New call */ 15364 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15365 return -1; 15366 } 15367 /* Get the command XXX */ 15368 15369 cmd = req->rlPart1; 15370 e = req->rlPart2; 15371 15372 /* Save useragent of the client */ 15373 useragent = get_header(req, "User-Agent"); 15374 if (!ast_strlen_zero(useragent)) 15375 ast_string_field_set(p, useragent, useragent); 15376 15377 /* Find out SIP method for incoming request */ 15378 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15379 /* Response to our request -- Do some sanity checks */ 15380 if (!p->initreq.headers) { 15381 if (option_debug) 15382 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15383 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15384 return 0; 15385 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15386 if (option_debug) 15387 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15388 return -1; 15389 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15390 /* ignore means "don't do anything with it" but still have to 15391 respond appropriately */ 15392 ignore = TRUE; 15393 ast_set_flag(req, SIP_PKT_IGNORE); 15394 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15395 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15396 } else if (e) { 15397 e = ast_skip_blanks(e); 15398 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15399 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15400 } else { 15401 if (respid <= 0) { 15402 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15403 return 0; 15404 } 15405 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15406 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15407 extract_uri(p, req); 15408 handle_response(p, respid, e + len, req, ignore, seqno); 15409 } 15410 } 15411 return 0; 15412 } 15413 15414 /* New SIP request coming in 15415 (could be new request in existing SIP dialog as well...) 15416 */ 15417 15418 p->method = req->method; /* Find out which SIP method they are using */ 15419 if (option_debug > 3) 15420 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15421 15422 if (p->icseq && (p->icseq > seqno) ) { 15423 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15424 if (option_debug > 2) 15425 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15426 } else { 15427 if (option_debug) 15428 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15429 if (req->method != SIP_ACK) 15430 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15431 return -1; 15432 } 15433 } else if (p->icseq && 15434 p->icseq == seqno && 15435 req->method != SIP_ACK && 15436 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15437 /* ignore means "don't do anything with it" but still have to 15438 respond appropriately. We do this if we receive a repeat of 15439 the last sequence number */ 15440 ignore = 2; 15441 ast_set_flag(req, SIP_PKT_IGNORE); 15442 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15443 if (option_debug > 2) 15444 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15445 } 15446 15447 if (seqno >= p->icseq) 15448 /* Next should follow monotonically (but not necessarily 15449 incrementally -- thanks again to the genius authors of SIP -- 15450 increasing */ 15451 p->icseq = seqno; 15452 15453 /* Find their tag if we haven't got it */ 15454 if (ast_strlen_zero(p->theirtag)) { 15455 char tag[128]; 15456 15457 gettag(req, "From", tag, sizeof(tag)); 15458 ast_string_field_set(p, theirtag, tag); 15459 } 15460 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15461 15462 if (pedanticsipchecking) { 15463 /* If this is a request packet without a from tag, it's not 15464 correct according to RFC 3261 */ 15465 /* Check if this a new request in a new dialog with a totag already attached to it, 15466 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15467 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15468 /* If this is a first request and it got a to-tag, it is not for us */ 15469 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15470 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15471 /* Will cease to exist after ACK */ 15472 } else if (req->method != SIP_ACK) { 15473 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15474 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15475 } 15476 return res; 15477 } 15478 } 15479 15480 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15481 transmit_response(p, "400 Bad request", req); 15482 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15483 return -1; 15484 } 15485 15486 /* Handle various incoming SIP methods in requests */ 15487 switch (p->method) { 15488 case SIP_OPTIONS: 15489 res = handle_request_options(p, req); 15490 break; 15491 case SIP_INVITE: 15492 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15493 break; 15494 case SIP_REFER: 15495 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15496 break; 15497 case SIP_CANCEL: 15498 res = handle_request_cancel(p, req); 15499 break; 15500 case SIP_BYE: 15501 res = handle_request_bye(p, req); 15502 break; 15503 case SIP_MESSAGE: 15504 res = handle_request_message(p, req); 15505 break; 15506 case SIP_SUBSCRIBE: 15507 res = handle_request_subscribe(p, req, sin, seqno, e); 15508 break; 15509 case SIP_REGISTER: 15510 res = handle_request_register(p, req, sin, e); 15511 break; 15512 case SIP_INFO: 15513 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15514 ast_verbose("Receiving INFO!\n"); 15515 if (!ignore) 15516 handle_request_info(p, req); 15517 else /* if ignoring, transmit response */ 15518 transmit_response(p, "200 OK", req); 15519 break; 15520 case SIP_NOTIFY: 15521 res = handle_request_notify(p, req, sin, seqno, e); 15522 break; 15523 case SIP_ACK: 15524 /* Make sure we don't ignore this */ 15525 if (seqno == p->pendinginvite) { 15526 p->invitestate = INV_TERMINATED; 15527 p->pendinginvite = 0; 15528 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15529 if (find_sdp(req)) { 15530 if (process_sdp(p, req)) 15531 return -1; 15532 } 15533 check_pendings(p); 15534 } 15535 /* Got an ACK that we did not match. Ignore silently */ 15536 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15537 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15538 break; 15539 default: 15540 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15541 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15542 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15543 /* If this is some new method, and we don't have a call, destroy it now */ 15544 if (!p->initreq.headers) 15545 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15546 break; 15547 } 15548 return res; 15549 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14898 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().
14899 { 14900 struct ast_channel *c=NULL; 14901 int res; 14902 struct ast_channel *bridged_to; 14903 14904 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14905 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14906 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14907 14908 p->invitestate = INV_TERMINATED; 14909 14910 copy_request(&p->initreq, req); 14911 check_via(p, req); 14912 sip_alreadygone(p); 14913 14914 /* Get RTCP quality before end of call */ 14915 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14916 char *audioqos, *videoqos; 14917 if (p->rtp) { 14918 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14919 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14920 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14921 if (p->owner) 14922 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14923 } 14924 if (p->vrtp) { 14925 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14926 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14927 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14928 if (p->owner) 14929 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14930 } 14931 } 14932 14933 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14934 14935 if (!ast_strlen_zero(get_header(req, "Also"))) { 14936 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14937 ast_inet_ntoa(p->recv.sin_addr)); 14938 if (ast_strlen_zero(p->context)) 14939 ast_string_field_set(p, context, default_context); 14940 res = get_also_info(p, req); 14941 if (!res) { 14942 c = p->owner; 14943 if (c) { 14944 bridged_to = ast_bridged_channel(c); 14945 if (bridged_to) { 14946 /* Don't actually hangup here... */ 14947 ast_queue_control(c, AST_CONTROL_UNHOLD); 14948 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14949 } else 14950 ast_queue_hangup(p->owner); 14951 } 14952 } else { 14953 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14954 if (p->owner) 14955 ast_queue_hangup(p->owner); 14956 } 14957 } else if (p->owner) { 14958 ast_queue_hangup(p->owner); 14959 if (option_debug > 2) 14960 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14961 } else { 14962 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14963 if (option_debug > 2) 14964 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14965 } 14966 transmit_response(p, "200 OK", req); 14967 14968 return 1; 14969 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14792 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().
14793 { 14794 14795 check_via(p, req); 14796 sip_alreadygone(p); 14797 14798 /* At this point, we could have cancelled the invite at the same time 14799 as the other side sends a CANCEL. Our final reply with error code 14800 might not have been received by the other side before the CANCEL 14801 was sent, so let's just give up retransmissions and waiting for 14802 ACK on our error code. The call is hanging up any way. */ 14803 if (p->invitestate == INV_TERMINATED) 14804 __sip_pretend_ack(p); 14805 else 14806 p->invitestate = INV_CANCELLED; 14807 14808 if (p->owner && p->owner->_state == AST_STATE_UP) { 14809 /* This call is up, cancel is ignored, we need a bye */ 14810 transmit_response(p, "200 OK", req); 14811 if (option_debug) 14812 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14813 return 0; 14814 } 14815 14816 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14817 update_call_counter(p, DEC_CALL_LIMIT); 14818 14819 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14820 if (p->owner) 14821 ast_queue_hangup(p->owner); 14822 else 14823 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14824 if (p->initreq.len > 0) { 14825 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14826 transmit_response(p, "200 OK", req); 14827 return 1; 14828 } else { 14829 transmit_response(p, "481 Call Leg Does Not Exist", req); 14830 return 0; 14831 } 14832 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11257 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().
11258 { 11259 char buf[1024]; 11260 unsigned int event; 11261 const char *c = get_header(req, "Content-Type"); 11262 11263 /* Need to check the media/type */ 11264 if (!strcasecmp(c, "application/dtmf-relay") || 11265 !strcasecmp(c, "application/DTMF") || 11266 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11267 unsigned int duration = 0; 11268 11269 /* Try getting the "signal=" part */ 11270 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11271 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11272 transmit_response(p, "200 OK", req); /* Should return error */ 11273 return; 11274 } else { 11275 ast_copy_string(buf, c, sizeof(buf)); 11276 } 11277 11278 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11279 duration = atoi(c); 11280 if (!duration) 11281 duration = 100; /* 100 ms */ 11282 11283 if (!p->owner) { /* not a PBX call */ 11284 transmit_response(p, "481 Call leg/transaction does not exist", req); 11285 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11286 return; 11287 } 11288 11289 if (ast_strlen_zero(buf)) { 11290 transmit_response(p, "200 OK", req); 11291 return; 11292 } 11293 11294 if (buf[0] == '*') 11295 event = 10; 11296 else if (buf[0] == '#') 11297 event = 11; 11298 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11299 event = 12 + buf[0] - 'A'; 11300 else 11301 event = atoi(buf); 11302 if (event == 16) { 11303 /* send a FLASH event */ 11304 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11305 ast_queue_frame(p->owner, &f); 11306 if (sipdebug) 11307 ast_verbose("* DTMF-relay event received: FLASH\n"); 11308 } else { 11309 /* send a DTMF event */ 11310 struct ast_frame f = { AST_FRAME_DTMF, }; 11311 if (event < 10) { 11312 f.subclass = '0' + event; 11313 } else if (event < 11) { 11314 f.subclass = '*'; 11315 } else if (event < 12) { 11316 f.subclass = '#'; 11317 } else if (event < 16) { 11318 f.subclass = 'A' + (event - 12); 11319 } 11320 f.len = duration; 11321 ast_queue_frame(p->owner, &f); 11322 if (sipdebug) 11323 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11324 } 11325 transmit_response(p, "200 OK", req); 11326 return; 11327 } else if (!strcasecmp(c, "application/media_control+xml")) { 11328 /* Eh, we'll just assume it's a fast picture update for now */ 11329 if (p->owner) 11330 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11331 transmit_response(p, "200 OK", req); 11332 return; 11333 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11334 /* Client code (from SNOM phone) */ 11335 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11336 if (p->owner && p->owner->cdr) 11337 ast_cdr_setuserfield(p->owner, c); 11338 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11339 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11340 transmit_response(p, "200 OK", req); 11341 } else { 11342 transmit_response(p, "403 Unauthorized", req); 11343 } 11344 return; 11345 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11346 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11347 transmit_response(p, "200 OK", req); 11348 return; 11349 } 11350 11351 /* Other type of INFO message, not really understood by Asterisk */ 11352 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11353 11354 /* Nothing in the header is interesting, now check if content-length is 0 */ 11355 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11356 transmit_response(p, "200 OK", req); 11357 return; 11358 } /* else ... there issomething in the message body, do something with it if you need to */ 11359 11360 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11361 transmit_response(p, "415 Unsupported media type", req); 11362 return; 11363 }
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 13829 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().
13830 { 13831 int res = 1; 13832 int gotdest; 13833 const char *p_replaces; 13834 char *replace_id = NULL; 13835 const char *required; 13836 unsigned int required_profile = 0; 13837 struct ast_channel *c = NULL; /* New channel */ 13838 int reinvite = 0; 13839 13840 /* Find out what they support */ 13841 if (!p->sipoptions) { 13842 const char *supported = get_header(req, "Supported"); 13843 if (!ast_strlen_zero(supported)) 13844 parse_sip_options(p, supported); 13845 } 13846 13847 /* Find out what they require */ 13848 required = get_header(req, "Require"); 13849 if (!ast_strlen_zero(required)) { 13850 required_profile = parse_sip_options(NULL, required); 13851 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13852 /* At this point we only support REPLACES */ 13853 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13854 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13855 p->invitestate = INV_COMPLETED; 13856 if (!p->lastinvite) 13857 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13858 return -1; 13859 } 13860 } 13861 13862 /* Check if this is a loop */ 13863 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13864 /* This is a call to ourself. Send ourselves an error code and stop 13865 processing immediately, as SIP really has no good mechanism for 13866 being able to call yourself */ 13867 /* If pedantic is on, we need to check the tags. If they're different, this is 13868 in fact a forked call through a SIP proxy somewhere. */ 13869 transmit_response(p, "482 Loop Detected", req); 13870 p->invitestate = INV_COMPLETED; 13871 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13872 return 0; 13873 } 13874 13875 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13876 /* We already have a pending invite. Sorry. You are on hold. */ 13877 transmit_response(p, "491 Request Pending", req); 13878 if (option_debug) 13879 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13880 /* Don't destroy dialog here */ 13881 return 0; 13882 } 13883 13884 p_replaces = get_header(req, "Replaces"); 13885 if (!ast_strlen_zero(p_replaces)) { 13886 /* We have a replaces header */ 13887 char *ptr; 13888 char *fromtag = NULL; 13889 char *totag = NULL; 13890 char *start, *to; 13891 int error = 0; 13892 13893 if (p->owner) { 13894 if (option_debug > 2) 13895 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13896 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13897 /* Do not destroy existing call */ 13898 return -1; 13899 } 13900 13901 if (sipdebug && option_debug > 2) 13902 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13903 /* Create a buffer we can manipulate */ 13904 replace_id = ast_strdupa(p_replaces); 13905 ast_uri_decode(replace_id); 13906 13907 if (!p->refer && !sip_refer_allocate(p)) { 13908 transmit_response(p, "500 Server Internal Error", req); 13909 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13910 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13911 p->invitestate = INV_COMPLETED; 13912 return -1; 13913 } 13914 13915 /* Todo: (When we find phones that support this) 13916 if the replaces header contains ";early-only" 13917 we can only replace the call in early 13918 stage, not after it's up. 13919 13920 If it's not in early mode, 486 Busy. 13921 */ 13922 13923 /* Skip leading whitespace */ 13924 replace_id = ast_skip_blanks(replace_id); 13925 13926 start = replace_id; 13927 while ( (ptr = strsep(&start, ";")) ) { 13928 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13929 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13930 totag = to + 7; /* skip the keyword */ 13931 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13932 fromtag = to + 9; /* skip the keyword */ 13933 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13934 } 13935 } 13936 13937 if (sipdebug && option_debug > 3) 13938 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>"); 13939 13940 13941 /* Try to find call that we are replacing 13942 If we have a Replaces header, we need to cancel that call if we succeed with this call 13943 */ 13944 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13945 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13946 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13947 error = 1; 13948 } 13949 13950 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13951 13952 /* The matched call is the call from the transferer to Asterisk . 13953 We want to bridge the bridged part of the call to the 13954 incoming invite, thus taking over the refered call */ 13955 13956 if (p->refer->refer_call == p) { 13957 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13958 p->refer->refer_call = NULL; 13959 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13960 error = 1; 13961 } 13962 13963 if (!error && !p->refer->refer_call->owner) { 13964 /* Oops, someting wrong anyway, no owner, no call */ 13965 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13966 /* Check for better return code */ 13967 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13968 error = 1; 13969 } 13970 13971 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 ) { 13972 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13973 transmit_response(p, "603 Declined (Replaces)", req); 13974 error = 1; 13975 } 13976 13977 if (error) { /* Give up this dialog */ 13978 append_history(p, "Xfer", "INVITE/Replace Failed."); 13979 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13980 ast_mutex_unlock(&p->lock); 13981 if (p->refer->refer_call) { 13982 ast_mutex_unlock(&p->refer->refer_call->lock); 13983 ast_channel_unlock(p->refer->refer_call->owner); 13984 } 13985 p->invitestate = INV_COMPLETED; 13986 return -1; 13987 } 13988 } 13989 13990 13991 /* Check if this is an INVITE that sets up a new dialog or 13992 a re-invite in an existing dialog */ 13993 13994 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13995 int newcall = (p->initreq.headers ? TRUE : FALSE); 13996 13997 if (sip_cancel_destroy(p)) 13998 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13999 /* This also counts as a pending invite */ 14000 p->pendinginvite = seqno; 14001 check_via(p, req); 14002 14003 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14004 if (!p->owner) { /* Not a re-invite */ 14005 if (debug) 14006 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14007 if (newcall) 14008 append_history(p, "Invite", "New call: %s", p->callid); 14009 parse_ok_contact(p, req); 14010 } else { /* Re-invite on existing call */ 14011 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14012 /* Handle SDP here if we already have an owner */ 14013 if (find_sdp(req)) { 14014 if (process_sdp(p, req)) { 14015 transmit_response(p, "488 Not acceptable here", req); 14016 if (!p->lastinvite) 14017 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14018 return -1; 14019 } 14020 } else { 14021 p->jointcapability = p->capability; 14022 if (option_debug > 2) 14023 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14024 /* Some devices signal they want to be put off hold by sending a re-invite 14025 *without* an SDP, which is supposed to mean "Go back to your state" 14026 and since they put os on remote hold, we go back to off hold */ 14027 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14028 change_hold_state(p, req, FALSE, 0); 14029 } 14030 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14031 append_history(p, "ReInv", "Re-invite received"); 14032 } 14033 } else if (debug) 14034 ast_verbose("Ignoring this INVITE request\n"); 14035 14036 14037 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14038 /* This is a new invite */ 14039 /* Handle authentication if this is our first invite */ 14040 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14041 if (res == AUTH_CHALLENGE_SENT) { 14042 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14043 return 0; 14044 } 14045 if (res < 0) { /* Something failed in authentication */ 14046 if (res == AUTH_FAKE_AUTH) { 14047 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14048 transmit_fake_auth_response(p, req, 1); 14049 } else { 14050 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14051 transmit_response_reliable(p, "403 Forbidden", req); 14052 } 14053 p->invitestate = INV_COMPLETED; 14054 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14055 ast_string_field_free(p, theirtag); 14056 return 0; 14057 } 14058 14059 /* We have a succesful authentication, process the SDP portion if there is one */ 14060 if (find_sdp(req)) { 14061 if (process_sdp(p, req)) { 14062 /* Unacceptable codecs */ 14063 transmit_response_reliable(p, "488 Not acceptable here", req); 14064 p->invitestate = INV_COMPLETED; 14065 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14066 if (option_debug) 14067 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14068 return -1; 14069 } 14070 } else { /* No SDP in invite, call control session */ 14071 p->jointcapability = p->capability; 14072 if (option_debug > 1) 14073 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14074 } 14075 14076 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14077 /* This seems redundant ... see !p-owner above */ 14078 if (p->owner) 14079 ast_queue_frame(p->owner, &ast_null_frame); 14080 14081 14082 /* Initialize the context if it hasn't been already */ 14083 if (ast_strlen_zero(p->context)) 14084 ast_string_field_set(p, context, default_context); 14085 14086 14087 /* Check number of concurrent calls -vs- incoming limit HERE */ 14088 if (option_debug) 14089 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14090 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14091 if (res < 0) { 14092 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14093 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14094 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14095 p->invitestate = INV_COMPLETED; 14096 } 14097 return 0; 14098 } 14099 gotdest = get_destination(p, NULL); /* Get destination right away */ 14100 get_rdnis(p, NULL); /* Get redirect information */ 14101 extract_uri(p, req); /* Get the Contact URI */ 14102 build_contact(p); /* Build our contact header */ 14103 14104 if (p->rtp) { 14105 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14106 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14107 } 14108 14109 if (!replace_id && gotdest) { /* No matching extension found */ 14110 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14111 transmit_response_reliable(p, "484 Address Incomplete", req); 14112 else { 14113 transmit_response_reliable(p, "404 Not Found", req); 14114 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14115 " '%s' rejected because extension not found.\n", 14116 S_OR(p->username, p->peername), p->exten); 14117 } 14118 p->invitestate = INV_COMPLETED; 14119 update_call_counter(p, DEC_CALL_LIMIT); 14120 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14121 return 0; 14122 } else { 14123 /* If no extension was specified, use the s one */ 14124 /* Basically for calling to IP/Host name only */ 14125 if (ast_strlen_zero(p->exten)) 14126 ast_string_field_set(p, exten, "s"); 14127 /* Initialize our tag */ 14128 14129 make_our_tag(p->tag, sizeof(p->tag)); 14130 /* First invitation - create the channel */ 14131 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14132 *recount = 1; 14133 14134 /* Save Record-Route for any later requests we make on this dialogue */ 14135 build_route(p, req, 0); 14136 14137 if (c) { 14138 /* Pre-lock the call */ 14139 ast_channel_lock(c); 14140 } 14141 } 14142 } else { 14143 if (option_debug > 1 && sipdebug) { 14144 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14145 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14146 else 14147 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14148 } 14149 reinvite = 1; 14150 c = p->owner; 14151 } 14152 14153 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14154 p->lastinvite = seqno; 14155 14156 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14157 /* Go and take over the target call */ 14158 if (sipdebug && option_debug > 3) 14159 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14160 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14161 } 14162 14163 14164 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14165 switch(c->_state) { 14166 case AST_STATE_DOWN: 14167 if (option_debug > 1) 14168 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14169 transmit_response(p, "100 Trying", req); 14170 p->invitestate = INV_PROCEEDING; 14171 ast_setstate(c, AST_STATE_RING); 14172 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14173 enum ast_pbx_result res; 14174 14175 res = ast_pbx_start(c); 14176 14177 switch(res) { 14178 case AST_PBX_FAILED: 14179 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14180 p->invitestate = INV_COMPLETED; 14181 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14182 transmit_response(p, "503 Unavailable", req); 14183 else 14184 transmit_response_reliable(p, "503 Unavailable", req); 14185 break; 14186 case AST_PBX_CALL_LIMIT: 14187 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14188 p->invitestate = INV_COMPLETED; 14189 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14190 transmit_response(p, "480 Temporarily Unavailable", req); 14191 else 14192 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14193 break; 14194 case AST_PBX_SUCCESS: 14195 /* nothing to do */ 14196 break; 14197 } 14198 14199 if (res) { 14200 14201 /* Unlock locks so ast_hangup can do its magic */ 14202 ast_mutex_unlock(&c->lock); 14203 ast_mutex_unlock(&p->lock); 14204 ast_hangup(c); 14205 ast_mutex_lock(&p->lock); 14206 c = NULL; 14207 } 14208 } else { /* Pickup call in call group */ 14209 ast_channel_unlock(c); 14210 *nounlock = 1; 14211 if (ast_pickup_call(c)) { 14212 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14213 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14214 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14215 else 14216 transmit_response_reliable(p, "503 Unavailable", req); 14217 sip_alreadygone(p); 14218 /* Unlock locks so ast_hangup can do its magic */ 14219 ast_mutex_unlock(&p->lock); 14220 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14221 } else { 14222 ast_mutex_unlock(&p->lock); 14223 ast_setstate(c, AST_STATE_DOWN); 14224 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14225 } 14226 p->invitestate = INV_COMPLETED; 14227 ast_hangup(c); 14228 ast_mutex_lock(&p->lock); 14229 c = NULL; 14230 } 14231 break; 14232 case AST_STATE_RING: 14233 transmit_response(p, "100 Trying", req); 14234 p->invitestate = INV_PROCEEDING; 14235 break; 14236 case AST_STATE_RINGING: 14237 transmit_response(p, "180 Ringing", req); 14238 p->invitestate = INV_PROCEEDING; 14239 break; 14240 case AST_STATE_UP: 14241 if (option_debug > 1) 14242 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14243 14244 transmit_response(p, "100 Trying", req); 14245 14246 if (p->t38.state == T38_PEER_REINVITE) { 14247 struct ast_channel *bridgepeer = NULL; 14248 struct sip_pvt *bridgepvt = NULL; 14249 14250 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14251 /* 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*/ 14252 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14253 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14254 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14255 if (bridgepvt->t38.state == T38_DISABLED) { 14256 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14257 /* Send re-invite to the bridged channel */ 14258 sip_handle_t38_reinvite(bridgepeer, p, 1); 14259 } else { /* Something is wrong with peers udptl struct */ 14260 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14261 ast_mutex_lock(&bridgepvt->lock); 14262 bridgepvt->t38.state = T38_DISABLED; 14263 ast_mutex_unlock(&bridgepvt->lock); 14264 if (option_debug > 1) 14265 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14266 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14267 transmit_response(p, "488 Not acceptable here", req); 14268 else 14269 transmit_response_reliable(p, "488 Not acceptable here", req); 14270 14271 } 14272 } else { 14273 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14274 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14275 p->t38.state = T38_ENABLED; 14276 if (option_debug) 14277 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14278 } 14279 } else { 14280 /* Other side is not a SIP channel */ 14281 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14282 transmit_response(p, "488 Not acceptable here", req); 14283 else 14284 transmit_response_reliable(p, "488 Not acceptable here", req); 14285 p->t38.state = T38_DISABLED; 14286 if (option_debug > 1) 14287 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14288 14289 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14290 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14291 } 14292 } else { 14293 /* we are not bridged in a call */ 14294 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14295 p->t38.state = T38_ENABLED; 14296 if (option_debug) 14297 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14298 } 14299 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14300 int sendok = TRUE; 14301 14302 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14303 /* so handle it here (re-invite other party to RTP) */ 14304 struct ast_channel *bridgepeer = NULL; 14305 struct sip_pvt *bridgepvt = NULL; 14306 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14307 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14308 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14309 /* Does the bridged peer have T38 ? */ 14310 if (bridgepvt->t38.state == T38_ENABLED) { 14311 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14312 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14313 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14314 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14315 else 14316 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14317 sendok = FALSE; 14318 } 14319 /* No bridged peer with T38 enabled*/ 14320 } 14321 } 14322 /* Respond to normal re-invite */ 14323 if (sendok) 14324 /* If this is not a re-invite or something to ignore - it's critical */ 14325 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14326 } 14327 p->invitestate = INV_TERMINATED; 14328 break; 14329 default: 14330 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14331 transmit_response(p, "100 Trying", req); 14332 break; 14333 } 14334 } else { 14335 if (p && (p->autokillid == -1)) { 14336 const char *msg; 14337 14338 if (!p->jointcapability) 14339 msg = "488 Not Acceptable Here (codec error)"; 14340 else { 14341 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14342 msg = "503 Unavailable"; 14343 } 14344 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14345 transmit_response(p, msg, req); 14346 else 14347 transmit_response_reliable(p, msg, req); 14348 p->invitestate = INV_COMPLETED; 14349 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14350 } 14351 } 14352 return res; 14353 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14972 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().
14973 { 14974 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14975 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14976 ast_verbose("Receiving message!\n"); 14977 receive_message(p, req); 14978 } else 14979 transmit_response(p, "202 Accepted", req); 14980 return 1; 14981 }
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 13502 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().
13503 { 13504 /* This is mostly a skeleton for future improvements */ 13505 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13506 int res = 0; 13507 const char *event = get_header(req, "Event"); 13508 char *eventid = NULL; 13509 char *sep; 13510 13511 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13512 *sep++ = '\0'; 13513 eventid = sep; 13514 } 13515 13516 if (option_debug > 1 && sipdebug) 13517 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13518 13519 if (strcmp(event, "refer")) { 13520 /* We don't understand this event. */ 13521 /* Here's room to implement incoming voicemail notifications :-) */ 13522 transmit_response(p, "489 Bad event", req); 13523 res = -1; 13524 } else { 13525 /* Save nesting depth for now, since there might be other events we will 13526 support in the future */ 13527 13528 /* Handle REFER notifications */ 13529 13530 char buf[1024]; 13531 char *cmd, *code; 13532 int respcode; 13533 int success = TRUE; 13534 13535 /* EventID for each transfer... EventID is basically the REFER cseq 13536 13537 We are getting notifications on a call that we transfered 13538 We should hangup when we are getting a 200 OK in a sipfrag 13539 Check if we have an owner of this event */ 13540 13541 /* Check the content type */ 13542 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13543 /* We need a sipfrag */ 13544 transmit_response(p, "400 Bad request", req); 13545 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13546 return -1; 13547 } 13548 13549 /* Get the text of the attachment */ 13550 if (get_msg_text(buf, sizeof(buf), req)) { 13551 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13552 transmit_response(p, "400 Bad request", req); 13553 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13554 return -1; 13555 } 13556 13557 /* 13558 From the RFC... 13559 A minimal, but complete, implementation can respond with a single 13560 NOTIFY containing either the body: 13561 SIP/2.0 100 Trying 13562 13563 if the subscription is pending, the body: 13564 SIP/2.0 200 OK 13565 if the reference was successful, the body: 13566 SIP/2.0 503 Service Unavailable 13567 if the reference failed, or the body: 13568 SIP/2.0 603 Declined 13569 13570 if the REFER request was accepted before approval to follow the 13571 reference could be obtained and that approval was subsequently denied 13572 (see Section 2.4.7). 13573 13574 If there are several REFERs in the same dialog, we need to 13575 match the ID of the event header... 13576 */ 13577 if (option_debug > 2) 13578 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13579 cmd = ast_skip_blanks(buf); 13580 code = cmd; 13581 /* We are at SIP/2.0 */ 13582 while(*code && (*code > 32)) { /* Search white space */ 13583 code++; 13584 } 13585 *code++ = '\0'; 13586 code = ast_skip_blanks(code); 13587 sep = code; 13588 sep++; 13589 while(*sep && (*sep > 32)) { /* Search white space */ 13590 sep++; 13591 } 13592 *sep++ = '\0'; /* Response string */ 13593 respcode = atoi(code); 13594 switch (respcode) { 13595 case 100: /* Trying: */ 13596 case 101: /* dialog establishment */ 13597 /* Don't do anything yet */ 13598 break; 13599 case 183: /* Ringing: */ 13600 /* Don't do anything yet */ 13601 break; 13602 case 200: /* OK: The new call is up, hangup this call */ 13603 /* Hangup the call that we are replacing */ 13604 break; 13605 case 301: /* Moved permenantly */ 13606 case 302: /* Moved temporarily */ 13607 /* Do we get the header in the packet in this case? */ 13608 success = FALSE; 13609 break; 13610 case 503: /* Service Unavailable: The new call failed */ 13611 /* Cancel transfer, continue the call */ 13612 success = FALSE; 13613 break; 13614 case 603: /* Declined: Not accepted */ 13615 /* Cancel transfer, continue the current call */ 13616 success = FALSE; 13617 break; 13618 } 13619 if (!success) { 13620 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13621 } 13622 13623 /* Confirm that we received this packet */ 13624 transmit_response(p, "200 OK", req); 13625 }; 13626 13627 if (!p->lastinvite) 13628 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13629 13630 return res; 13631 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13634 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().
13635 { 13636 int res; 13637 13638 res = get_destination(p, req); 13639 build_contact(p); 13640 13641 /* XXX Should we authenticate OPTIONS? XXX */ 13642 13643 if (ast_strlen_zero(p->context)) 13644 ast_string_field_set(p, context, default_context); 13645 13646 if (ast_shutting_down()) 13647 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13648 else if (res < 0) 13649 transmit_response_with_allow(p, "404 Not Found", req, 0); 13650 else 13651 transmit_response_with_allow(p, "200 OK", req, 0); 13652 13653 /* Destroy if this OPTIONS was the opening request, but not if 13654 it's in the middle of a normal call flow. */ 13655 if (!p->lastinvite) 13656 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13657 13658 return res; 13659 }
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 14521 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().
14522 { 14523 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14524 /* Chan2: Call between asterisk and transferee */ 14525 14526 int res = 0; 14527 14528 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14529 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"); 14530 14531 if (!p->owner) { 14532 /* This is a REFER outside of an existing SIP dialog */ 14533 /* We can't handle that, so decline it */ 14534 if (option_debug > 2) 14535 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14536 transmit_response(p, "603 Declined (No dialog)", req); 14537 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14538 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14539 sip_alreadygone(p); 14540 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14541 } 14542 return 0; 14543 } 14544 14545 14546 /* Check if transfer is allowed from this device */ 14547 if (p->allowtransfer == TRANSFER_CLOSED ) { 14548 /* Transfer not allowed, decline */ 14549 transmit_response(p, "603 Declined (policy)", req); 14550 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14551 /* Do not destroy SIP session */ 14552 return 0; 14553 } 14554 14555 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14556 /* Already have a pending REFER */ 14557 transmit_response(p, "491 Request pending", req); 14558 append_history(p, "Xfer", "Refer failed. Request pending."); 14559 return 0; 14560 } 14561 14562 /* Allocate memory for call transfer data */ 14563 if (!p->refer && !sip_refer_allocate(p)) { 14564 transmit_response(p, "500 Internal Server Error", req); 14565 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14566 return -3; 14567 } 14568 14569 res = get_refer_info(p, req); /* Extract headers */ 14570 14571 p->refer->status = REFER_SENT; 14572 14573 if (res != 0) { 14574 switch (res) { 14575 case -2: /* Syntax error */ 14576 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14577 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14578 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14579 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14580 break; 14581 case -3: 14582 transmit_response(p, "603 Declined (Non sip: uri)", req); 14583 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14584 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14585 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14586 break; 14587 default: 14588 /* Refer-to extension not found, fake a failed transfer */ 14589 transmit_response(p, "202 Accepted", req); 14590 append_history(p, "Xfer", "Refer failed. Bad extension."); 14591 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14592 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14593 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14594 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14595 break; 14596 } 14597 return 0; 14598 } 14599 if (ast_strlen_zero(p->context)) 14600 ast_string_field_set(p, context, default_context); 14601 14602 /* If we do not support SIP domains, all transfers are local */ 14603 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14604 p->refer->localtransfer = 1; 14605 if (sipdebug && option_debug > 2) 14606 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14607 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14608 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14609 p->refer->localtransfer = 1; 14610 } else if (sipdebug && option_debug > 2) 14611 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14612 14613 /* Is this a repeat of a current request? Ignore it */ 14614 /* Don't know what else to do right now. */ 14615 if (ignore) 14616 return res; 14617 14618 /* If this is a blind transfer, we have the following 14619 channels to work with: 14620 - chan1, chan2: The current call between transferer and transferee (2 channels) 14621 - target_channel: A new call from the transferee to the target (1 channel) 14622 We need to stay tuned to what happens in order to be able 14623 to bring back the call to the transferer */ 14624 14625 /* If this is a attended transfer, we should have all call legs within reach: 14626 - chan1, chan2: The call between the transferer and transferee (2 channels) 14627 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14628 We want to bridge chan2 with targetcall_pvt! 14629 14630 The replaces call id in the refer message points 14631 to the call leg between Asterisk and the transferer. 14632 So we need to connect the target and the transferee channel 14633 and hangup the two other channels silently 14634 14635 If the target is non-local, the call ID could be on a remote 14636 machine and we need to send an INVITE with replaces to the 14637 target. We basically handle this as a blind transfer 14638 and let the sip_call function catch that we need replaces 14639 header in the INVITE. 14640 */ 14641 14642 14643 /* Get the transferer's channel */ 14644 current.chan1 = p->owner; 14645 14646 /* Find the other part of the bridge (2) - transferee */ 14647 current.chan2 = ast_bridged_channel(current.chan1); 14648 14649 if (sipdebug && option_debug > 2) 14650 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>"); 14651 14652 if (!current.chan2 && !p->refer->attendedtransfer) { 14653 /* No bridged channel, propably IVR or echo or similar... */ 14654 /* Guess we should masquerade or something here */ 14655 /* Until we figure it out, refuse transfer of such calls */ 14656 if (sipdebug && option_debug > 2) 14657 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14658 p->refer->status = REFER_FAILED; 14659 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14660 transmit_response(p, "603 Declined", req); 14661 return -1; 14662 } 14663 14664 if (current.chan2) { 14665 if (sipdebug && option_debug > 3) 14666 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14667 14668 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14669 } 14670 14671 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14672 14673 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14674 if (p->refer->attendedtransfer) { 14675 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14676 return res; /* We're done with the transfer */ 14677 /* Fall through for remote transfers that we did not find locally */ 14678 if (sipdebug && option_debug > 3) 14679 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14680 /* Fallthrough if we can't find the call leg internally */ 14681 } 14682 14683 14684 /* Parking a call */ 14685 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14686 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14687 *nounlock = 1; 14688 ast_channel_unlock(current.chan1); 14689 copy_request(¤t.req, req); 14690 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14691 p->refer->status = REFER_200OK; 14692 append_history(p, "Xfer", "REFER to call parking."); 14693 if (sipdebug && option_debug > 3) 14694 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14695 sip_park(current.chan2, current.chan1, req, seqno); 14696 return res; 14697 } 14698 14699 /* Blind transfers and remote attended xfers */ 14700 transmit_response(p, "202 Accepted", req); 14701 14702 if (current.chan1 && current.chan2) { 14703 if (option_debug > 2) 14704 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14705 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14706 } 14707 if (current.chan2) { 14708 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14709 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14710 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14711 /* One for the new channel */ 14712 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14713 /* Attended transfer to remote host, prepare headers for the INVITE */ 14714 if (p->refer->referred_by) 14715 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14716 } 14717 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14718 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14719 char tempheader[SIPBUFSIZE]; 14720 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14721 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14722 p->refer->replaces_callid_totag, 14723 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14724 p->refer->replaces_callid_fromtag); 14725 if (current.chan2) 14726 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14727 } 14728 /* Must release lock now, because it will not longer 14729 be accessible after the transfer! */ 14730 *nounlock = 1; 14731 ast_channel_unlock(current.chan1); 14732 14733 /* Connect the call */ 14734 14735 /* FAKE ringing if not attended transfer */ 14736 if (!p->refer->attendedtransfer) 14737 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14738 14739 /* For blind transfer, this will lead to a new call */ 14740 /* For attended transfer to remote host, this will lead to 14741 a new SIP call with a replaces header, if the dial plan allows it 14742 */ 14743 if (!current.chan2) { 14744 /* We have no bridge, so we're talking with Asterisk somehow */ 14745 /* We need to masquerade this call */ 14746 /* What to do to fix this situation: 14747 * Set up the new call in a new channel 14748 * Let the new channel masq into this channel 14749 Please add that code here :-) 14750 */ 14751 p->refer->status = REFER_FAILED; 14752 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14753 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14754 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14755 return -1; 14756 } 14757 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14758 14759 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14760 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14761 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14762 14763 if (!res) { 14764 /* Success - we have a new channel */ 14765 if (option_debug > 2) 14766 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14767 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14768 if (p->refer->localtransfer) 14769 p->refer->status = REFER_200OK; 14770 if (p->owner) 14771 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14772 append_history(p, "Xfer", "Refer succeeded."); 14773 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14774 /* Do not hangup call, the other side do that when we say 200 OK */ 14775 /* We could possibly implement a timer here, auto congestion */ 14776 res = 0; 14777 } else { 14778 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14779 if (option_debug > 2) 14780 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14781 append_history(p, "Xfer", "Refer failed."); 14782 /* Failure of some kind */ 14783 p->refer->status = REFER_FAILED; 14784 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14785 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14786 res = -1; 14787 } 14788 return res; 14789 }
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 15280 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().
15281 { 15282 enum check_auth_result res; 15283 15284 /* Use this as the basis */ 15285 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15286 ast_verbose("Using latest REGISTER request as basis request\n"); 15287 copy_request(&p->initreq, req); 15288 check_via(p, req); 15289 if ((res = register_verify(p, sin, req, e)) < 0) { 15290 const char *reason; 15291 15292 switch (res) { 15293 case AUTH_SECRET_FAILED: 15294 reason = "Wrong password"; 15295 break; 15296 case AUTH_USERNAME_MISMATCH: 15297 reason = "Username/auth name mismatch"; 15298 break; 15299 case AUTH_NOT_FOUND: 15300 reason = "No matching peer found"; 15301 break; 15302 case AUTH_UNKNOWN_DOMAIN: 15303 reason = "Not a local domain"; 15304 break; 15305 case AUTH_PEER_NOT_DYNAMIC: 15306 reason = "Peer is not supposed to register"; 15307 break; 15308 case AUTH_ACL_FAILED: 15309 reason = "Device does not match ACL"; 15310 break; 15311 default: 15312 reason = "Unknown failure"; 15313 break; 15314 } 15315 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15316 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15317 reason); 15318 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15319 } else 15320 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15321 15322 if (res < 1) { 15323 /* Destroy the session, but keep us around for just a bit in case they don't 15324 get our 200 OK */ 15325 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15326 } 15327 return res; 15328 }
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 14984 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().
14985 { 14986 int gotdest; 14987 int res = 0; 14988 int firststate = AST_EXTENSION_REMOVED; 14989 struct sip_peer *authpeer = NULL; 14990 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14991 const char *accept = get_header(req, "Accept"); 14992 int resubscribe = (p->subscribed != NONE); 14993 char *temp, *event; 14994 14995 if (p->initreq.headers) { 14996 /* We already have a dialog */ 14997 if (p->initreq.method != SIP_SUBSCRIBE) { 14998 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14999 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15000 transmit_response(p, "403 Forbidden (within dialog)", req); 15001 /* Do not destroy session, since we will break the call if we do */ 15002 if (option_debug) 15003 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); 15004 return 0; 15005 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15006 if (option_debug) { 15007 if (resubscribe) 15008 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15009 else 15010 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15011 } 15012 } 15013 } 15014 15015 /* Check if we have a global disallow setting on subscriptions. 15016 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15017 */ 15018 if (!global_allowsubscribe) { 15019 transmit_response(p, "403 Forbidden (policy)", req); 15020 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15021 return 0; 15022 } 15023 15024 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15025 const char *to = get_header(req, "To"); 15026 char totag[128]; 15027 15028 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15029 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15030 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15031 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15032 transmit_response(p, "481 Subscription does not exist", req); 15033 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15034 return 0; 15035 } 15036 15037 /* Use this as the basis */ 15038 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15039 ast_verbose("Creating new subscription\n"); 15040 15041 copy_request(&p->initreq, req); 15042 check_via(p, req); 15043 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15044 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15045 15046 /* Find parameters to Event: header value and remove them for now */ 15047 if (ast_strlen_zero(eventheader)) { 15048 transmit_response(p, "489 Bad Event", req); 15049 if (option_debug > 1) 15050 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15051 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15052 return 0; 15053 } 15054 15055 if ( (strchr(eventheader, ';'))) { 15056 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15057 temp = strchr(event, ';'); 15058 *temp = '\0'; /* Remove any options for now */ 15059 /* We might need to use them later :-) */ 15060 } else 15061 event = (char *) eventheader; /* XXX is this legal ? */ 15062 15063 /* Handle authentication */ 15064 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15065 /* if an authentication response was sent, we are done here */ 15066 if (res == AUTH_CHALLENGE_SENT) { 15067 if (authpeer) 15068 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15069 return 0; 15070 } 15071 if (res < 0) { 15072 if (res == AUTH_FAKE_AUTH) { 15073 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15074 transmit_fake_auth_response(p, req, 1); 15075 } else { 15076 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15077 transmit_response_reliable(p, "403 Forbidden", req); 15078 } 15079 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15080 if (authpeer) 15081 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15082 return 0; 15083 } 15084 15085 /* Check if this user/peer is allowed to subscribe at all */ 15086 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15087 transmit_response(p, "403 Forbidden (policy)", req); 15088 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15089 if (authpeer) 15090 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15091 return 0; 15092 } 15093 15094 /* Get destination right away */ 15095 gotdest = get_destination(p, NULL); 15096 15097 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15098 parse_ok_contact(p, req); 15099 15100 build_contact(p); 15101 if (strcmp(event, "message-summary") && gotdest) { 15102 transmit_response(p, "404 Not Found", req); 15103 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15104 if (authpeer) 15105 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15106 return 0; 15107 } 15108 15109 /* Initialize tag for new subscriptions */ 15110 if (ast_strlen_zero(p->tag)) 15111 make_our_tag(p->tag, sizeof(p->tag)); 15112 15113 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15114 if (authpeer) /* No need for authpeer here */ 15115 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15116 15117 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15118 /* Polycom phones only handle xpidf+xml, even if they say they can 15119 handle pidf+xml as well 15120 */ 15121 if (strstr(p->useragent, "Polycom")) { 15122 p->subscribed = XPIDF_XML; 15123 } else if (strstr(accept, "application/pidf+xml")) { 15124 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15125 } else if (strstr(accept, "application/dialog-info+xml")) { 15126 p->subscribed = DIALOG_INFO_XML; 15127 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15128 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15129 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15130 } else if (strstr(accept, "application/xpidf+xml")) { 15131 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15132 } else if (ast_strlen_zero(accept)) { 15133 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15134 transmit_response(p, "489 Bad Event", req); 15135 15136 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15137 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15138 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15139 return 0; 15140 } 15141 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15142 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15143 } else { 15144 /* Can't find a format for events that we know about */ 15145 char mybuf[200]; 15146 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15147 transmit_response(p, mybuf, req); 15148 15149 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15150 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15151 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15152 return 0; 15153 } 15154 } else if (!strcmp(event, "message-summary")) { 15155 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15156 /* Format requested that we do not support */ 15157 transmit_response(p, "406 Not Acceptable", req); 15158 if (option_debug > 1) 15159 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15160 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15161 if (authpeer) /* No need for authpeer here */ 15162 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15163 return 0; 15164 } 15165 /* Looks like they actually want a mailbox status 15166 This version of Asterisk supports mailbox subscriptions 15167 The subscribed URI needs to exist in the dial plan 15168 In most devices, this is configurable to the voicemailmain extension you use 15169 */ 15170 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15171 transmit_response(p, "404 Not found (no mailbox)", req); 15172 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15173 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15174 if (authpeer) /* No need for authpeer here */ 15175 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15176 return 0; 15177 } 15178 15179 p->subscribed = MWI_NOTIFICATION; 15180 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15181 /* We only allow one subscription per peer */ 15182 sip_destroy(authpeer->mwipvt); 15183 authpeer->mwipvt = p; /* Link from peer to pvt */ 15184 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15185 } else { /* At this point, Asterisk does not understand the specified event */ 15186 transmit_response(p, "489 Bad Event", req); 15187 if (option_debug > 1) 15188 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15189 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15190 if (authpeer) /* No need for authpeer here */ 15191 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15192 return 0; 15193 } 15194 15195 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15196 if (p->stateid > -1) 15197 ast_extension_state_del(p->stateid, cb_extensionstate); 15198 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15199 } 15200 15201 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15202 p->lastinvite = seqno; 15203 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15204 p->expiry = atoi(get_header(req, "Expires")); 15205 15206 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15207 if (p->expiry > max_expiry) 15208 p->expiry = max_expiry; 15209 if (p->expiry < min_expiry && p->expiry > 0) 15210 p->expiry = min_expiry; 15211 15212 if (sipdebug || option_debug > 1) { 15213 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15214 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15215 else 15216 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15217 } 15218 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15219 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15220 if (p->expiry > 0) 15221 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15222 15223 if (p->subscribed == MWI_NOTIFICATION) { 15224 transmit_response(p, "200 OK", req); 15225 if (p->relatedpeer) { /* Send first notification */ 15226 ASTOBJ_WRLOCK(p->relatedpeer); 15227 sip_send_mwi_to_peer(p->relatedpeer); 15228 ASTOBJ_UNLOCK(p->relatedpeer); 15229 } 15230 } else { 15231 struct sip_pvt *p_old; 15232 15233 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15234 15235 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)); 15236 transmit_response(p, "404 Not found", req); 15237 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15238 return 0; 15239 } 15240 15241 transmit_response(p, "200 OK", req); 15242 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15243 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15244 /* hide the 'complete' exten/context in the refer_to field for later display */ 15245 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15246 15247 /* remove any old subscription from this peer for the same exten/context, 15248 as the peer has obviously forgotten about it and it's wasteful to wait 15249 for it to expire and send NOTIFY messages to the peer only to have them 15250 ignored (or generate errors) 15251 */ 15252 ast_mutex_lock(&iflock); 15253 for (p_old = iflist; p_old; p_old = p_old->next) { 15254 if (p_old == p) 15255 continue; 15256 if (p_old->initreq.method != SIP_SUBSCRIBE) 15257 continue; 15258 if (p_old->subscribed == NONE) 15259 continue; 15260 ast_mutex_lock(&p_old->lock); 15261 if (!strcmp(p_old->username, p->username)) { 15262 if (!strcmp(p_old->exten, p->exten) && 15263 !strcmp(p_old->context, p->context)) { 15264 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15265 ast_mutex_unlock(&p_old->lock); 15266 break; 15267 } 15268 } 15269 ast_mutex_unlock(&p_old->lock); 15270 } 15271 ast_mutex_unlock(&iflock); 15272 } 15273 if (!p->expiry) 15274 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15275 } 15276 return 1; 15277 }
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 12787 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.
12788 { 12789 struct ast_channel *owner; 12790 int sipmethod; 12791 int res = 1; 12792 const char *c = get_header(req, "Cseq"); 12793 const char *msg = strchr(c, ' '); 12794 12795 if (!msg) 12796 msg = ""; 12797 else 12798 msg++; 12799 sipmethod = find_sip_method(msg); 12800 12801 owner = p->owner; 12802 if (owner) 12803 owner->hangupcause = hangup_sip2cause(resp); 12804 12805 /* Acknowledge whatever it is destined for */ 12806 if ((resp >= 100) && (resp <= 199)) 12807 __sip_semi_ack(p, seqno, 0, sipmethod); 12808 else 12809 __sip_ack(p, seqno, 0, sipmethod); 12810 12811 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12812 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12813 p->pendinginvite = 0; 12814 12815 /* Get their tag if we haven't already */ 12816 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12817 char tag[128]; 12818 12819 gettag(req, "To", tag, sizeof(tag)); 12820 ast_string_field_set(p, theirtag, tag); 12821 } 12822 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12823 /* We don't really care what the response is, just that it replied back. 12824 Well, as long as it's not a 100 response... since we might 12825 need to hang around for something more "definitive" */ 12826 if (resp != 100) 12827 handle_response_peerpoke(p, resp, req); 12828 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12829 switch(resp) { 12830 case 100: /* 100 Trying */ 12831 case 101: /* 101 Dialog establishment */ 12832 if (sipmethod == SIP_INVITE) 12833 handle_response_invite(p, resp, rest, req, seqno); 12834 break; 12835 case 183: /* 183 Session Progress */ 12836 if (sipmethod == SIP_INVITE) 12837 handle_response_invite(p, resp, rest, req, seqno); 12838 break; 12839 case 180: /* 180 Ringing */ 12840 if (sipmethod == SIP_INVITE) 12841 handle_response_invite(p, resp, rest, req, seqno); 12842 break; 12843 case 182: /* 182 Queued */ 12844 if (sipmethod == SIP_INVITE) 12845 handle_response_invite(p, resp, rest, req, seqno); 12846 break; 12847 case 200: /* 200 OK */ 12848 p->authtries = 0; /* Reset authentication counter */ 12849 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12850 /* We successfully transmitted a message 12851 or a video update request in INFO */ 12852 /* Nothing happens here - the message is inside a dialog */ 12853 } else if (sipmethod == SIP_INVITE) { 12854 handle_response_invite(p, resp, rest, req, seqno); 12855 } else if (sipmethod == SIP_NOTIFY) { 12856 /* They got the notify, this is the end */ 12857 if (p->owner) { 12858 if (!p->refer) { 12859 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12860 ast_queue_hangup(p->owner); 12861 } else if (option_debug > 3) 12862 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12863 } else { 12864 if (p->subscribed == NONE) 12865 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12866 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12867 /* Ready to send the next state we have on queue */ 12868 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12869 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 12870 } 12871 } 12872 } else if (sipmethod == SIP_REGISTER) 12873 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12874 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12875 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12876 break; 12877 case 202: /* Transfer accepted */ 12878 if (sipmethod == SIP_REFER) 12879 handle_response_refer(p, resp, rest, req, seqno); 12880 break; 12881 case 401: /* Not www-authorized on SIP method */ 12882 if (sipmethod == SIP_INVITE) 12883 handle_response_invite(p, resp, rest, req, seqno); 12884 else if (sipmethod == SIP_REFER) 12885 handle_response_refer(p, resp, rest, req, seqno); 12886 else if (p->registry && sipmethod == SIP_REGISTER) 12887 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12888 else if (sipmethod == SIP_BYE) { 12889 if (ast_strlen_zero(p->authname)) { 12890 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12891 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12892 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12893 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12894 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12895 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12896 /* We fail to auth bye on our own call, but still needs to tear down the call. 12897 Life, they call it. */ 12898 } 12899 } else { 12900 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12901 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12902 } 12903 break; 12904 case 403: /* Forbidden - we failed authentication */ 12905 if (sipmethod == SIP_INVITE) 12906 handle_response_invite(p, resp, rest, req, seqno); 12907 else if (p->registry && sipmethod == SIP_REGISTER) 12908 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12909 else { 12910 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12911 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12912 } 12913 break; 12914 case 404: /* Not found */ 12915 if (p->registry && sipmethod == SIP_REGISTER) 12916 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12917 else if (sipmethod == SIP_INVITE) 12918 handle_response_invite(p, resp, rest, req, seqno); 12919 else if (owner) 12920 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12921 break; 12922 case 407: /* Proxy auth required */ 12923 if (sipmethod == SIP_INVITE) 12924 handle_response_invite(p, resp, rest, req, seqno); 12925 else if (sipmethod == SIP_REFER) 12926 handle_response_refer(p, resp, rest, req, seqno); 12927 else if (p->registry && sipmethod == SIP_REGISTER) 12928 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12929 else if (sipmethod == SIP_BYE) { 12930 if (ast_strlen_zero(p->authname)) { 12931 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12932 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12933 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12934 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12935 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12936 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12937 } 12938 } else /* We can't handle this, giving up in a bad way */ 12939 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12940 12941 break; 12942 case 408: /* Request timeout - terminate dialog */ 12943 if (sipmethod == SIP_INVITE) 12944 handle_response_invite(p, resp, rest, req, seqno); 12945 else if (sipmethod == SIP_REGISTER) 12946 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12947 else if (sipmethod == SIP_BYE) { 12948 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12949 if (option_debug) 12950 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12951 } else { 12952 if (owner) 12953 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12954 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12955 } 12956 break; 12957 case 481: /* Call leg does not exist */ 12958 if (sipmethod == SIP_INVITE) { 12959 handle_response_invite(p, resp, rest, req, seqno); 12960 } else if (sipmethod == SIP_REFER) { 12961 handle_response_refer(p, resp, rest, req, seqno); 12962 } else if (sipmethod == SIP_BYE) { 12963 /* The other side has no transaction to bye, 12964 just assume it's all right then */ 12965 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12966 } else if (sipmethod == SIP_CANCEL) { 12967 /* The other side has no transaction to cancel, 12968 just assume it's all right then */ 12969 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12970 } else { 12971 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12972 /* Guessing that this is not an important request */ 12973 } 12974 break; 12975 case 487: 12976 if (sipmethod == SIP_INVITE) 12977 handle_response_invite(p, resp, rest, req, seqno); 12978 break; 12979 case 488: /* Not acceptable here - codec error */ 12980 if (sipmethod == SIP_INVITE) 12981 handle_response_invite(p, resp, rest, req, seqno); 12982 break; 12983 case 491: /* Pending */ 12984 if (sipmethod == SIP_INVITE) 12985 handle_response_invite(p, resp, rest, req, seqno); 12986 else { 12987 if (option_debug) 12988 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12989 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12990 } 12991 break; 12992 case 501: /* Not Implemented */ 12993 if (sipmethod == SIP_INVITE) 12994 handle_response_invite(p, resp, rest, req, seqno); 12995 else if (sipmethod == SIP_REFER) 12996 handle_response_refer(p, resp, rest, req, seqno); 12997 else 12998 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12999 break; 13000 case 603: /* Declined transfer */ 13001 if (sipmethod == SIP_REFER) { 13002 handle_response_refer(p, resp, rest, req, seqno); 13003 break; 13004 } 13005 /* Fallthrough */ 13006 default: 13007 if ((resp >= 300) && (resp < 700)) { 13008 /* Fatal response */ 13009 if ((option_verbose > 2) && (resp != 487)) 13010 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13011 13012 if (sipmethod == SIP_INVITE) 13013 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13014 13015 /* XXX Locking issues?? XXX */ 13016 switch(resp) { 13017 case 300: /* Multiple Choices */ 13018 case 301: /* Moved permenantly */ 13019 case 302: /* Moved temporarily */ 13020 case 305: /* Use Proxy */ 13021 parse_moved_contact(p, req); 13022 /* Fall through */ 13023 case 486: /* Busy here */ 13024 case 600: /* Busy everywhere */ 13025 case 603: /* Decline */ 13026 if (p->owner) 13027 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13028 break; 13029 case 482: /* 13030 \note SIP is incapable of performing a hairpin call, which 13031 is yet another failure of not having a layer 2 (again, YAY 13032 IETF for thinking ahead). So we treat this as a call 13033 forward and hope we end up at the right place... */ 13034 if (option_debug) 13035 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13036 if (p->owner) 13037 ast_string_field_build(p->owner, call_forward, 13038 "Local/%s@%s", p->username, p->context); 13039 /* Fall through */ 13040 case 480: /* Temporarily Unavailable */ 13041 case 404: /* Not Found */ 13042 case 410: /* Gone */ 13043 case 400: /* Bad Request */ 13044 case 500: /* Server error */ 13045 if (sipmethod == SIP_REFER) { 13046 handle_response_refer(p, resp, rest, req, seqno); 13047 break; 13048 } 13049 /* Fall through */ 13050 case 502: /* Bad gateway */ 13051 case 503: /* Service Unavailable */ 13052 case 504: /* Server Timeout */ 13053 if (owner) 13054 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13055 break; 13056 default: 13057 /* Send hangup */ 13058 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13059 ast_queue_hangup(p->owner); 13060 break; 13061 } 13062 /* ACK on invite */ 13063 if (sipmethod == SIP_INVITE) 13064 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13065 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13066 sip_alreadygone(p); 13067 if (!p->owner) 13068 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13069 } else if ((resp >= 100) && (resp < 200)) { 13070 if (sipmethod == SIP_INVITE) { 13071 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13072 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13073 if (find_sdp(req)) 13074 process_sdp(p, req); 13075 if (p->owner) { 13076 /* Queue a progress frame */ 13077 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13078 } 13079 } 13080 } else 13081 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)); 13082 } 13083 } else { 13084 /* Responses to OUTGOING SIP requests on INCOMING calls 13085 get handled here. As well as out-of-call message responses */ 13086 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13087 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13088 13089 if (sipmethod == SIP_INVITE && resp == 200) { 13090 /* Tags in early session is replaced by the tag in 200 OK, which is 13091 the final reply to our INVITE */ 13092 char tag[128]; 13093 13094 gettag(req, "To", tag, sizeof(tag)); 13095 ast_string_field_set(p, theirtag, tag); 13096 } 13097 13098 switch(resp) { 13099 case 200: 13100 if (sipmethod == SIP_INVITE) { 13101 handle_response_invite(p, resp, rest, req, seqno); 13102 } else if (sipmethod == SIP_CANCEL) { 13103 if (option_debug) 13104 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13105 13106 /* Wait for 487, then destroy */ 13107 } else if (sipmethod == SIP_NOTIFY) { 13108 /* They got the notify, this is the end */ 13109 if (p->owner) { 13110 if (p->refer) { 13111 if (option_debug) 13112 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13113 } else 13114 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13115 /* ast_queue_hangup(p->owner); Disabled */ 13116 } else { 13117 if (!p->subscribed && !p->refer) 13118 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13119 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13120 /* Ready to send the next state we have on queue */ 13121 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13122 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13123 } 13124 } 13125 } else if (sipmethod == SIP_BYE) 13126 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13127 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13128 /* We successfully transmitted a message or 13129 a video update request in INFO */ 13130 ; 13131 else if (sipmethod == SIP_BYE) 13132 /* Ok, we're ready to go */ 13133 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13134 break; 13135 case 202: /* Transfer accepted */ 13136 if (sipmethod == SIP_REFER) 13137 handle_response_refer(p, resp, rest, req, seqno); 13138 break; 13139 case 401: /* www-auth */ 13140 case 407: 13141 if (sipmethod == SIP_REFER) 13142 handle_response_refer(p, resp, rest, req, seqno); 13143 else if (sipmethod == SIP_INVITE) 13144 handle_response_invite(p, resp, rest, req, seqno); 13145 else if (sipmethod == SIP_BYE) { 13146 char *auth, *auth2; 13147 13148 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13149 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13150 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13151 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13152 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13153 } 13154 } 13155 break; 13156 case 481: /* Call leg does not exist */ 13157 if (sipmethod == SIP_INVITE) { 13158 /* Re-invite failed */ 13159 handle_response_invite(p, resp, rest, req, seqno); 13160 } else if (sipmethod == SIP_BYE) { 13161 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13162 } else if (sipdebug) { 13163 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13164 } 13165 break; 13166 case 501: /* Not Implemented */ 13167 if (sipmethod == SIP_INVITE) 13168 handle_response_invite(p, resp, rest, req, seqno); 13169 else if (sipmethod == SIP_REFER) 13170 handle_response_refer(p, resp, rest, req, seqno); 13171 break; 13172 case 603: /* Declined transfer */ 13173 if (sipmethod == SIP_REFER) { 13174 handle_response_refer(p, resp, rest, req, seqno); 13175 break; 13176 } 13177 /* Fallthrough */ 13178 default: /* Errors without handlers */ 13179 if ((resp >= 100) && (resp < 200)) { 13180 if (sipmethod == SIP_INVITE) { /* re-invite */ 13181 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13182 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13183 } 13184 } 13185 if ((resp >= 300) && (resp < 700)) { 13186 if ((option_verbose > 2) && (resp != 487)) 13187 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)); 13188 switch(resp) { 13189 case 488: /* Not acceptable here - codec error */ 13190 case 603: /* Decline */ 13191 case 500: /* Server error */ 13192 case 502: /* Bad gateway */ 13193 case 503: /* Service Unavailable */ 13194 case 504: /* Server timeout */ 13195 13196 /* re-invite failed */ 13197 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13198 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13199 break; 13200 } 13201 } 13202 break; 13203 } 13204 } 13205 }
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 12198 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().
12199 { 12200 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12201 int res = 0; 12202 int xmitres = 0; 12203 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12204 struct ast_channel *bridgepeer = NULL; 12205 12206 if (option_debug > 3) { 12207 if (reinvite) 12208 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12209 else 12210 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12211 } 12212 12213 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12214 if (option_debug) 12215 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12216 return; 12217 } 12218 12219 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12220 /* Don't auto congest anymore since we've gotten something useful back */ 12221 AST_SCHED_DEL(sched, p->initid); 12222 12223 /* RFC3261 says we must treat every 1xx response (but not 100) 12224 that we don't recognize as if it was 183. 12225 */ 12226 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12227 resp = 183; 12228 12229 /* Any response between 100 and 199 is PROCEEDING */ 12230 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12231 p->invitestate = INV_PROCEEDING; 12232 12233 /* Final response, not 200 ? */ 12234 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12235 p->invitestate = INV_COMPLETED; 12236 12237 12238 switch (resp) { 12239 case 100: /* Trying */ 12240 case 101: /* Dialog establishment */ 12241 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12242 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12243 check_pendings(p); 12244 break; 12245 12246 case 180: /* 180 Ringing */ 12247 case 182: /* 182 Queued */ 12248 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12249 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12250 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12251 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12252 if (p->owner->_state != AST_STATE_UP) { 12253 ast_setstate(p->owner, AST_STATE_RINGING); 12254 } 12255 } 12256 if (find_sdp(req)) { 12257 if (p->invitestate != INV_CANCELLED) 12258 p->invitestate = INV_EARLY_MEDIA; 12259 res = process_sdp(p, req); 12260 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12261 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12262 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12263 } 12264 } 12265 check_pendings(p); 12266 break; 12267 12268 case 183: /* Session progress */ 12269 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12270 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12271 /* Ignore 183 Session progress without SDP */ 12272 if (find_sdp(req)) { 12273 if (p->invitestate != INV_CANCELLED) 12274 p->invitestate = INV_EARLY_MEDIA; 12275 res = process_sdp(p, req); 12276 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12277 /* Queue a progress frame */ 12278 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12279 } 12280 } 12281 check_pendings(p); 12282 break; 12283 12284 case 200: /* 200 OK on invite - someone's answering our call */ 12285 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12286 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12287 p->authtries = 0; 12288 if (find_sdp(req)) { 12289 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12290 if (!reinvite) 12291 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12292 /* For re-invites, we try to recover */ 12293 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12294 } 12295 12296 /* Parse contact header for continued conversation */ 12297 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12298 /* This is important when we have a SIP proxy between us and the phone */ 12299 if (outgoing) { 12300 update_call_counter(p, DEC_CALL_RINGING); 12301 parse_ok_contact(p, req); 12302 if(set_address_from_contact(p)) { 12303 /* Bad contact - we don't know how to reach this device */ 12304 /* We need to ACK, but then send a bye */ 12305 /* OEJ: Possible issue that may need a check: 12306 If we have a proxy route between us and the device, 12307 should we care about resolving the contact 12308 or should we just send it? 12309 */ 12310 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12311 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12312 } 12313 12314 /* Save Record-Route for any later requests we make on this dialogue */ 12315 if (!reinvite) 12316 build_route(p, req, 1); 12317 } 12318 12319 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12320 struct sip_pvt *bridgepvt = NULL; 12321 12322 if (!bridgepeer->tech) { 12323 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12324 break; 12325 } 12326 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12327 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12328 if (bridgepvt->udptl) { 12329 if (p->t38.state == T38_PEER_REINVITE) { 12330 sip_handle_t38_reinvite(bridgepeer, p, 0); 12331 ast_rtp_set_rtptimers_onhold(p->rtp); 12332 if (p->vrtp) 12333 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12334 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12335 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12336 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12337 /* XXXX Should we really destroy this session here, without any response at all??? */ 12338 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12339 } 12340 } else { 12341 if (option_debug > 1) 12342 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12343 ast_mutex_lock(&bridgepvt->lock); 12344 bridgepvt->t38.state = T38_DISABLED; 12345 ast_mutex_unlock(&bridgepvt->lock); 12346 if (option_debug) 12347 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12348 p->t38.state = T38_DISABLED; 12349 if (option_debug > 1) 12350 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12351 } 12352 } else { 12353 /* Other side is not a SIP channel */ 12354 if (option_debug > 1) 12355 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12356 p->t38.state = T38_DISABLED; 12357 if (option_debug > 1) 12358 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12359 } 12360 } 12361 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12362 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12363 p->t38.state = T38_ENABLED; 12364 if (option_debug) 12365 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12366 } 12367 12368 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12369 if (!reinvite) { 12370 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12371 } else { /* RE-invite */ 12372 ast_queue_frame(p->owner, &ast_null_frame); 12373 } 12374 } else { 12375 /* It's possible we're getting an 200 OK after we've tried to disconnect 12376 by sending CANCEL */ 12377 /* First send ACK, then send bye */ 12378 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12379 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12380 } 12381 /* If I understand this right, the branch is different for a non-200 ACK only */ 12382 p->invitestate = INV_TERMINATED; 12383 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12384 check_pendings(p); 12385 break; 12386 case 407: /* Proxy authentication */ 12387 case 401: /* Www auth */ 12388 /* First we ACK */ 12389 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12390 if (p->options) 12391 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12392 12393 /* Then we AUTH */ 12394 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12395 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12396 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12397 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12398 if (p->authtries < MAX_AUTHTRIES) 12399 p->invitestate = INV_CALLING; 12400 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12401 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12402 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12403 sip_alreadygone(p); 12404 if (p->owner) 12405 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12406 } 12407 } 12408 break; 12409 12410 case 403: /* Forbidden */ 12411 /* First we ACK */ 12412 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12413 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12414 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12415 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12416 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12417 sip_alreadygone(p); 12418 break; 12419 12420 case 404: /* Not found */ 12421 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12422 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12423 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12424 sip_alreadygone(p); 12425 break; 12426 12427 case 408: /* Request timeout */ 12428 case 481: /* Call leg does not exist */ 12429 /* Could be REFER caused INVITE with replaces */ 12430 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12431 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12432 if (p->owner) 12433 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12434 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12435 break; 12436 case 487: /* Cancelled transaction */ 12437 /* We have sent CANCEL on an outbound INVITE 12438 This transaction is already scheduled to be killed by sip_hangup(). 12439 */ 12440 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12441 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12442 ast_queue_hangup(p->owner); 12443 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12444 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12445 update_call_counter(p, DEC_CALL_LIMIT); 12446 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12447 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12448 sip_alreadygone(p); 12449 } 12450 break; 12451 case 488: /* Not acceptable here */ 12452 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12453 if (reinvite && p->udptl) { 12454 /* If this is a T.38 call, we should go back to 12455 audio. If this is an audio call - something went 12456 terribly wrong since we don't renegotiate codecs, 12457 only IP/port . 12458 */ 12459 p->t38.state = T38_DISABLED; 12460 /* Try to reset RTP timers */ 12461 ast_rtp_set_rtptimers_onhold(p->rtp); 12462 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12463 12464 /*! \bug Is there any way we can go back to the audio call on both 12465 sides here? 12466 */ 12467 /* While figuring that out, hangup the call */ 12468 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12469 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12470 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12471 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12472 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12473 right now we can't fall back to audio so totally abort. 12474 */ 12475 p->t38.state = T38_DISABLED; 12476 /* Try to reset RTP timers */ 12477 ast_rtp_set_rtptimers_onhold(p->rtp); 12478 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12479 12480 /* The dialog is now terminated */ 12481 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12482 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12483 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12484 sip_alreadygone(p); 12485 } else { 12486 /* We can't set up this call, so give up */ 12487 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12488 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12489 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12490 /* If there's no dialog to end, then mark p as already gone */ 12491 if (!reinvite) 12492 sip_alreadygone(p); 12493 } 12494 break; 12495 case 491: /* Pending */ 12496 /* we really should have to wait a while, then retransmit 12497 * We should support the retry-after at some point 12498 * At this point, we treat this as a congestion if the call is not in UP state 12499 */ 12500 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12501 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12502 if (p->owner->_state != AST_STATE_UP) { 12503 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12504 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12505 } else { 12506 /* This is a re-invite that failed. 12507 * Reset the flag after a while 12508 */ 12509 int wait = 3 + ast_random() % 5; 12510 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12511 if (option_debug > 2) 12512 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12513 } 12514 } 12515 break; 12516 12517 case 501: /* Not implemented */ 12518 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12519 if (p->owner) 12520 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12521 break; 12522 } 12523 if (xmitres == XMIT_ERROR) 12524 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12525 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12720 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().
12721 { 12722 struct sip_peer *peer = p->relatedpeer; 12723 int statechanged, is_reachable, was_reachable; 12724 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12725 12726 /* 12727 * Compute the response time to a ping (goes in peer->lastms.) 12728 * -1 means did not respond, 0 means unknown, 12729 * 1..maxms is a valid response, >maxms means late response. 12730 */ 12731 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12732 pingtime = 1; 12733 12734 /* Now determine new state and whether it has changed. 12735 * Use some helper variables to simplify the writing 12736 * of the expressions. 12737 */ 12738 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12739 is_reachable = pingtime <= peer->maxms; 12740 statechanged = peer->lastms == 0 /* yes, unknown before */ 12741 || was_reachable != is_reachable; 12742 12743 peer->lastms = pingtime; 12744 peer->call = NULL; 12745 if (statechanged) { 12746 const char *s = is_reachable ? "Reachable" : "Lagged"; 12747 12748 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12749 peer->name, s, pingtime, peer->maxms); 12750 ast_device_state_changed("SIP/%s", peer->name); 12751 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12752 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12753 peer->name, s, pingtime); 12754 } 12755 12756 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12757 struct sip_peer *peer_ptr = peer; 12758 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12759 } 12760 12761 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12762 12763 /* Try again eventually */ 12764 peer->pokeexpire = ast_sched_add(sched, 12765 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12766 sip_poke_peer_s, ASTOBJ_REF(peer)); 12767 12768 if (peer->pokeexpire == -1) { 12769 ASTOBJ_UNREF(peer, sip_destroy_peer); 12770 } 12771 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12530 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().
12531 { 12532 char *auth = "Proxy-Authenticate"; 12533 char *auth2 = "Proxy-Authorization"; 12534 12535 /* If no refer structure exists, then do nothing */ 12536 if (!p->refer) 12537 return; 12538 12539 switch (resp) { 12540 case 202: /* Transfer accepted */ 12541 /* We need to do something here */ 12542 /* The transferee is now sending INVITE to target */ 12543 p->refer->status = REFER_ACCEPTED; 12544 /* Now wait for next message */ 12545 if (option_debug > 2) 12546 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12547 /* We should hang along, waiting for NOTIFY's here */ 12548 break; 12549 12550 case 401: /* Not www-authorized on SIP method */ 12551 case 407: /* Proxy auth */ 12552 if (ast_strlen_zero(p->authname)) { 12553 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12554 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12555 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12556 } 12557 if (resp == 401) { 12558 auth = "WWW-Authenticate"; 12559 auth2 = "Authorization"; 12560 } 12561 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12562 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12563 p->refer->status = REFER_NOAUTH; 12564 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12565 } 12566 break; 12567 case 481: /* Call leg does not exist */ 12568 12569 /* A transfer with Replaces did not work */ 12570 /* OEJ: We should Set flag, cancel the REFER, go back 12571 to original call - but right now we can't */ 12572 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12573 if (p->owner) 12574 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12575 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12576 break; 12577 12578 case 500: /* Server error */ 12579 case 501: /* Method not implemented */ 12580 /* Return to the current call onhold */ 12581 /* Status flag needed to be reset */ 12582 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12583 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12584 p->refer->status = REFER_FAILED; 12585 break; 12586 case 603: /* Transfer declined */ 12587 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12588 p->refer->status = REFER_FAILED; 12589 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12590 break; 12591 } 12592 }
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 12595 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().
12596 { 12597 int expires, expires_ms; 12598 struct sip_registry *r; 12599 r=p->registry; 12600 12601 switch (resp) { 12602 case 401: /* Unauthorized */ 12603 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12604 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12605 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12606 } 12607 break; 12608 case 403: /* Forbidden */ 12609 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12610 if (global_regattempts_max) 12611 p->registry->regattempts = global_regattempts_max+1; 12612 AST_SCHED_DEL(sched, r->timeout); 12613 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12614 break; 12615 case 404: /* Not found */ 12616 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12617 if (global_regattempts_max) 12618 p->registry->regattempts = global_regattempts_max+1; 12619 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12620 r->call = NULL; 12621 AST_SCHED_DEL(sched, r->timeout); 12622 break; 12623 case 407: /* Proxy auth */ 12624 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12625 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12626 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12627 } 12628 break; 12629 case 408: /* Request timeout */ 12630 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12631 r->call = NULL; 12632 AST_SCHED_DEL(sched, r->timeout); 12633 break; 12634 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12635 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12636 if (global_regattempts_max) 12637 p->registry->regattempts = global_regattempts_max+1; 12638 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12639 r->call = NULL; 12640 AST_SCHED_DEL(sched, r->timeout); 12641 break; 12642 case 200: /* 200 OK */ 12643 if (!r) { 12644 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12645 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12646 return 0; 12647 } 12648 12649 r->regstate = REG_STATE_REGISTERED; 12650 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12651 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12652 r->regattempts = 0; 12653 if (option_debug) 12654 ast_log(LOG_DEBUG, "Registration successful\n"); 12655 if (r->timeout > -1) { 12656 if (option_debug) 12657 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12658 } 12659 AST_SCHED_DEL(sched, r->timeout); 12660 r->call = NULL; 12661 p->registry = NULL; 12662 /* Let this one hang around until we have all the responses */ 12663 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12664 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12665 12666 /* set us up for re-registering */ 12667 /* figure out how long we got registered for */ 12668 AST_SCHED_DEL(sched, r->expire); 12669 /* according to section 6.13 of RFC, contact headers override 12670 expires headers, so check those first */ 12671 expires = 0; 12672 12673 /* XXX todo: try to save the extra call */ 12674 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12675 const char *contact = NULL; 12676 const char *tmptmp = NULL; 12677 int start = 0; 12678 for(;;) { 12679 contact = __get_header(req, "Contact", &start); 12680 /* this loop ensures we get a contact header about our register request */ 12681 if(!ast_strlen_zero(contact)) { 12682 if( (tmptmp=strstr(contact, p->our_contact))) { 12683 contact=tmptmp; 12684 break; 12685 } 12686 } else 12687 break; 12688 } 12689 tmptmp = strcasestr(contact, "expires="); 12690 if (tmptmp) { 12691 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12692 expires = 0; 12693 } 12694 12695 } 12696 if (!expires) 12697 expires=atoi(get_header(req, "expires")); 12698 if (!expires) 12699 expires=default_expiry; 12700 12701 expires_ms = expires * 1000; 12702 if (expires <= EXPIRY_GUARD_LIMIT) 12703 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12704 else 12705 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12706 if (sipdebug) 12707 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12708 12709 r->refresh= (int) expires_ms / 1000; 12710 12711 /* Schedule re-registration before we expire */ 12712 AST_SCHED_DEL(sched, r->expire); 12713 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12714 ASTOBJ_UNREF(r, sip_registry_destroy); 12715 } 12716 return 1; 12717 }
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 3458 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().
03459 { 03460 switch (cause) { 03461 case AST_CAUSE_UNALLOCATED: /* 1 */ 03462 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03463 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03464 return "404 Not Found"; 03465 case AST_CAUSE_CONGESTION: /* 34 */ 03466 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03467 return "503 Service Unavailable"; 03468 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03469 return "408 Request Timeout"; 03470 case AST_CAUSE_NO_ANSWER: /* 19 */ 03471 return "480 Temporarily unavailable"; 03472 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03473 return "403 Forbidden"; 03474 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03475 return "410 Gone"; 03476 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03477 return "480 Temporarily unavailable"; 03478 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03479 return "484 Address incomplete"; 03480 case AST_CAUSE_USER_BUSY: 03481 return "486 Busy here"; 03482 case AST_CAUSE_FAILURE: 03483 return "500 Server internal failure"; 03484 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03485 return "501 Not Implemented"; 03486 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03487 return "503 Service Unavailable"; 03488 /* Used in chan_iax2 */ 03489 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03490 return "502 Bad Gateway"; 03491 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03492 return "488 Not Acceptable Here"; 03493 03494 case AST_CAUSE_NOTDEFINED: 03495 default: 03496 if (option_debug) 03497 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03498 return NULL; 03499 } 03500 03501 /* Never reached */ 03502 return 0; 03503 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3346 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().
03347 { 03348 /* Possible values taken from causes.h */ 03349 03350 switch(cause) { 03351 case 401: /* Unauthorized */ 03352 return AST_CAUSE_CALL_REJECTED; 03353 case 403: /* Not found */ 03354 return AST_CAUSE_CALL_REJECTED; 03355 case 404: /* Not found */ 03356 return AST_CAUSE_UNALLOCATED; 03357 case 405: /* Method not allowed */ 03358 return AST_CAUSE_INTERWORKING; 03359 case 407: /* Proxy authentication required */ 03360 return AST_CAUSE_CALL_REJECTED; 03361 case 408: /* No reaction */ 03362 return AST_CAUSE_NO_USER_RESPONSE; 03363 case 409: /* Conflict */ 03364 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03365 case 410: /* Gone */ 03366 return AST_CAUSE_UNALLOCATED; 03367 case 411: /* Length required */ 03368 return AST_CAUSE_INTERWORKING; 03369 case 413: /* Request entity too large */ 03370 return AST_CAUSE_INTERWORKING; 03371 case 414: /* Request URI too large */ 03372 return AST_CAUSE_INTERWORKING; 03373 case 415: /* Unsupported media type */ 03374 return AST_CAUSE_INTERWORKING; 03375 case 420: /* Bad extension */ 03376 return AST_CAUSE_NO_ROUTE_DESTINATION; 03377 case 480: /* No answer */ 03378 return AST_CAUSE_NO_ANSWER; 03379 case 481: /* No answer */ 03380 return AST_CAUSE_INTERWORKING; 03381 case 482: /* Loop detected */ 03382 return AST_CAUSE_INTERWORKING; 03383 case 483: /* Too many hops */ 03384 return AST_CAUSE_NO_ANSWER; 03385 case 484: /* Address incomplete */ 03386 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03387 case 485: /* Ambigous */ 03388 return AST_CAUSE_UNALLOCATED; 03389 case 486: /* Busy everywhere */ 03390 return AST_CAUSE_BUSY; 03391 case 487: /* Request terminated */ 03392 return AST_CAUSE_INTERWORKING; 03393 case 488: /* No codecs approved */ 03394 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03395 case 491: /* Request pending */ 03396 return AST_CAUSE_INTERWORKING; 03397 case 493: /* Undecipherable */ 03398 return AST_CAUSE_INTERWORKING; 03399 case 500: /* Server internal failure */ 03400 return AST_CAUSE_FAILURE; 03401 case 501: /* Call rejected */ 03402 return AST_CAUSE_FACILITY_REJECTED; 03403 case 502: 03404 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03405 case 503: /* Service unavailable */ 03406 return AST_CAUSE_CONGESTION; 03407 case 504: /* Gateway timeout */ 03408 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03409 case 505: /* SIP version not supported */ 03410 return AST_CAUSE_INTERWORKING; 03411 case 600: /* Busy everywhere */ 03412 return AST_CAUSE_USER_BUSY; 03413 case 603: /* Decline */ 03414 return AST_CAUSE_CALL_REJECTED; 03415 case 604: /* Does not exist anywhere */ 03416 return AST_CAUSE_UNALLOCATED; 03417 case 606: /* Not acceptable */ 03418 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03419 default: 03420 return AST_CAUSE_NORMAL; 03421 } 03422 /* Never reached */ 03423 return 0; 03424 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5927 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05928 { 05929 /* Initialize a request */ 05930 memset(req, 0, sizeof(*req)); 05931 req->method = sipmethod; 05932 req->header[0] = req->data; 05933 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05934 req->len = strlen(req->header[0]); 05935 req->headers++; 05936 return 0; 05937 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5914 of file chan_sip.c.
References SIP_RESPONSE.
05915 { 05916 /* Initialize a response */ 05917 memset(resp, 0, sizeof(*resp)); 05918 resp->method = SIP_RESPONSE; 05919 resp->header[0] = resp->data; 05920 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05921 resp->len = strlen(resp->header[0]); 05922 resp->headers++; 05923 return 0; 05924 }
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 1647 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().
01648 { 01649 if (p->initreq.headers && option_debug) { 01650 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01651 } 01652 /* Use this as the basis */ 01653 copy_request(&p->initreq, req); 01654 parse_request(&p->initreq); 01655 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01656 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01657 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7014 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().
07015 { 07016 char invite_buf[256] = ""; 07017 char *invite = invite_buf; 07018 size_t invite_max = sizeof(invite_buf); 07019 char from[256]; 07020 char to[256]; 07021 char tmp[SIPBUFSIZE/2]; 07022 char tmp2[SIPBUFSIZE/2]; 07023 const char *l = NULL, *n = NULL; 07024 const char *urioptions = ""; 07025 07026 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07027 const char *s = p->username; /* being a string field, cannot be NULL */ 07028 07029 /* Test p->username against allowed characters in AST_DIGIT_ANY 07030 If it matches the allowed characters list, then sipuser = ";user=phone" 07031 If not, then sipuser = "" 07032 */ 07033 /* + is allowed in first position in a tel: uri */ 07034 if (*s == '+') 07035 s++; 07036 for (; *s; s++) { 07037 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07038 break; 07039 } 07040 /* If we have only digits, add ;user=phone to the uri */ 07041 if (*s) 07042 urioptions = ";user=phone"; 07043 } 07044 07045 07046 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07047 07048 if (p->owner) { 07049 l = p->owner->cid.cid_num; 07050 n = p->owner->cid.cid_name; 07051 } 07052 /* if we are not sending RPID and user wants his callerid restricted */ 07053 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07054 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07055 l = CALLERID_UNKNOWN; 07056 n = l; 07057 } 07058 if (ast_strlen_zero(l)) 07059 l = default_callerid; 07060 if (ast_strlen_zero(n)) 07061 n = l; 07062 /* Allow user to be overridden */ 07063 if (!ast_strlen_zero(p->fromuser)) 07064 l = p->fromuser; 07065 else /* Save for any further attempts */ 07066 ast_string_field_set(p, fromuser, l); 07067 07068 /* Allow user to be overridden */ 07069 if (!ast_strlen_zero(p->fromname)) 07070 n = p->fromname; 07071 else /* Save for any further attempts */ 07072 ast_string_field_set(p, fromname, n); 07073 07074 if (pedanticsipchecking) { 07075 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07076 n = tmp; 07077 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07078 l = tmp2; 07079 } 07080 07081 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07082 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); 07083 else 07084 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07085 07086 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07087 if (!ast_strlen_zero(p->fullcontact)) { 07088 /* If we have full contact, trust it */ 07089 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07090 } else { 07091 /* Otherwise, use the username while waiting for registration */ 07092 ast_build_string(&invite, &invite_max, "sip:"); 07093 if (!ast_strlen_zero(p->username)) { 07094 n = p->username; 07095 if (pedanticsipchecking) { 07096 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07097 n = tmp; 07098 } 07099 ast_build_string(&invite, &invite_max, "%s@", n); 07100 } 07101 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07102 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07103 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07104 ast_build_string(&invite, &invite_max, "%s", urioptions); 07105 } 07106 07107 /* If custom URI options have been provided, append them */ 07108 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07109 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07110 07111 ast_string_field_set(p, uri, invite_buf); 07112 07113 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07114 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07115 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07116 } else if (p->options && p->options->vxml_url) { 07117 /* If there is a VXML URL append it to the SIP URL */ 07118 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07119 } else 07120 snprintf(to, sizeof(to), "<%s>", p->uri); 07121 07122 init_req(req, sipmethod, p->uri); 07123 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07124 07125 add_header(req, "Via", p->via); 07126 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07127 * OTOH, then we won't have anything in p->route anyway */ 07128 /* Build Remote Party-ID and From */ 07129 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07130 build_rpid(p); 07131 add_header(req, "From", p->rpid_from); 07132 } else 07133 add_header(req, "From", from); 07134 add_header(req, "To", to); 07135 ast_string_field_set(p, exten, l); 07136 build_contact(p); 07137 add_header(req, "Contact", p->our_contact); 07138 add_header(req, "Call-ID", p->callid); 07139 add_header(req, "CSeq", tmp); 07140 if (!ast_strlen_zero(global_useragent)) 07141 add_header(req, "User-Agent", global_useragent); 07142 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07143 if (!ast_strlen_zero(p->rpid)) 07144 add_header(req, "Remote-Party-ID", p->rpid); 07145 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10204 of file chan_sip.c.
Referenced by _sip_show_peer().
10205 { 10206 if (port && invite) 10207 return "port,invite"; 10208 else if (port) 10209 return "port"; 10210 else if (invite) 10211 return "invite"; 10212 else 10213 return "no"; 10214 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8352 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08353 { 08354 if (!route) 08355 ast_verbose("list_route: no route\n"); 08356 else { 08357 for (;route; route = route->next) 08358 ast_verbose("list_route: hop: <%s>\n", route->hop); 08359 } 08360 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18300 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.
18301 { 18302 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18303 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18304 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18305 18306 if (!(sched = sched_context_create())) { 18307 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18308 return AST_MODULE_LOAD_FAILURE; 18309 } 18310 18311 if (!(io = io_context_create())) { 18312 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18313 sched_context_destroy(sched); 18314 return AST_MODULE_LOAD_FAILURE; 18315 } 18316 18317 sip_reloadreason = CHANNEL_MODULE_LOAD; 18318 18319 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18320 return AST_MODULE_LOAD_DECLINE; 18321 18322 /* Make sure we can register our sip channel type */ 18323 if (ast_channel_register(&sip_tech)) { 18324 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18325 io_context_destroy(io); 18326 sched_context_destroy(sched); 18327 return AST_MODULE_LOAD_FAILURE; 18328 } 18329 18330 /* Register all CLI functions for SIP */ 18331 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18332 18333 /* Tell the RTP subdriver that we're here */ 18334 ast_rtp_proto_register(&sip_rtp); 18335 18336 /* Tell the UDPTL subdriver that we're here */ 18337 ast_udptl_proto_register(&sip_udptl); 18338 18339 /* Register dialplan applications */ 18340 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18341 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18342 18343 /* Register dialplan functions */ 18344 ast_custom_function_register(&sip_header_function); 18345 ast_custom_function_register(&sippeer_function); 18346 ast_custom_function_register(&sipchaninfo_function); 18347 ast_custom_function_register(&checksipdomain_function); 18348 18349 /* Register manager commands */ 18350 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18351 "List SIP peers (text format)", mandescr_show_peers); 18352 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18353 "Show SIP peer (text format)", mandescr_show_peer); 18354 18355 sip_poke_all_peers(); 18356 sip_send_all_registers(); 18357 18358 /* And start the monitor for the first time */ 18359 restart_monitor(); 18360 18361 return AST_MODULE_LOAD_SUCCESS; 18362 }
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 14357 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().
14358 { 14359 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14360 /* Chan 2: Call from Asterisk to target */ 14361 int res = 0; 14362 struct sip_pvt *targetcall_pvt; 14363 14364 /* Check if the call ID of the replaces header does exist locally */ 14365 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14366 transferer->refer->replaces_callid_fromtag))) { 14367 if (transferer->refer->localtransfer) { 14368 /* We did not find the refered call. Sorry, can't accept then */ 14369 transmit_response(transferer, "202 Accepted", req); 14370 /* Let's fake a response from someone else in order 14371 to follow the standard */ 14372 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14373 append_history(transferer, "Xfer", "Refer failed"); 14374 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14375 transferer->refer->status = REFER_FAILED; 14376 return -1; 14377 } 14378 /* Fall through for remote transfers that we did not find locally */ 14379 if (option_debug > 2) 14380 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14381 return 0; 14382 } 14383 14384 /* Ok, we can accept this transfer */ 14385 transmit_response(transferer, "202 Accepted", req); 14386 append_history(transferer, "Xfer", "Refer accepted"); 14387 if (!targetcall_pvt->owner) { /* No active channel */ 14388 if (option_debug > 3) 14389 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14390 /* Cancel transfer */ 14391 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14392 append_history(transferer, "Xfer", "Refer failed"); 14393 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14394 transferer->refer->status = REFER_FAILED; 14395 ast_mutex_unlock(&targetcall_pvt->lock); 14396 ast_channel_unlock(current->chan1); 14397 return -1; 14398 } 14399 14400 /* We have a channel, find the bridge */ 14401 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14402 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14403 14404 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14405 /* Wrong state of new channel */ 14406 if (option_debug > 3) { 14407 if (target.chan2) 14408 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14409 else if (target.chan1->_state != AST_STATE_RING) 14410 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14411 else 14412 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14413 } 14414 } 14415 14416 /* Transfer */ 14417 if (option_debug > 3 && sipdebug) { 14418 if (current->chan2) /* We have two bridges */ 14419 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14420 else /* One bridge, propably transfer of IVR/voicemail etc */ 14421 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14422 } 14423 14424 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14425 14426 /* Perform the transfer */ 14427 res = attempt_transfer(current, &target); 14428 ast_mutex_unlock(&targetcall_pvt->lock); 14429 if (res) { 14430 /* Failed transfer */ 14431 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14432 append_history(transferer, "Xfer", "Refer failed"); 14433 transferer->refer->status = REFER_FAILED; 14434 if (targetcall_pvt->owner) 14435 ast_channel_unlock(targetcall_pvt->owner); 14436 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14437 if (res != -2) 14438 ast_hangup(transferer->owner); 14439 else 14440 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14441 } else { 14442 /* Transfer succeeded! */ 14443 14444 /* Tell transferer that we're done. */ 14445 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14446 append_history(transferer, "Xfer", "Refer succeeded"); 14447 transferer->refer->status = REFER_200OK; 14448 if (targetcall_pvt->owner) { 14449 if (option_debug) 14450 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14451 ast_channel_unlock(targetcall_pvt->owner); 14452 } 14453 } 14454 return 1; 14455 }
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 4827 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04828 { 04829 int h = 0, t = 0; 04830 int lws = 0; 04831 04832 for (; h < len;) { 04833 /* Eliminate all CRs */ 04834 if (msgbuf[h] == '\r') { 04835 h++; 04836 continue; 04837 } 04838 /* Check for end-of-line */ 04839 if (msgbuf[h] == '\n') { 04840 /* Check for end-of-message */ 04841 if (h + 1 == len) 04842 break; 04843 /* Check for a continuation line */ 04844 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04845 /* Merge continuation line */ 04846 h++; 04847 continue; 04848 } 04849 /* Propagate LF and start new line */ 04850 msgbuf[t++] = msgbuf[h++]; 04851 lws = 0; 04852 continue; 04853 } 04854 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04855 if (lws) { 04856 h++; 04857 continue; 04858 } 04859 msgbuf[t++] = msgbuf[h++]; 04860 lws = 1; 04861 continue; 04862 } 04863 msgbuf[t++] = msgbuf[h++]; 04864 if (lws) 04865 lws = 0; 04866 } 04867 msgbuf[t] = '\0'; 04868 return t; 04869 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4495 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().
04496 { 04497 snprintf(tagbuf, len, "as%08lx", ast_random()); 04498 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10449 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().
10450 { 10451 const char *a[4]; 10452 const char *peer; 10453 int ret; 10454 10455 peer = astman_get_header(m,"Peer"); 10456 if (ast_strlen_zero(peer)) { 10457 astman_send_error(s, m, "Peer: <name> missing.\n"); 10458 return 0; 10459 } 10460 a[0] = "sip"; 10461 a[1] = "show"; 10462 a[2] = "peer"; 10463 a[3] = peer; 10464 10465 ret = _sip_show_peer(1, -1, s, m, 4, a); 10466 astman_append(s, "\r\n\r\n" ); 10467 return ret; 10468 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10000 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().
10001 { 10002 const char *id = astman_get_header(m,"ActionID"); 10003 const char *a[] = {"sip", "show", "peers"}; 10004 char idtext[256] = ""; 10005 int total = 0; 10006 10007 if (!ast_strlen_zero(id)) 10008 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10009 10010 astman_send_ack(s, m, "Peer status list will follow"); 10011 /* List the peers in separate manager events */ 10012 _sip_show_peers(-1, &total, s, m, 3, a); 10013 /* Send final confirmation */ 10014 astman_append(s, 10015 "Event: PeerlistComplete\r\n" 10016 "ListItems: %d\r\n" 10017 "%s" 10018 "\r\n", total, idtext); 10019 return 0; 10020 }
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 1673 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01674 { 01675 int len = strlen(sip_methods[id].text); 01676 int l_name = name ? strlen(name) : 0; 01677 /* true if the string is long enough, and ends with whitespace, and matches */ 01678 return (l_name >= len && name[len] < 33 && 01679 !strncasecmp(sip_methods[id].text, name, len)); 01680 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9903 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().
09904 { 09905 switch(nat) { 09906 case SIP_NAT_NEVER: 09907 return "No"; 09908 case SIP_NAT_ROUTE: 09909 return "Route"; 09910 case SIP_NAT_ALWAYS: 09911 return "Always"; 09912 case SIP_NAT_RFC3581: 09913 return "RFC3581"; 09914 default: 09915 return "Unknown"; 09916 } 09917 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2258 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02259 { 02260 memset(dst, 0, sizeof(*dst)); 02261 memcpy(dst->data, src->data, sizeof(dst->data)); 02262 dst->len = src->len; 02263 parse_request(dst); 02264 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12099 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().
12100 { 12101 char tmp[SIPBUFSIZE]; 12102 char *s, *e, *uri, *t; 12103 char *domain; 12104 12105 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12106 if ((t = strchr(tmp, ','))) 12107 *t = '\0'; 12108 s = get_in_brackets(tmp); 12109 uri = ast_strdupa(s); 12110 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12111 if (!strncasecmp(s, "sip:", 4)) 12112 s += 4; 12113 e = strchr(s, ';'); 12114 if (e) 12115 *e = '\0'; 12116 if (option_debug) 12117 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12118 if (p->owner) 12119 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12120 } else { 12121 e = strchr(tmp, '@'); 12122 if (e) { 12123 *e++ = '\0'; 12124 domain = e; 12125 } else { 12126 /* No username part */ 12127 domain = tmp; 12128 } 12129 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12130 if (e) 12131 *e = '\0'; 12132 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12133 if (e) 12134 *e = '\0'; 12135 12136 if (!strncasecmp(s, "sip:", 4)) 12137 s += 4; 12138 if (option_debug > 1) 12139 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12140 if (p->owner) { 12141 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12142 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12143 ast_string_field_set(p->owner, call_forward, s); 12144 } 12145 } 12146 }
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 8093 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().
08094 { 08095 char contact[SIPBUFSIZE]; 08096 char *c; 08097 08098 /* Look for brackets */ 08099 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08100 c = get_in_brackets(contact); 08101 08102 /* Save full contact to call pvt for later bye or re-invite */ 08103 ast_string_field_set(pvt, fullcontact, c); 08104 08105 /* Save URI for later ACKs, BYE or RE-invites */ 08106 ast_string_field_set(pvt, okcontacturi, c); 08107 08108 /* We should return false for URI:s we can't handle, 08109 like sips:, tel:, mailto:,ldap: etc */ 08110 return TRUE; 08111 }
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 8177 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_set_flag, 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_pvt::flags, 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_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_pvt::sockfd, sip_peer::sockfd, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08178 { 08179 char contact[SIPBUFSIZE]; 08180 char data[SIPBUFSIZE]; 08181 const char *expires = get_header(req, "Expires"); 08182 int expiry = atoi(expires); 08183 char *curi, *n, *pt; 08184 int port; 08185 const char *useragent; 08186 struct hostent *hp; 08187 struct ast_hostent ahp; 08188 struct sockaddr_in oldsin; 08189 08190 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08191 08192 if (ast_strlen_zero(expires)) { /* No expires header */ 08193 expires = strcasestr(contact, ";expires="); 08194 if (expires) { 08195 /* XXX bug here, we overwrite the string */ 08196 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08197 if (sscanf(expires + 9, "%d", &expiry) != 1) 08198 expiry = default_expiry; 08199 } else { 08200 /* Nothing has been specified */ 08201 expiry = default_expiry; 08202 } 08203 } 08204 08205 /* Look for brackets */ 08206 curi = contact; 08207 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08208 strsep(&curi, ";"); /* This is Header options, not URI options */ 08209 curi = get_in_brackets(contact); 08210 08211 /* if they did not specify Contact: or Expires:, they are querying 08212 what we currently have stored as their contact address, so return 08213 it 08214 */ 08215 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08216 /* If we have an active registration, tell them when the registration is going to expire */ 08217 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08218 pvt->expiry = ast_sched_when(sched, peer->expire); 08219 return PARSE_REGISTER_QUERY; 08220 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08221 /* This means remove all registrations and return OK */ 08222 memset(&peer->addr, 0, sizeof(peer->addr)); 08223 if (!AST_SCHED_DEL(sched, peer->expire)) { 08224 struct sip_peer *peer_ptr = peer; 08225 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08226 } 08227 08228 destroy_association(peer); 08229 08230 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08231 peer->fullcontact[0] = '\0'; 08232 peer->useragent[0] = '\0'; 08233 peer->sipoptions = 0; 08234 peer->lastms = 0; 08235 08236 if (option_verbose > 2) 08237 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08238 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08239 return PARSE_REGISTER_UPDATE; 08240 } 08241 08242 /* Store whatever we got as a contact from the client */ 08243 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08244 08245 /* For the 200 OK, we should use the received contact */ 08246 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08247 08248 /* Make sure it's a SIP URL */ 08249 if (strncasecmp(curi, "sip:", 4)) { 08250 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08251 } else 08252 curi += 4; 08253 /* Ditch q */ 08254 curi = strsep(&curi, ";"); 08255 /* Grab host */ 08256 n = strchr(curi, '@'); 08257 if (!n) { 08258 n = curi; 08259 curi = NULL; 08260 } else 08261 *n++ = '\0'; 08262 pt = strchr(n, ':'); 08263 if (pt) { 08264 *pt++ = '\0'; 08265 port = atoi(pt); 08266 } else 08267 port = STANDARD_SIP_PORT; 08268 oldsin = peer->addr; 08269 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08270 /* XXX This could block for a long time XXX */ 08271 hp = ast_gethostbyname(n, &ahp); 08272 if (!hp) { 08273 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08274 return PARSE_REGISTER_FAILED; 08275 } 08276 peer->addr.sin_family = AF_INET; 08277 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08278 peer->addr.sin_port = htons(port); 08279 } else { 08280 /* Don't trust the contact field. Just use what they came to us 08281 with */ 08282 peer->addr = pvt->recv; 08283 } 08284 08285 /* Save SIP options profile */ 08286 peer->sipoptions = pvt->sipoptions; 08287 08288 if (curi && ast_strlen_zero(peer->username)) 08289 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08290 08291 if (!AST_SCHED_DEL(sched, peer->expire)) { 08292 struct sip_peer *peer_ptr = peer; 08293 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08294 } 08295 if (expiry > max_expiry) 08296 expiry = max_expiry; 08297 if (expiry < min_expiry) 08298 expiry = min_expiry; 08299 if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) { 08300 peer->expire = -1; 08301 } else { 08302 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08303 if (peer->expire == -1) { 08304 struct sip_peer *peer_ptr = peer; 08305 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08306 } 08307 } 08308 pvt->expiry = expiry; 08309 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); 08310 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08311 ast_db_put("SIP/Registry", peer->name, data); 08312 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08313 08314 /* Is this a new IP address for us? */ 08315 if (inaddrcmp(&peer->addr, &oldsin)) { 08316 sip_poke_peer(peer); 08317 if (option_verbose > 2) 08318 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); 08319 register_peer_exten(peer, 1); 08320 } 08321 08322 /* Save User agent */ 08323 useragent = get_header(req, "User-Agent"); 08324 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08325 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08326 if (option_verbose > 3) 08327 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08328 } 08329 08330 /* Allocate A TCP Soccket of incoming connection*/ 08331 if (((!ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP)) || (peer->sockfd != pvt->sockfd)) && (ast_test_flag(&pvt->flags[1], SIP_PAGE2_TCP))) { 08332 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP); 08333 peer->sockfd=pvt->sockfd; 08334 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 08335 } 08336 return PARSE_REGISTER_UPDATE; 08337 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4874 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().
04875 { 04876 /* Divide fields by NULL's */ 04877 char *c; 04878 int f = 0; 04879 04880 c = req->data; 04881 04882 /* First header starts immediately */ 04883 req->header[f] = c; 04884 while(*c) { 04885 if (*c == '\n') { 04886 /* We've got a new header */ 04887 *c = 0; 04888 04889 if (sipdebug && option_debug > 3) 04890 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04891 if (ast_strlen_zero(req->header[f])) { 04892 /* Line by itself means we're now in content */ 04893 c++; 04894 break; 04895 } 04896 if (f >= SIP_MAX_HEADERS - 1) { 04897 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04898 } else 04899 f++; 04900 req->header[f] = c + 1; 04901 } else if (*c == '\r') { 04902 /* Ignore but eliminate \r's */ 04903 *c = 0; 04904 } 04905 c++; 04906 } 04907 /* Check for last header */ 04908 if (!ast_strlen_zero(req->header[f])) { 04909 if (sipdebug && option_debug > 3) 04910 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04911 f++; 04912 } 04913 req->headers = f; 04914 /* Now we process any mime content */ 04915 f = 0; 04916 req->line[f] = c; 04917 while(*c) { 04918 if (*c == '\n') { 04919 /* We've got a new line */ 04920 *c = 0; 04921 if (sipdebug && option_debug > 3) 04922 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04923 if (f >= SIP_MAX_LINES - 1) { 04924 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04925 } else 04926 f++; 04927 req->line[f] = c + 1; 04928 } else if (*c == '\r') { 04929 /* Ignore and eliminate \r's */ 04930 *c = 0; 04931 } 04932 c++; 04933 } 04934 /* Check for last line */ 04935 if (!ast_strlen_zero(req->line[f])) 04936 f++; 04937 req->lines = f; 04938 if (*c) 04939 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04940 /* Split up the first line parts */ 04941 return determine_firstline_parts(req); 04942 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1697 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().
01698 { 01699 char *next, *sep; 01700 char *temp; 01701 unsigned int profile = 0; 01702 int i, found; 01703 01704 if (ast_strlen_zero(supported) ) 01705 return 0; 01706 temp = ast_strdupa(supported); 01707 01708 if (option_debug > 2 && sipdebug) 01709 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01710 01711 for (next = temp; next; next = sep) { 01712 found = FALSE; 01713 if ( (sep = strchr(next, ',')) != NULL) 01714 *sep++ = '\0'; 01715 next = ast_skip_blanks(next); 01716 if (option_debug > 2 && sipdebug) 01717 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01718 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01719 if (!strcasecmp(next, sip_options[i].text)) { 01720 profile |= sip_options[i].id; 01721 found = TRUE; 01722 if (option_debug > 2 && sipdebug) 01723 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01724 break; 01725 } 01726 } 01727 if (!found && option_debug > 2 && sipdebug) { 01728 if (!strncasecmp(next, "x-", 2)) 01729 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01730 else 01731 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01732 } 01733 } 01734 01735 if (pvt) 01736 pvt->sipoptions = profile; 01737 return profile; 01738 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9922 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09923 { 09924 int res = 0; 09925 if (peer->maxms) { 09926 if (peer->lastms < 0) { 09927 ast_copy_string(status, "UNREACHABLE", statuslen); 09928 } else if (peer->lastms > peer->maxms) { 09929 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09930 res = 1; 09931 } else if (peer->lastms) { 09932 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09933 res = 1; 09934 } else { 09935 ast_copy_string(status, "UNKNOWN", statuslen); 09936 } 09937 } else { 09938 ast_copy_string(status, "Unmonitored", statuslen); 09939 /* Checking if port is 0 */ 09940 res = -1; 09941 } 09942 return res; 09943 }
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 10390 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().
10391 { 10392 int x, codec; 10393 10394 for(x = 0; x < 32 ; x++) { 10395 codec = ast_codec_pref_index(pref, x); 10396 if (!codec) 10397 break; 10398 ast_cli(fd, "%s", ast_getformatname(codec)); 10399 ast_cli(fd, ":%d", pref->framing[x]); 10400 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10401 ast_cli(fd, ","); 10402 } 10403 if (!x) 10404 ast_cli(fd, "none"); 10405 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10181 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10182 { 10183 char buf[256]; 10184 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10185 }
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 5075 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.
05076 { 05077 const char *m; /* SDP media offer */ 05078 const char *c; 05079 const char *a; 05080 char host[258]; 05081 int len = -1; 05082 int portno = -1; /*!< RTP Audio port number */ 05083 int vportno = -1; /*!< RTP Video port number */ 05084 int udptlportno = -1; 05085 int peert38capability = 0; 05086 char s[256]; 05087 int old = 0; 05088 05089 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05090 int peercapability = 0, peernoncodeccapability = 0; 05091 int vpeercapability = 0, vpeernoncodeccapability = 0; 05092 struct sockaddr_in sin; /*!< media socket address */ 05093 struct sockaddr_in vsin; /*!< Video socket address */ 05094 05095 const char *codecs; 05096 struct hostent *hp; /*!< RTP Audio host IP */ 05097 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05098 struct ast_hostent audiohp; 05099 struct ast_hostent videohp; 05100 int codec; 05101 int destiterator = 0; 05102 int iterator; 05103 int sendonly = -1; 05104 int numberofports; 05105 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05106 int newjointcapability; /* Negotiated capability */ 05107 int newpeercapability; 05108 int newnoncodeccapability; 05109 int numberofmediastreams = 0; 05110 int debug = sip_debug_test_pvt(p); 05111 05112 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05113 int last_rtpmap_codec=0; 05114 05115 if (!p->rtp) { 05116 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05117 return -1; 05118 } 05119 05120 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05121 newaudiortp = alloca(ast_rtp_alloc_size()); 05122 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05123 ast_rtp_new_init(newaudiortp); 05124 ast_rtp_pt_clear(newaudiortp); 05125 05126 newvideortp = alloca(ast_rtp_alloc_size()); 05127 memset(newvideortp, 0, ast_rtp_alloc_size()); 05128 ast_rtp_new_init(newvideortp); 05129 ast_rtp_pt_clear(newvideortp); 05130 05131 /* Update our last rtprx when we receive an SDP, too */ 05132 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05133 05134 05135 /* Try to find first media stream */ 05136 m = get_sdp(req, "m"); 05137 destiterator = req->sdp_start; 05138 c = get_sdp_iterate(&destiterator, req, "c"); 05139 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05140 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05141 return -1; 05142 } 05143 05144 /* Check for IPv4 address (not IPv6 yet) */ 05145 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05146 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05147 return -1; 05148 } 05149 05150 /* XXX This could block for a long time, and block the main thread! XXX */ 05151 hp = ast_gethostbyname(host, &audiohp); 05152 if (!hp) { 05153 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05154 return -1; 05155 } 05156 vhp = hp; /* Copy to video address as default too */ 05157 05158 iterator = req->sdp_start; 05159 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05160 05161 05162 /* Find media streams in this SDP offer */ 05163 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05164 int x; 05165 int audio = FALSE; 05166 05167 numberofports = 1; 05168 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05169 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05170 audio = TRUE; 05171 numberofmediastreams++; 05172 /* Found audio stream in this media definition */ 05173 portno = x; 05174 /* Scan through the RTP payload types specified in a "m=" line: */ 05175 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05176 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05177 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05178 return -1; 05179 } 05180 if (debug) 05181 ast_verbose("Found RTP audio format %d\n", codec); 05182 ast_rtp_set_m_type(newaudiortp, codec); 05183 } 05184 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05185 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05186 /* If it is not audio - is it video ? */ 05187 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05188 numberofmediastreams++; 05189 vportno = x; 05190 /* Scan through the RTP payload types specified in a "m=" line: */ 05191 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05192 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05193 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05194 return -1; 05195 } 05196 if (debug) 05197 ast_verbose("Found RTP video format %d\n", codec); 05198 ast_rtp_set_m_type(newvideortp, codec); 05199 } 05200 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05201 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05202 if (debug) 05203 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05204 udptlportno = x; 05205 numberofmediastreams++; 05206 05207 if (p->owner && p->lastinvite) { 05208 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05209 if (option_debug > 1) 05210 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05211 } else { 05212 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05213 if (option_debug > 1) 05214 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05215 } 05216 } else 05217 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05218 if (numberofports > 1) 05219 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05220 05221 05222 /* Check for Media-description-level-address for audio */ 05223 c = get_sdp_iterate(&destiterator, req, "c"); 05224 if (!ast_strlen_zero(c)) { 05225 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05226 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05227 } else { 05228 /* XXX This could block for a long time, and block the main thread! XXX */ 05229 if (audio) { 05230 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05231 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05232 return -2; 05233 } 05234 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05235 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05236 return -2; 05237 } 05238 } 05239 05240 } 05241 } 05242 if (portno == -1 && vportno == -1 && udptlportno == -1) 05243 /* No acceptable offer found in SDP - we have no ports */ 05244 /* Do not change RTP or VRTP if this is a re-invite */ 05245 return -2; 05246 05247 if (numberofmediastreams > 2) 05248 /* We have too many fax, audio and/or video media streams, fail this offer */ 05249 return -3; 05250 05251 /* RTP addresses and ports for audio and video */ 05252 sin.sin_family = AF_INET; 05253 vsin.sin_family = AF_INET; 05254 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05255 if (vhp) 05256 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05257 05258 /* Setup UDPTL port number */ 05259 if (p->udptl) { 05260 if (udptlportno > 0) { 05261 sin.sin_port = htons(udptlportno); 05262 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05263 struct sockaddr_in peer; 05264 ast_rtp_get_peer(p->rtp, &peer); 05265 if (peer.sin_addr.s_addr) { 05266 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(&sin.sin_addr)); 05267 if (debug) { 05268 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)); 05269 } 05270 } 05271 } 05272 ast_udptl_set_peer(p->udptl, &sin); 05273 if (debug) 05274 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05275 } else { 05276 ast_udptl_stop(p->udptl); 05277 if (debug) 05278 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05279 } 05280 } 05281 05282 05283 if (p->rtp) { 05284 if (portno > 0) { 05285 sin.sin_port = htons(portno); 05286 ast_rtp_set_peer(p->rtp, &sin); 05287 if (debug) 05288 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05289 } else { 05290 if (udptlportno > 0) { 05291 if (debug) 05292 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05293 } else { 05294 ast_rtp_stop(p->rtp); 05295 if (debug) 05296 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05297 } 05298 } 05299 } 05300 /* Setup video port number */ 05301 if (vportno != -1) 05302 vsin.sin_port = htons(vportno); 05303 05304 /* Next, scan through each "a=rtpmap:" line, noting each 05305 * specified RTP payload type (with corresponding MIME subtype): 05306 */ 05307 /* XXX This needs to be done per media stream, since it's media stream specific */ 05308 iterator = req->sdp_start; 05309 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05310 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05311 if (option_debug > 1) { 05312 int breakout = FALSE; 05313 05314 /* If we're debugging, check for unsupported sdp options */ 05315 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05316 if (debug) 05317 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05318 breakout = TRUE; 05319 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05320 /* Format parameters: Not supported */ 05321 /* Note: This is used for codec parameters, like bitrate for 05322 G722 and video formats for H263 and H264 05323 See RFC2327 for an example */ 05324 if (debug) 05325 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05326 breakout = TRUE; 05327 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05328 /* Video stuff: Not supported */ 05329 if (debug) 05330 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05331 breakout = TRUE; 05332 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05333 /* Video stuff: Not supported */ 05334 if (debug) 05335 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05336 breakout = TRUE; 05337 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05338 /* SRTP stuff, not yet supported */ 05339 if (debug) 05340 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05341 breakout = TRUE; 05342 } 05343 if (breakout) /* We have a match, skip to next header */ 05344 continue; 05345 } 05346 if (!strcasecmp(a, "sendonly")) { 05347 if (sendonly == -1) 05348 sendonly = 1; 05349 continue; 05350 } else if (!strcasecmp(a, "inactive")) { 05351 if (sendonly == -1) 05352 sendonly = 2; 05353 continue; 05354 } else if (!strcasecmp(a, "sendrecv")) { 05355 if (sendonly == -1) 05356 sendonly = 0; 05357 continue; 05358 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05359 char *tmp = strrchr(a, ':'); 05360 long int framing = 0; 05361 if (tmp) { 05362 tmp++; 05363 framing = strtol(tmp, NULL, 10); 05364 if (framing == LONG_MIN || framing == LONG_MAX) { 05365 framing = 0; 05366 if (option_debug) 05367 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05368 } 05369 } 05370 if (framing && p->autoframing) { 05371 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05372 int codec_n; 05373 int format = 0; 05374 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05375 format = ast_rtp_codec_getformat(codec_n); 05376 if (!format) /* non-codec or not found */ 05377 continue; 05378 if (option_debug) 05379 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05380 ast_codec_pref_setsize(pref, format, framing); 05381 } 05382 ast_rtp_codec_setpref(p->rtp, pref); 05383 } 05384 continue; 05385 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05386 /* We have a rtpmap to handle */ 05387 int found = FALSE; 05388 /* We should propably check if this is an audio or video codec 05389 so we know where to look */ 05390 05391 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05392 /* Note: should really look at the 'freq' and '#chans' params too */ 05393 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05394 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05395 if (debug) 05396 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05397 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05398 last_rtpmap_codec++; 05399 found = TRUE; 05400 05401 } else if (p->vrtp) { 05402 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05403 if (debug) 05404 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05405 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05406 last_rtpmap_codec++; 05407 found = TRUE; 05408 } 05409 } 05410 } else { 05411 if (debug) 05412 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05413 } 05414 05415 if (!found) { 05416 /* Remove this codec since it's an unknown media type for us */ 05417 /* XXX This is buggy since the media line for audio and video can have the 05418 same numbers. We need to check as described above, but for testing this works... */ 05419 ast_rtp_unset_m_type(newaudiortp, codec); 05420 ast_rtp_unset_m_type(newvideortp, codec); 05421 if (debug) 05422 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05423 } 05424 } 05425 } 05426 05427 if (udptlportno != -1) { 05428 int found = 0, x; 05429 05430 old = 0; 05431 05432 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05433 iterator = req->sdp_start; 05434 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05435 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05436 found = 1; 05437 if (option_debug > 2) 05438 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05439 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05440 found = 1; 05441 if (option_debug > 2) 05442 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05443 switch (x) { 05444 case 14400: 05445 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05446 break; 05447 case 12000: 05448 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05449 break; 05450 case 9600: 05451 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05452 break; 05453 case 7200: 05454 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05455 break; 05456 case 4800: 05457 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05458 break; 05459 case 2400: 05460 peert38capability |= T38FAX_RATE_2400; 05461 break; 05462 } 05463 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05464 found = 1; 05465 if (option_debug > 2) 05466 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05467 if (x == 0) 05468 peert38capability |= T38FAX_VERSION_0; 05469 else if (x == 1) 05470 peert38capability |= T38FAX_VERSION_1; 05471 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05472 found = 1; 05473 if (option_debug > 2) 05474 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05475 ast_udptl_set_far_max_datagram(p->udptl, x); 05476 ast_udptl_set_local_max_datagram(p->udptl, x); 05477 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05478 found = 1; 05479 if (option_debug > 2) 05480 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05481 if (x == 1) 05482 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05483 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05484 found = 1; 05485 if (option_debug > 2) 05486 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05487 if (x == 1) 05488 peert38capability |= T38FAX_TRANSCODING_MMR; 05489 } 05490 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05491 found = 1; 05492 if (option_debug > 2) 05493 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05494 if (x == 1) 05495 peert38capability |= T38FAX_TRANSCODING_JBIG; 05496 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05497 found = 1; 05498 if (option_debug > 2) 05499 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05500 if (!strcasecmp(s, "localTCF")) 05501 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05502 else if (!strcasecmp(s, "transferredTCF")) 05503 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05504 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05505 found = 1; 05506 if (option_debug > 2) 05507 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05508 if (!strcasecmp(s, "t38UDPRedundancy")) { 05509 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05510 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05511 } else if (!strcasecmp(s, "t38UDPFEC")) { 05512 peert38capability |= T38FAX_UDP_EC_FEC; 05513 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05514 } else { 05515 peert38capability |= T38FAX_UDP_EC_NONE; 05516 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05517 } 05518 } 05519 } 05520 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05521 p->t38.peercapability = peert38capability; 05522 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05523 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05524 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05525 } 05526 if (debug) 05527 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05528 p->t38.capability, 05529 p->t38.peercapability, 05530 p->t38.jointcapability); 05531 } else { 05532 p->t38.state = T38_DISABLED; 05533 if (option_debug > 2) 05534 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05535 } 05536 05537 /* Now gather all of the codecs that we are asked for: */ 05538 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05539 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05540 05541 newjointcapability = p->capability & (peercapability | vpeercapability); 05542 newpeercapability = (peercapability | vpeercapability); 05543 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05544 05545 05546 if (debug) { 05547 /* shame on whoever coded this.... */ 05548 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05549 05550 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05551 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05552 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05553 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05554 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05555 05556 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05557 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05558 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05559 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05560 } 05561 if (!newjointcapability) { 05562 /* If T.38 was not negotiated either, totally bail out... */ 05563 if (!p->t38.jointcapability || !udptlportno) { 05564 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05565 /* Do NOT Change current setting */ 05566 return -1; 05567 } else { 05568 if (option_debug > 2) 05569 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05570 return 0; 05571 } 05572 } 05573 05574 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05575 they are acceptable */ 05576 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05577 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05578 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05579 05580 ast_rtp_pt_copy(p->rtp, newaudiortp); 05581 if (p->vrtp) 05582 ast_rtp_pt_copy(p->vrtp, newvideortp); 05583 05584 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05585 ast_clear_flag(&p->flags[0], SIP_DTMF); 05586 if (newnoncodeccapability & AST_RTP_DTMF) { 05587 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05588 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05589 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05590 ast_rtp_setdtmf(p->rtp, 1); 05591 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05592 } else { 05593 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05594 } 05595 } 05596 05597 /* Setup audio port number */ 05598 if (p->rtp && sin.sin_port) { 05599 ast_rtp_set_peer(p->rtp, &sin); 05600 if (debug) 05601 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05602 } 05603 05604 /* Setup video port number */ 05605 if (p->vrtp && vsin.sin_port) { 05606 ast_rtp_set_peer(p->vrtp, &vsin); 05607 if (debug) 05608 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05609 } 05610 05611 /* Ok, we're going with this offer */ 05612 if (option_debug > 1) { 05613 char buf[SIPBUFSIZE]; 05614 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05615 } 05616 05617 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05618 return 0; 05619 05620 if (option_debug > 3) 05621 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05622 05623 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05624 if (debug) { 05625 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05626 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05627 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05628 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05629 } 05630 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05631 ast_set_read_format(p->owner, p->owner->readformat); 05632 ast_set_write_format(p->owner, p->owner->writeformat); 05633 } 05634 05635 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05636 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05637 /* Activate a re-invite */ 05638 ast_queue_frame(p->owner, &ast_null_frame); 05639 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05640 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05641 S_OR(p->mohsuggest, NULL), 05642 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05643 if (sendonly) 05644 ast_rtp_stop(p->rtp); 05645 /* RTCP needs to go ahead, even if we're on hold!!! */ 05646 /* Activate a re-invite */ 05647 ast_queue_frame(p->owner, &ast_null_frame); 05648 } 05649 05650 /* Manager Hold and Unhold events must be generated, if necessary */ 05651 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05652 change_hold_state(p, req, FALSE, sendonly); 05653 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05654 change_hold_state(p, req, TRUE, sendonly); 05655 return 0; 05656 }
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 2523 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.
02524 { 02525 struct sip_peer *peer=NULL; 02526 struct ast_variable *var = NULL; 02527 struct ast_config *peerlist = NULL; 02528 struct ast_variable *tmp; 02529 struct ast_flags flags = {0}; 02530 const char *iabuf = NULL; 02531 char portstring[6]; /*up to five digits plus null terminator*/ 02532 const char *insecure; 02533 char *cat = NULL; 02534 unsigned short portnum; 02535 02536 /* First check on peer name */ 02537 if (newpeername) { 02538 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02539 if (!var && sin) 02540 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02541 if (!var) { 02542 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02543 /*!\note 02544 * If this one loaded something, then we need to ensure that the host 02545 * field matched. The only reason why we can't have this as a criteria 02546 * is because we only have the IP address and the host field might be 02547 * set as a name (and the reverse PTR might not match). 02548 */ 02549 if (var && sin) { 02550 for (tmp = var; tmp; tmp = tmp->next) { 02551 if (!strcasecmp(tmp->name, "host")) { 02552 struct hostent *hp; 02553 struct ast_hostent ahp; 02554 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02555 /* No match */ 02556 ast_variables_destroy(var); 02557 var = NULL; 02558 } 02559 break; 02560 } 02561 } 02562 } 02563 } 02564 } 02565 02566 if (!var && sin) { /* Then check on IP address */ 02567 iabuf = ast_inet_ntoa(sin->sin_addr); 02568 portnum = ntohs(sin->sin_port); 02569 sprintf(portstring, "%d", portnum); 02570 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02571 if (!var) 02572 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02573 if (!var) { 02574 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02575 if(peerlist){ 02576 while((cat = ast_category_browse(peerlist, cat))) 02577 { 02578 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02579 set_insecure_flags(&flags, insecure, -1); 02580 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02581 var = ast_category_root(peerlist, cat); 02582 break; 02583 } 02584 } 02585 } 02586 if(!var) { 02587 ast_config_destroy(peerlist); 02588 peerlist = NULL; /*for safety's sake*/ 02589 cat = NULL; 02590 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02591 if(peerlist) { 02592 while((cat = ast_category_browse(peerlist, cat))) 02593 { 02594 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02595 set_insecure_flags(&flags, insecure, -1); 02596 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02597 var = ast_category_root(peerlist, cat); 02598 break; 02599 } 02600 } 02601 } 02602 } 02603 } 02604 } 02605 02606 if (!var) { 02607 if(peerlist) 02608 ast_config_destroy(peerlist); 02609 return NULL; 02610 } 02611 02612 for (tmp = var; tmp; tmp = tmp->next) { 02613 /* If this is type=user, then skip this object. */ 02614 if (!strcasecmp(tmp->name, "type") && 02615 !strcasecmp(tmp->value, "user")) { 02616 ast_variables_destroy(var); 02617 return NULL; 02618 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02619 newpeername = tmp->value; 02620 } 02621 } 02622 02623 if (!newpeername) { /* Did not find peer in realtime */ 02624 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02625 if(peerlist) 02626 ast_config_destroy(peerlist); 02627 else 02628 ast_variables_destroy(var); 02629 return NULL; 02630 } 02631 02632 /* Peer found in realtime, now build it in memory */ 02633 peer = build_peer(newpeername, var, NULL, 1); 02634 if (!peer) { 02635 if(peerlist) 02636 ast_config_destroy(peerlist); 02637 else 02638 ast_variables_destroy(var); 02639 return NULL; 02640 } 02641 02642 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02643 /* Cache peer */ 02644 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02645 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02646 if (!AST_SCHED_DEL(sched, peer->expire)) { 02647 struct sip_peer *peer_ptr = peer; 02648 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02649 } 02650 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02651 if (peer->expire == -1) { 02652 struct sip_peer *peer_ptr = peer; 02653 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02654 } 02655 } 02656 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02657 } else { 02658 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02659 } 02660 if(peerlist) 02661 ast_config_destroy(peerlist); 02662 else 02663 ast_variables_destroy(var); 02664 return peer; 02665 }
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 2412 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.
02413 { 02414 char port[10]; 02415 char ipaddr[INET_ADDRSTRLEN]; 02416 char regseconds[20]; 02417 02418 char *sysname = ast_config_AST_SYSTEM_NAME; 02419 char *syslabel = NULL; 02420 02421 time_t nowtime = time(NULL) + expirey; 02422 const char *fc = fullcontact ? "fullcontact" : NULL; 02423 02424 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02425 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02426 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02427 02428 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02429 sysname = NULL; 02430 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02431 syslabel = "regserver"; 02432 02433 if (fc) 02434 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02435 "port", port, "regseconds", regseconds, 02436 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02437 else 02438 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02439 "port", port, "regseconds", regseconds, 02440 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02441 }
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 2715 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02716 { 02717 struct ast_variable *var; 02718 struct ast_variable *tmp; 02719 struct sip_user *user = NULL; 02720 02721 var = ast_load_realtime("sipusers", "name", username, NULL); 02722 02723 if (!var) 02724 return NULL; 02725 02726 for (tmp = var; tmp; tmp = tmp->next) { 02727 if (!strcasecmp(tmp->name, "type") && 02728 !strcasecmp(tmp->value, "peer")) { 02729 ast_variables_destroy(var); 02730 return NULL; 02731 } 02732 } 02733 02734 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02735 02736 if (!user) { /* No user found */ 02737 ast_variables_destroy(var); 02738 return NULL; 02739 } 02740 02741 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02742 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02743 suserobjs++; 02744 ASTOBJ_CONTAINER_LINK(&userl,user); 02745 } else { 02746 /* Move counter from s to r... */ 02747 suserobjs--; 02748 ruserobjs++; 02749 ast_set_flag(&user->flags[0], SIP_REALTIME); 02750 } 02751 ast_variables_destroy(var); 02752 return user; 02753 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9805 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().
09806 { 09807 char buf[1024]; 09808 struct ast_frame f; 09809 const char *content_type = get_header(req, "Content-Type"); 09810 09811 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09812 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09813 if (!p->owner) 09814 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09815 return; 09816 } 09817 09818 if (get_msg_text(buf, sizeof(buf), req)) { 09819 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09820 transmit_response(p, "202 Accepted", req); 09821 if (!p->owner) 09822 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09823 return; 09824 } 09825 09826 if (p->owner) { 09827 if (sip_debug_test_pvt(p)) 09828 ast_verbose("Message received: '%s'\n", buf); 09829 memset(&f, 0, sizeof(f)); 09830 f.frametype = AST_FRAME_TEXT; 09831 f.subclass = 0; 09832 f.offset = 0; 09833 f.data = buf; 09834 f.datalen = strlen(buf); 09835 ast_queue_frame(p->owner, &f); 09836 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09837 } else { /* Message outside of a call, we do not support that */ 09838 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); 09839 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09840 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09841 } 09842 return; 09843 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1632 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01633 { 01634 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01635 int x; 01636 01637 for (x = 0; x < i; x++) { 01638 if (referstatusstrings[x].status == rstatus) 01639 return (char *) referstatusstrings[x].text; 01640 } 01641 return ""; 01642 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8021 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, siptcpsock, strsep(), TRUE, sip_peer::username, and username.
08022 { 08023 char data[256]; 08024 struct in_addr in; 08025 int expiry; 08026 int port; 08027 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08028 08029 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08030 return; 08031 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08032 return; 08033 08034 scan = data; 08035 addr = strsep(&scan, ":"); 08036 port_str = strsep(&scan, ":"); 08037 expiry_str = strsep(&scan, ":"); 08038 username = strsep(&scan, ":"); 08039 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08040 08041 if (!inet_aton(addr, &in)) 08042 return; 08043 08044 if (port_str) 08045 port = atoi(port_str); 08046 else 08047 return; 08048 08049 if (expiry_str) 08050 expiry = atoi(expiry_str); 08051 else 08052 return; 08053 08054 if (username) 08055 ast_copy_string(peer->username, username, sizeof(peer->username)); 08056 if (contact) 08057 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08058 08059 if (option_debug > 1) 08060 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08061 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08062 08063 memset(&peer->addr, 0, sizeof(peer->addr)); 08064 peer->addr.sin_family = AF_INET; 08065 peer->addr.sin_addr = in; 08066 peer->addr.sin_port = htons(port); 08067 if ((sipsock < 0) || (siptcpsock < 0)){ 08068 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08069 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08070 struct sip_peer *peer_ptr = peer; 08071 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08072 } 08073 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08074 if (peer->pokeexpire == -1) { 08075 struct sip_peer *peer_ptr = peer; 08076 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08077 } 08078 } else 08079 sip_poke_peer(peer); 08080 if (!AST_SCHED_DEL(sched, peer->expire)) { 08081 struct sip_peer *peer_ptr = peer; 08082 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08083 } 08084 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08085 if (peer->expire == -1) { 08086 struct sip_peer *peer_ptr = peer; 08087 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08088 } 08089 register_peer_exten(peer, TRUE); 08090 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2444 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().
02445 { 02446 char multi[256]; 02447 char *stringp, *ext, *context; 02448 02449 /* XXX note that global_regcontext is both a global 'enable' flag and 02450 * the name of the global regexten context, if not specified 02451 * individually. 02452 */ 02453 if (ast_strlen_zero(global_regcontext)) 02454 return; 02455 02456 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02457 stringp = multi; 02458 while ((ext = strsep(&stringp, "&"))) { 02459 if ((context = strchr(ext, '@'))) { 02460 *context++ = '\0'; /* split ext@context */ 02461 if (!ast_context_find(context)) { 02462 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02463 continue; 02464 } 02465 } else { 02466 context = global_regcontext; 02467 } 02468 if (onoff) 02469 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02470 ast_strdup(peer->name), ast_free, "SIP"); 02471 else 02472 ast_context_remove_extension(context, ext, 1, NULL); 02473 } 02474 }
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 8725 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.
08727 { 08728 enum check_auth_result res = AUTH_NOT_FOUND; 08729 struct sip_peer *peer; 08730 char tmp[256]; 08731 char *name, *c; 08732 char *t; 08733 char *domain; 08734 08735 /* Terminate URI */ 08736 t = uri; 08737 while(*t && (*t > 32) && (*t != ';')) 08738 t++; 08739 *t = '\0'; 08740 08741 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08742 if (pedanticsipchecking) 08743 ast_uri_decode(tmp); 08744 08745 c = get_in_brackets(tmp); 08746 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08747 08748 if (!strncasecmp(c, "sip:", 4)) { 08749 name = c + 4; 08750 } else { 08751 name = c; 08752 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08753 } 08754 08755 /* Strip off the domain name */ 08756 if ((c = strchr(name, '@'))) { 08757 *c++ = '\0'; 08758 domain = c; 08759 if ((c = strchr(domain, ':'))) /* Remove :port */ 08760 *c = '\0'; 08761 if (!AST_LIST_EMPTY(&domain_list)) { 08762 if (!check_sip_domain(domain, NULL, 0)) { 08763 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08764 return AUTH_UNKNOWN_DOMAIN; 08765 } 08766 } 08767 } 08768 08769 ast_string_field_set(p, exten, name); 08770 build_contact(p); 08771 peer = find_peer(name, NULL, 1); 08772 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08773 /* Peer fails ACL check */ 08774 if (peer) { 08775 ASTOBJ_UNREF(peer, sip_destroy_peer); 08776 res = AUTH_ACL_FAILED; 08777 } else 08778 res = AUTH_NOT_FOUND; 08779 } 08780 if (peer) { 08781 /* Set Frame packetization */ 08782 if (p->rtp) { 08783 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08784 p->autoframing = peer->autoframing; 08785 } 08786 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08787 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08788 res = AUTH_PEER_NOT_DYNAMIC; 08789 } else { 08790 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08791 transmit_response(p, "100 Trying", req); 08792 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08793 if (sip_cancel_destroy(p)) 08794 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08795 08796 /* We have a succesful registration attemp with proper authentication, 08797 now, update the peer */ 08798 switch (parse_register_contact(p, peer, req)) { 08799 case PARSE_REGISTER_FAILED: 08800 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08801 transmit_response_with_date(p, "400 Bad Request", req); 08802 peer->lastmsgssent = -1; 08803 res = 0; 08804 break; 08805 case PARSE_REGISTER_QUERY: 08806 transmit_response_with_date(p, "200 OK", req); 08807 peer->lastmsgssent = -1; 08808 res = 0; 08809 break; 08810 case PARSE_REGISTER_UPDATE: 08811 update_peer(peer, p->expiry); 08812 /* Say OK and ask subsystem to retransmit msg counter */ 08813 transmit_response_with_date(p, "200 OK", req); 08814 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08815 peer->lastmsgssent = -1; 08816 res = 0; 08817 break; 08818 } 08819 } 08820 } 08821 } 08822 if (!peer && autocreatepeer) { 08823 /* Create peer if we have autocreate mode enabled */ 08824 peer = temp_peer(name); 08825 if (peer) { 08826 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08827 if (sip_cancel_destroy(p)) 08828 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08829 switch (parse_register_contact(p, peer, req)) { 08830 case PARSE_REGISTER_FAILED: 08831 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08832 transmit_response_with_date(p, "400 Bad Request", req); 08833 peer->lastmsgssent = -1; 08834 res = 0; 08835 break; 08836 case PARSE_REGISTER_QUERY: 08837 transmit_response_with_date(p, "200 OK", req); 08838 peer->lastmsgssent = -1; 08839 res = 0; 08840 break; 08841 case PARSE_REGISTER_UPDATE: 08842 /* Say OK and ask subsystem to retransmit msg counter */ 08843 transmit_response_with_date(p, "200 OK", req); 08844 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08845 peer->lastmsgssent = -1; 08846 res = 0; 08847 break; 08848 } 08849 } 08850 } 08851 if (!res) { 08852 ast_device_state_changed("SIP/%s", peer->name); 08853 } 08854 if (res < 0) { 08855 switch (res) { 08856 case AUTH_SECRET_FAILED: 08857 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08858 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08859 break; 08860 case AUTH_USERNAME_MISMATCH: 08861 /* Username and digest username does not match. 08862 Asterisk uses the From: username for authentication. We need the 08863 users to use the same authentication user name until we support 08864 proper authentication by digest auth name */ 08865 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08866 break; 08867 case AUTH_NOT_FOUND: 08868 case AUTH_PEER_NOT_DYNAMIC: 08869 case AUTH_ACL_FAILED: 08870 if (global_alwaysauthreject) { 08871 transmit_fake_auth_response(p, &p->initreq, 1); 08872 } else { 08873 /* URI not found */ 08874 if (res == AUTH_PEER_NOT_DYNAMIC) 08875 transmit_response(p, "403 Forbidden", &p->initreq); 08876 else 08877 transmit_response(p, "404 Not found", &p->initreq); 08878 } 08879 break; 08880 default: 08881 break; 08882 } 08883 } 08884 if (peer) 08885 ASTOBJ_UNREF(peer, sip_destroy_peer); 08886 08887 return res; 08888 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7506 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.
07507 { 07508 switch(regstate) { 07509 case REG_STATE_FAILED: 07510 return "Failed"; 07511 case REG_STATE_UNREGISTERED: 07512 return "Unregistered"; 07513 case REG_STATE_REGSENT: 07514 return "Request Sent"; 07515 case REG_STATE_AUTHSENT: 07516 return "Auth. Sent"; 07517 case REG_STATE_REGISTERED: 07518 return "Registered"; 07519 case REG_STATE_REJECTED: 07520 return "Rejected"; 07521 case REG_STATE_TIMEOUT: 07522 return "Timeout"; 07523 case REG_STATE_NOAUTH: 07524 return "No Authentication"; 07525 default: 07526 return "Unknown"; 07527 } 07528 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18186 of file chan_sip.c.
References sip_reload().
18187 { 18188 return sip_reload(0, 0, NULL); 18189 }
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 17029 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().
17030 { 17031 struct ast_config *cfg, *ucfg; 17032 struct ast_variable *v; 17033 struct sip_peer *peer; 17034 struct sip_user *user; 17035 struct ast_hostent ahp; 17036 char *cat, *stringp, *context, *oldregcontext; 17037 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17038 struct hostent *hp; 17039 int format; 17040 struct ast_flags dummy[2]; 17041 int auto_sip_domains = FALSE; 17042 struct sockaddr_in old_bindaddr = bindaddr; 17043 int registry_count = 0, peer_count = 0, user_count = 0; 17044 unsigned int temp_tos = 0; 17045 struct ast_flags debugflag = {0}; 17046 17047 cfg = ast_config_load(config); 17048 17049 /* We *must* have a config file otherwise stop immediately */ 17050 if (!cfg) { 17051 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17052 return -1; 17053 } 17054 17055 if (option_debug > 3) 17056 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17057 17058 clear_realm_authentication(authl); 17059 clear_sip_domains(); 17060 authl = NULL; 17061 17062 /* First, destroy all outstanding registry calls */ 17063 /* This is needed, since otherwise active registry entries will not be destroyed */ 17064 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17065 ASTOBJ_RDLOCK(iterator); 17066 if (iterator->call) { 17067 if (option_debug > 2) 17068 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17069 /* This will also remove references to the registry */ 17070 sip_destroy(iterator->call); 17071 } 17072 ASTOBJ_UNLOCK(iterator); 17073 17074 } while(0)); 17075 17076 /* Then, actually destroy users and registry */ 17077 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17078 if (option_debug > 3) 17079 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17080 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17081 if (option_debug > 3) 17082 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17083 ASTOBJ_CONTAINER_MARKALL(&peerl); 17084 17085 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17086 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17087 oldregcontext = oldcontexts; 17088 17089 /* Clear all flags before setting default values */ 17090 /* Preserve debugging settings for console */ 17091 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17092 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17093 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17094 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17095 17096 /* Reset IP addresses */ 17097 memset(&bindaddr, 0, sizeof(bindaddr)); 17098 ast_free_ha(localaddr); 17099 memset(&localaddr, 0, sizeof(localaddr)); 17100 memset(&externip, 0, sizeof(externip)); 17101 memset(&default_prefs, 0 , sizeof(default_prefs)); 17102 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17103 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17104 ourport = STANDARD_SIP_PORT; 17105 srvlookup = DEFAULT_SRVLOOKUP; 17106 global_tos_sip = DEFAULT_TOS_SIP; 17107 global_tos_audio = DEFAULT_TOS_AUDIO; 17108 global_tos_video = DEFAULT_TOS_VIDEO; 17109 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17110 externexpire = 0; /* Expiration for DNS re-issuing */ 17111 externrefresh = 10; 17112 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17113 17114 /* Reset channel settings to default before re-configuring */ 17115 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17116 global_regcontext[0] = '\0'; 17117 expiry = DEFAULT_EXPIRY; 17118 global_notifyringing = DEFAULT_NOTIFYRINGING; 17119 global_limitonpeers = FALSE; 17120 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17121 global_notifyhold = FALSE; 17122 global_alwaysauthreject = 0; 17123 global_allowsubscribe = FALSE; 17124 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17125 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17126 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17127 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17128 else 17129 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17130 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17131 compactheaders = DEFAULT_COMPACTHEADERS; 17132 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17133 global_regattempts_max = 0; 17134 pedanticsipchecking = DEFAULT_PEDANTIC; 17135 global_mwitime = DEFAULT_MWITIME; 17136 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17137 global_autoframing = 0; 17138 global_allowguest = DEFAULT_ALLOWGUEST; 17139 global_rtptimeout = 0; 17140 global_rtpholdtimeout = 0; 17141 global_rtpkeepalive = 0; 17142 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17143 global_rtautoclear = 120; 17144 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17145 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17146 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17147 17148 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17149 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17150 default_subscribecontext[0] = '\0'; 17151 default_language[0] = '\0'; 17152 default_fromdomain[0] = '\0'; 17153 default_qualify = DEFAULT_QUALIFY; 17154 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17155 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17156 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17157 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17158 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17159 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17160 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17161 17162 /* Debugging settings, always default to off */ 17163 dumphistory = FALSE; 17164 recordhistory = FALSE; 17165 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17166 17167 /* Misc settings for the channel */ 17168 global_relaxdtmf = FALSE; 17169 global_callevents = FALSE; 17170 global_t1min = DEFAULT_T1MIN; 17171 17172 global_matchexterniplocally = FALSE; 17173 17174 /* Copy the default jb config over global_jbconf */ 17175 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17176 17177 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17178 17179 /* Read the [general] config section of sip.conf (or from realtime config) */ 17180 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17181 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17182 continue; 17183 /* handle jb conf */ 17184 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17185 continue; 17186 17187 /* Create the interface list */ 17188 if (!strcasecmp(v->name, "context")) { 17189 ast_copy_string(default_context, v->value, sizeof(default_context)); 17190 } else if (!strcasecmp(v->name, "subscribecontext")) { 17191 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17192 } else if (!strcasecmp(v->name, "allowguest")) { 17193 global_allowguest = ast_true(v->value) ? 1 : 0; 17194 } else if (!strcasecmp(v->name, "realm")) { 17195 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17196 } else if (!strcasecmp(v->name, "useragent")) { 17197 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17198 if (option_debug) 17199 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17200 } else if (!strcasecmp(v->name, "allowtransfer")) { 17201 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17202 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17203 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17204 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17205 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17206 } else if (!strcasecmp(v->name, "rtupdate")) { 17207 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17208 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17209 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17210 } else if (!strcasecmp(v->name, "t1min")) { 17211 global_t1min = atoi(v->value); 17212 } else if (!strcasecmp(v->name, "rtautoclear")) { 17213 int i = atoi(v->value); 17214 if (i > 0) 17215 global_rtautoclear = i; 17216 else 17217 i = 0; 17218 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17219 } else if (!strcasecmp(v->name, "usereqphone")) { 17220 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17221 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17222 global_relaxdtmf = ast_true(v->value); 17223 } else if (!strcasecmp(v->name, "checkmwi")) { 17224 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17225 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17226 global_mwitime = DEFAULT_MWITIME; 17227 } 17228 } else if (!strcasecmp(v->name, "vmexten")) { 17229 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17230 } else if (!strcasecmp(v->name, "rtptimeout")) { 17231 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17232 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17233 global_rtptimeout = 0; 17234 } 17235 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17236 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17237 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17238 global_rtpholdtimeout = 0; 17239 } 17240 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17241 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17242 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17243 global_rtpkeepalive = 0; 17244 } 17245 } else if (!strcasecmp(v->name, "compactheaders")) { 17246 compactheaders = ast_true(v->value); 17247 } else if (!strcasecmp(v->name, "notifymimetype")) { 17248 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17249 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17250 global_limitonpeers = ast_true(v->value); 17251 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17252 global_directrtpsetup = ast_true(v->value); 17253 } else if (!strcasecmp(v->name, "notifyringing")) { 17254 global_notifyringing = ast_true(v->value); 17255 } else if (!strcasecmp(v->name, "notifyhold")) { 17256 global_notifyhold = ast_true(v->value); 17257 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17258 global_alwaysauthreject = ast_true(v->value); 17259 } else if (!strcasecmp(v->name, "mohinterpret") 17260 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17261 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17262 } else if (!strcasecmp(v->name, "mohsuggest")) { 17263 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17264 } else if (!strcasecmp(v->name, "language")) { 17265 ast_copy_string(default_language, v->value, sizeof(default_language)); 17266 } else if (!strcasecmp(v->name, "regcontext")) { 17267 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17268 stringp = newcontexts; 17269 /* Let's remove any contexts that are no longer defined in regcontext */ 17270 cleanup_stale_contexts(stringp, oldregcontext); 17271 /* Create contexts if they don't exist already */ 17272 while ((context = strsep(&stringp, "&"))) { 17273 if (!ast_context_find(context)) 17274 ast_context_create(NULL, context,"SIP"); 17275 } 17276 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17277 } else if (!strcasecmp(v->name, "callerid")) { 17278 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17279 } else if (!strcasecmp(v->name, "fromdomain")) { 17280 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17281 } else if (!strcasecmp(v->name, "outboundproxy")) { 17282 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17283 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17284 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17285 /* Port needs to be after IP */ 17286 sscanf(v->value, "%d", &format); 17287 outboundproxyip.sin_port = htons(format); 17288 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17289 autocreatepeer = ast_true(v->value); 17290 } else if (!strcasecmp(v->name, "srvlookup")) { 17291 srvlookup = ast_true(v->value); 17292 } else if (!strcasecmp(v->name, "pedantic")) { 17293 pedanticsipchecking = ast_true(v->value); 17294 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17295 max_expiry = atoi(v->value); 17296 if (max_expiry < 1) 17297 max_expiry = DEFAULT_MAX_EXPIRY; 17298 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17299 min_expiry = atoi(v->value); 17300 if (min_expiry < 1) 17301 min_expiry = DEFAULT_MIN_EXPIRY; 17302 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17303 default_expiry = atoi(v->value); 17304 if (default_expiry < 1) 17305 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17306 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17307 if (ast_true(v->value)) 17308 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17309 } else if (!strcasecmp(v->name, "dumphistory")) { 17310 dumphistory = ast_true(v->value); 17311 } else if (!strcasecmp(v->name, "recordhistory")) { 17312 recordhistory = ast_true(v->value); 17313 } else if (!strcasecmp(v->name, "registertimeout")) { 17314 global_reg_timeout = atoi(v->value); 17315 if (global_reg_timeout < 1) 17316 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17317 } else if (!strcasecmp(v->name, "registerattempts")) { 17318 global_regattempts_max = atoi(v->value); 17319 } else if (!strcasecmp(v->name, "bindaddr")) { 17320 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17321 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17322 } else { 17323 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17324 } 17325 } else if (!strcasecmp(v->name, "localnet")) { 17326 struct ast_ha *na; 17327 if (!(na = ast_append_ha("d", v->value, localaddr))) 17328 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17329 else 17330 localaddr = na; 17331 } else if (!strcasecmp(v->name, "localmask")) { 17332 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17333 } else if (!strcasecmp(v->name, "externip")) { 17334 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17335 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17336 else 17337 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17338 externexpire = 0; 17339 } else if (!strcasecmp(v->name, "externhost")) { 17340 ast_copy_string(externhost, v->value, sizeof(externhost)); 17341 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17342 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17343 else 17344 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17345 externexpire = time(NULL); 17346 } else if (!strcasecmp(v->name, "externrefresh")) { 17347 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17348 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17349 externrefresh = 10; 17350 } 17351 } else if (!strcasecmp(v->name, "allow")) { 17352 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17353 } else if (!strcasecmp(v->name, "disallow")) { 17354 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17355 } else if (!strcasecmp(v->name, "autoframing")) { 17356 global_autoframing = ast_true(v->value); 17357 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17358 allow_external_domains = ast_true(v->value); 17359 } else if (!strcasecmp(v->name, "autodomain")) { 17360 auto_sip_domains = ast_true(v->value); 17361 } else if (!strcasecmp(v->name, "domain")) { 17362 char *domain = ast_strdupa(v->value); 17363 char *context = strchr(domain, ','); 17364 17365 if (context) 17366 *context++ = '\0'; 17367 17368 if (option_debug && ast_strlen_zero(context)) 17369 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17370 if (ast_strlen_zero(domain)) 17371 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17372 else 17373 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17374 } else if (!strcasecmp(v->name, "register")) { 17375 if (sip_register(v->value, v->lineno) == 0) 17376 registry_count++; 17377 } else if (!strcasecmp(v->name, "tos")) { 17378 if (!ast_str2tos(v->value, &temp_tos)) { 17379 global_tos_sip = temp_tos; 17380 global_tos_audio = temp_tos; 17381 global_tos_video = temp_tos; 17382 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17383 } else 17384 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17385 } else if (!strcasecmp(v->name, "tos_sip")) { 17386 if (ast_str2tos(v->value, &global_tos_sip)) 17387 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17388 } else if (!strcasecmp(v->name, "tos_audio")) { 17389 if (ast_str2tos(v->value, &global_tos_audio)) 17390 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17391 } else if (!strcasecmp(v->name, "tos_video")) { 17392 if (ast_str2tos(v->value, &global_tos_video)) 17393 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17394 } else if (!strcasecmp(v->name, "bindport")) { 17395 if (sscanf(v->value, "%d", &ourport) == 1) { 17396 bindaddr.sin_port = htons(ourport); 17397 } else { 17398 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17399 } 17400 } else if (!strcasecmp(v->name, "qualify")) { 17401 if (!strcasecmp(v->value, "no")) { 17402 default_qualify = 0; 17403 } else if (!strcasecmp(v->value, "yes")) { 17404 default_qualify = DEFAULT_MAXMS; 17405 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17406 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17407 default_qualify = 0; 17408 } 17409 } else if (!strcasecmp(v->name, "callevents")) { 17410 global_callevents = ast_true(v->value); 17411 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17412 default_maxcallbitrate = atoi(v->value); 17413 if (default_maxcallbitrate < 0) 17414 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17415 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17416 global_matchexterniplocally = ast_true(v->value); 17417 } 17418 } 17419 17420 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17421 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17422 allow_external_domains = 1; 17423 } 17424 17425 /* Build list of authentication to various SIP realms, i.e. service providers */ 17426 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17427 /* Format for authentication is auth = username:password@realm */ 17428 if (!strcasecmp(v->name, "auth")) 17429 authl = add_realm_authentication(authl, v->value, v->lineno); 17430 } 17431 17432 ucfg = ast_config_load("users.conf"); 17433 if (ucfg) { 17434 struct ast_variable *gen; 17435 int genhassip, genregistersip; 17436 const char *hassip, *registersip; 17437 17438 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17439 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17440 gen = ast_variable_browse(ucfg, "general"); 17441 cat = ast_category_browse(ucfg, NULL); 17442 while (cat) { 17443 if (strcasecmp(cat, "general")) { 17444 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17445 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17446 if (ast_true(hassip) || (!hassip && genhassip)) { 17447 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17448 if (user) { 17449 ASTOBJ_CONTAINER_LINK(&userl,user); 17450 ASTOBJ_UNREF(user, sip_destroy_user); 17451 user_count++; 17452 } 17453 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17454 if (peer) { 17455 ast_device_state_changed("SIP/%s", peer->name); 17456 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17457 ASTOBJ_UNREF(peer, sip_destroy_peer); 17458 peer_count++; 17459 } 17460 } 17461 if (ast_true(registersip) || (!registersip && genregistersip)) { 17462 char tmp[256]; 17463 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17464 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17465 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17466 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17467 if (!host) 17468 host = ast_variable_retrieve(ucfg, "general", "host"); 17469 if (!username) 17470 username = ast_variable_retrieve(ucfg, "general", "username"); 17471 if (!secret) 17472 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17473 if (!contact) 17474 contact = "s"; 17475 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17476 if (!ast_strlen_zero(secret)) 17477 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17478 else 17479 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17480 if (sip_register(tmp, 0) == 0) 17481 registry_count++; 17482 } 17483 } 17484 } 17485 cat = ast_category_browse(ucfg, cat); 17486 } 17487 ast_config_destroy(ucfg); 17488 } 17489 17490 17491 /* Load peers, users and friends */ 17492 cat = NULL; 17493 while ( (cat = ast_category_browse(cfg, cat)) ) { 17494 const char *utype; 17495 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17496 continue; 17497 utype = ast_variable_retrieve(cfg, cat, "type"); 17498 if (!utype) { 17499 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17500 continue; 17501 } else { 17502 int is_user = 0, is_peer = 0; 17503 if (!strcasecmp(utype, "user")) 17504 is_user = 1; 17505 else if (!strcasecmp(utype, "friend")) 17506 is_user = is_peer = 1; 17507 else if (!strcasecmp(utype, "peer")) 17508 is_peer = 1; 17509 else { 17510 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17511 continue; 17512 } 17513 if (is_user) { 17514 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17515 if (user) { 17516 ASTOBJ_CONTAINER_LINK(&userl,user); 17517 ASTOBJ_UNREF(user, sip_destroy_user); 17518 user_count++; 17519 } 17520 } 17521 if (is_peer) { 17522 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17523 if (peer) { 17524 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17525 ASTOBJ_UNREF(peer, sip_destroy_peer); 17526 peer_count++; 17527 } 17528 } 17529 } 17530 } 17531 if (ast_find_ourip(&__ourip, bindaddr)) { 17532 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17533 ast_config_destroy(cfg); 17534 return 0; 17535 } 17536 if (!ntohs(bindaddr.sin_port)) 17537 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17538 bindaddr.sin_family = AF_INET; 17539 ast_mutex_lock(&netlock); 17540 if (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in))) { 17541 if (sipsock > -1) { 17542 close(sipsock); 17543 sipsock = -1; 17544 } 17545 if (siptcpsock > -1) { 17546 close(siptcpsock); 17547 siptcpsock = -1; 17548 } 17549 } 17550 if (sipsock < 0) { 17551 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17552 if (sipsock < 0) { 17553 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17554 } else { 17555 /* Allow SIP clients on the same host to access us: */ 17556 const int reuseFlag = 1; 17557 17558 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17559 (const char*)&reuseFlag, 17560 sizeof reuseFlag); 17561 17562 ast_enable_packet_fragmentation(sipsock); 17563 17564 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17565 ast_log(LOG_WARNING, "Failed to bind to UDP %s:%d: %s\n", 17566 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17567 strerror(errno)); 17568 close(sipsock); 17569 sipsock = -1; 17570 } else { 17571 if (option_verbose > 1) { 17572 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on UDP %s:%d\n", 17573 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17574 ast_verbose(VERBOSE_PREFIX_2 "Using SIP UDP TOS: %s\n", ast_tos2str(global_tos_sip)); 17575 } 17576 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17577 ast_log(LOG_WARNING, "Unable to set SIP UDP TOS to %s\n", ast_tos2str(global_tos_sip)); 17578 } 17579 } 17580 } 17581 if (siptcpsock < 0) { 17582 siptcpsock = socket(AF_INET, SOCK_STREAM, 0); 17583 if (siptcpsock < 0) { 17584 ast_log(LOG_WARNING, "Unable to create SIP TCP socket: %s\n", strerror(errno)); 17585 } else { 17586 /* Allow SIP clients on the same host to access us: */ 17587 const int reuseFlag = 1; 17588 17589 setsockopt(siptcpsock, SOL_SOCKET, SO_REUSEADDR, 17590 (const char*)&reuseFlag, 17591 sizeof reuseFlag); 17592 17593 ast_enable_packet_fragmentation(sipsock); 17594 17595 if (bind(siptcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17596 ast_log(LOG_WARNING, "Failed to bind to TCP %s:%d: %s\n", 17597 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17598 strerror(errno)); 17599 close(siptcpsock); 17600 siptcpsock = -1; 17601 } else { 17602 if (listen(siptcpsock, 30) < 0) { 17603 ast_log(LOG_WARNING, "Failed to listen on SIP TCP\n"); 17604 } else { 17605 if (option_verbose > 1) { 17606 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on TCP %s:%d\n", 17607 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17608 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TCP TOS: %s\n", ast_tos2str(global_tos_sip)); 17609 } 17610 if (setsockopt(siptcpsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17611 ast_log(LOG_WARNING, "Unable to set SIP TCP TOS to %s\n", ast_tos2str(global_tos_sip)); 17612 } 17613 } 17614 } 17615 } 17616 if ((sipsock < 0) && (siptcpsock <0)) { 17617 ast_config_destroy(cfg); 17618 return -1; 17619 } 17620 ast_mutex_unlock(&netlock); 17621 17622 /* Add default domains - host name, IP address and IP:port */ 17623 /* Only do this if user added any sip domain with "localdomains" */ 17624 /* In order to *not* break backwards compatibility */ 17625 /* Some phones address us at IP only, some with additional port number */ 17626 if (auto_sip_domains) { 17627 char temp[MAXHOSTNAMELEN]; 17628 17629 /* First our default IP address */ 17630 if (bindaddr.sin_addr.s_addr) 17631 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17632 else 17633 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17634 17635 /* Our extern IP address, if configured */ 17636 if (externip.sin_addr.s_addr) 17637 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17638 17639 /* Extern host name (NAT traversal support) */ 17640 if (!ast_strlen_zero(externhost)) 17641 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17642 17643 /* Our host name */ 17644 if (!gethostname(temp, sizeof(temp))) 17645 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17646 } 17647 17648 /* Release configuration from memory */ 17649 ast_config_destroy(cfg); 17650 17651 /* Load the list of manual NOTIFY types to support */ 17652 if (notify_types) 17653 ast_config_destroy(notify_types); 17654 notify_types = ast_config_load(notify_config); 17655 17656 /* Done, tell the manager */ 17657 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); 17658 17659 return 0; 17660 }
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 11607 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().
11608 { 11609 char tmp[512]; 11610 char *c; 11611 char oldnonce[256]; 11612 11613 /* table of recognised keywords, and places where they should be copied */ 11614 const struct x { 11615 const char *key; 11616 int field_index; 11617 } *i, keys[] = { 11618 { "realm=", ast_string_field_index(p, realm) }, 11619 { "nonce=", ast_string_field_index(p, nonce) }, 11620 { "opaque=", ast_string_field_index(p, opaque) }, 11621 { "qop=", ast_string_field_index(p, qop) }, 11622 { "domain=", ast_string_field_index(p, domain) }, 11623 { NULL, 0 }, 11624 }; 11625 11626 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11627 if (ast_strlen_zero(tmp)) 11628 return -1; 11629 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11630 ast_log(LOG_WARNING, "missing Digest.\n"); 11631 return -1; 11632 } 11633 c = tmp + strlen("Digest "); 11634 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11635 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11636 for (i = keys; i->key != NULL; i++) { 11637 char *src, *separator; 11638 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11639 continue; 11640 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11641 c += strlen(i->key); 11642 if (*c == '"') { 11643 src = ++c; 11644 separator = "\""; 11645 } else { 11646 src = c; 11647 separator = ","; 11648 } 11649 strsep(&c, separator); /* clear separator and move ptr */ 11650 ast_string_field_index_set(p, i->field_index, src); 11651 break; 11652 } 11653 if (i->key == NULL) /* not found, try ',' */ 11654 strsep(&c, ","); 11655 } 11656 /* Reset nonce count */ 11657 if (strcmp(p->nonce, oldnonce)) 11658 p->noncecount = 0; 11659 11660 /* Save auth data for following registrations */ 11661 if (p->registry) { 11662 struct sip_registry *r = p->registry; 11663 11664 if (strcmp(r->nonce, p->nonce)) { 11665 ast_string_field_set(r, realm, p->realm); 11666 ast_string_field_set(r, nonce, p->nonce); 11667 ast_string_field_set(r, domain, p->domain); 11668 ast_string_field_set(r, opaque, p->opaque); 11669 ast_string_field_set(r, qop, p->qop); 11670 r->noncecount = 0; 11671 } 11672 } 11673 return build_reply_digest(p, sipmethod, digest, digest_len); 11674 }
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 5989 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.
05990 { 05991 struct sip_request *orig = &p->initreq; 05992 char stripped[80]; 05993 char tmp[80]; 05994 char newto[256]; 05995 const char *c; 05996 const char *ot, *of; 05997 int is_strict = FALSE; /*!< Strict routing flag */ 05998 05999 memset(req, 0, sizeof(struct sip_request)); 06000 06001 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06002 06003 if (!seqno) { 06004 p->ocseq++; 06005 seqno = p->ocseq; 06006 } 06007 06008 if (newbranch) { 06009 p->branch ^= ast_random(); 06010 build_via(p); 06011 } 06012 06013 /* Check for strict or loose router */ 06014 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06015 is_strict = TRUE; 06016 if (sipdebug) 06017 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06018 } 06019 06020 if (sipmethod == SIP_CANCEL) 06021 c = p->initreq.rlPart2; /* Use original URI */ 06022 else if (sipmethod == SIP_ACK) { 06023 /* Use URI from Contact: in 200 OK (if INVITE) 06024 (we only have the contacturi on INVITEs) */ 06025 if (!ast_strlen_zero(p->okcontacturi)) 06026 c = is_strict ? p->route->hop : p->okcontacturi; 06027 else 06028 c = p->initreq.rlPart2; 06029 } else if (!ast_strlen_zero(p->okcontacturi)) 06030 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06031 else if (!ast_strlen_zero(p->uri)) 06032 c = p->uri; 06033 else { 06034 char *n; 06035 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06036 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06037 sizeof(stripped)); 06038 n = get_in_brackets(stripped); 06039 c = strsep(&n, ";"); /* trim ; and beyond */ 06040 } 06041 init_req(req, sipmethod, c); 06042 06043 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06044 06045 add_header(req, "Via", p->via); 06046 if (p->route) { 06047 set_destination(p, p->route->hop); 06048 add_route(req, is_strict ? p->route->next : p->route); 06049 } 06050 06051 ot = get_header(orig, "To"); 06052 of = get_header(orig, "From"); 06053 06054 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06055 as our original request, including tag (or presumably lack thereof) */ 06056 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06057 /* Add the proper tag if we don't have it already. If they have specified 06058 their tag, use it. Otherwise, use our own tag */ 06059 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06060 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06061 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06062 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06063 else 06064 snprintf(newto, sizeof(newto), "%s", ot); 06065 ot = newto; 06066 } 06067 06068 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06069 add_header(req, "From", of); 06070 add_header(req, "To", ot); 06071 } else { 06072 add_header(req, "From", ot); 06073 add_header(req, "To", of); 06074 } 06075 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06076 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06077 add_header(req, "Contact", p->our_contact); 06078 06079 copy_header(req, orig, "Call-ID"); 06080 add_header(req, "CSeq", tmp); 06081 06082 if (!ast_strlen_zero(global_useragent)) 06083 add_header(req, "User-Agent", global_useragent); 06084 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06085 06086 if (!ast_strlen_zero(p->rpid)) 06087 add_header(req, "Remote-Party-ID", p->rpid); 06088 06089 return 0; 06090 }
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 5941 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.
05942 { 05943 char newto[256]; 05944 const char *ot; 05945 05946 init_resp(resp, msg); 05947 copy_via_headers(p, resp, req, "Via"); 05948 if (msg[0] == '1' || msg[0] == '2') 05949 copy_all_header(resp, req, "Record-Route"); 05950 copy_header(resp, req, "From"); 05951 ot = get_header(req, "To"); 05952 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05953 /* Add the proper tag if we don't have it already. If they have specified 05954 their tag, use it. Otherwise, use our own tag */ 05955 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05956 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05957 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05958 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05959 else 05960 ast_copy_string(newto, ot, sizeof(newto)); 05961 ot = newto; 05962 } 05963 add_header(resp, "To", ot); 05964 copy_header(resp, req, "Call-ID"); 05965 copy_header(resp, req, "CSeq"); 05966 if (!ast_strlen_zero(global_useragent)) 05967 add_header(resp, "User-Agent", global_useragent); 05968 add_header(resp, "Allow", ALLOWED_METHODS); 05969 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05970 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05971 /* For registration responses, we also need expiry and 05972 contact info */ 05973 char tmp[256]; 05974 05975 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05976 add_header(resp, "Expires", tmp); 05977 if (p->expiry) { /* Only add contact if we have an expiry time */ 05978 char contact[SIPBUFSIZE]; 05979 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05980 add_header(resp, "Contact", contact); /* Not when we unregister */ 05981 } 05982 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05983 add_header(resp, "Contact", p->our_contact); 05984 } 05985 return 0; 05986 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15937 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.
15938 { 15939 /* If we're supposed to be stopped -- stay stopped */ 15940 if (monitor_thread == AST_PTHREADT_STOP) 15941 return 0; 15942 ast_mutex_lock(&monlock); 15943 if (monitor_thread == pthread_self()) { 15944 ast_mutex_unlock(&monlock); 15945 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15946 return -1; 15947 } 15948 if (monitor_thread != AST_PTHREADT_NULL) { 15949 /* Wake up the thread */ 15950 pthread_kill(monitor_thread, SIGURG); 15951 } else { 15952 /* Start a new monitor */ 15953 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15954 ast_mutex_unlock(&monlock); 15955 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15956 return -1; 15957 } 15958 } 15959 ast_mutex_unlock(&monlock); 15960 return 0; 15961 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1914 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, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01915 { 01916 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01917 int reschedule = DEFAULT_RETRANS; 01918 int xmitres = 0; 01919 01920 /* Lock channel PVT */ 01921 ast_mutex_lock(&pkt->owner->lock); 01922 01923 if (pkt->retrans < MAX_RETRANS) { 01924 pkt->retrans++; 01925 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01926 if (sipdebug && option_debug > 3) 01927 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); 01928 } else { 01929 int siptimer_a; 01930 01931 if (sipdebug && option_debug > 3) 01932 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01933 if (!pkt->timer_a) 01934 pkt->timer_a = 2 ; 01935 else 01936 pkt->timer_a = 2 * pkt->timer_a; 01937 01938 /* For non-invites, a maximum of 4 secs */ 01939 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01940 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01941 siptimer_a = 4000; 01942 01943 /* Reschedule re-transmit */ 01944 reschedule = siptimer_a; 01945 if (option_debug > 3) 01946 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); 01947 } 01948 01949 if (sip_debug_test_pvt(pkt->owner)) { 01950 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01951 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01952 pkt->retrans, sip_nat_mode(pkt->owner), 01953 ast_inet_ntoa(dst->sin_addr), 01954 ntohs(dst->sin_port), pkt->data); 01955 } 01956 01957 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01958 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01959 ast_mutex_unlock(&pkt->owner->lock); 01960 if (xmitres == XMIT_ERROR) 01961 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01962 else 01963 return reschedule; 01964 } 01965 /* Too many retries */ 01966 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01967 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01968 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s from %s for packet seqno %d (%s %s %s)\n", pkt->owner->callid, pkt->owner->from, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response: " : "Request: ", sip_methods[pkt->method].text); 01969 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01970 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01971 } 01972 if (xmitres == XMIT_ERROR) { 01973 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01974 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01975 } else 01976 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01977 01978 pkt->retransid = -1; 01979 01980 if (ast_test_flag(pkt, FLAG_FATAL)) { 01981 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01982 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01983 } 01984 01985 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01986 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01987 01988 if (pkt->owner->owner) { 01989 sip_alreadygone(pkt->owner); 01990 ast_log(LOG_WARNING, "Hanging up call %s from channel %s . No reply to our critical packet after %d retries.\n", pkt->owner->callid, pkt->owner->owner->name, pkt->retrans); 01991 ast_queue_hangup(pkt->owner->owner); 01992 ast_channel_unlock(pkt->owner->owner); 01993 } else { 01994 /* If no channel owner, destroy now */ 01995 01996 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01997 if (pkt->method != SIP_OPTIONS) { 01998 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01999 sip_alreadygone(pkt->owner); 02000 if (option_debug) 02001 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02002 } 02003 } 02004 } 02005 02006 if (pkt->method == SIP_BYE) { 02007 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02008 if (pkt->owner->owner) 02009 ast_channel_unlock(pkt->owner->owner); 02010 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02011 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02012 } 02013 02014 /* In any case, go ahead and remove the packet */ 02015 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02016 if (cur == pkt) 02017 break; 02018 } 02019 if (cur) { 02020 if (prev) 02021 prev->next = cur->next; 02022 else 02023 pkt->owner->packets = cur->next; 02024 ast_mutex_unlock(&pkt->owner->lock); 02025 free(cur); 02026 pkt = NULL; 02027 } else 02028 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02029 if (pkt) 02030 ast_mutex_unlock(&pkt->owner->lock); 02031 return 0; 02032 }
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 2305 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.
02306 { 02307 int res; 02308 02309 add_blank(req); 02310 if (sip_debug_test_pvt(p)) { 02311 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02312 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); 02313 else 02314 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); 02315 } 02316 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02317 struct sip_request tmp; 02318 parse_copy(&tmp, req); 02319 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02320 } 02321 res = (reliable) ? 02322 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02323 __sip_xmit(p, req->data, req->len); 02324 return res; 02325 }
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 2277 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.
02278 { 02279 int res; 02280 02281 add_blank(req); 02282 if (sip_debug_test_pvt(p)) { 02283 const struct sockaddr_in *dst = sip_real_dst(p); 02284 02285 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02286 reliable ? "Reliably " : "", sip_nat_mode(p), 02287 ast_inet_ntoa(dst->sin_addr), 02288 ntohs(dst->sin_port), req->data); 02289 } 02290 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02291 struct sip_request tmp; 02292 parse_copy(&tmp, req); 02293 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02294 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02295 } 02296 res = (reliable) ? 02297 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02298 __sip_xmit(p, req->data, req->len); 02299 if (res > 0) 02300 return 0; 02301 return res; 02302 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8114 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().
08115 { 08116 struct hostent *hp; 08117 struct ast_hostent ahp; 08118 int port; 08119 char *c, *host, *pt; 08120 char contact_buf[256]; 08121 char *contact; 08122 08123 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08124 /* NAT: Don't trust the contact field. Just use what they came to us 08125 with. */ 08126 pvt->sa = pvt->recv; 08127 return 0; 08128 } 08129 08130 /* Work on a copy */ 08131 ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); 08132 contact = contact_buf; 08133 08134 /* Make sure it's a SIP URL */ 08135 if (strncasecmp(contact, "sip:", 4)) { 08136 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08137 } else 08138 contact += 4; 08139 08140 /* Ditch arguments */ 08141 /* XXX this code is replicated also shortly below */ 08142 08143 /* Grab host */ 08144 host = strchr(contact, '@'); 08145 if (!host) { /* No username part */ 08146 host = contact; 08147 c = NULL; 08148 } else { 08149 *host++ = '\0'; 08150 } 08151 pt = strchr(host, ':'); 08152 if (pt) { 08153 *pt++ = '\0'; 08154 port = atoi(pt); 08155 } else 08156 port = STANDARD_SIP_PORT; 08157 08158 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08159 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08160 08161 /* XXX This could block for a long time XXX */ 08162 /* We should only do this if it's a name, not an IP */ 08163 hp = ast_gethostbyname(host, &ahp); 08164 if (!hp) { 08165 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08166 return -1; 08167 } 08168 pvt->sa.sin_family = AF_INET; 08169 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08170 pvt->sa.sin_port = htons(port); 08171 08172 return 0; 08173 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5850 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().
05851 { 05852 char *h, *maddr, hostname[256]; 05853 int port, hn; 05854 struct hostent *hp; 05855 struct ast_hostent ahp; 05856 int debug=sip_debug_test_pvt(p); 05857 05858 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05859 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05860 05861 if (debug) 05862 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05863 05864 /* Find and parse hostname */ 05865 h = strchr(uri, '@'); 05866 if (h) 05867 ++h; 05868 else { 05869 h = uri; 05870 if (strncasecmp(h, "sip:", 4) == 0) 05871 h += 4; 05872 else if (strncasecmp(h, "sips:", 5) == 0) 05873 h += 5; 05874 } 05875 hn = strcspn(h, ":;>") + 1; 05876 if (hn > sizeof(hostname)) 05877 hn = sizeof(hostname); 05878 ast_copy_string(hostname, h, hn); 05879 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05880 h += hn - 1; 05881 05882 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05883 if (*h == ':') { 05884 /* Parse port */ 05885 ++h; 05886 port = strtol(h, &h, 10); 05887 } 05888 else 05889 port = STANDARD_SIP_PORT; 05890 05891 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05892 maddr = strstr(h, "maddr="); 05893 if (maddr) { 05894 maddr += 6; 05895 hn = strspn(maddr, "0123456789.") + 1; 05896 if (hn > sizeof(hostname)) 05897 hn = sizeof(hostname); 05898 ast_copy_string(hostname, maddr, hn); 05899 } 05900 05901 hp = ast_gethostbyname(hostname, &ahp); 05902 if (hp == NULL) { 05903 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05904 return; 05905 } 05906 p->sa.sin_family = AF_INET; 05907 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05908 p->sa.sin_port = htons(port); 05909 if (debug) 05910 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05911 }
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 16266 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().
16267 { 16268 static int dep_insecure_very = 0; 16269 static int dep_insecure_yes = 0; 16270 16271 if (ast_strlen_zero(value)) 16272 return; 16273 16274 if (!strcasecmp(value, "very")) { 16275 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16276 if(!dep_insecure_very) { 16277 if(lineno != -1) 16278 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16279 else 16280 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16281 dep_insecure_very = 1; 16282 } 16283 } 16284 else if (ast_true(value)) { 16285 ast_set_flag(flags, SIP_INSECURE_PORT); 16286 if(!dep_insecure_yes) { 16287 if(lineno != -1) 16288 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16289 else 16290 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16291 dep_insecure_yes = 1; 16292 } 16293 } 16294 else if (!ast_false(value)) { 16295 char buf[64]; 16296 char *word, *next; 16297 ast_copy_string(buf, value, sizeof(buf)); 16298 next = buf; 16299 while ((word = strsep(&next, ","))) { 16300 if (!strcasecmp(word, "port")) 16301 ast_set_flag(flags, SIP_INSECURE_PORT); 16302 else if (!strcasecmp(word, "invite")) 16303 ast_set_flag(flags, SIP_INSECURE_INVITE); 16304 else 16305 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16306 } 16307 } 16308 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16697 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().
16698 { 16699 if (peer->expire == 0) { 16700 /* Don't reset expire or port time during reload 16701 if we have an active registration 16702 */ 16703 peer->expire = -1; 16704 peer->pokeexpire = -1; 16705 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16706 } 16707 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16708 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16709 strcpy(peer->context, default_context); 16710 strcpy(peer->subscribecontext, default_subscribecontext); 16711 strcpy(peer->language, default_language); 16712 strcpy(peer->mohinterpret, default_mohinterpret); 16713 strcpy(peer->mohsuggest, default_mohsuggest); 16714 peer->addr.sin_family = AF_INET; 16715 peer->defaddr.sin_family = AF_INET; 16716 peer->capability = global_capability; 16717 peer->maxcallbitrate = default_maxcallbitrate; 16718 peer->rtptimeout = global_rtptimeout; 16719 peer->rtpholdtimeout = global_rtpholdtimeout; 16720 peer->rtpkeepalive = global_rtpkeepalive; 16721 peer->allowtransfer = global_allowtransfer; 16722 peer->autoframing = global_autoframing; 16723 strcpy(peer->vmexten, default_vmexten); 16724 peer->secret[0] = '\0'; 16725 peer->md5secret[0] = '\0'; 16726 peer->cid_num[0] = '\0'; 16727 peer->cid_name[0] = '\0'; 16728 peer->fromdomain[0] = '\0'; 16729 peer->fromuser[0] = '\0'; 16730 peer->regexten[0] = '\0'; 16731 peer->mailbox[0] = '\0'; 16732 peer->callgroup = 0; 16733 peer->pickupgroup = 0; 16734 peer->maxms = default_qualify; 16735 peer->prefs = default_prefs; 16736 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17999 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().
18000 { 18001 int no = 0; 18002 int ok = FALSE; 18003 char varbuf[30]; 18004 char *inbuf = (char *) data; 18005 18006 if (ast_strlen_zero(inbuf)) { 18007 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18008 return 0; 18009 } 18010 ast_channel_lock(chan); 18011 18012 /* Check for headers */ 18013 while (!ok && no <= 50) { 18014 no++; 18015 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 18016 18017 /* Compare without the leading underscore */ 18018 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 18019 ok = TRUE; 18020 } 18021 if (ok) { 18022 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18023 if (sipdebug) 18024 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18025 } else { 18026 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18027 } 18028 ast_channel_unlock(chan); 18029 return 0; 18030 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2668 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02669 { 02670 /* We know name is the first field, so we can cast */ 02671 struct sip_peer *p = (struct sip_peer *) name; 02672 return !(!inaddrcmp(&p->addr, sin) || 02673 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02674 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02675 }
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 4501 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().
04503 { 04504 struct sip_pvt *p; 04505 04506 if (!(p = ast_calloc(1, sizeof(*p)))) 04507 return NULL; 04508 04509 if (ast_string_field_init(p, 512)) { 04510 free(p); 04511 return NULL; 04512 } 04513 04514 ast_mutex_init(&p->lock); 04515 04516 p->method = intended_method; 04517 p->initid = -1; 04518 p->waitid = -1; 04519 p->autokillid = -1; 04520 p->subscribed = NONE; 04521 p->stateid = -1; 04522 p->sockfd=-1; 04523 p->prefs = default_prefs; /* Set default codecs for this call */ 04524 04525 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04526 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04527 04528 if (sin) { 04529 p->sa = *sin; 04530 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04531 p->ourip = __ourip; 04532 } else 04533 p->ourip = __ourip; 04534 04535 /* Copy global flags to this PVT at setup. */ 04536 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04537 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04538 04539 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04540 04541 p->branch = ast_random(); 04542 make_our_tag(p->tag, sizeof(p->tag)); 04543 p->ocseq = INITIAL_CSEQ; 04544 04545 if (sip_methods[intended_method].need_rtp) { 04546 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04547 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04548 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04549 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04550 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04551 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04552 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04553 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04554 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04555 ast_mutex_destroy(&p->lock); 04556 if (p->chanvars) { 04557 ast_variables_destroy(p->chanvars); 04558 p->chanvars = NULL; 04559 } 04560 free(p); 04561 return NULL; 04562 } 04563 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04564 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04565 ast_rtp_settos(p->rtp, global_tos_audio); 04566 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04567 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04568 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04569 if (p->vrtp) { 04570 ast_rtp_settos(p->vrtp, global_tos_video); 04571 ast_rtp_setdtmf(p->vrtp, 0); 04572 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04573 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04574 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04575 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04576 } 04577 if (p->udptl) 04578 ast_udptl_settos(p->udptl, global_tos_audio); 04579 p->maxcallbitrate = default_maxcallbitrate; 04580 p->autoframing = global_autoframing; 04581 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04582 } 04583 04584 if (useglobal_nat && sin) { 04585 /* Setup NAT structure according to global settings if we have an address */ 04586 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04587 p->recv = *sin; 04588 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04589 } 04590 04591 if (p->method != SIP_REGISTER) 04592 ast_string_field_set(p, fromdomain, default_fromdomain); 04593 build_via(p); 04594 if (!callid) 04595 build_callid_pvt(p); 04596 else 04597 ast_string_field_set(p, callid, callid); 04598 /* Assign default music on hold class */ 04599 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04600 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04601 p->capability = global_capability; 04602 p->allowtransfer = global_allowtransfer; 04603 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04604 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04605 p->noncodeccapability |= AST_RTP_DTMF; 04606 if (p->udptl) { 04607 p->t38.capability = global_t38_capability; 04608 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04609 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04610 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04611 p->t38.capability |= T38FAX_UDP_EC_FEC; 04612 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04613 p->t38.capability |= T38FAX_UDP_EC_NONE; 04614 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04615 p->t38.jointcapability = p->t38.capability; 04616 } 04617 ast_string_field_set(p, context, default_context); 04618 04619 /* Add to active dialog list */ 04620 ast_mutex_lock(&iflock); 04621 p->next = iflist; 04622 iflist = p; 04623 ast_mutex_unlock(&iflock); 04624 if (option_debug) 04625 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"); 04626 return p; 04627 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1659 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().
01660 { 01661 if (option_debug > 2) 01662 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01663 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01664 }
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 3693 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.
03694 { 03695 int res = 0; 03696 struct sip_pvt *p = ast->tech_pvt; 03697 03698 ast_mutex_lock(&p->lock); 03699 if (ast->_state != AST_STATE_UP) { 03700 try_suggested_sip_codec(p); 03701 03702 ast_setstate(ast, AST_STATE_UP); 03703 if (option_debug) 03704 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03705 if (p->t38.state == T38_PEER_DIRECT) { 03706 p->t38.state = T38_ENABLED; 03707 if (option_debug > 1) 03708 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03709 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03710 } else { 03711 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03712 } 03713 } 03714 ast_mutex_unlock(&p->lock); 03715 return res; 03716 }
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 2974 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.
02975 { 02976 int res, xmitres = 0; 02977 struct sip_pvt *p; 02978 struct varshead *headp; 02979 struct ast_var_t *current; 02980 const char *referer = NULL; /* SIP refererer */ 02981 02982 p = ast->tech_pvt; 02983 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02984 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02985 return -1; 02986 } 02987 02988 /* Check whether there is vxml_url, distinctive ring variables */ 02989 headp=&ast->varshead; 02990 AST_LIST_TRAVERSE(headp,current,entries) { 02991 /* Check whether there is a VXML_URL variable */ 02992 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02993 p->options->vxml_url = ast_var_value(current); 02994 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02995 p->options->uri_options = ast_var_value(current); 02996 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02997 /* Check whether there is a ALERT_INFO variable */ 02998 p->options->distinctive_ring = ast_var_value(current); 02999 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03000 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03001 p->options->addsipheaders = 1; 03002 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03003 /* This is a transfered call */ 03004 p->options->transfer = 1; 03005 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03006 /* This is the referer */ 03007 referer = ast_var_value(current); 03008 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03009 /* We're replacing a call. */ 03010 p->options->replaces = ast_var_value(current); 03011 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 03012 p->t38.state = T38_LOCAL_DIRECT; 03013 if (option_debug) 03014 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03015 } 03016 03017 } 03018 03019 res = 0; 03020 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03021 03022 if (p->options->transfer) { 03023 char buf[SIPBUFSIZE/2]; 03024 03025 if (referer) { 03026 if (sipdebug && option_debug > 2) 03027 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03028 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03029 } else 03030 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03031 ast_string_field_set(p, cid_name, buf); 03032 } 03033 if (option_debug) 03034 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03035 03036 res = update_call_counter(p, INC_CALL_RINGING); 03037 if ( res != -1 ) { 03038 p->callingpres = ast->cid.cid_pres; 03039 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03040 p->jointnoncodeccapability = p->noncodeccapability; 03041 03042 /* If there are no audio formats left to offer, punt */ 03043 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03044 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03045 res = -1; 03046 } else { 03047 p->t38.jointcapability = p->t38.capability; 03048 if (option_debug > 1) 03049 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03050 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03051 if (xmitres == XMIT_ERROR) 03052 return -1; /* Transmission error */ 03053 03054 p->invitestate = INV_CALLING; 03055 03056 /* Initialize auto-congest time */ 03057 AST_SCHED_DEL(sched, p->initid); 03058 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03059 } 03060 } 03061 return res; 03062 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2147 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().
02148 { 02149 int res = 0; 02150 if (p->autokillid > -1) { 02151 if (!(res = ast_sched_del(sched, p->autokillid))) { 02152 append_history(p, "CancelDestroy", ""); 02153 p->autokillid = -1; 02154 } 02155 } 02156 return res; 02157 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1741 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01742 { 01743 if (!sipdebug) 01744 return 0; 01745 if (debugaddr.sin_addr.s_addr) { 01746 if (((ntohs(debugaddr.sin_port) != 0) 01747 && (debugaddr.sin_port != addr->sin_port)) 01748 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01749 return 0; 01750 } 01751 return 1; 01752 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1767 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().
01768 { 01769 if (!sipdebug) 01770 return 0; 01771 return sip_debug_test_addr(sip_real_dst(p)); 01772 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3336 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().
03337 { 03338 ast_mutex_lock(&iflock); 03339 if (option_debug > 2) 03340 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03341 __sip_destroy(p, 1); 03342 ast_mutex_unlock(&iflock); 03343 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2477 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().
02478 { 02479 if (option_debug > 2) 02480 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02481 02482 /* Delete it, it needs to disappear */ 02483 if (peer->call) 02484 sip_destroy(peer->call); 02485 02486 if (peer->mwipvt) /* We have an active subscription, delete it */ 02487 sip_destroy(peer->mwipvt); 02488 02489 if (peer->chanvars) { 02490 ast_variables_destroy(peer->chanvars); 02491 peer->chanvars = NULL; 02492 } 02493 02494 register_peer_exten(peer, FALSE); 02495 ast_free_ha(peer->ha); 02496 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02497 apeerobjs--; 02498 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02499 rpeerobjs--; 02500 else 02501 speerobjs--; 02502 clear_realm_authentication(peer->auth); 02503 peer->auth = NULL; 02504 free(peer); 02505 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2696 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().
02697 { 02698 if (option_debug > 2) 02699 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02700 ast_free_ha(user->ha); 02701 if (user->chanvars) { 02702 ast_variables_destroy(user->chanvars); 02703 user->chanvars = NULL; 02704 } 02705 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02706 ruserobjs--; 02707 else 02708 suserobjs--; 02709 free(user); 02710 }
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 16108 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().
16109 { 16110 char *host; 16111 char *tmp; 16112 16113 struct hostent *hp; 16114 struct ast_hostent ahp; 16115 struct sip_peer *p; 16116 16117 int res = AST_DEVICE_INVALID; 16118 16119 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16120 host = ast_strdupa(data ? data : ""); 16121 if ((tmp = strchr(host, '@'))) 16122 host = tmp + 1; 16123 16124 if (option_debug > 2) 16125 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16126 16127 if ((p = find_peer(host, NULL, 1))) { 16128 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16129 /* we have an address for the peer */ 16130 16131 /* Check status in this order 16132 - Hold 16133 - Ringing 16134 - Busy (enforced only by call limit) 16135 - Inuse (we have a call) 16136 - Unreachable (qualify) 16137 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16138 for registered devices */ 16139 16140 if (p->onHold) 16141 /* First check for hold or ring states */ 16142 res = AST_DEVICE_ONHOLD; 16143 else if (p->inRinging) { 16144 if (p->inRinging == p->inUse) 16145 res = AST_DEVICE_RINGING; 16146 else 16147 res = AST_DEVICE_RINGINUSE; 16148 } else if (p->call_limit && (p->inUse == p->call_limit)) 16149 /* check call limit */ 16150 res = AST_DEVICE_BUSY; 16151 else if (p->call_limit && p->inUse) 16152 /* Not busy, but we do have a call */ 16153 res = AST_DEVICE_INUSE; 16154 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16155 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16156 res = AST_DEVICE_UNAVAILABLE; 16157 else /* Default reply if we're registered and have no other data */ 16158 res = AST_DEVICE_NOT_INUSE; 16159 } else { 16160 /* there is no address, it's unavailable */ 16161 res = AST_DEVICE_UNAVAILABLE; 16162 } 16163 ASTOBJ_UNREF(p,sip_destroy_peer); 16164 } else { 16165 char *port = strchr(host, ':'); 16166 if (port) 16167 *port = '\0'; 16168 hp = ast_gethostbyname(host, &ahp); 16169 if (hp) 16170 res = AST_DEVICE_UNKNOWN; 16171 } 16172 16173 return res; 16174 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11420 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.
11421 { 11422 int oldsipdebug = sipdebug_console; 11423 if (argc != 3) { 11424 if (argc != 5) 11425 return RESULT_SHOWUSAGE; 11426 else if (strcmp(argv[3], "ip") == 0) 11427 return sip_do_debug_ip(fd, argc, argv); 11428 else if (strcmp(argv[3], "peer") == 0) 11429 return sip_do_debug_peer(fd, argc, argv); 11430 else 11431 return RESULT_SHOWUSAGE; 11432 } 11433 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11434 memset(&debugaddr, 0, sizeof(debugaddr)); 11435 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11436 return RESULT_SUCCESS; 11437 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11439 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.
11440 { 11441 int oldsipdebug = sipdebug_console; 11442 char *newargv[6] = { "sip", "set", "debug", NULL }; 11443 if (argc != 2) { 11444 if (argc != 4) 11445 return RESULT_SHOWUSAGE; 11446 else if (strcmp(argv[2], "ip") == 0) { 11447 newargv[3] = argv[2]; 11448 newargv[4] = argv[3]; 11449 return sip_do_debug_ip(fd, argc + 1, newargv); 11450 } else if (strcmp(argv[2], "peer") == 0) { 11451 newargv[3] = argv[2]; 11452 newargv[4] = argv[3]; 11453 return sip_do_debug_peer(fd, argc + 1, newargv); 11454 } else 11455 return RESULT_SHOWUSAGE; 11456 } 11457 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11458 memset(&debugaddr, 0, sizeof(debugaddr)); 11459 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11460 return RESULT_SUCCESS; 11461 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11366 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().
11367 { 11368 struct hostent *hp; 11369 struct ast_hostent ahp; 11370 int port = 0; 11371 char *p, *arg; 11372 11373 /* sip set debug ip <ip> */ 11374 if (argc != 5) 11375 return RESULT_SHOWUSAGE; 11376 p = arg = argv[4]; 11377 strsep(&p, ":"); 11378 if (p) 11379 port = atoi(p); 11380 hp = ast_gethostbyname(arg, &ahp); 11381 if (hp == NULL) 11382 return RESULT_SHOWUSAGE; 11383 11384 debugaddr.sin_family = AF_INET; 11385 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11386 debugaddr.sin_port = htons(port); 11387 if (port == 0) 11388 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11389 else 11390 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11391 11392 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11393 11394 return RESULT_SUCCESS; 11395 }
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 11398 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().
11399 { 11400 struct sip_peer *peer; 11401 if (argc != 5) 11402 return RESULT_SHOWUSAGE; 11403 peer = find_peer(argv[4], NULL, 1); 11404 if (peer) { 11405 if (peer->addr.sin_addr.s_addr) { 11406 debugaddr.sin_family = AF_INET; 11407 debugaddr.sin_addr = peer->addr.sin_addr; 11408 debugaddr.sin_port = peer->addr.sin_port; 11409 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11410 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11411 } else 11412 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11413 ASTOBJ_UNREF(peer,sip_destroy_peer); 11414 } else 11415 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11416 return RESULT_SUCCESS; 11417 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11539 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11540 { 11541 if (argc != 2) { 11542 return RESULT_SHOWUSAGE; 11543 } 11544 recordhistory = TRUE; 11545 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11546 return RESULT_SUCCESS; 11547 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18145 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().
18146 { 18147 reload_config(reason); 18148 18149 /* Prune peers who still are supposed to be deleted */ 18150 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18151 if (option_debug > 3) 18152 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18153 18154 /* Send qualify (OPTIONS) to all peers */ 18155 sip_poke_all_peers(); 18156 18157 /* Register with all services */ 18158 sip_send_all_registers(); 18159 18160 if (option_debug > 3) 18161 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18162 18163 return 0; 18164 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17944 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().
17945 { 17946 struct sip_pvt *p; 17947 char *mode; 17948 if (data) 17949 mode = (char *)data; 17950 else { 17951 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17952 return 0; 17953 } 17954 ast_channel_lock(chan); 17955 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17956 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17957 ast_channel_unlock(chan); 17958 return 0; 17959 } 17960 p = chan->tech_pvt; 17961 if (!p) { 17962 ast_channel_unlock(chan); 17963 return 0; 17964 } 17965 ast_mutex_lock(&p->lock); 17966 if (!strcasecmp(mode,"info")) { 17967 ast_clear_flag(&p->flags[0], SIP_DTMF); 17968 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17969 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17970 } else if (!strcasecmp(mode,"rfc2833")) { 17971 ast_clear_flag(&p->flags[0], SIP_DTMF); 17972 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17973 p->jointnoncodeccapability |= AST_RTP_DTMF; 17974 } else if (!strcasecmp(mode,"inband")) { 17975 ast_clear_flag(&p->flags[0], SIP_DTMF); 17976 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17977 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17978 } else 17979 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17980 if (p->rtp) 17981 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17982 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17983 if (!p->vad) { 17984 p->vad = ast_dsp_new(); 17985 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17986 } 17987 } else { 17988 if (p->vad) { 17989 ast_dsp_free(p->vad); 17990 p->vad = NULL; 17991 } 17992 } 17993 ast_mutex_unlock(&p->lock); 17994 ast_channel_unlock(chan); 17995 return 0; 17996 }
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 11224 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().
11225 { 11226 int x = 0; 11227 struct sip_history *hist; 11228 static int errmsg = 0; 11229 11230 if (!dialog) 11231 return; 11232 11233 if (!option_debug && !sipdebug) { 11234 if (!errmsg) { 11235 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11236 errmsg = 1; 11237 } 11238 return; 11239 } 11240 11241 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11242 if (dialog->subscribed) 11243 ast_log(LOG_DEBUG, " * Subscription\n"); 11244 else 11245 ast_log(LOG_DEBUG, " * SIP Call\n"); 11246 if (dialog->history) 11247 AST_LIST_TRAVERSE(dialog->history, hist, list) 11248 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11249 if (!x) 11250 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11251 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11252 }
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 3797 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.
03798 { 03799 int ret = -1; 03800 struct sip_pvt *p; 03801 03802 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03803 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03804 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03805 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03806 03807 if (!newchan || !newchan->tech_pvt) { 03808 if (!newchan) 03809 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03810 else 03811 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03812 return -1; 03813 } 03814 p = newchan->tech_pvt; 03815 03816 if (!p) { 03817 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03818 return -1; 03819 } 03820 03821 ast_mutex_lock(&p->lock); 03822 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03823 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03824 if (p->owner != oldchan) 03825 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03826 else { 03827 p->owner = newchan; 03828 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03829 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03830 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03831 redirect of both channels). Note that a channel can not be masqueraded *into* 03832 a native bridge. So there is no danger that this breaks a native bridge that 03833 should stay up. */ 03834 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03835 ret = 0; 03836 } 03837 if (option_debug > 2) 03838 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03839 03840 ast_mutex_unlock(&p->lock); 03841 return ret; 03842 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18089 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
18090 { 18091 struct sip_pvt *p = chan->tech_pvt; 18092 return p->peercapability ? p->peercapability : p->capability; 18093 }
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 17797 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.
17798 { 17799 struct sip_pvt *p = NULL; 17800 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17801 17802 if (!(p = chan->tech_pvt)) 17803 return AST_RTP_GET_FAILED; 17804 17805 ast_mutex_lock(&p->lock); 17806 if (!(p->rtp)) { 17807 ast_mutex_unlock(&p->lock); 17808 return AST_RTP_GET_FAILED; 17809 } 17810 17811 *rtp = p->rtp; 17812 17813 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17814 res = AST_RTP_TRY_PARTIAL; 17815 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17816 res = AST_RTP_TRY_NATIVE; 17817 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17818 res = AST_RTP_GET_FAILED; 17819 17820 ast_mutex_unlock(&p->lock); 17821 17822 return res; 17823 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 17662 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.
17663 { 17664 struct sip_pvt *p; 17665 struct ast_udptl *udptl = NULL; 17666 17667 p = chan->tech_pvt; 17668 if (!p) 17669 return NULL; 17670 17671 ast_mutex_lock(&p->lock); 17672 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17673 udptl = p->udptl; 17674 ast_mutex_unlock(&p->lock); 17675 return udptl; 17676 }
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 17826 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.
17827 { 17828 struct sip_pvt *p = NULL; 17829 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17830 17831 if (!(p = chan->tech_pvt)) 17832 return AST_RTP_GET_FAILED; 17833 17834 ast_mutex_lock(&p->lock); 17835 if (!(p->vrtp)) { 17836 ast_mutex_unlock(&p->lock); 17837 return AST_RTP_GET_FAILED; 17838 } 17839 17840 *rtp = p->vrtp; 17841 17842 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17843 res = AST_RTP_TRY_NATIVE; 17844 17845 ast_mutex_unlock(&p->lock); 17846 17847 return res; 17848 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 17714 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().
17715 { 17716 struct sip_pvt *p; 17717 int flag = 0; 17718 17719 p = chan->tech_pvt; 17720 if (!p || !pvt->udptl) 17721 return -1; 17722 17723 /* Setup everything on the other side like offered/responded from first side */ 17724 ast_mutex_lock(&p->lock); 17725 17726 /*! \todo check if this is not set earlier when setting up the PVT. If not 17727 maybe it should move there. */ 17728 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17729 17730 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17731 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17732 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17733 17734 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17735 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17736 not really T38 re-invites which are different. In this 17737 case it's used properly, to see if we can reinvite over 17738 NAT 17739 */ 17740 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17741 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17742 flag =1; 17743 } else { 17744 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17745 } 17746 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17747 if (!p->pendinginvite) { 17748 if (option_debug > 2) { 17749 if (flag) 17750 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)); 17751 else 17752 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)); 17753 } 17754 transmit_reinvite_with_t38_sdp(p); 17755 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17756 if (option_debug > 2) { 17757 if (flag) 17758 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)); 17759 else 17760 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)); 17761 } 17762 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17763 } 17764 } 17765 /* Reset lastrtprx timer */ 17766 p->lastrtprx = p->lastrtptx = time(NULL); 17767 ast_mutex_unlock(&p->lock); 17768 return 0; 17769 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17770 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17771 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17772 flag = 1; 17773 } else { 17774 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17775 } 17776 if (option_debug > 2) { 17777 if (flag) 17778 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)); 17779 else 17780 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)); 17781 } 17782 pvt->t38.state = T38_ENABLED; 17783 p->t38.state = T38_ENABLED; 17784 if (option_debug > 1) { 17785 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17786 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17787 } 17788 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17789 p->lastrtprx = p->lastrtptx = time(NULL); 17790 ast_mutex_unlock(&p->lock); 17791 return 0; 17792 } 17793 }
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 3508 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.
03509 { 03510 struct sip_pvt *p = ast->tech_pvt; 03511 int needcancel = FALSE; 03512 int needdestroy = 0; 03513 struct ast_channel *oldowner = ast; 03514 03515 if (!p) { 03516 if (option_debug) 03517 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03518 return 0; 03519 } 03520 03521 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03522 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03523 if (option_debug && sipdebug) 03524 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03525 update_call_counter(p, DEC_CALL_LIMIT); 03526 } 03527 if (option_debug >3) 03528 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03529 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03530 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03531 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03532 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03533 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03534 p->owner->tech_pvt = NULL; 03535 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03536 return 0; 03537 } 03538 if (option_debug) { 03539 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03540 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03541 else { 03542 if (option_debug) 03543 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03544 } 03545 } 03546 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03547 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03548 03549 ast_mutex_lock(&p->lock); 03550 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03551 if (option_debug && sipdebug) 03552 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03553 update_call_counter(p, DEC_CALL_LIMIT); 03554 } 03555 03556 /* Determine how to disconnect */ 03557 if (p->owner != ast) { 03558 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03559 ast_mutex_unlock(&p->lock); 03560 return 0; 03561 } 03562 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03563 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03564 needcancel = TRUE; 03565 if (option_debug > 3) 03566 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03567 } 03568 03569 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03570 03571 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03572 03573 /* Disconnect */ 03574 if (p->vad) 03575 ast_dsp_free(p->vad); 03576 03577 p->owner = NULL; 03578 ast->tech_pvt = NULL; 03579 03580 ast_module_unref(ast_module_info->self); 03581 03582 /* Do not destroy this pvt until we have timeout or 03583 get an answer to the BYE or INVITE/CANCEL 03584 If we get no answer during retransmit period, drop the call anyway. 03585 (Sorry, mother-in-law, you can't deny a hangup by sending 03586 603 declined to BYE...) 03587 */ 03588 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03589 needdestroy = 1; /* Set destroy flag at end of this function */ 03590 else if (p->invitestate != INV_CALLING) 03591 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03592 03593 /* Start the process if it's not already started */ 03594 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03595 if (needcancel) { /* Outgoing call, not up */ 03596 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03597 /* stop retransmitting an INVITE that has not received a response */ 03598 __sip_pretend_ack(p); 03599 p->invitestate = INV_CANCELLED; 03600 03601 /* if we can't send right now, mark it pending */ 03602 if (p->invitestate == INV_CALLING) { 03603 /* We can't send anything in CALLING state */ 03604 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03605 /* 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. */ 03606 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03607 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03608 } else { 03609 /* Send a new request: CANCEL */ 03610 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03611 /* Actually don't destroy us yet, wait for the 487 on our original 03612 INVITE, but do set an autodestruct just in case we never get it. */ 03613 needdestroy = 0; 03614 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03615 } 03616 if ( p->initid != -1 ) { 03617 /* channel still up - reverse dec of inUse counter 03618 only if the channel is not auto-congested */ 03619 update_call_counter(p, INC_CALL_LIMIT); 03620 } 03621 } else { /* Incoming call, not up */ 03622 const char *res; 03623 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03624 transmit_response_reliable(p, res, &p->initreq); 03625 else 03626 transmit_response_reliable(p, "603 Declined", &p->initreq); 03627 p->invitestate = INV_TERMINATED; 03628 } 03629 } else { /* Call is in UP state, send BYE */ 03630 if (!p->pendinginvite) { 03631 char *audioqos = ""; 03632 char *videoqos = ""; 03633 if (p->rtp) 03634 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03635 if (p->vrtp) 03636 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03637 /* Send a hangup */ 03638 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03639 03640 /* Get RTCP quality before end of call */ 03641 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03642 if (p->rtp) 03643 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03644 if (p->vrtp) 03645 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03646 } 03647 if (p->rtp && oldowner) 03648 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03649 if (p->vrtp && oldowner) 03650 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03651 } else { 03652 /* Note we will need a BYE when this all settles out 03653 but we can't send one while we have "INVITE" outstanding. */ 03654 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03655 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03656 AST_SCHED_DEL(sched, p->waitid); 03657 if (sip_cancel_destroy(p)) 03658 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03659 } 03660 } 03661 } 03662 if (needdestroy) 03663 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03664 ast_mutex_unlock(&p->lock); 03665 return 0; 03666 }
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 3913 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.
03914 { 03915 struct sip_pvt *p = ast->tech_pvt; 03916 int res = 0; 03917 03918 ast_mutex_lock(&p->lock); 03919 switch(condition) { 03920 case AST_CONTROL_RINGING: 03921 if (ast->_state == AST_STATE_RING) { 03922 p->invitestate = INV_EARLY_MEDIA; 03923 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03924 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03925 /* Send 180 ringing if out-of-band seems reasonable */ 03926 transmit_response(p, "180 Ringing", &p->initreq); 03927 ast_set_flag(&p->flags[0], SIP_RINGING); 03928 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03929 break; 03930 } else { 03931 /* Well, if it's not reasonable, just send in-band */ 03932 } 03933 } 03934 res = -1; 03935 break; 03936 case AST_CONTROL_BUSY: 03937 if (ast->_state != AST_STATE_UP) { 03938 transmit_response(p, "486 Busy Here", &p->initreq); 03939 p->invitestate = INV_COMPLETED; 03940 sip_alreadygone(p); 03941 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03942 break; 03943 } 03944 res = -1; 03945 break; 03946 case AST_CONTROL_CONGESTION: 03947 if (ast->_state != AST_STATE_UP) { 03948 transmit_response(p, "503 Service Unavailable", &p->initreq); 03949 p->invitestate = INV_COMPLETED; 03950 sip_alreadygone(p); 03951 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03952 break; 03953 } 03954 res = -1; 03955 break; 03956 case AST_CONTROL_PROCEEDING: 03957 if ((ast->_state != AST_STATE_UP) && 03958 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03959 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03960 transmit_response(p, "100 Trying", &p->initreq); 03961 p->invitestate = INV_PROCEEDING; 03962 break; 03963 } 03964 res = -1; 03965 break; 03966 case AST_CONTROL_PROGRESS: 03967 if ((ast->_state != AST_STATE_UP) && 03968 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03969 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03970 p->invitestate = INV_EARLY_MEDIA; 03971 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03972 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03973 break; 03974 } 03975 res = -1; 03976 break; 03977 case AST_CONTROL_HOLD: 03978 ast_rtp_new_source(p->rtp); 03979 ast_moh_start(ast, data, p->mohinterpret); 03980 break; 03981 case AST_CONTROL_UNHOLD: 03982 ast_rtp_new_source(p->rtp); 03983 ast_moh_stop(ast); 03984 break; 03985 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03986 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03987 transmit_info_with_vidupdate(p); 03988 /* ast_rtcp_send_h261fur(p->vrtp); */ 03989 } else 03990 res = -1; 03991 break; 03992 case AST_CONTROL_SRCUPDATE: 03993 ast_rtp_new_source(p->rtp); 03994 break; 03995 case -1: 03996 res = -1; 03997 break; 03998 default: 03999 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04000 res = -1; 04001 break; 04002 } 04003 ast_mutex_unlock(&p->lock); 04004 return res; 04005 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1761 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().
01762 { 01763 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01764 }
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 4013 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(), ast_verbose(), 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, f, 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, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04014 { 04015 struct ast_channel *tmp; 04016 struct ast_variable *v = NULL; 04017 int fmt; 04018 int what; 04019 int needvideo = 0, video = 0; 04020 char *decoded_exten; 04021 04022 if (option_debug != 0) { 04023 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04024 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04025 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04026 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04027 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04028 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04029 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04030 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04031 } 04032 04033 { 04034 char my_name[128]; /* pick a good name */ 04035 const char *f, *fromdomain = NULL; 04036 04037 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04038 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04039 else 04040 fromdomain = i->fromdomain; 04041 04042 if (!ast_strlen_zero(i->username)) { 04043 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04044 /* title not empty and different from username */ 04045 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04046 } else { 04047 /* username not empty, title is empty or equal to username */ 04048 snprintf(my_name, sizeof(my_name), "%s", i->username); 04049 } 04050 } else { /* username empty */ 04051 if (!ast_strlen_zero(i->peername)) { 04052 /* call from unregisted peer */ 04053 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04054 } else { /* username and peername empty */ 04055 if (!ast_strlen_zero(title)) { /* title not empty */ 04056 snprintf(my_name, sizeof(my_name), "%s", title); 04057 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04058 f = i->from; 04059 if (!strncmp(f, "sip:", 4)) 04060 f += 4; 04061 snprintf(my_name, sizeof(my_name), "%s", f); 04062 } else { /* fallback to fromdomain */ 04063 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04064 } 04065 } 04066 } 04067 ast_mutex_unlock(&i->lock); 04068 /* Don't hold a sip pvt lock while we allocate a channel */ 04069 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); 04070 04071 } 04072 if (!tmp) { 04073 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04074 ast_mutex_lock(&i->lock); 04075 return NULL; 04076 } 04077 ast_mutex_lock(&i->lock); 04078 04079 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04080 tmp->tech = &sip_tech_info; 04081 else 04082 tmp->tech = &sip_tech; 04083 04084 /* Select our native format based on codec preference until we receive 04085 something from another device to the contrary. */ 04086 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04087 what = i->jointcapability; 04088 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04089 } else if (i->capability) { /* Our configured capability for this peer */ 04090 what = i->capability; 04091 video = i->capability & AST_FORMAT_VIDEO_MASK; 04092 } else { 04093 what = global_capability; /* Global codec support */ 04094 video = global_capability & AST_FORMAT_VIDEO_MASK; 04095 } 04096 04097 /* Set the native formats for audio and merge in video */ 04098 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04099 if (option_debug > 2) { 04100 char buf[SIPBUFSIZE]; 04101 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04102 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04103 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04104 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04105 if (i->prefcodec) 04106 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04107 } 04108 04109 /* XXX Why are we choosing a codec from the native formats?? */ 04110 fmt = ast_best_codec(tmp->nativeformats); 04111 04112 /* If we have a prefcodec setting, we have an inbound channel that set a 04113 preferred format for this call. Otherwise, we check the jointcapability 04114 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04115 */ 04116 if (i->vrtp) { 04117 if (i->prefcodec) 04118 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04119 else 04120 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04121 } 04122 04123 if (option_debug > 2) { 04124 if (needvideo) 04125 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04126 else 04127 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04128 } 04129 04130 04131 04132 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04133 i->vad = ast_dsp_new(); 04134 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04135 if (global_relaxdtmf) 04136 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04137 } 04138 if (i->rtp) { 04139 tmp->fds[0] = ast_rtp_fd(i->rtp); 04140 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04141 } 04142 if (needvideo && i->vrtp) { 04143 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04144 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04145 } 04146 if (i->udptl) { 04147 tmp->fds[5] = ast_udptl_fd(i->udptl); 04148 } 04149 if (state == AST_STATE_RING) 04150 tmp->rings = 1; 04151 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04152 tmp->writeformat = fmt; 04153 tmp->rawwriteformat = fmt; 04154 tmp->readformat = fmt; 04155 tmp->rawreadformat = fmt; 04156 tmp->tech_pvt = i; 04157 04158 tmp->callgroup = i->callgroup; 04159 tmp->pickupgroup = i->pickupgroup; 04160 tmp->cid.cid_pres = i->callingpres; 04161 if (!ast_strlen_zero(i->accountcode)) 04162 ast_string_field_set(tmp, accountcode, i->accountcode); 04163 if (i->amaflags) 04164 tmp->amaflags = i->amaflags; 04165 if (!ast_strlen_zero(i->language)) 04166 ast_string_field_set(tmp, language, i->language); 04167 i->owner = tmp; 04168 ast_module_ref(ast_module_info->self); 04169 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04170 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04171 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04172 * structure so that there aren't issues when forming URI's 04173 */ 04174 decoded_exten = ast_strdupa(i->exten); 04175 ast_uri_decode(decoded_exten); 04176 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04177 04178 /* Don't use ast_set_callerid() here because it will 04179 * generate an unnecessary NewCallerID event */ 04180 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04181 if (!ast_strlen_zero(i->rdnis)) 04182 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04183 04184 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04185 tmp->cid.cid_dnid = ast_strdup(i->exten); 04186 04187 tmp->priority = 1; 04188 if (!ast_strlen_zero(i->uri)) 04189 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04190 if (!ast_strlen_zero(i->domain)) 04191 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04192 if (!ast_strlen_zero(i->useragent)) 04193 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04194 if (!ast_strlen_zero(i->callid)) 04195 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04196 if (i->rtp) 04197 ast_jb_configure(tmp, &global_jbconf); 04198 04199 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04200 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04201 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04202 04203 /* Set channel variables for this call from configuration */ 04204 for (v = i->chanvars ; v ; v = v->next) 04205 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04206 04207 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04208 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04209 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04210 ast_hangup(tmp); 04211 tmp = NULL; 04212 } 04213 04214 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04215 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04216 04217 return tmp; 04218 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11520 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11521 { 11522 if (argc != 4) 11523 return RESULT_SHOWUSAGE; 11524 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11525 ast_cli(fd, "SIP Debugging Disabled\n"); 11526 return RESULT_SUCCESS; 11527 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11529 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11530 { 11531 if (argc != 3) 11532 return RESULT_SHOWUSAGE; 11533 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11534 ast_cli(fd, "SIP Debugging Disabled\n"); 11535 return RESULT_SUCCESS; 11536 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11550 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11551 { 11552 if (argc != 3) { 11553 return RESULT_SHOWUSAGE; 11554 } 11555 recordhistory = FALSE; 11556 ast_cli(fd, "SIP History Recording Disabled\n"); 11557 return RESULT_SUCCESS; 11558 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11464 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.
11465 { 11466 struct ast_variable *varlist; 11467 int i; 11468 11469 if (argc < 4) 11470 return RESULT_SHOWUSAGE; 11471 11472 if (!notify_types) { 11473 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11474 return RESULT_FAILURE; 11475 } 11476 11477 varlist = ast_variable_browse(notify_types, argv[2]); 11478 11479 if (!varlist) { 11480 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11481 return RESULT_FAILURE; 11482 } 11483 11484 for (i = 3; i < argc; i++) { 11485 struct sip_pvt *p; 11486 struct sip_request req; 11487 struct ast_variable *var; 11488 11489 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11490 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11491 return RESULT_FAILURE; 11492 } 11493 11494 if (create_addr(p, argv[i])) { 11495 /* Maybe they're not registered, etc. */ 11496 sip_destroy(p); 11497 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11498 continue; 11499 } 11500 11501 initreqprep(&req, p, SIP_NOTIFY); 11502 11503 for (var = varlist; var; var = var->next) 11504 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11505 11506 /* Recalculate our side, and recalculate Call ID */ 11507 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11508 p->ourip = __ourip; 11509 build_via(p); 11510 build_callid_pvt(p); 11511 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11512 transmit_sip_request(p, &req); 11513 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11514 } 11515 11516 return RESULT_SUCCESS; 11517 }
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 13280 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().
13281 { 13282 struct sip_dual *d; 13283 struct ast_channel *transferee, *transferer; 13284 /* Chan2m: The transferer, chan1m: The transferee */ 13285 pthread_t th; 13286 13287 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13288 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13289 if ((!transferer) || (!transferee)) { 13290 if (transferee) { 13291 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13292 ast_hangup(transferee); 13293 } 13294 if (transferer) { 13295 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13296 ast_hangup(transferer); 13297 } 13298 return -1; 13299 } 13300 13301 /* Make formats okay */ 13302 transferee->readformat = chan1->readformat; 13303 transferee->writeformat = chan1->writeformat; 13304 13305 /* Prepare for taking over the channel */ 13306 ast_channel_masquerade(transferee, chan1); 13307 13308 /* Setup the extensions and such */ 13309 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13310 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13311 transferee->priority = chan1->priority; 13312 13313 /* We make a clone of the peer channel too, so we can play 13314 back the announcement */ 13315 13316 /* Make formats okay */ 13317 transferer->readformat = chan2->readformat; 13318 transferer->writeformat = chan2->writeformat; 13319 13320 /* Prepare for taking over the channel. Go ahead and grab this channel 13321 * lock here to avoid a deadlock with callbacks into the channel driver 13322 * that hold the channel lock and want the pvt lock. */ 13323 while (ast_channel_trylock(chan2)) { 13324 struct sip_pvt *pvt = chan2->tech_pvt; 13325 DEADLOCK_AVOIDANCE(&pvt->lock); 13326 } 13327 ast_channel_masquerade(transferer, chan2); 13328 ast_channel_unlock(chan2); 13329 13330 /* Setup the extensions and such */ 13331 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13332 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13333 transferer->priority = chan2->priority; 13334 13335 ast_channel_lock(transferer); 13336 if (ast_do_masquerade(transferer)) { 13337 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13338 ast_channel_unlock(transferer); 13339 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13340 ast_hangup(transferer); 13341 return -1; 13342 } 13343 ast_channel_unlock(transferer); 13344 if (!transferer || !transferee) { 13345 if (!transferer) { 13346 if (option_debug) 13347 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13348 } 13349 if (!transferee) { 13350 if (option_debug) 13351 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13352 } 13353 return -1; 13354 } 13355 if ((d = ast_calloc(1, sizeof(*d)))) { 13356 pthread_attr_t attr; 13357 13358 pthread_attr_init(&attr); 13359 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13360 13361 /* Save original request for followup */ 13362 copy_request(&d->req, req); 13363 d->chan1 = transferee; /* Transferee */ 13364 d->chan2 = transferer; /* Transferer */ 13365 d->seqno = seqno; 13366 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13367 /* Could not start thread */ 13368 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13369 by sip_park_thread() */ 13370 pthread_attr_destroy(&attr); 13371 return 0; 13372 } 13373 pthread_attr_destroy(&attr); 13374 } 13375 return -1; 13376 }
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 13213 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().
13214 { 13215 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13216 struct sip_dual *d; 13217 struct sip_request req; 13218 int ext; 13219 int res; 13220 13221 d = stuff; 13222 transferee = d->chan1; 13223 transferer = d->chan2; 13224 copy_request(&req, &d->req); 13225 free(d); 13226 13227 if (!transferee || !transferer) { 13228 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13229 return NULL; 13230 } 13231 if (option_debug > 3) 13232 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13233 13234 ast_channel_lock(transferee); 13235 if (ast_do_masquerade(transferee)) { 13236 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13237 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13238 ast_channel_unlock(transferee); 13239 return NULL; 13240 } 13241 ast_channel_unlock(transferee); 13242 13243 res = ast_park_call(transferee, transferer, 0, &ext); 13244 13245 13246 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13247 if (!res) { 13248 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13249 } else { 13250 /* Then tell the transferer what happened */ 13251 sprintf(buf, "Call parked on extension '%d'", ext); 13252 transmit_message_with_text(transferer->tech_pvt, buf); 13253 } 13254 #endif 13255 13256 /* Any way back to the current call??? */ 13257 /* Transmit response to the REFER request */ 13258 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13259 if (!res) { 13260 /* Transfer succeeded */ 13261 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13262 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13263 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13264 ast_hangup(transferer); /* This will cause a BYE */ 13265 if (option_debug) 13266 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13267 } else { 13268 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13269 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13270 if (option_debug) 13271 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13272 /* Do not hangup call */ 13273 } 13274 return NULL; 13275 }
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 8649 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().
08650 { 08651 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08652 08653 if (!peer) 08654 return; 08655 08656 /* If they put someone on hold, increment the value... otherwise decrement it */ 08657 if (hold) 08658 peer->onHold++; 08659 else 08660 peer->onHold--; 08661 08662 /* Request device state update */ 08663 ast_device_state_changed("SIP/%s", peer->name); 08664 08665 return; 08666 }
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 18099 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().
18100 { 18101 int ms = 0; 18102 18103 if (!speerobjs) /* No peers, just give up */ 18104 return; 18105 18106 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18107 ASTOBJ_WRLOCK(iterator); 18108 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18109 struct sip_peer *peer_ptr = iterator; 18110 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18111 } 18112 ms += 100; 18113 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18114 if (iterator->pokeexpire == -1) { 18115 struct sip_peer *peer_ptr = iterator; 18116 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18117 } 18118 ASTOBJ_UNLOCK(iterator); 18119 } while (0) 18120 ); 18121 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15964 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().
15965 { 15966 struct sip_peer *peer = (struct sip_peer *)data; 15967 15968 peer->pokeexpire = -1; 15969 if (peer->lastms > -1) { 15970 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15971 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15972 } 15973 if (peer->call) 15974 sip_destroy(peer->call); 15975 peer->call = NULL; 15976 peer->lastms = -1; 15977 ast_device_state_changed("SIP/%s", peer->name); 15978 15979 /* This function gets called one place outside of the scheduler ... */ 15980 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 15981 struct sip_peer *peer_ptr = peer; 15982 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 15983 } 15984 15985 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 15986 * inherit the reference that the current callback already has. */ 15987 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15988 if (peer->pokeexpire == -1) { 15989 ASTOBJ_UNREF(peer, sip_destroy_peer); 15990 } 15991 15992 return 0; 15993 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15998 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_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_noanswer(), sipdebug, sip_peer::sockfd, sip_pvt::sockfd, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15999 { 16000 struct sip_pvt *p; 16001 int xmitres = 0; 16002 16003 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16004 /* IF we have no IP, or this isn't to be monitored, return 16005 imeediately after clearing things out */ 16006 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16007 struct sip_peer *peer_ptr = peer; 16008 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16009 } 16010 peer->lastms = 0; 16011 peer->call = NULL; 16012 return 0; 16013 } 16014 if (peer->call) { 16015 if (sipdebug) 16016 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16017 sip_destroy(peer->call); 16018 } 16019 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16020 return -1; 16021 16022 p->sa = peer->addr; 16023 p->recv = peer->addr; 16024 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16025 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16026 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 16027 p->sockfd = peer->sockfd; 16028 16029 /* Send OPTIONs to peer's fullcontact */ 16030 if (!ast_strlen_zero(peer->fullcontact)) 16031 ast_string_field_set(p, fullcontact, peer->fullcontact); 16032 16033 if (!ast_strlen_zero(peer->tohost)) 16034 ast_string_field_set(p, tohost, peer->tohost); 16035 else 16036 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16037 16038 /* Recalculate our side, and recalculate Call ID */ 16039 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16040 p->ourip = __ourip; 16041 build_via(p); 16042 build_callid_pvt(p); 16043 16044 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16045 struct sip_peer *peer_ptr = peer; 16046 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16047 } 16048 16049 p->relatedpeer = ASTOBJ_REF(peer); 16050 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16051 #ifdef VOCAL_DATA_HACK 16052 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16053 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16054 #else 16055 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16056 #endif 16057 gettimeofday(&peer->ps, NULL); 16058 if (xmitres == XMIT_ERROR) { 16059 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16060 } else { 16061 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16062 struct sip_peer *peer_ptr = peer; 16063 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16064 } 16065 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16066 if (peer->pokeexpire == -1) { 16067 struct sip_peer *peer_ptr = peer; 16068 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16069 } 16070 } 16071 16072 return 0; 16073 }
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 8007 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().
08008 { 08009 struct sip_peer *peer = (struct sip_peer *) data; 08010 08011 peer->pokeexpire = -1; 08012 08013 sip_poke_peer(peer); 08014 08015 ASTOBJ_UNREF(peer, sip_destroy_peer); 08016 08017 return 0; 08018 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10243 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.
10244 { 10245 struct sip_peer *peer; 10246 struct sip_user *user; 10247 int pruneuser = FALSE; 10248 int prunepeer = FALSE; 10249 int multi = FALSE; 10250 char *name = NULL; 10251 regex_t regexbuf; 10252 10253 switch (argc) { 10254 case 4: 10255 if (!strcasecmp(argv[3], "user")) 10256 return RESULT_SHOWUSAGE; 10257 if (!strcasecmp(argv[3], "peer")) 10258 return RESULT_SHOWUSAGE; 10259 if (!strcasecmp(argv[3], "like")) 10260 return RESULT_SHOWUSAGE; 10261 if (!strcasecmp(argv[3], "all")) { 10262 multi = TRUE; 10263 pruneuser = prunepeer = TRUE; 10264 } else { 10265 pruneuser = prunepeer = TRUE; 10266 name = argv[3]; 10267 } 10268 break; 10269 case 5: 10270 if (!strcasecmp(argv[4], "like")) 10271 return RESULT_SHOWUSAGE; 10272 if (!strcasecmp(argv[3], "all")) 10273 return RESULT_SHOWUSAGE; 10274 if (!strcasecmp(argv[3], "like")) { 10275 multi = TRUE; 10276 name = argv[4]; 10277 pruneuser = prunepeer = TRUE; 10278 } else if (!strcasecmp(argv[3], "user")) { 10279 pruneuser = TRUE; 10280 if (!strcasecmp(argv[4], "all")) 10281 multi = TRUE; 10282 else 10283 name = argv[4]; 10284 } else if (!strcasecmp(argv[3], "peer")) { 10285 prunepeer = TRUE; 10286 if (!strcasecmp(argv[4], "all")) 10287 multi = TRUE; 10288 else 10289 name = argv[4]; 10290 } else 10291 return RESULT_SHOWUSAGE; 10292 break; 10293 case 6: 10294 if (strcasecmp(argv[4], "like")) 10295 return RESULT_SHOWUSAGE; 10296 if (!strcasecmp(argv[3], "user")) { 10297 pruneuser = TRUE; 10298 name = argv[5]; 10299 } else if (!strcasecmp(argv[3], "peer")) { 10300 prunepeer = TRUE; 10301 name = argv[5]; 10302 } else 10303 return RESULT_SHOWUSAGE; 10304 break; 10305 default: 10306 return RESULT_SHOWUSAGE; 10307 } 10308 10309 if (multi && name) { 10310 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10311 return RESULT_SHOWUSAGE; 10312 } 10313 10314 if (multi) { 10315 if (prunepeer) { 10316 int pruned = 0; 10317 10318 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10319 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10320 ASTOBJ_RDLOCK(iterator); 10321 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10322 ASTOBJ_UNLOCK(iterator); 10323 continue; 10324 }; 10325 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10326 ASTOBJ_MARK(iterator); 10327 pruned++; 10328 } 10329 ASTOBJ_UNLOCK(iterator); 10330 } while (0) ); 10331 if (pruned) { 10332 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10333 ast_cli(fd, "%d peers pruned.\n", pruned); 10334 } else 10335 ast_cli(fd, "No peers found to prune.\n"); 10336 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10337 } 10338 if (pruneuser) { 10339 int pruned = 0; 10340 10341 ASTOBJ_CONTAINER_WRLOCK(&userl); 10342 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10343 ASTOBJ_RDLOCK(iterator); 10344 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10345 ASTOBJ_UNLOCK(iterator); 10346 continue; 10347 }; 10348 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10349 ASTOBJ_MARK(iterator); 10350 pruned++; 10351 } 10352 ASTOBJ_UNLOCK(iterator); 10353 } while (0) ); 10354 if (pruned) { 10355 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10356 ast_cli(fd, "%d users pruned.\n", pruned); 10357 } else 10358 ast_cli(fd, "No users found to prune.\n"); 10359 ASTOBJ_CONTAINER_UNLOCK(&userl); 10360 } 10361 } else { 10362 if (prunepeer) { 10363 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10364 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10365 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10366 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10367 } else 10368 ast_cli(fd, "Peer '%s' pruned.\n", name); 10369 ASTOBJ_UNREF(peer, sip_destroy_peer); 10370 } else 10371 ast_cli(fd, "Peer '%s' not found.\n", name); 10372 } 10373 if (pruneuser) { 10374 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10375 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10376 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10377 ASTOBJ_CONTAINER_LINK(&userl, user); 10378 } else 10379 ast_cli(fd, "User '%s' pruned.\n", name); 10380 ASTOBJ_UNREF(user, sip_destroy_user); 10381 } else 10382 ast_cli(fd, "User '%s' not found.\n", name); 10383 } 10384 } 10385 10386 return RESULT_SUCCESS; 10387 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4421 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().
04422 { 04423 struct ast_frame *fr; 04424 struct sip_pvt *p = ast->tech_pvt; 04425 int faxdetected = FALSE; 04426 04427 ast_mutex_lock(&p->lock); 04428 fr = sip_rtp_read(ast, p, &faxdetected); 04429 p->lastrtprx = time(NULL); 04430 04431 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04432 /* 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 */ 04433 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04434 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04435 if (!p->pendinginvite) { 04436 if (option_debug > 2) 04437 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04438 p->t38.state = T38_LOCAL_REINVITE; 04439 transmit_reinvite_with_t38_sdp(p); 04440 if (option_debug > 1) 04441 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04442 } 04443 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04444 if (option_debug > 2) 04445 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04446 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04447 } 04448 } 04449 04450 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04451 if (fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04452 fr = &ast_null_frame; 04453 } 04454 04455 ast_mutex_unlock(&p->lock); 04456 return fr; 04457 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1755 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().
01756 { 01757 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01758 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7808 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().
07809 { 07810 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07811 return p->refer ? 1 : 0; 07812 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7563 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().
07564 { 07565 07566 /* if we are here, our registration timed out, so we'll just do it over */ 07567 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07568 struct sip_pvt *p; 07569 int res; 07570 07571 /* if we couldn't get a reference to the registry object, punt */ 07572 if (!r) 07573 return 0; 07574 07575 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07576 if (r->call) { 07577 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07578 in the single SIP manager thread. */ 07579 p = r->call; 07580 ast_mutex_lock(&p->lock); 07581 if (p->registry) 07582 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07583 r->call = NULL; 07584 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07585 /* Pretend to ACK anything just in case */ 07586 __sip_pretend_ack(p); 07587 ast_mutex_unlock(&p->lock); 07588 } 07589 /* If we have a limit, stop registration and give up */ 07590 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07591 /* Ok, enough is enough. Don't try any more */ 07592 /* We could add an external notification here... 07593 steal it from app_voicemail :-) */ 07594 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07595 r->regstate = REG_STATE_FAILED; 07596 } else { 07597 r->regstate = REG_STATE_UNREGISTERED; 07598 r->timeout = -1; 07599 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07600 } 07601 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)); 07602 ASTOBJ_UNREF(r, sip_registry_destroy); 07603 return 0; 07604 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4749 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.
04750 { 04751 struct sip_registry *reg; 04752 int portnum = 0; 04753 char username[256] = ""; 04754 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04755 char *porta=NULL; 04756 char *contact=NULL; 04757 04758 if (!value) 04759 return -1; 04760 ast_copy_string(username, value, sizeof(username)); 04761 /* First split around the last '@' then parse the two components. */ 04762 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04763 if (hostname) 04764 *hostname++ = '\0'; 04765 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04766 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04767 return -1; 04768 } 04769 /* split user[:secret[:authuser]] */ 04770 secret = strchr(username, ':'); 04771 if (secret) { 04772 *secret++ = '\0'; 04773 authuser = strchr(secret, ':'); 04774 if (authuser) 04775 *authuser++ = '\0'; 04776 } 04777 /* split host[:port][/contact] */ 04778 contact = strchr(hostname, '/'); 04779 if (contact) 04780 *contact++ = '\0'; 04781 if (ast_strlen_zero(contact)) 04782 contact = "s"; 04783 porta = strchr(hostname, ':'); 04784 if (porta) { 04785 *porta++ = '\0'; 04786 portnum = atoi(porta); 04787 if (portnum == 0) { 04788 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04789 return -1; 04790 } 04791 } 04792 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04793 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04794 return -1; 04795 } 04796 04797 if (ast_string_field_init(reg, 256)) { 04798 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04799 free(reg); 04800 return -1; 04801 } 04802 04803 regobjs++; 04804 ASTOBJ_INIT(reg); 04805 ast_string_field_set(reg, contact, contact); 04806 if (!ast_strlen_zero(username)) 04807 ast_string_field_set(reg, username, username); 04808 if (hostname) 04809 ast_string_field_set(reg, hostname, hostname); 04810 if (authuser) 04811 ast_string_field_set(reg, authuser, authuser); 04812 if (secret) 04813 ast_string_field_set(reg, secret, secret); 04814 reg->expire = -1; 04815 reg->timeout = -1; 04816 reg->refresh = default_expiry; 04817 reg->portno = portnum; 04818 reg->callid_valid = FALSE; 04819 reg->ocseq = INITIAL_CSEQ; 04820 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04821 ASTOBJ_UNREF(reg,sip_registry_destroy); 04822 return 0; 04823 }
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 3066 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().
03067 { 03068 /* Really delete */ 03069 if (option_debug > 2) 03070 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03071 03072 if (reg->call) { 03073 /* Clear registry before destroying to ensure 03074 we don't get reentered trying to grab the registry lock */ 03075 reg->call->registry = NULL; 03076 if (option_debug > 2) 03077 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03078 sip_destroy(reg->call); 03079 } 03080 AST_SCHED_DEL(sched, reg->expire); 03081 AST_SCHED_DEL(sched, reg->timeout); 03082 ast_string_field_free_memory(reg); 03083 regobjs--; 03084 free(reg); 03085 03086 }
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 12187 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12188 { 12189 struct sip_pvt *p = (struct sip_pvt *) data; 12190 12191 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12192 p->waitid = -1; 12193 return 0; 12194 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18167 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().
18168 { 18169 ast_mutex_lock(&sip_reload_lock); 18170 if (sip_reloading) 18171 ast_verbose("Previous SIP reload not yet done\n"); 18172 else { 18173 sip_reloading = TRUE; 18174 if (fd) 18175 sip_reloadreason = CHANNEL_CLI_RELOAD; 18176 else 18177 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18178 } 18179 ast_mutex_unlock(&sip_reload_lock); 18180 restart_monitor(); 18181 18182 return 0; 18183 }
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 16178 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.
16179 { 16180 int oldformat; 16181 struct sip_pvt *p; 16182 struct ast_channel *tmpc = NULL; 16183 char *ext, *host; 16184 char tmp[256]; 16185 char *dest = data; 16186 16187 oldformat = format; 16188 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16189 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)); 16190 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16191 return NULL; 16192 } 16193 if (option_debug) 16194 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16195 16196 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16197 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16198 *cause = AST_CAUSE_SWITCH_CONGESTION; 16199 return NULL; 16200 } 16201 16202 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16203 16204 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16205 sip_destroy(p); 16206 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16207 *cause = AST_CAUSE_SWITCH_CONGESTION; 16208 return NULL; 16209 } 16210 16211 ast_copy_string(tmp, dest, sizeof(tmp)); 16212 host = strchr(tmp, '@'); 16213 if (host) { 16214 *host++ = '\0'; 16215 ext = tmp; 16216 } else { 16217 ext = strchr(tmp, '/'); 16218 if (ext) 16219 *ext++ = '\0'; 16220 host = tmp; 16221 } 16222 16223 if (create_addr(p, host)) { 16224 *cause = AST_CAUSE_UNREGISTERED; 16225 if (option_debug > 2) 16226 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16227 sip_destroy(p); 16228 return NULL; 16229 } 16230 if (ast_strlen_zero(p->peername) && ext) 16231 ast_string_field_set(p, peername, ext); 16232 /* Recalculate our side, and recalculate Call ID */ 16233 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16234 p->ourip = __ourip; 16235 build_via(p); 16236 build_callid_pvt(p); 16237 16238 /* We have an extension to call, don't use the full contact here */ 16239 /* This to enable dialing registered peers with extension dialling, 16240 like SIP/peername/extension 16241 SIP/peername will still use the full contact */ 16242 if (ext) { 16243 ast_string_field_set(p, username, ext); 16244 ast_string_field_free(p, fullcontact); 16245 } 16246 #if 0 16247 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16248 #endif 16249 p->prefcodec = oldformat; /* Format for this call */ 16250 ast_mutex_lock(&p->lock); 16251 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16252 ast_mutex_unlock(&p->lock); 16253 if (!tmpc) 16254 sip_destroy(p); 16255 ast_update_use_count(); 16256 restart_monitor(); 16257 return tmpc; 16258 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7531 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().
07532 { 07533 /* if we are here, we know that we need to reregister. */ 07534 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07535 07536 /* if we couldn't get a reference to the registry object, punt */ 07537 if (!r) 07538 return 0; 07539 07540 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07541 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07542 /* Since registry's are only added/removed by the the monitor thread, this 07543 may be overkill to reference/dereference at all here */ 07544 if (sipdebug) 07545 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07546 07547 r->expire = -1; 07548 __sip_do_register(r); 07549 ASTOBJ_UNREF(r, sip_registry_destroy); 07550 return 0; 07551 }
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 4351 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().
04352 { 04353 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04354 struct ast_frame *f; 04355 04356 if (!p->rtp) { 04357 /* We have no RTP allocated for this channel */ 04358 return &ast_null_frame; 04359 } 04360 04361 switch(ast->fdno) { 04362 case 0: 04363 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04364 break; 04365 case 1: 04366 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04367 break; 04368 case 2: 04369 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04370 break; 04371 case 3: 04372 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04373 break; 04374 case 5: 04375 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04376 break; 04377 default: 04378 f = &ast_null_frame; 04379 } 04380 /* Don't forward RFC2833 if we're not supposed to */ 04381 if (f && (f->frametype == AST_FRAME_DTMF) && 04382 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04383 return &ast_null_frame; 04384 04385 /* We already hold the channel lock */ 04386 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04387 return f; 04388 04389 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04390 if (!(f->subclass & p->jointcapability)) { 04391 if (option_debug) { 04392 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04393 ast_getformatname(f->subclass), p->owner->name); 04394 } 04395 return &ast_null_frame; 04396 } 04397 if (option_debug) 04398 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04399 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04400 ast_set_read_format(p->owner, p->owner->readformat); 04401 ast_set_write_format(p->owner, p->owner->writeformat); 04402 } 04403 04404 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04405 f = ast_dsp_process(p->owner, p->vad, f); 04406 if (f && f->frametype == AST_FRAME_DTMF) { 04407 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04408 if (option_debug) 04409 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04410 *faxdetect = 1; 04411 } else if (option_debug) { 04412 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04413 } 04414 } 04415 } 04416 04417 return f; 04418 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2130 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, 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().
02131 { 02132 if (ms < 0) { 02133 if (p->timer_t1 == 0) 02134 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02135 ms = p->timer_t1 * 64; 02136 } 02137 if (sip_debug_test_pvt(p)) 02138 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02139 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02140 append_history(p, "SchedDestroy", "%d ms", ms); 02141 02142 AST_SCHED_DEL(sched, p->autokillid); 02143 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02144 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 18124 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().
18125 { 18126 int ms; 18127 int regspacing; 18128 if (!regobjs) 18129 return; 18130 regspacing = default_expiry * 1000/regobjs; 18131 if (regspacing > 100) 18132 regspacing = 100; 18133 ms = regspacing; 18134 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18135 ASTOBJ_WRLOCK(iterator); 18136 AST_SCHED_DEL(sched, iterator->expire); 18137 ms += regspacing; 18138 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18139 ASTOBJ_UNLOCK(iterator); 18140 } while (0) 18141 ); 18142 }
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 15689 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().
15690 { 15691 /* Called with peerl lock, but releases it */ 15692 struct sip_pvt *p; 15693 int newmsgs, oldmsgs; 15694 15695 /* Do we have an IP address? If not, skip this peer */ 15696 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15697 return 0; 15698 15699 /* Check for messages */ 15700 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15701 15702 peer->lastmsgcheck = time(NULL); 15703 15704 /* Return now if it's the same thing we told them last time */ 15705 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15706 return 0; 15707 } 15708 15709 15710 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15711 15712 if (peer->mwipvt) { 15713 /* Base message on subscription */ 15714 p = peer->mwipvt; 15715 } else { 15716 /* Build temporary dialog for this message */ 15717 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15718 return -1; 15719 if (create_addr_from_peer(p, peer)) { 15720 /* Maybe they're not registered, etc. */ 15721 sip_destroy(p); 15722 return 0; 15723 } 15724 /* Recalculate our side, and recalculate Call ID */ 15725 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15726 p->ourip = __ourip; 15727 build_via(p); 15728 build_callid_pvt(p); 15729 /* Destroy this session after 32 secs */ 15730 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15731 } 15732 /* Send MWI */ 15733 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15734 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15735 return 0; 15736 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3844 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.
03845 { 03846 struct sip_pvt *p = ast->tech_pvt; 03847 int res = 0; 03848 03849 ast_mutex_lock(&p->lock); 03850 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03851 case SIP_DTMF_INBAND: 03852 res = -1; /* Tell Asterisk to generate inband indications */ 03853 break; 03854 case SIP_DTMF_RFC2833: 03855 if (p->rtp) 03856 ast_rtp_senddigit_begin(p->rtp, digit); 03857 break; 03858 default: 03859 break; 03860 } 03861 ast_mutex_unlock(&p->lock); 03862 03863 return res; 03864 }
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 3868 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().
03869 { 03870 struct sip_pvt *p = ast->tech_pvt; 03871 int res = 0; 03872 03873 ast_mutex_lock(&p->lock); 03874 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03875 case SIP_DTMF_INFO: 03876 transmit_info_with_digit(p, digit, duration); 03877 break; 03878 case SIP_DTMF_RFC2833: 03879 if (p->rtp) 03880 ast_rtp_senddigit_end(p->rtp, digit); 03881 break; 03882 case SIP_DTMF_INBAND: 03883 res = -1; /* Tell Asterisk to stop inband indications */ 03884 break; 03885 } 03886 ast_mutex_unlock(&p->lock); 03887 03888 return res; 03889 }
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 2390 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().
02391 { 02392 struct sip_pvt *p = ast->tech_pvt; 02393 int debug = sip_debug_test_pvt(p); 02394 02395 if (debug) 02396 ast_verbose("Sending text %s on %s\n", text, ast->name); 02397 if (!p) 02398 return -1; 02399 if (ast_strlen_zero(text)) 02400 return 0; 02401 if (debug) 02402 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02403 transmit_message_with_text(p, text); 02404 return 0; 02405 }
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 17851 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().
17852 { 17853 struct sip_pvt *p; 17854 int changed = 0; 17855 17856 p = chan->tech_pvt; 17857 if (!p) 17858 return -1; 17859 17860 /* Disable early RTP bridge */ 17861 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17862 return 0; 17863 17864 ast_mutex_lock(&p->lock); 17865 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17866 /* If we're destroyed, don't bother */ 17867 ast_mutex_unlock(&p->lock); 17868 return 0; 17869 } 17870 17871 /* if this peer cannot handle reinvites of the media stream to devices 17872 that are known to be behind a NAT, then stop the process now 17873 */ 17874 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17875 ast_mutex_unlock(&p->lock); 17876 return 0; 17877 } 17878 17879 if (rtp) { 17880 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17881 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17882 memset(&p->redirip, 0, sizeof(p->redirip)); 17883 changed = 1; 17884 } 17885 if (vrtp) { 17886 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17887 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17888 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17889 changed = 1; 17890 } 17891 if (codecs) { 17892 if ((p->redircodecs != codecs)) { 17893 p->redircodecs = codecs; 17894 changed = 1; 17895 } 17896 if ((p->capability & codecs) != p->capability) { 17897 p->jointcapability &= codecs; 17898 p->capability &= codecs; 17899 changed = 1; 17900 } 17901 } 17902 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17903 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17904 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17905 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17906 if (option_debug) 17907 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)); 17908 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17909 if (option_debug > 2) { 17910 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)); 17911 } 17912 transmit_reinvite_with_sdp(p); 17913 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17914 if (option_debug > 2) { 17915 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)); 17916 } 17917 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17918 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17919 } 17920 } 17921 /* Reset lastrtprx timer */ 17922 p->lastrtprx = p->lastrtptx = time(NULL); 17923 ast_mutex_unlock(&p->lock); 17924 return 0; 17925 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17678 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.
17679 { 17680 struct sip_pvt *p; 17681 17682 p = chan->tech_pvt; 17683 if (!p) 17684 return -1; 17685 ast_mutex_lock(&p->lock); 17686 if (udptl) 17687 ast_udptl_get_peer(udptl, &p->udptlredirip); 17688 else 17689 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17690 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17691 if (!p->pendinginvite) { 17692 if (option_debug > 2) { 17693 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); 17694 } 17695 transmit_reinvite_with_t38_sdp(p); 17696 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17697 if (option_debug > 2) { 17698 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); 17699 } 17700 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17701 } 17702 } 17703 /* Reset lastrtprx timer */ 17704 p->lastrtprx = p->lastrtptx = time(NULL); 17705 ast_mutex_unlock(&p->lock); 17706 return 0; 17707 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11119 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().
11120 { 11121 struct sip_pvt *cur; 11122 size_t len; 11123 int found = 0; 11124 11125 if (argc != 4) 11126 return RESULT_SHOWUSAGE; 11127 len = strlen(argv[3]); 11128 ast_mutex_lock(&iflock); 11129 for (cur = iflist; cur; cur = cur->next) { 11130 if (!strncasecmp(cur->callid, argv[3], len)) { 11131 char formatbuf[SIPBUFSIZE/2]; 11132 ast_cli(fd,"\n"); 11133 if (cur->subscribed != NONE) 11134 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11135 else 11136 ast_cli(fd, " * SIP Call\n"); 11137 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11138 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11139 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11140 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11141 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11142 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11143 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11144 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11145 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11146 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11147 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11148 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11149 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11150 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)" ); 11151 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11152 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11153 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11154 if (!ast_strlen_zero(cur->username)) 11155 ast_cli(fd, " Username: %s\n", cur->username); 11156 if (!ast_strlen_zero(cur->peername)) 11157 ast_cli(fd, " Peername: %s\n", cur->peername); 11158 if (!ast_strlen_zero(cur->uri)) 11159 ast_cli(fd, " Original uri: %s\n", cur->uri); 11160 if (!ast_strlen_zero(cur->cid_num)) 11161 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11162 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11163 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11164 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11165 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11166 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11167 ast_cli(fd, " SIP Options: "); 11168 if (cur->sipoptions) { 11169 int x; 11170 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11171 if (cur->sipoptions & sip_options[x].id) 11172 ast_cli(fd, "%s ", sip_options[x].text); 11173 } 11174 } else 11175 ast_cli(fd, "(none)\n"); 11176 ast_cli(fd, "\n\n"); 11177 found++; 11178 } 11179 } 11180 ast_mutex_unlock(&iflock); 11181 if (!found) 11182 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11183 return RESULT_SUCCESS; 11184 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10910 of file chan_sip.c.
References __sip_show_channels().
10911 { 10912 return __sip_show_channels(fd, argc, argv, 0); 10913 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10421 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.
10422 { 10423 struct domain *d; 10424 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10425 10426 if (AST_LIST_EMPTY(&domain_list)) { 10427 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10428 return RESULT_SUCCESS; 10429 } else { 10430 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10431 AST_LIST_LOCK(&domain_list); 10432 AST_LIST_TRAVERSE(&domain_list, d, list) 10433 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10434 domain_mode_to_text(d->mode)); 10435 AST_LIST_UNLOCK(&domain_list); 10436 ast_cli(fd, "\n"); 10437 return RESULT_SUCCESS; 10438 } 10439 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11187 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.
11188 { 11189 struct sip_pvt *cur; 11190 size_t len; 11191 int found = 0; 11192 11193 if (argc != 4) 11194 return RESULT_SHOWUSAGE; 11195 if (!recordhistory) 11196 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11197 len = strlen(argv[3]); 11198 ast_mutex_lock(&iflock); 11199 for (cur = iflist; cur; cur = cur->next) { 11200 if (!strncasecmp(cur->callid, argv[3], len)) { 11201 struct sip_history *hist; 11202 int x = 0; 11203 11204 ast_cli(fd,"\n"); 11205 if (cur->subscribed != NONE) 11206 ast_cli(fd, " * Subscription\n"); 11207 else 11208 ast_cli(fd, " * SIP Call\n"); 11209 if (cur->history) 11210 AST_LIST_TRAVERSE(cur->history, hist, list) 11211 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11212 if (x == 0) 11213 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11214 found++; 11215 } 11216 } 11217 ast_mutex_unlock(&iflock); 11218 if (!found) 11219 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11220 return RESULT_SUCCESS; 11221 }
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 9846 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.
09847 { 09848 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09849 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09850 char ilimits[40]; 09851 char iused[40]; 09852 int showall = FALSE; 09853 09854 if (argc < 3) 09855 return RESULT_SHOWUSAGE; 09856 09857 if (argc == 4 && !strcmp(argv[3],"all")) 09858 showall = TRUE; 09859 09860 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09861 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09862 ASTOBJ_RDLOCK(iterator); 09863 if (iterator->call_limit) 09864 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09865 else 09866 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09867 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09868 if (showall || iterator->call_limit) 09869 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09870 ASTOBJ_UNLOCK(iterator); 09871 } while (0) ); 09872 09873 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09874 09875 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09876 ASTOBJ_RDLOCK(iterator); 09877 if (iterator->call_limit) 09878 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09879 else 09880 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09881 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09882 if (showall || iterator->call_limit) 09883 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09884 ASTOBJ_UNLOCK(iterator); 09885 } while (0) ); 09886 09887 return RESULT_SUCCESS; 09888 #undef FORMAT 09889 #undef FORMAT2 09890 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10167 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10168 { 10169 char tmp[256]; 10170 if (argc != 3) 10171 return RESULT_SHOWUSAGE; 10172 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10173 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10174 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10175 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10176 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10177 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10178 return RESULT_SUCCESS; 10179 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10473 of file chan_sip.c.
References _sip_show_peer().
10474 { 10475 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10476 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10023 of file chan_sip.c.
References _sip_show_peers().
10024 { 10025 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10026 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10747 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.
10748 { 10749 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10750 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10751 char host[80]; 10752 char tmpdat[256]; 10753 struct tm tm; 10754 10755 10756 if (argc != 3) 10757 return RESULT_SHOWUSAGE; 10758 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10759 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10760 ASTOBJ_RDLOCK(iterator); 10761 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10762 if (iterator->regtime) { 10763 ast_localtime(&iterator->regtime, &tm, NULL); 10764 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10765 } else { 10766 tmpdat[0] = 0; 10767 } 10768 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10769 ASTOBJ_UNLOCK(iterator); 10770 } while(0)); 10771 return RESULT_SUCCESS; 10772 #undef FORMAT 10773 #undef FORMAT2 10774 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10777 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().
10778 { 10779 int realtimepeers; 10780 int realtimeusers; 10781 char codec_buf[SIPBUFSIZE]; 10782 10783 realtimepeers = ast_check_realtime("sippeers"); 10784 realtimeusers = ast_check_realtime("sipusers"); 10785 10786 if (argc != 3) 10787 return RESULT_SHOWUSAGE; 10788 ast_cli(fd, "\n\nGlobal Settings:\n"); 10789 ast_cli(fd, "----------------\n"); 10790 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10791 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10792 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10793 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10794 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10795 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10796 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10797 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10798 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10799 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10800 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10801 ast_cli(fd, " Our auth realm %s\n", global_realm); 10802 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10803 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10804 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10805 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10806 ast_cli(fd, " User Agent: %s\n", global_useragent); 10807 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10808 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10809 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10810 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10811 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10812 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10813 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10814 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10815 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10816 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10817 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10818 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10819 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10820 #endif 10821 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10822 if (!realtimepeers && !realtimeusers) 10823 ast_cli(fd, " SIP realtime: Disabled\n" ); 10824 else 10825 ast_cli(fd, " SIP realtime: Enabled\n" ); 10826 10827 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10828 ast_cli(fd, "---------------------------\n"); 10829 ast_cli(fd, " Codecs: "); 10830 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10831 ast_cli(fd, "%s\n", codec_buf); 10832 ast_cli(fd, " Codec Order: "); 10833 print_codec_to_cli(fd, &default_prefs); 10834 ast_cli(fd, "\n"); 10835 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10836 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10837 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10838 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10839 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10840 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10841 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10842 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10843 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10844 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10845 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10846 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10847 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10848 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10849 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10850 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10851 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10852 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10853 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10854 ast_cli(fd, "\nDefault Settings:\n"); 10855 ast_cli(fd, "-----------------\n"); 10856 ast_cli(fd, " Context: %s\n", default_context); 10857 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10858 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10859 ast_cli(fd, " Qualify: %d\n", default_qualify); 10860 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10861 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" ); 10862 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10863 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10864 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10865 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10866 10867 10868 if (realtimepeers || realtimeusers) { 10869 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10870 ast_cli(fd, "----------------------\n"); 10871 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10872 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10873 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10874 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10875 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10876 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10877 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10878 } 10879 ast_cli(fd, "\n----\n"); 10880 return RESULT_SUCCESS; 10881 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10916 of file chan_sip.c.
References __sip_show_channels().
10917 { 10918 return __sip_show_channels(fd, argc, argv, 1); 10919 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10692 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.
10693 { 10694 char cbuf[256]; 10695 struct sip_user *user; 10696 struct ast_variable *v; 10697 int load_realtime; 10698 10699 if (argc < 4) 10700 return RESULT_SHOWUSAGE; 10701 10702 /* Load from realtime storage? */ 10703 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10704 10705 user = find_user(argv[3], load_realtime); 10706 if (user) { 10707 ast_cli(fd,"\n\n"); 10708 ast_cli(fd, " * Name : %s\n", user->name); 10709 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10710 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10711 ast_cli(fd, " Context : %s\n", user->context); 10712 ast_cli(fd, " Language : %s\n", user->language); 10713 if (!ast_strlen_zero(user->accountcode)) 10714 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10715 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10716 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10717 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10718 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10719 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10720 ast_cli(fd, " Callgroup : "); 10721 print_group(fd, user->callgroup, 0); 10722 ast_cli(fd, " Pickupgroup : "); 10723 print_group(fd, user->pickupgroup, 0); 10724 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10725 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10726 ast_cli(fd, " Codec Order : ("); 10727 print_codec_to_cli(fd, &user->prefs); 10728 ast_cli(fd, ")\n"); 10729 10730 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10731 if (user->chanvars) { 10732 ast_cli(fd, " Variables :\n"); 10733 for (v = user->chanvars ; v ; v = v->next) 10734 ast_cli(fd, " %s = %s\n", v->name, v->value); 10735 } 10736 ast_cli(fd,"\n"); 10737 ASTOBJ_UNREF(user,sip_destroy_user); 10738 } else { 10739 ast_cli(fd,"User %s not found.\n", argv[3]); 10740 ast_cli(fd,"\n"); 10741 } 10742 10743 return RESULT_SUCCESS; 10744 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9946 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.
09947 { 09948 regex_t regexbuf; 09949 int havepattern = FALSE; 09950 09951 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09952 09953 switch (argc) { 09954 case 5: 09955 if (!strcasecmp(argv[3], "like")) { 09956 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09957 return RESULT_SHOWUSAGE; 09958 havepattern = TRUE; 09959 } else 09960 return RESULT_SHOWUSAGE; 09961 case 3: 09962 break; 09963 default: 09964 return RESULT_SHOWUSAGE; 09965 } 09966 09967 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09968 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09969 ASTOBJ_RDLOCK(iterator); 09970 09971 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09972 ASTOBJ_UNLOCK(iterator); 09973 continue; 09974 } 09975 09976 ast_cli(fd, FORMAT, iterator->name, 09977 iterator->secret, 09978 iterator->accountcode, 09979 iterator->context, 09980 iterator->ha ? "Yes" : "No", 09981 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09982 ASTOBJ_UNLOCK(iterator); 09983 } while (0) 09984 ); 09985 09986 if (havepattern) 09987 regfree(®exbuf); 09988 09989 return RESULT_SUCCESS; 09990 #undef FORMAT 09991 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18038 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().
18039 { 18040 char *cdest; 18041 char *extension, *host, *port; 18042 char tmp[80]; 18043 18044 cdest = ast_strdupa(dest); 18045 18046 extension = strsep(&cdest, "@"); 18047 host = strsep(&cdest, ":"); 18048 port = strsep(&cdest, ":"); 18049 if (ast_strlen_zero(extension)) { 18050 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18051 return 0; 18052 } 18053 18054 /* we'll issue the redirect message here */ 18055 if (!host) { 18056 char *localtmp; 18057 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18058 if (ast_strlen_zero(tmp)) { 18059 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18060 return 0; 18061 } 18062 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18063 char lhost[80], lport[80]; 18064 memset(lhost, 0, sizeof(lhost)); 18065 memset(lport, 0, sizeof(lport)); 18066 localtmp++; 18067 /* This is okey because lhost and lport are as big as tmp */ 18068 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18069 if (ast_strlen_zero(lhost)) { 18070 ast_log(LOG_ERROR, "Can't find the host address\n"); 18071 return 0; 18072 } 18073 host = ast_strdupa(lhost); 18074 if (!ast_strlen_zero(lport)) { 18075 port = ast_strdupa(lport); 18076 } 18077 } 18078 } 18079 18080 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18081 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18082 18083 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18084 sip_alreadygone(p); 18085 return 0; 18086 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3892 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().
03893 { 03894 struct sip_pvt *p = ast->tech_pvt; 03895 int res; 03896 03897 if (dest == NULL) /* functions below do not take a NULL */ 03898 dest = ""; 03899 ast_mutex_lock(&p->lock); 03900 if (ast->_state == AST_STATE_RING) 03901 res = sip_sipredirect(p, dest); 03902 else 03903 res = transmit_refer(p, dest); 03904 ast_mutex_unlock(&p->lock); 03905 return res; 03906 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3719 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.
03720 { 03721 struct sip_pvt *p = ast->tech_pvt; 03722 int res = 0; 03723 03724 switch (frame->frametype) { 03725 case AST_FRAME_VOICE: 03726 if (!(frame->subclass & ast->nativeformats)) { 03727 char s1[512], s2[512], s3[512]; 03728 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03729 frame->subclass, 03730 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03731 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03732 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03733 ast->readformat, 03734 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03735 ast->writeformat); 03736 return 0; 03737 } 03738 if (p) { 03739 ast_mutex_lock(&p->lock); 03740 if (p->rtp) { 03741 /* If channel is not up, activate early media session */ 03742 if ((ast->_state != AST_STATE_UP) && 03743 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03744 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03745 ast_rtp_new_source(p->rtp); 03746 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03747 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03748 } 03749 p->lastrtptx = time(NULL); 03750 res = ast_rtp_write(p->rtp, frame); 03751 } 03752 ast_mutex_unlock(&p->lock); 03753 } 03754 break; 03755 case AST_FRAME_VIDEO: 03756 if (p) { 03757 ast_mutex_lock(&p->lock); 03758 if (p->vrtp) { 03759 /* Activate video early media */ 03760 if ((ast->_state != AST_STATE_UP) && 03761 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03762 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03763 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03764 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03765 } 03766 p->lastrtptx = time(NULL); 03767 res = ast_rtp_write(p->vrtp, frame); 03768 } 03769 ast_mutex_unlock(&p->lock); 03770 } 03771 break; 03772 case AST_FRAME_IMAGE: 03773 return 0; 03774 break; 03775 case AST_FRAME_MODEM: 03776 if (p) { 03777 ast_mutex_lock(&p->lock); 03778 /* UDPTL requires two-way communication, so early media is not needed here. 03779 we simply forget the frames if we get modem frames before the bridge is up. 03780 Fax will re-transmit. 03781 */ 03782 if (p->udptl && ast->_state == AST_STATE_UP) 03783 res = ast_udptl_write(p->udptl, frame); 03784 ast_mutex_unlock(&p->lock); 03785 } 03786 break; 03787 default: 03788 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03789 return 0; 03790 } 03791 03792 return res; 03793 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15556 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_PAGE2_TCP, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor(), and siptcpsock_accept().
15557 { 15558 struct sip_request req; 15559 struct sockaddr_in sin = { 0, }; 15560 struct sip_pvt *p; 15561 int res; 15562 socklen_t len = sizeof(sin); 15563 int nounlock; 15564 int recount = 0; 15565 int lockretry; 15566 15567 memset(&req, 0, sizeof(req)); 15568 if (fd == sipsock) 15569 res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15570 else { 15571 if (getpeername(fd, (struct sockaddr *)&sin, &len) < 0) { 15572 close(fd); 15573 return 1; 15574 } 15575 if ((res = read(fd, req.data, sizeof(req.data) - 1)) == 0) { 15576 close(fd); 15577 return 1; 15578 } 15579 } 15580 if (res < 0) { 15581 #if !defined(__FreeBSD__) 15582 if (errno == EAGAIN) 15583 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15584 else 15585 #endif 15586 if (errno != ECONNREFUSED) 15587 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15588 return 1; 15589 } 15590 if (option_debug && res == sizeof(req.data) - 1) 15591 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15592 15593 req.data[res] = '\0'; 15594 req.len = res; 15595 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15596 ast_set_flag(&req, SIP_PKT_DEBUG); 15597 if (pedanticsipchecking) 15598 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15599 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15600 ast_verbose("\n<--- SIP read from %s:%d:%s --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 15601 fd == sipsock ? "UDP" : "TCP",req.data); 15602 15603 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 15604 return 1; 15605 15606 req.method = find_sip_method(req.rlPart1); 15607 15608 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15609 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15610 15611 if (req.headers < 2) /* Must have at least two headers */ 15612 return 1; 15613 15614 /* Process request, with netlock held, and with usual deadlock avoidance */ 15615 for (lockretry = 100; lockretry > 0; lockretry--) { 15616 ast_mutex_lock(&netlock); 15617 15618 /* Find the active SIP dialog or create a new one */ 15619 p = find_call(&req, &sin, req.method); /* returns p locked */ 15620 if (p == NULL) { 15621 if (option_debug) 15622 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15623 ast_mutex_unlock(&netlock); 15624 return 1; 15625 } 15626 /* Go ahead and lock the owner if it has one -- we may need it */ 15627 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15628 if (!p->owner || !ast_channel_trylock(p->owner)) 15629 break; /* locking succeeded */ 15630 if (option_debug) 15631 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15632 ast_mutex_unlock(&p->lock); 15633 ast_mutex_unlock(&netlock); 15634 /* Sleep for a very short amount of time */ 15635 usleep(1); 15636 } 15637 p->recv = sin; 15638 15639 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15640 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15641 15642 if (!lockretry) { 15643 if (p->owner) 15644 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15645 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15646 if (req.method != SIP_ACK) 15647 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15648 /* XXX We could add retry-after to make sure they come back */ 15649 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15650 return 1; 15651 } 15652 nounlock = 0; 15653 /* Is this a TCP connection ?? if so set the socket accordingly*/ 15654 if (fd != sipsock) { 15655 p->sockfd=fd; 15656 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP); 15657 } else { 15658 p->sockfd=-1; 15659 } 15660 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15661 /* Request failed */ 15662 if (option_debug) 15663 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15664 } 15665 15666 if (p->owner && !nounlock) 15667 ast_channel_unlock(p->owner); 15668 ast_mutex_unlock(&p->lock); 15669 ast_mutex_unlock(&netlock); 15670 if (recount) 15671 ast_update_use_count(); 15672 15673 return 1; 15674 }
static int siptcpsock_accept | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Accept incoming TCP connections.
Definition at line 15677 of file chan_sip.c.
References ast_io_add(), AST_IO_IN, io, sipsock_read(), and siptcpsock.
Referenced by do_monitor().
15678 { 15679 struct sockaddr_in sa; 15680 socklen_t sa_len=sizeof(sa); 15681 int newfd; 15682 15683 if ((newfd=accept(siptcpsock, (struct sockaddr *)&sa, &sa_len)) >= 0) 15684 ast_io_add(io, newfd, sipsock_read, AST_IO_IN, NULL); 15685 return 1; 15686 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12774 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().
12775 { 12776 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12777 if (p->rtp) 12778 ast_rtp_stop(p->rtp); 12779 if (p->vrtp) 12780 ast_rtp_stop(p->vrtp); 12781 if (p->udptl) 12782 ast_udptl_stop(p->udptl); 12783 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10884 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10885 { 10886 int i; 10887 10888 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10889 if (subscription_types[i].type == subtype) { 10890 return subscription_types[i].text; 10891 } 10892 } 10893 return subscription_types[0].text; 10894 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6341 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().
06342 { 06343 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06344 06345 if (maxrate & T38FAX_RATE_14400) { 06346 if (option_debug > 1) 06347 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06348 return 14400; 06349 } else if (maxrate & T38FAX_RATE_12000) { 06350 if (option_debug > 1) 06351 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06352 return 12000; 06353 } else if (maxrate & T38FAX_RATE_9600) { 06354 if (option_debug > 1) 06355 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06356 return 9600; 06357 } else if (maxrate & T38FAX_RATE_7200) { 06358 if (option_debug > 1) 06359 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06360 return 7200; 06361 } else if (maxrate & T38FAX_RATE_4800) { 06362 if (option_debug > 1) 06363 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06364 return 4800; 06365 } else if (maxrate & T38FAX_RATE_2400) { 06366 if (option_debug > 1) 06367 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06368 return 2400; 06369 } else { 06370 if (option_debug > 1) 06371 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06372 return 0; 06373 } 06374 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16739 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().
16740 { 16741 struct sip_peer *peer; 16742 16743 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16744 return NULL; 16745 16746 apeerobjs++; 16747 ASTOBJ_INIT(peer); 16748 set_peer_defaults(peer); 16749 16750 ast_copy_string(peer->name, name, sizeof(peer->name)); 16751 16752 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16753 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16754 peer->prefs = default_prefs; 16755 reg_source_db(peer); 16756 16757 return peer; 16758 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6116 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06117 { 06118 struct sip_pvt *p = data; 06119 06120 ast_string_field_free_memory(p); 06121 06122 free(data); 06123 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9893 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().
09894 { 09895 if (mode == TRANSFER_OPENFORALL) 09896 return "open"; 09897 else if (mode == TRANSFER_CLOSED) 09898 return "closed"; 09899 return "strict"; 09900 }
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 8714 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().
08715 { 08716 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08717 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08718 }
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 7889 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07890 { 07891 struct sip_request req; 07892 07893 reqprep(&req, p, SIP_INFO, 0, 1); 07894 add_digit(&req, digit, duration); 07895 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07896 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7899 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07900 { 07901 struct sip_request req; 07902 07903 reqprep(&req, p, SIP_INFO, 0, 1); 07904 add_vidupdate(&req); 07905 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07906 }
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 7148 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().
07149 { 07150 struct sip_request req; 07151 07152 req.method = sipmethod; 07153 if (init) { /* Seems like init always is 2 */ 07154 /* Bump branch even on initial requests */ 07155 p->branch ^= ast_random(); 07156 build_via(p); 07157 if (init > 1) 07158 initreqprep(&req, p, sipmethod); 07159 else 07160 reqprep(&req, p, sipmethod, 0, 1); 07161 } else 07162 reqprep(&req, p, sipmethod, 0, 1); 07163 07164 if (p->options && p->options->auth) 07165 add_header(&req, p->options->authheader, p->options->auth); 07166 append_date(&req); 07167 if (sipmethod == SIP_REFER) { /* Call transfer */ 07168 if (p->refer) { 07169 char buf[SIPBUFSIZE]; 07170 if (!ast_strlen_zero(p->refer->refer_to)) 07171 add_header(&req, "Refer-To", p->refer->refer_to); 07172 if (!ast_strlen_zero(p->refer->referred_by)) { 07173 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07174 add_header(&req, "Referred-By", buf); 07175 } 07176 } 07177 } 07178 /* This new INVITE is part of an attended transfer. Make sure that the 07179 other end knows and replace the current call with this new call */ 07180 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07181 add_header(&req, "Replaces", p->options->replaces); 07182 add_header(&req, "Require", "replaces"); 07183 } 07184 07185 add_header(&req, "Allow", ALLOWED_METHODS); 07186 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07187 if (p->options && p->options->addsipheaders && p->owner) { 07188 struct ast_channel *chan = p->owner; /* The owner channel */ 07189 struct varshead *headp; 07190 07191 ast_channel_lock(chan); 07192 07193 headp = &chan->varshead; 07194 07195 if (!headp) 07196 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07197 else { 07198 const struct ast_var_t *current; 07199 AST_LIST_TRAVERSE(headp, current, entries) { 07200 /* SIPADDHEADER: Add SIP header to outgoing call */ 07201 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07202 char *content, *end; 07203 const char *header = ast_var_value(current); 07204 char *headdup = ast_strdupa(header); 07205 07206 /* Strip of the starting " (if it's there) */ 07207 if (*headdup == '"') 07208 headdup++; 07209 if ((content = strchr(headdup, ':'))) { 07210 *content++ = '\0'; 07211 content = ast_skip_blanks(content); /* Skip white space */ 07212 /* Strip the ending " (if it's there) */ 07213 end = content + strlen(content) -1; 07214 if (*end == '"') 07215 *end = '\0'; 07216 07217 add_header(&req, headdup, content); 07218 if (sipdebug) 07219 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07220 } 07221 } 07222 } 07223 } 07224 07225 ast_channel_unlock(chan); 07226 } 07227 if (sdp) { 07228 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07229 ast_udptl_offered_from_local(p->udptl, 1); 07230 if (option_debug) 07231 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07232 add_t38_sdp(&req, p); 07233 } else if (p->rtp) 07234 add_sdp(&req, p); 07235 } else { 07236 add_header_contentLength(&req, 0); 07237 } 07238 07239 if (!p->initreq.headers) 07240 initialize_initreq(p, &req); 07241 p->lastinvite = p->ocseq; 07242 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07243 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7798 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().
07799 { 07800 struct sip_request req; 07801 07802 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07803 add_text(&req, text); 07804 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07805 }
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 7434 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().
07435 { 07436 struct sip_request req; 07437 char tmp[500]; 07438 char *t = tmp; 07439 size_t maxbytes = sizeof(tmp); 07440 07441 initreqprep(&req, p, SIP_NOTIFY); 07442 add_header(&req, "Event", "message-summary"); 07443 add_header(&req, "Content-Type", default_notifymime); 07444 07445 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07446 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07447 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07448 /* Cisco has a bug in the SIP stack where it can't accept the 07449 (0/0) notification. This can temporarily be disabled in 07450 sip.conf with the "buggymwi" option */ 07451 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)")); 07452 07453 if (p->subscribed) { 07454 if (p->expiry) 07455 add_header(&req, "Subscription-State", "active"); 07456 else /* Expired */ 07457 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07458 } 07459 07460 if (t > tmp + sizeof(tmp)) 07461 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07462 07463 add_header_contentLength(&req, strlen(tmp)); 07464 add_line(&req, tmp); 07465 07466 if (!p->initreq.headers) 07467 initialize_initreq(p, &req); 07468 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07469 }
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 7480 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().
07481 { 07482 struct sip_request req; 07483 char tmp[SIPBUFSIZE/2]; 07484 07485 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07486 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07487 add_header(&req, "Event", tmp); 07488 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07489 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07490 add_header(&req, "Allow", ALLOWED_METHODS); 07491 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07492 07493 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07494 add_header_contentLength(&req, strlen(tmp)); 07495 add_line(&req, tmp); 07496 07497 if (!p->initreq.headers) 07498 initialize_initreq(p, &req); 07499 07500 p->lastnoninvite = p->ocseq; 07501 07502 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07503 }
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 7819 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().
07820 { 07821 struct sip_request req = { 07822 .headers = 0, 07823 }; 07824 char from[256]; 07825 const char *of; 07826 char *c; 07827 char referto[256]; 07828 char *ttag, *ftag; 07829 char *theirtag = ast_strdupa(p->theirtag); 07830 07831 if (option_debug || sipdebug) 07832 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07833 07834 /* Are we transfering an inbound or outbound call ? */ 07835 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07836 of = get_header(&p->initreq, "To"); 07837 ttag = theirtag; 07838 ftag = p->tag; 07839 } else { 07840 of = get_header(&p->initreq, "From"); 07841 ftag = theirtag; 07842 ttag = p->tag; 07843 } 07844 07845 ast_copy_string(from, of, sizeof(from)); 07846 of = get_in_brackets(from); 07847 ast_string_field_set(p, from, of); 07848 if (strncasecmp(of, "sip:", 4)) 07849 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07850 else 07851 of += 4; 07852 /* Get just the username part */ 07853 if ((c = strchr(dest, '@'))) 07854 c = NULL; 07855 else if ((c = strchr(of, '@'))) 07856 *c++ = '\0'; 07857 if (c) 07858 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07859 else 07860 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07861 07862 /* save in case we get 407 challenge */ 07863 sip_refer_allocate(p); 07864 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07865 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07866 p->refer->status = REFER_SENT; /* Set refer status */ 07867 07868 reqprep(&req, p, SIP_REFER, 0, 1); 07869 07870 add_header(&req, "Refer-To", referto); 07871 add_header(&req, "Allow", ALLOWED_METHODS); 07872 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07873 if (!ast_strlen_zero(p->our_contact)) 07874 add_header(&req, "Referred-By", p->our_contact); 07875 07876 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07877 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07878 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07879 07880 /*! \todo In theory, we should hang around and wait for a reply, before 07881 returning to the dial plan here. Don't know really how that would 07882 affect the transfer() app or the pbx, but, well, to make this 07883 useful we should have a STATUS code on transfer(). 07884 */ 07885 }
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 7607 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().
07608 { 07609 struct sip_request req; 07610 char from[256]; 07611 char to[256]; 07612 char tmp[80]; 07613 char addr[80]; 07614 struct sip_pvt *p; 07615 07616 /* exit if we are already in process with this registrar ?*/ 07617 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07618 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07619 return 0; 07620 } 07621 07622 if (r->call) { /* We have a registration */ 07623 if (!auth) { 07624 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07625 return 0; 07626 } else { 07627 p = r->call; 07628 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07629 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07630 } 07631 } else { 07632 /* Build callid for registration if we haven't registered before */ 07633 if (!r->callid_valid) { 07634 build_callid_registry(r, __ourip, default_fromdomain); 07635 r->callid_valid = TRUE; 07636 } 07637 /* Allocate SIP packet for registration */ 07638 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07639 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07640 return 0; 07641 } 07642 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07643 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07644 /* Find address to hostname */ 07645 if (create_addr(p, r->hostname)) { 07646 /* we have what we hope is a temporary network error, 07647 * probably DNS. We need to reschedule a registration try */ 07648 sip_destroy(p); 07649 07650 if (r->timeout > -1) 07651 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07652 else 07653 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); 07654 07655 AST_SCHED_DEL(sched, r->timeout); 07656 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07657 r->regattempts++; 07658 return 0; 07659 } 07660 /* Copy back Call-ID in case create_addr changed it */ 07661 ast_string_field_set(r, callid, p->callid); 07662 if (r->portno) { 07663 p->sa.sin_port = htons(r->portno); 07664 p->recv.sin_port = htons(r->portno); 07665 } else /* Set registry port to the port set from the peer definition/srv or default */ 07666 r->portno = ntohs(p->sa.sin_port); 07667 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07668 r->call=p; /* Save pointer to SIP packet */ 07669 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07670 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07671 ast_string_field_set(p, peersecret, r->secret); 07672 if (!ast_strlen_zero(r->md5secret)) 07673 ast_string_field_set(p, peermd5secret, r->md5secret); 07674 /* User name in this realm 07675 - if authuser is set, use that, otherwise use username */ 07676 if (!ast_strlen_zero(r->authuser)) { 07677 ast_string_field_set(p, peername, r->authuser); 07678 ast_string_field_set(p, authname, r->authuser); 07679 } else if (!ast_strlen_zero(r->username)) { 07680 ast_string_field_set(p, peername, r->username); 07681 ast_string_field_set(p, authname, r->username); 07682 ast_string_field_set(p, fromuser, r->username); 07683 } 07684 if (!ast_strlen_zero(r->username)) 07685 ast_string_field_set(p, username, r->username); 07686 /* Save extension in packet */ 07687 ast_string_field_set(p, exten, r->contact); 07688 07689 /* 07690 check which address we should use in our contact header 07691 based on whether the remote host is on the external or 07692 internal network so we can register through nat 07693 */ 07694 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07695 p->ourip = bindaddr.sin_addr; 07696 build_contact(p); 07697 } 07698 07699 /* set up a timeout */ 07700 if (auth == NULL) { 07701 if (r->timeout > -1) 07702 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07703 AST_SCHED_DEL(sched, r->timeout); 07704 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07705 if (option_debug) 07706 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07707 } 07708 07709 if (strchr(r->username, '@')) { 07710 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07711 if (!ast_strlen_zero(p->theirtag)) 07712 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07713 else 07714 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07715 } else { 07716 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07717 if (!ast_strlen_zero(p->theirtag)) 07718 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07719 else 07720 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07721 } 07722 07723 /* Fromdomain is what we are registering to, regardless of actual 07724 host name from SRV */ 07725 if (!ast_strlen_zero(p->fromdomain)) { 07726 if (r->portno && r->portno != STANDARD_SIP_PORT) 07727 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07728 else 07729 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07730 } else { 07731 if (r->portno && r->portno != STANDARD_SIP_PORT) 07732 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07733 else 07734 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07735 } 07736 ast_string_field_set(p, uri, addr); 07737 07738 p->branch ^= ast_random(); 07739 07740 init_req(&req, sipmethod, addr); 07741 07742 /* Add to CSEQ */ 07743 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07744 p->ocseq = r->ocseq; 07745 07746 build_via(p); 07747 add_header(&req, "Via", p->via); 07748 add_header(&req, "From", from); 07749 add_header(&req, "To", to); 07750 add_header(&req, "Call-ID", p->callid); 07751 add_header(&req, "CSeq", tmp); 07752 if (!ast_strlen_zero(global_useragent)) 07753 add_header(&req, "User-Agent", global_useragent); 07754 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07755 07756 07757 if (auth) /* Add auth header */ 07758 add_header(&req, authheader, auth); 07759 else if (!ast_strlen_zero(r->nonce)) { 07760 char digest[1024]; 07761 07762 /* We have auth data to reuse, build a digest header! */ 07763 if (sipdebug) 07764 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07765 ast_string_field_set(p, realm, r->realm); 07766 ast_string_field_set(p, nonce, r->nonce); 07767 ast_string_field_set(p, domain, r->domain); 07768 ast_string_field_set(p, opaque, r->opaque); 07769 ast_string_field_set(p, qop, r->qop); 07770 r->noncecount++; 07771 p->noncecount = r->noncecount; 07772 07773 memset(digest,0,sizeof(digest)); 07774 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07775 add_header(&req, "Authorization", digest); 07776 else 07777 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07778 07779 } 07780 07781 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07782 add_header(&req, "Expires", tmp); 07783 add_header(&req, "Contact", p->our_contact); 07784 add_header(&req, "Event", "registration"); 07785 add_header_contentLength(&req, 0); 07786 07787 initialize_initreq(p, &req); 07788 if (sip_debug_test_pvt(p)) 07789 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07790 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07791 r->regattempts++; /* Another attempt */ 07792 if (option_debug > 3) 07793 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07794 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07795 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6868 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().
06869 { 06870 struct sip_request req; 06871 06872 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06873 06874 add_header(&req, "Allow", ALLOWED_METHODS); 06875 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06876 if (sipdebug) 06877 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06878 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06879 append_history(p, "ReInv", "Re-invite sent"); 06880 add_sdp(&req, p); 06881 /* Use this as the basis */ 06882 initialize_initreq(p, &req); 06883 p->lastinvite = p->ocseq; 06884 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06885 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06886 }
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 6892 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().
06893 { 06894 struct sip_request req; 06895 06896 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06897 06898 add_header(&req, "Allow", ALLOWED_METHODS); 06899 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06900 if (sipdebug) 06901 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06902 ast_udptl_offered_from_local(p->udptl, 1); 06903 add_t38_sdp(&req, p); 06904 /* Use this as the basis */ 06905 initialize_initreq(p, &req); 06906 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06907 p->lastinvite = p->ocseq; 06908 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06909 }
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 7911 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().
07912 { 07913 struct sip_request resp; 07914 07915 if (sipmethod == SIP_ACK) 07916 p->invitestate = INV_CONFIRMED; 07917 07918 reqprep(&resp, p, sipmethod, seqno, newbranch); 07919 add_header_contentLength(&resp, 0); 07920 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07921 }
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 7924 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().
07925 { 07926 struct sip_request resp; 07927 07928 reqprep(&resp, p, sipmethod, seqno, newbranch); 07929 if (!ast_strlen_zero(p->realm)) { 07930 char digest[1024]; 07931 07932 memset(digest, 0, sizeof(digest)); 07933 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07934 if (p->options && p->options->auth_type == PROXY_AUTH) 07935 add_header(&resp, "Proxy-Authorization", digest); 07936 else if (p->options && p->options->auth_type == WWW_AUTH) 07937 add_header(&resp, "Authorization", digest); 07938 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07939 add_header(&resp, "Proxy-Authorization", digest); 07940 } else 07941 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07942 } 07943 /* If we are hanging up and know a cause for that, send it in clear text to make 07944 debugging easier. */ 07945 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07946 char buf[10]; 07947 07948 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07949 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07950 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07951 } 07952 07953 add_header_contentLength(&resp, 0); 07954 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07955 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6177 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06178 { 06179 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06180 }
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 6196 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().
06197 { 06198 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06199 }
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 6126 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.
06127 { 06128 struct sip_pvt *p = NULL; 06129 06130 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06131 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06132 return -1; 06133 } 06134 06135 /* if the structure was just allocated, initialize it */ 06136 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06137 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06138 if (ast_string_field_init(p, 512)) 06139 return -1; 06140 } 06141 06142 /* Initialize the bare minimum */ 06143 p->method = intended_method; 06144 06145 if (sin) { 06146 p->sa = *sin; 06147 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06148 p->ourip = __ourip; 06149 } else 06150 p->ourip = __ourip; 06151 06152 p->branch = ast_random(); 06153 make_our_tag(p->tag, sizeof(p->tag)); 06154 p->ocseq = INITIAL_CSEQ; 06155 06156 if (useglobal_nat && sin) { 06157 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06158 p->recv = *sin; 06159 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06160 } 06161 check_via(p, req); 06162 06163 ast_string_field_set(p, fromdomain, default_fromdomain); 06164 build_via(p); 06165 ast_string_field_set(p, callid, callid); 06166 06167 /* Use this temporary pvt structure to send the message */ 06168 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06169 06170 /* Free the string fields, but not the pool space */ 06171 ast_string_field_reset_all(p); 06172 06173 return 0; 06174 }
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 6224 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06225 { 06226 struct sip_request resp; 06227 respprep(&resp, p, msg, req); 06228 add_header(&resp, "Accept", "application/sdp"); 06229 add_header_contentLength(&resp, 0); 06230 return send_response(p, &resp, reliable, 0); 06231 }
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 6234 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().
06235 { 06236 struct sip_request resp; 06237 char tmp[512]; 06238 int seqno = 0; 06239 06240 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06241 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06242 return -1; 06243 } 06244 /* Stale means that they sent us correct authentication, but 06245 based it on an old challenge (nonce) */ 06246 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06247 respprep(&resp, p, msg, req); 06248 add_header(&resp, header, tmp); 06249 add_header_contentLength(&resp, 0); 06250 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06251 return send_response(p, &resp, reliable, seqno); 06252 }
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 6214 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06215 { 06216 struct sip_request resp; 06217 respprep(&resp, p, msg, req); 06218 append_date(&resp); 06219 add_header_contentLength(&resp, 0); 06220 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06221 }
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 6797 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().
06798 { 06799 struct sip_request resp; 06800 int seqno; 06801 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06802 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06803 return -1; 06804 } 06805 respprep(&resp, p, msg, req); 06806 if (p->rtp) { 06807 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06808 if (option_debug) 06809 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06810 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06811 } 06812 try_suggested_sip_codec(p); 06813 add_sdp(&resp, p); 06814 } else 06815 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06816 if (reliable && !p->pendinginvite) 06817 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06818 return send_response(p, &resp, reliable, seqno); 06819 }
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 6757 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().
06758 { 06759 struct sip_request resp; 06760 int seqno; 06761 06762 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06763 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06764 return -1; 06765 } 06766 respprep(&resp, p, msg, req); 06767 if (p->udptl) { 06768 ast_udptl_offered_from_local(p->udptl, 0); 06769 add_t38_sdp(&resp, p); 06770 } else 06771 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06772 if (retrans && !p->pendinginvite) 06773 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06774 return send_response(p, &resp, retrans, seqno); 06775 }
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 6183 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06184 { 06185 struct sip_request resp; 06186 respprep(&resp, p, msg, req); 06187 append_date(&resp); 06188 add_header(&resp, "Unsupported", unsupported); 06189 add_header_contentLength(&resp, 0); 06190 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06191 }
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 7472 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().
07473 { 07474 if (!p->initreq.headers) /* Initialize first request before sending */ 07475 initialize_initreq(p, req); 07476 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07477 }
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 7246 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().
07247 { 07248 char tmp[4000], from[256], to[256]; 07249 char *t = tmp, *c, *mfrom, *mto; 07250 size_t maxbytes = sizeof(tmp); 07251 struct sip_request req; 07252 char hint[AST_MAX_EXTENSION]; 07253 char *statestring = "terminated"; 07254 const struct cfsubscription_types *subscriptiontype; 07255 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07256 char *pidfstate = "--"; 07257 char *pidfnote= "Ready"; 07258 07259 memset(from, 0, sizeof(from)); 07260 memset(to, 0, sizeof(to)); 07261 memset(tmp, 0, sizeof(tmp)); 07262 07263 switch (state) { 07264 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07265 statestring = (global_notifyringing) ? "early" : "confirmed"; 07266 local_state = NOTIFY_INUSE; 07267 pidfstate = "busy"; 07268 pidfnote = "Ringing"; 07269 break; 07270 case AST_EXTENSION_RINGING: 07271 statestring = "early"; 07272 local_state = NOTIFY_INUSE; 07273 pidfstate = "busy"; 07274 pidfnote = "Ringing"; 07275 break; 07276 case AST_EXTENSION_INUSE: 07277 statestring = "confirmed"; 07278 local_state = NOTIFY_INUSE; 07279 pidfstate = "busy"; 07280 pidfnote = "On the phone"; 07281 break; 07282 case AST_EXTENSION_BUSY: 07283 statestring = "confirmed"; 07284 local_state = NOTIFY_CLOSED; 07285 pidfstate = "busy"; 07286 pidfnote = "On the phone"; 07287 break; 07288 case AST_EXTENSION_UNAVAILABLE: 07289 statestring = "terminated"; 07290 local_state = NOTIFY_CLOSED; 07291 pidfstate = "away"; 07292 pidfnote = "Unavailable"; 07293 break; 07294 case AST_EXTENSION_ONHOLD: 07295 statestring = "confirmed"; 07296 local_state = NOTIFY_CLOSED; 07297 pidfstate = "busy"; 07298 pidfnote = "On Hold"; 07299 break; 07300 case AST_EXTENSION_NOT_INUSE: 07301 default: 07302 /* Default setting */ 07303 break; 07304 } 07305 07306 subscriptiontype = find_subscription_type(p->subscribed); 07307 07308 /* Check which device/devices we are watching and if they are registered */ 07309 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07310 char *hint2 = hint, *individual_hint = NULL; 07311 int hint_count = 0, unavailable_count = 0; 07312 07313 while ((individual_hint = strsep(&hint2, "&"))) { 07314 hint_count++; 07315 07316 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07317 unavailable_count++; 07318 } 07319 07320 /* If none of the hinted devices are registered, we will 07321 * override notification and show no availability. 07322 */ 07323 if (hint_count > 0 && hint_count == unavailable_count) { 07324 local_state = NOTIFY_CLOSED; 07325 pidfstate = "away"; 07326 pidfnote = "Not online"; 07327 } 07328 } 07329 07330 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07331 c = get_in_brackets(from); 07332 if (strncasecmp(c, "sip:", 4)) { 07333 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07334 return -1; 07335 } 07336 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07337 07338 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07339 c = get_in_brackets(to); 07340 if (strncasecmp(c, "sip:", 4)) { 07341 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07342 return -1; 07343 } 07344 mto = strsep(&c, ";"); /* trim ; and beyond */ 07345 07346 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07347 07348 07349 add_header(&req, "Event", subscriptiontype->event); 07350 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07351 switch(state) { 07352 case AST_EXTENSION_DEACTIVATED: 07353 if (timeout) 07354 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07355 else { 07356 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07357 add_header(&req, "Retry-After", "60"); 07358 } 07359 break; 07360 case AST_EXTENSION_REMOVED: 07361 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07362 break; 07363 default: 07364 if (p->expiry) 07365 add_header(&req, "Subscription-State", "active"); 07366 else /* Expired */ 07367 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07368 } 07369 switch (p->subscribed) { 07370 case XPIDF_XML: 07371 case CPIM_PIDF_XML: 07372 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07373 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07374 ast_build_string(&t, &maxbytes, "<presence>\n"); 07375 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07376 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07377 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07378 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07379 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07380 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07381 break; 07382 case PIDF_XML: /* Eyebeam supports this format */ 07383 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07384 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); 07385 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07386 if (pidfstate[0] != '-') 07387 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07388 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07389 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07390 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07391 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07392 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07393 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07394 else 07395 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07396 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07397 break; 07398 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07399 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07400 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); 07401 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07402 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07403 else 07404 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07405 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07406 if (state == AST_EXTENSION_ONHOLD) { 07407 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07408 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07409 "</target>\n</local>\n", mto); 07410 } 07411 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07412 break; 07413 case NONE: 07414 default: 07415 break; 07416 } 07417 07418 if (t > tmp + sizeof(tmp)) 07419 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07420 07421 add_header_contentLength(&req, strlen(tmp)); 07422 add_line(&req, tmp); 07423 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07424 07425 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07426 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3669 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().
03670 { 03671 int fmt; 03672 const char *codec; 03673 03674 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03675 if (!codec) 03676 return; 03677 03678 fmt = ast_getformatbyname(codec); 03679 if (fmt) { 03680 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03681 if (p->jointcapability & fmt) { 03682 p->jointcapability &= fmt; 03683 p->capability &= fmt; 03684 } else 03685 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03686 } else 03687 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03688 return; 03689 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18365 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, siptcpsock, TRUE, and userl.
18366 { 18367 struct sip_pvt *p, *pl; 18368 18369 /* First, take us out of the channel type list */ 18370 ast_channel_unregister(&sip_tech); 18371 18372 /* Unregister dial plan functions */ 18373 ast_custom_function_unregister(&sipchaninfo_function); 18374 ast_custom_function_unregister(&sippeer_function); 18375 ast_custom_function_unregister(&sip_header_function); 18376 ast_custom_function_unregister(&checksipdomain_function); 18377 18378 /* Unregister dial plan applications */ 18379 ast_unregister_application(app_dtmfmode); 18380 ast_unregister_application(app_sipaddheader); 18381 18382 /* Unregister CLI commands */ 18383 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18384 18385 /* Disconnect from the RTP subsystem */ 18386 ast_rtp_proto_unregister(&sip_rtp); 18387 18388 /* Disconnect from UDPTL */ 18389 ast_udptl_proto_unregister(&sip_udptl); 18390 18391 /* Unregister AMI actions */ 18392 ast_manager_unregister("SIPpeers"); 18393 ast_manager_unregister("SIPshowpeer"); 18394 18395 ast_mutex_lock(&iflock); 18396 /* Hangup all interfaces if they have an owner */ 18397 for (p = iflist; p ; p = p->next) { 18398 if (p->owner) 18399 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18400 } 18401 ast_mutex_unlock(&iflock); 18402 18403 ast_mutex_lock(&monlock); 18404 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18405 pthread_cancel(monitor_thread); 18406 pthread_kill(monitor_thread, SIGURG); 18407 pthread_join(monitor_thread, NULL); 18408 } 18409 monitor_thread = AST_PTHREADT_STOP; 18410 ast_mutex_unlock(&monlock); 18411 18412 restartdestroy: 18413 ast_mutex_lock(&iflock); 18414 /* Destroy all the interfaces and free their memory */ 18415 p = iflist; 18416 while (p) { 18417 pl = p; 18418 p = p->next; 18419 if (__sip_destroy(pl, TRUE) < 0) { 18420 /* Something is still bridged, let it react to getting a hangup */ 18421 iflist = p; 18422 ast_mutex_unlock(&iflock); 18423 usleep(1); 18424 goto restartdestroy; 18425 } 18426 } 18427 iflist = NULL; 18428 ast_mutex_unlock(&iflock); 18429 18430 /* Free memory for local network address mask */ 18431 ast_free_ha(localaddr); 18432 18433 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18434 ASTOBJ_CONTAINER_DESTROY(&userl); 18435 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18436 ASTOBJ_CONTAINER_DESTROY(&peerl); 18437 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18438 ASTOBJ_CONTAINER_DESTROY(®l); 18439 18440 clear_realm_authentication(authl); 18441 clear_sip_domains(); 18442 close(sipsock); 18443 close(siptcpsock); 18444 sched_context_destroy(sched); 18445 18446 return 0; 18447 }
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 3221 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().
03222 { 03223 char name[256]; 03224 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03225 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03226 struct sip_user *u = NULL; 03227 struct sip_peer *p = NULL; 03228 03229 if (option_debug > 2) 03230 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03231 03232 /* Test if we need to check call limits, in order to avoid 03233 realtime lookups if we do not need it */ 03234 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03235 return 0; 03236 03237 ast_copy_string(name, fup->username, sizeof(name)); 03238 03239 /* Check the list of users only for incoming calls */ 03240 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03241 inuse = &u->inUse; 03242 call_limit = &u->call_limit; 03243 inringing = NULL; 03244 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03245 inuse = &p->inUse; 03246 call_limit = &p->call_limit; 03247 inringing = &p->inRinging; 03248 ast_copy_string(name, fup->peername, sizeof(name)); 03249 } 03250 if (!p && !u) { 03251 if (option_debug > 1) 03252 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03253 return 0; 03254 } 03255 03256 switch(event) { 03257 /* incoming and outgoing affects the inUse counter */ 03258 case DEC_CALL_LIMIT: 03259 if ( *inuse > 0 ) { 03260 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03261 (*inuse)--; 03262 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03263 } 03264 } else { 03265 *inuse = 0; 03266 } 03267 if (inringing) { 03268 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03269 if (*inringing > 0) 03270 (*inringing)--; 03271 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03272 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03273 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03274 } 03275 } 03276 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03277 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03278 sip_peer_hold(fup, 0); 03279 } 03280 if (option_debug > 1 || sipdebug) { 03281 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03282 } 03283 break; 03284 03285 case INC_CALL_RINGING: 03286 case INC_CALL_LIMIT: 03287 if (*call_limit > 0 ) { 03288 /* Let call limit affect only outgoing calls */ 03289 if (outgoing && (*inuse >= *call_limit)) { 03290 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); 03291 if (u) 03292 ASTOBJ_UNREF(u, sip_destroy_user); 03293 else 03294 ASTOBJ_UNREF(p, sip_destroy_peer); 03295 return -1; 03296 } 03297 } 03298 if (inringing && (event == INC_CALL_RINGING)) { 03299 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03300 (*inringing)++; 03301 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03302 } 03303 } 03304 /* Continue */ 03305 (*inuse)++; 03306 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03307 if (option_debug > 1 || sipdebug) { 03308 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03309 } 03310 break; 03311 03312 case DEC_CALL_RINGING: 03313 if (inringing) { 03314 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03315 if (*inringing > 0) 03316 (*inringing)--; 03317 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03318 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03319 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03320 } 03321 } 03322 break; 03323 03324 default: 03325 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03326 } 03327 if (p) { 03328 ast_device_state_changed("SIP/%s", p->name); 03329 ASTOBJ_UNREF(p, sip_destroy_peer); 03330 } else /* u must be set */ 03331 ASTOBJ_UNREF(u, sip_destroy_user); 03332 return 0; 03333 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2508 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().
02509 { 02510 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02511 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02512 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02513 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02514 } 02515 }
struct in_addr __ourip [static] |
Definition at line 1214 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 565 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 581 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17929 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17931 of file chan_sip.c.
Definition at line 1202 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 545 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1208 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 18191 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 18196 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 559 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 231 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11812 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1217 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 525 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 522 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 192 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 222 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 524 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 533 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 530 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 531 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 534 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 528 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 529 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17928 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17934 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 561 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 1211 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 1210 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 1209 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 552 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 553 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 569 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 542 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 568 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 566 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 537 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 584 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 229 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 538 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 571 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 555 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 541 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 540 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 562 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 550 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 551 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 563 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 546 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 539 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 549 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 547 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 567 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 557 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 556 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 558 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 564 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 11829 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 605 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1213 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 10442 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 9993 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 191 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 190 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 599 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 11821 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 11825 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 232 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 1219 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 11761 of file chan_sip.c.
int ourport [static] |
Definition at line 1216 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1215 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 544 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 11803 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 560 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 582 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 580 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 578 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 604 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 11785 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 11781 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 11756 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 11789 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 11776 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 11842 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 11798 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 11793 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 11808 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 11846 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 11838 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 11771 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 11766 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 11834 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 601 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 602 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 1616 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 1558 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 1584 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 1625 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 12083 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12003 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication UDP
Definition at line 1206 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 606 of file chan_sip.c.
int siptcpsock = -1 [static] |
Main socket for SIP network communication TCP
Definition at line 1207 of file chan_sip.c.
Referenced by do_monitor(), reg_source_db(), siptcpsock_accept(), and unload_module().
int* siptcpsock_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 579 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 543 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 577 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17927 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17932 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.