#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Include dependency graph for chan_sip.c:
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_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 void | __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 void | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
The user list: Users and friends. |
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 476 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1841 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 369 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 370 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 368 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
#define DEC_CALL_LIMIT 0 |
Definition at line 609 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 611 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 504 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 495 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 189 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 204 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 203 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 515 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 176 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), transmit_refer(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 202 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 497 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 513 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 175 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 206 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 503 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 514 of file chan_sip.c.
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 506 of file chan_sip.c.
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 505 of file chan_sip.c.
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 507 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 211 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 517 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 498 of file chan_sip.c.
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 181 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 183 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 187 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 180 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 154 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1026 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
Referenced by __sip_show_channels().
#define INC_CALL_LIMIT 1 |
Definition at line 610 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 220 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 167 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 197 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 212 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1024 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 207 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 236 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 409 of file chan_sip.c.
#define RTP 1 |
Definition at line 235 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 218 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6426 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 716 of file chan_sip.c.
Referenced by handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 757 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 745 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 746 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 731 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 732 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 736 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 734 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 735 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 733 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 762 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_FREE_BIT (1 << 14) |
----
Definition at line 730 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 760 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 723 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 759 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 750 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 749 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 214 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 215 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 216 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 742 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 739 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 740 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 741 of file chan_sip.c.
Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 717 of file chan_sip.c.
Referenced by __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 721 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 756 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 718 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 412 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 413 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 729 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 784 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 783 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 796 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 791 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
23: Inactive hold
Definition at line 794 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 793 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 777 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 778 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 779 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 780 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI)
Definition at line 799 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 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_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 804 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 806 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 805 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 754 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 755 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 720 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 724 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 727 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 747 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 758 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 208 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 725 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 728 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 726 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 161 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 836 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 837 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 838 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 482 of file chan_sip.c.
Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_address_from_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 408 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 479 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 811 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 830 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 831 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 826 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 827 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 828 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 829 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 816 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 815 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 813 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 812 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 819 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 818 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 820 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 822 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 823 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 824 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1602 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 165 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 163 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 344 of file chan_sip.c.
00344 { 00345 AUTH_SUCCESSFUL = 0, 00346 AUTH_CHALLENGE_SENT = 1, 00347 AUTH_SECRET_FAILED = -1, 00348 AUTH_USERNAME_MISMATCH = -2, 00349 AUTH_NOT_FOUND = -3, 00350 AUTH_FAKE_AUTH = -4, 00351 AUTH_UNKNOWN_DOMAIN = -5, 00352 AUTH_PEER_NOT_DYNAMIC = -6, 00353 AUTH_ACL_FAILED = -7, 00354 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 679 of file chan_sip.c.
00679 { 00680 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00681 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00682 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 255 of file chan_sip.c.
00255 { 00256 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00257 INV_CALLING = 1, /*!< Invite sent, no answer */ 00258 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00259 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00260 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00261 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00262 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00263 The only way out of this is a BYE from one side */ 00264 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00265 };
Definition at line 282 of file chan_sip.c.
00282 { 00283 PARSE_REGISTER_FAILED, 00284 PARSE_REGISTER_UPDATE, 00285 PARSE_REGISTER_QUERY, 00286 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 860 of file chan_sip.c.
00860 { 00861 REFER_IDLE, /*!< No REFER is in progress */ 00862 REFER_SENT, /*!< Sent REFER to transferee */ 00863 REFER_RECEIVED, /*!< Received REFER from transferer */ 00864 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00865 REFER_ACCEPTED, /*!< Accepted by transferee */ 00866 REFER_RINGING, /*!< Target Ringing */ 00867 REFER_200OK, /*!< Answered by transfer target */ 00868 REFER_FAILED, /*!< REFER declined - go on */ 00869 REFER_NOAUTH /*!< We had no auth for REFER */ 00870 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 338 of file chan_sip.c.
00338 { 00339 PROXY_AUTH, 00340 WWW_AUTH, 00341 };
enum sip_result |
Definition at line 247 of file chan_sip.c.
00247 { 00248 AST_SUCCESS = 0, 00249 AST_FAILURE = -1, 00250 };
enum sipmethod |
SIP Request methods known by Asterisk.
SIP_UNKNOWN | |
SIP_RESPONSE | |
SIP_REGISTER | |
SIP_OPTIONS | |
SIP_NOTIFY | |
SIP_INVITE | |
SIP_ACK | |
SIP_PRACK | |
SIP_BYE | |
SIP_REFER | |
SIP_SUBSCRIBE | |
SIP_MESSAGE | |
SIP_UPDATE | |
SIP_INFO | |
SIP_CANCEL | |
SIP_PUBLISH | |
SIP_PING |
Definition at line 313 of file chan_sip.c.
00313 { 00314 SIP_UNKNOWN, /* Unknown response */ 00315 SIP_RESPONSE, /* Not request, response to outbound request */ 00316 SIP_REGISTER, 00317 SIP_OPTIONS, 00318 SIP_NOTIFY, 00319 SIP_INVITE, 00320 SIP_ACK, 00321 SIP_PRACK, /* Not supported at all */ 00322 SIP_BYE, 00323 SIP_REFER, 00324 SIP_SUBSCRIBE, 00325 SIP_MESSAGE, 00326 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00327 SIP_INFO, 00328 SIP_CANCEL, 00329 SIP_PUBLISH, /* Not supported at all */ 00330 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00331 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 357 of file chan_sip.c.
00357 { 00358 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00359 REG_STATE_REGSENT, /*!< Registration request sent */ 00360 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00361 REG_STATE_REGISTERED, /*!< Registred and done */ 00362 REG_STATE_REJECTED, /*!< Registration rejected */ 00363 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00364 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00365 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00366 };
enum subscriptiontype |
Definition at line 288 of file chan_sip.c.
00288 { 00289 NONE = 0, 00290 XPIDF_XML, 00291 DIALOG_INFO_XML, 00292 CPIM_PIDF_XML, 00293 PIDF_XML, 00294 MWI_NOTIFICATION 00295 };
enum t38state |
T38 States for a call.
Definition at line 841 of file chan_sip.c.
00841 { 00842 T38_DISABLED = 0, /*!< Not enabled */ 00843 T38_LOCAL_DIRECT, /*!< Offered from local */ 00844 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00845 T38_PEER_DIRECT, /*!< Offered from peer */ 00846 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00847 T38_ENABLED /*!< Negotiated (enabled) */ 00848 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 241 of file chan_sip.c.
00241 { 00242 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00243 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00244 };
enum xmittype |
Definition at line 275 of file chan_sip.c.
00275 { 00276 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00277 If it fails, it's critical and will cause a teardown of the session */ 00278 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00279 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00280 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4241 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04242 { 04243 int pass; 04244 04245 /* 04246 * Technically you can place arbitrary whitespace both before and after the ':' in 04247 * a header, although RFC3261 clearly says you shouldn't before, and place just 04248 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04249 * a good idea to say you can do it, and if you can do it, why in the hell would. 04250 * you say you shouldn't. 04251 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04252 * and we always allow spaces after that for compatibility. 04253 */ 04254 for (pass = 0; name && pass < 2;pass++) { 04255 int x, len = strlen(name); 04256 for (x=*start; x<req->headers; x++) { 04257 if (!strncasecmp(req->header[x], name, len)) { 04258 char *r = req->header[x] + len; /* skip name */ 04259 if (pedanticsipchecking) 04260 r = ast_skip_blanks(r); 04261 04262 if (*r == ':') { 04263 *start = x+1; 04264 return ast_skip_blanks(r+1); 04265 } 04266 } 04267 } 04268 if (pass == 0) /* Try aliases */ 04269 name = find_alias(name, NULL); 04270 } 04271 04272 /* Don't return NULL, so get_header is always a valid pointer */ 04273 return ""; 04274 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2143 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02144 { 02145 struct sip_pkt *cur, *prev = NULL; 02146 02147 /* Just in case... */ 02148 char *msg; 02149 int res = FALSE; 02150 02151 msg = sip_methods[sipmethod].text; 02152 02153 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02154 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02155 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02156 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02157 if (!resp && (seqno == p->pendinginvite)) { 02158 if (option_debug) 02159 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02160 p->pendinginvite = 0; 02161 } 02162 /* this is our baby */ 02163 res = TRUE; 02164 UNLINK(cur, p->packets, prev); 02165 if (cur->retransid > -1) { 02166 if (sipdebug && option_debug > 3) 02167 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02168 } 02169 /* This odd section is designed to thwart a 02170 * race condition in the packet scheduler. There are 02171 * two conditions under which deleting the packet from the 02172 * scheduler can fail. 02173 * 02174 * 1. The packet has been removed from the scheduler because retransmission 02175 * is being attempted. The problem is that if the packet is currently attempting 02176 * retransmission and we are at this point in the code, then that MUST mean 02177 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02178 * lock temporarily to allow retransmission. 02179 * 02180 * 2. The packet has reached its maximum number of retransmissions and has 02181 * been permanently removed from the packet scheduler. If this is the case, then 02182 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02183 * of the retransid to -1 is ensured since in both cases p's lock is held. 02184 */ 02185 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02186 ast_mutex_unlock(&p->lock); 02187 usleep(1); 02188 ast_mutex_lock(&p->lock); 02189 } 02190 free(cur); 02191 break; 02192 } 02193 } 02194 if (option_debug) 02195 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"); 02196 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2066 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02067 { 02068 struct sip_pvt *p = (struct sip_pvt *)data; 02069 02070 /* If this is a subscription, tell the phone that we got a timeout */ 02071 if (p->subscribed) { 02072 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02073 p->subscribed = NONE; 02074 append_history(p, "Subscribestatus", "timeout"); 02075 if (option_debug > 2) 02076 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02077 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02078 } 02079 02080 /* If there are packets still waiting for delivery, delay the destruction */ 02081 if (p->packets) { 02082 if (option_debug > 2) 02083 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02084 append_history(p, "ReliableXmit", "timeout"); 02085 return 10000; 02086 } 02087 02088 /* If we're destroying a subscription, dereference peer object too */ 02089 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02090 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02091 02092 /* Reset schedule ID */ 02093 p->autokillid = -1; 02094 02095 if (option_debug) 02096 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02097 append_history(p, "AutoDestroy", "%s", p->callid); 02098 if (p->owner) { 02099 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02100 ast_queue_hangup(p->owner); 02101 } else if (p->refer) { 02102 if (option_debug > 2) 02103 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02104 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02105 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02106 } else 02107 sip_destroy(p); 02108 return 0; 02109 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3073 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, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, cfsip_methods::text, UNLINK, and update_call_counter().
Referenced by do_monitor(), sip_destroy(), and unload_module().
03074 { 03075 struct sip_pvt *cur, *prev = NULL; 03076 struct sip_pkt *cp; 03077 03078 if (sip_debug_test_pvt(p) || option_debug > 2) 03079 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03080 03081 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03082 update_call_counter(p, DEC_CALL_LIMIT); 03083 if (option_debug > 1) 03084 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03085 } 03086 03087 /* Unlink us from the owner if we have one */ 03088 if (p->owner) { 03089 if (lockowner) 03090 ast_channel_lock(p->owner); 03091 if (option_debug) 03092 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03093 p->owner->tech_pvt = NULL; 03094 /* Make sure that the channel knows its backend is going away */ 03095 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03096 if (lockowner) 03097 ast_channel_unlock(p->owner); 03098 /* Give the channel a chance to react before deallocation */ 03099 usleep(1); 03100 } 03101 03102 /* Remove link from peer to subscription of MWI */ 03103 if (p->relatedpeer && p->relatedpeer->mwipvt) 03104 p->relatedpeer->mwipvt = NULL; 03105 03106 if (dumphistory) 03107 sip_dump_history(p); 03108 03109 if (p->options) 03110 free(p->options); 03111 03112 if (p->stateid > -1) 03113 ast_extension_state_del(p->stateid, NULL); 03114 AST_SCHED_DEL(sched, p->initid); 03115 AST_SCHED_DEL(sched, p->waitid); 03116 AST_SCHED_DEL(sched, p->autokillid); 03117 03118 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03119 if (p->rtp) { 03120 while (ast_rtp_get_bridged(p->rtp)) 03121 usleep(1); 03122 ast_rtp_destroy(p->rtp); 03123 } 03124 if (p->vrtp) { 03125 while (ast_rtp_get_bridged(p->vrtp)) 03126 usleep(1); 03127 ast_rtp_destroy(p->vrtp); 03128 } 03129 if (p->udptl) 03130 ast_udptl_destroy(p->udptl); 03131 if (p->refer) 03132 free(p->refer); 03133 if (p->route) { 03134 free_old_route(p->route); 03135 p->route = NULL; 03136 } 03137 if (p->registry) { 03138 if (p->registry->call == p) 03139 p->registry->call = NULL; 03140 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03141 } 03142 03143 /* Clear history */ 03144 if (p->history) { 03145 struct sip_history *hist; 03146 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03147 free(hist); 03148 p->history_entries--; 03149 } 03150 free(p->history); 03151 p->history = NULL; 03152 } 03153 03154 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03155 if (cur == p) { 03156 UNLINK(cur, iflist, prev); 03157 break; 03158 } 03159 } 03160 if (!cur) { 03161 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03162 return; 03163 } 03164 03165 /* remove all current packets in this dialog */ 03166 while((cp = p->packets)) { 03167 p->packets = p->packets->next; 03168 AST_SCHED_DEL(sched, cp->retransid); 03169 free(cp); 03170 } 03171 if (p->chanvars) { 03172 ast_variables_destroy(p->chanvars); 03173 p->chanvars = NULL; 03174 } 03175 ast_mutex_destroy(&p->lock); 03176 03177 ast_string_field_free_memory(p); 03178 03179 free(p); 03180 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7481 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07482 { 07483 int res; 07484 07485 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07486 return res; 07487 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2200 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02201 { 02202 struct sip_pkt *cur = NULL; 02203 02204 while (p->packets) { 02205 int method; 02206 if (cur == p->packets) { 02207 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02208 return; 02209 } 02210 cur = p->packets; 02211 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02212 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02213 } 02214 }
static enum sip_result __sip_reliable_xmit | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
char * | data, | |||
int | len, | |||
int | fatal, | |||
int | sipmethod | |||
) | [static] |
Transmit packet with retransmits.
Definition at line 2019 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02020 { 02021 struct sip_pkt *pkt; 02022 int siptimer_a = DEFAULT_RETRANS; 02023 int xmitres = 0; 02024 02025 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02026 return AST_FAILURE; 02027 memcpy(pkt->data, data, len); 02028 pkt->method = sipmethod; 02029 pkt->packetlen = len; 02030 pkt->next = p->packets; 02031 pkt->owner = p; 02032 pkt->seqno = seqno; 02033 if (resp) 02034 ast_set_flag(pkt, FLAG_RESPONSE); 02035 pkt->data[len] = '\0'; 02036 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02037 pkt->retransid = -1; 02038 if (fatal) 02039 ast_set_flag(pkt, FLAG_FATAL); 02040 if (pkt->timer_t1) 02041 siptimer_a = pkt->timer_t1 * 2; 02042 02043 if (option_debug > 3 && sipdebug) 02044 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02045 pkt->retransid = -1; 02046 pkt->next = p->packets; 02047 p->packets = pkt; 02048 if (sipmethod == SIP_INVITE) { 02049 /* Note this is a pending invite */ 02050 p->pendinginvite = seqno; 02051 } 02052 02053 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02054 02055 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02056 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02057 return AST_FAILURE; 02058 } else { 02059 /* Schedule retransmission */ 02060 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02061 return AST_SUCCESS; 02062 } 02063 }
static int __sip_semi_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acks receipt of packet, keep it around (used for provisional responses).
Definition at line 2217 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().
02218 { 02219 struct sip_pkt *cur; 02220 int res = -1; 02221 02222 for (cur = p->packets; cur; cur = cur->next) { 02223 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02224 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02225 /* this is our baby */ 02226 if (cur->retransid > -1) { 02227 if (option_debug > 3 && sipdebug) 02228 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02229 } 02230 AST_SCHED_DEL(sched, cur->retransid); 02231 res = 0; 02232 break; 02233 } 02234 } 02235 if (option_debug) 02236 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"); 02237 return res; 02238 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10810 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10811 { 10812 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10813 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10814 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10815 struct sip_pvt *cur; 10816 int numchans = 0; 10817 char *referstatus = NULL; 10818 10819 if (argc != 3) 10820 return RESULT_SHOWUSAGE; 10821 ast_mutex_lock(&iflock); 10822 cur = iflist; 10823 if (!subscriptions) 10824 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10825 else 10826 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10827 for (; cur; cur = cur->next) { 10828 referstatus = ""; 10829 if (cur->refer) { /* SIP transfer in progress */ 10830 referstatus = referstatus2str(cur->refer->status); 10831 } 10832 if (cur->subscribed == NONE && !subscriptions) { 10833 char formatbuf[SIPBUFSIZE/2]; 10834 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10835 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10836 cur->callid, 10837 cur->ocseq, cur->icseq, 10838 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10839 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10840 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10841 cur->lastmsg , 10842 referstatus 10843 ); 10844 numchans++; 10845 } 10846 if (cur->subscribed != NONE && subscriptions) { 10847 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10848 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10849 cur->callid, 10850 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10851 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10852 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10853 subscription_type2str(cur->subscribed), 10854 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10855 ); 10856 numchans++; 10857 } 10858 } 10859 ast_mutex_unlock(&iflock); 10860 if (!subscriptions) 10861 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10862 else 10863 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10864 return RESULT_SUCCESS; 10865 #undef FORMAT 10866 #undef FORMAT2 10867 #undef FORMAT3 10868 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1769 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01770 { 01771 int res; 01772 const struct sockaddr_in *dst = sip_real_dst(p); 01773 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01774 01775 if (res == -1) { 01776 switch (errno) { 01777 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01778 case EHOSTUNREACH: /* Host can't be reached */ 01779 case ENETDOWN: /* Inteface down */ 01780 case ENETUNREACH: /* Network failure */ 01781 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01782 } 01783 } 01784 if (res != len) 01785 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)); 01786 return res; 01787 }
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 6020 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().
06021 { 06022 struct sip_request resp; 06023 int seqno = 0; 06024 06025 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06026 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06027 return -1; 06028 } 06029 respprep(&resp, p, msg, req); 06030 add_header_contentLength(&resp, 0); 06031 /* If we are cancelling an incoming invite for some reason, add information 06032 about the reason why we are doing this in clear text */ 06033 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06034 char buf[10]; 06035 06036 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06037 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06038 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06039 } 06040 return send_response(p, &resp, reliable, seqno); 06041 }
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 10362 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10363 { 10364 char status[30] = ""; 10365 char cbuf[256]; 10366 struct sip_peer *peer; 10367 char codec_buf[512]; 10368 struct ast_codec_pref *pref; 10369 struct ast_variable *v; 10370 struct sip_auth *auth; 10371 int x = 0, codec = 0, load_realtime; 10372 int realtimepeers; 10373 10374 realtimepeers = ast_check_realtime("sippeers"); 10375 10376 if (argc < 4) 10377 return RESULT_SHOWUSAGE; 10378 10379 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10380 peer = find_peer(argv[3], NULL, load_realtime); 10381 if (s) { /* Manager */ 10382 if (peer) { 10383 const char *id = astman_get_header(m,"ActionID"); 10384 10385 astman_append(s, "Response: Success\r\n"); 10386 if (!ast_strlen_zero(id)) 10387 astman_append(s, "ActionID: %s\r\n",id); 10388 } else { 10389 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10390 astman_send_error(s, m, cbuf); 10391 return 0; 10392 } 10393 } 10394 if (peer && type==0 ) { /* Normal listing */ 10395 ast_cli(fd,"\n\n"); 10396 ast_cli(fd, " * Name : %s\n", peer->name); 10397 if (realtimepeers) { /* Realtime is enabled */ 10398 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10399 } 10400 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10401 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10402 for (auth = peer->auth; auth; auth = auth->next) { 10403 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10404 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10405 } 10406 ast_cli(fd, " Context : %s\n", peer->context); 10407 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10408 ast_cli(fd, " Language : %s\n", peer->language); 10409 if (!ast_strlen_zero(peer->accountcode)) 10410 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10411 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10412 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10413 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10414 if (!ast_strlen_zero(peer->fromuser)) 10415 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10416 if (!ast_strlen_zero(peer->fromdomain)) 10417 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10418 ast_cli(fd, " Callgroup : "); 10419 print_group(fd, peer->callgroup, 0); 10420 ast_cli(fd, " Pickupgroup : "); 10421 print_group(fd, peer->pickupgroup, 0); 10422 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10423 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10424 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10425 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10426 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10427 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10428 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10429 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10430 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))); 10431 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10432 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10433 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10434 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10435 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10436 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10437 #endif 10438 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10439 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10440 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10441 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10442 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10443 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10444 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10445 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10446 10447 /* - is enumerated */ 10448 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10449 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10450 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10451 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)); 10452 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10453 if (!ast_strlen_zero(global_regcontext)) 10454 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10455 ast_cli(fd, " Def. Username: %s\n", peer->username); 10456 ast_cli(fd, " SIP Options : "); 10457 if (peer->sipoptions) { 10458 int lastoption = -1; 10459 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10460 if (sip_options[x].id != lastoption) { 10461 if (peer->sipoptions & sip_options[x].id) 10462 ast_cli(fd, "%s ", sip_options[x].text); 10463 lastoption = x; 10464 } 10465 } 10466 } else 10467 ast_cli(fd, "(none)"); 10468 10469 ast_cli(fd, "\n"); 10470 ast_cli(fd, " Codecs : "); 10471 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10472 ast_cli(fd, "%s\n", codec_buf); 10473 ast_cli(fd, " Codec Order : ("); 10474 print_codec_to_cli(fd, &peer->prefs); 10475 ast_cli(fd, ")\n"); 10476 10477 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10478 ast_cli(fd, " Status : "); 10479 peer_status(peer, status, sizeof(status)); 10480 ast_cli(fd, "%s\n",status); 10481 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10482 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10483 if (peer->chanvars) { 10484 ast_cli(fd, " Variables :\n"); 10485 for (v = peer->chanvars ; v ; v = v->next) 10486 ast_cli(fd, " %s = %s\n", v->name, v->value); 10487 } 10488 ast_cli(fd,"\n"); 10489 ASTOBJ_UNREF(peer,sip_destroy_peer); 10490 } else if (peer && type == 1) { /* manager listing */ 10491 char buf[256]; 10492 astman_append(s, "Channeltype: SIP\r\n"); 10493 astman_append(s, "ObjectName: %s\r\n", peer->name); 10494 astman_append(s, "ChanObjectType: peer\r\n"); 10495 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10496 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10497 astman_append(s, "Context: %s\r\n", peer->context); 10498 astman_append(s, "Language: %s\r\n", peer->language); 10499 if (!ast_strlen_zero(peer->accountcode)) 10500 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10501 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10502 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10503 if (!ast_strlen_zero(peer->fromuser)) 10504 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10505 if (!ast_strlen_zero(peer->fromdomain)) 10506 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10507 astman_append(s, "Callgroup: "); 10508 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10509 astman_append(s, "Pickupgroup: "); 10510 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10511 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10512 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10513 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10514 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10515 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10516 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10517 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10518 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10519 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))); 10520 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10521 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10522 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10523 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10524 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10525 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10526 10527 /* - is enumerated */ 10528 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10529 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10530 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10531 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)); 10532 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)); 10533 astman_append(s, "Default-Username: %s\r\n", peer->username); 10534 if (!ast_strlen_zero(global_regcontext)) 10535 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10536 astman_append(s, "Codecs: "); 10537 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10538 astman_append(s, "%s\r\n", codec_buf); 10539 astman_append(s, "CodecOrder: "); 10540 pref = &peer->prefs; 10541 for(x = 0; x < 32 ; x++) { 10542 codec = ast_codec_pref_index(pref,x); 10543 if (!codec) 10544 break; 10545 astman_append(s, "%s", ast_getformatname(codec)); 10546 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10547 astman_append(s, ","); 10548 } 10549 10550 astman_append(s, "\r\n"); 10551 astman_append(s, "Status: "); 10552 peer_status(peer, status, sizeof(status)); 10553 astman_append(s, "%s\r\n", status); 10554 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10555 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10556 if (peer->chanvars) { 10557 for (v = peer->chanvars ; v ; v = v->next) { 10558 astman_append(s, "ChanVariable:\n"); 10559 astman_append(s, " %s,%s\r\n", v->name, v->value); 10560 } 10561 } 10562 10563 ASTOBJ_UNREF(peer,sip_destroy_peer); 10564 10565 } else { 10566 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10567 ast_cli(fd,"\n"); 10568 } 10569 10570 return RESULT_SUCCESS; 10571 }
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 9912 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().
09913 { 09914 regex_t regexbuf; 09915 int havepattern = FALSE; 09916 09917 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09918 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09919 09920 char name[256]; 09921 int total_peers = 0; 09922 int peers_mon_online = 0; 09923 int peers_mon_offline = 0; 09924 int peers_unmon_offline = 0; 09925 int peers_unmon_online = 0; 09926 const char *id; 09927 char idtext[256] = ""; 09928 int realtimepeers; 09929 09930 realtimepeers = ast_check_realtime("sippeers"); 09931 09932 if (s) { /* Manager - get ActionID */ 09933 id = astman_get_header(m,"ActionID"); 09934 if (!ast_strlen_zero(id)) 09935 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09936 } 09937 09938 switch (argc) { 09939 case 5: 09940 if (!strcasecmp(argv[3], "like")) { 09941 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09942 return RESULT_SHOWUSAGE; 09943 havepattern = TRUE; 09944 } else 09945 return RESULT_SHOWUSAGE; 09946 case 3: 09947 break; 09948 default: 09949 return RESULT_SHOWUSAGE; 09950 } 09951 09952 if (!s) /* Normal list */ 09953 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09954 09955 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09956 char status[20] = ""; 09957 char srch[2000]; 09958 char pstatus; 09959 09960 ASTOBJ_RDLOCK(iterator); 09961 09962 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09963 ASTOBJ_UNLOCK(iterator); 09964 continue; 09965 } 09966 09967 if (!ast_strlen_zero(iterator->username) && !s) 09968 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09969 else 09970 ast_copy_string(name, iterator->name, sizeof(name)); 09971 09972 pstatus = peer_status(iterator, status, sizeof(status)); 09973 if (pstatus == 1) 09974 peers_mon_online++; 09975 else if (pstatus == 0) 09976 peers_mon_offline++; 09977 else { 09978 if (iterator->addr.sin_port == 0) 09979 peers_unmon_offline++; 09980 else 09981 peers_unmon_online++; 09982 } 09983 09984 snprintf(srch, sizeof(srch), FORMAT, name, 09985 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09986 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09987 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09988 iterator->ha ? " A " : " ", /* permit/deny */ 09989 ntohs(iterator->addr.sin_port), status, 09990 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09991 09992 if (!s) {/* Normal CLI list */ 09993 ast_cli(fd, FORMAT, name, 09994 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09995 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09996 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09997 iterator->ha ? " A " : " ", /* permit/deny */ 09998 09999 ntohs(iterator->addr.sin_port), status, 10000 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10001 } else { /* Manager format */ 10002 /* The names here need to be the same as other channels */ 10003 astman_append(s, 10004 "Event: PeerEntry\r\n%s" 10005 "Channeltype: SIP\r\n" 10006 "ObjectName: %s\r\n" 10007 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10008 "IPaddress: %s\r\n" 10009 "IPport: %d\r\n" 10010 "Dynamic: %s\r\n" 10011 "Natsupport: %s\r\n" 10012 "VideoSupport: %s\r\n" 10013 "ACL: %s\r\n" 10014 "Status: %s\r\n" 10015 "RealtimeDevice: %s\r\n\r\n", 10016 idtext, 10017 iterator->name, 10018 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10019 ntohs(iterator->addr.sin_port), 10020 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10021 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10022 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10023 iterator->ha ? "yes" : "no", /* permit/deny */ 10024 status, 10025 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10026 } 10027 10028 ASTOBJ_UNLOCK(iterator); 10029 10030 total_peers++; 10031 } while(0) ); 10032 10033 if (!s) 10034 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10035 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10036 10037 if (havepattern) 10038 regfree(®exbuf); 10039 10040 if (total) 10041 *total = total_peers; 10042 10043 10044 return RESULT_SUCCESS; 10045 #undef FORMAT 10046 #undef FORMAT2 10047 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14688 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.
14689 { 14690 struct ast_rtp_quality qos; 14691 struct sip_pvt *p = chan->tech_pvt; 14692 char *all = "", *parse = ast_strdupa(preparse); 14693 AST_DECLARE_APP_ARGS(args, 14694 AST_APP_ARG(param); 14695 AST_APP_ARG(type); 14696 AST_APP_ARG(field); 14697 ); 14698 AST_STANDARD_APP_ARGS(args, parse); 14699 14700 /* Sanity check */ 14701 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14702 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14703 return 0; 14704 } 14705 14706 if (strcasecmp(args.param, "rtpqos")) 14707 return 0; 14708 14709 /* Default arguments of audio,all */ 14710 if (ast_strlen_zero(args.type)) 14711 args.type = "audio"; 14712 if (ast_strlen_zero(args.field)) 14713 args.field = "all"; 14714 14715 memset(buf, 0, buflen); 14716 memset(&qos, 0, sizeof(qos)); 14717 14718 if (strcasecmp(args.type, "AUDIO") == 0) { 14719 all = ast_rtp_get_quality(p->rtp, &qos); 14720 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14721 all = ast_rtp_get_quality(p->vrtp, &qos); 14722 } 14723 14724 if (strcasecmp(args.field, "local_ssrc") == 0) 14725 snprintf(buf, buflen, "%u", qos.local_ssrc); 14726 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14727 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14728 else if (strcasecmp(args.field, "local_jitter") == 0) 14729 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14730 else if (strcasecmp(args.field, "local_count") == 0) 14731 snprintf(buf, buflen, "%u", qos.local_count); 14732 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14733 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14734 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14735 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14736 else if (strcasecmp(args.field, "remote_jitter") == 0) 14737 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14738 else if (strcasecmp(args.field, "remote_count") == 0) 14739 snprintf(buf, buflen, "%u", qos.remote_count); 14740 else if (strcasecmp(args.field, "rtt") == 0) 14741 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14742 else if (strcasecmp(args.field, "all") == 0) 14743 ast_copy_string(buf, all, buflen); 14744 else { 14745 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14746 return -1; 14747 } 14748 return 0; 14749 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2251 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02252 { 02253 if (!req->lines) { 02254 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02255 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02256 req->len += strlen(req->data + req->len); 02257 } 02258 }
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 6225 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().
06228 { 06229 int rtp_code; 06230 struct ast_format_list fmt; 06231 06232 06233 if (debug) 06234 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06235 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06236 return; 06237 06238 if (p->rtp) { 06239 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06240 fmt = ast_codec_pref_getsize(pref, codec); 06241 } 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 */ 06242 return; 06243 ast_build_string(m_buf, m_size, " %d", rtp_code); 06244 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06245 ast_rtp_lookup_mime_subtype(1, codec, 06246 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06247 sample_rate); 06248 if (codec == AST_FORMAT_G729A) { 06249 /* Indicate that we don't support VAD (G.729 annex B) */ 06250 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06251 } else if (codec == AST_FORMAT_G723_1) { 06252 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06253 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06254 } else if (codec == AST_FORMAT_ILBC) { 06255 /* Add information about us using only 20/30 ms packetization */ 06256 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06257 } 06258 06259 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06260 *min_packet_size = fmt.cur_ms; 06261 06262 /* Our first codec packetization processed cannot be less than zero */ 06263 if ((*min_packet_size) == 0 && fmt.cur_ms) 06264 *min_packet_size = fmt.cur_ms; 06265 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6193 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06194 { 06195 char tmp[256]; 06196 06197 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06198 add_header(req, "Content-Type", "application/dtmf-relay"); 06199 add_header_contentLength(req, strlen(tmp)); 06200 add_line(req, tmp); 06201 return 0; 06202 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5587 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.
05588 { 05589 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05590 05591 if (req->headers == SIP_MAX_HEADERS) { 05592 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05593 return -1; 05594 } 05595 05596 if (req->lines) { 05597 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05598 return -1; 05599 } 05600 05601 if (maxlen <= 0) { 05602 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05603 return -1; 05604 } 05605 05606 req->header[req->headers] = req->data + req->len; 05607 05608 if (compactheaders) 05609 var = find_alias(var, var); 05610 05611 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05612 req->len += strlen(req->header[req->headers]); 05613 req->headers++; 05614 05615 return 0; 05616 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5619 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().
05620 { 05621 char clen[10]; 05622 05623 snprintf(clen, sizeof(clen), "%d", len); 05624 return add_header(req, "Content-Length", clen); 05625 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5628 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05629 { 05630 if (req->lines == SIP_MAX_LINES) { 05631 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05632 return -1; 05633 } 05634 if (!req->lines) { 05635 /* Add extra empty return */ 05636 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05637 req->len += strlen(req->data + req->len); 05638 } 05639 if (req->len >= sizeof(req->data) - 4) { 05640 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05641 return -1; 05642 } 05643 req->line[req->lines] = req->data + req->len; 05644 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05645 req->len += strlen(req->line[req->lines]); 05646 req->lines++; 05647 return 0; 05648 }
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 6401 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().
06404 { 06405 int rtp_code; 06406 06407 if (debug) 06408 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06409 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06410 return; 06411 06412 ast_build_string(m_buf, m_size, " %d", rtp_code); 06413 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06414 ast_rtp_lookup_mime_subtype(0, format, 0), 06415 sample_rate); 06416 if (format == AST_RTP_DTMF) 06417 /* Indicate we support DTMF and FLASH... */ 06418 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06419 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 16276 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().
16277 { 16278 char authcopy[256]; 16279 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16280 char *stringp; 16281 struct sip_auth *a, *b, *auth; 16282 16283 if (ast_strlen_zero(configuration)) 16284 return authlist; 16285 16286 if (option_debug) 16287 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16288 16289 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16290 stringp = authcopy; 16291 16292 username = stringp; 16293 realm = strrchr(stringp, '@'); 16294 if (realm) 16295 *realm++ = '\0'; 16296 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16297 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16298 return authlist; 16299 } 16300 stringp = username; 16301 username = strsep(&stringp, ":"); 16302 if (username) { 16303 secret = strsep(&stringp, ":"); 16304 if (!secret) { 16305 stringp = username; 16306 md5secret = strsep(&stringp,"#"); 16307 } 16308 } 16309 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16310 return authlist; 16311 16312 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16313 ast_copy_string(auth->username, username, sizeof(auth->username)); 16314 if (secret) 16315 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16316 if (md5secret) 16317 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16318 16319 /* find the end of the list */ 16320 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16321 ; 16322 if (b) 16323 b->next = auth; /* Add structure add end of list */ 16324 else 16325 authlist = auth; 16326 16327 if (option_verbose > 2) 16328 ast_verbose("Added authentication for realm %s\n", realm); 16329 16330 return authlist; 16331 16332 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5749 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05750 { 05751 char r[SIPBUFSIZE*2], *p; 05752 int n, rem = sizeof(r); 05753 05754 if (!route) 05755 return; 05756 05757 p = r; 05758 for (;route ; route = route->next) { 05759 n = strlen(route->hop); 05760 if (rem < n+3) /* we need room for ",<route>" */ 05761 break; 05762 if (p != r) { /* add a separator after fist route */ 05763 *p++ = ','; 05764 --rem; 05765 } 05766 *p++ = '<'; 05767 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05768 p += n; 05769 *p++ = '>'; 05770 rem -= (n+2); 05771 } 05772 *p = '\0'; 05773 add_header(req, "Route", r); 05774 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6429 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.
06430 { 06431 int len = 0; 06432 int alreadysent = 0; 06433 06434 struct sockaddr_in sin; 06435 struct sockaddr_in vsin; 06436 struct sockaddr_in dest; 06437 struct sockaddr_in vdest = { 0, }; 06438 06439 /* SDP fields */ 06440 char *version = "v=0\r\n"; /* Protocol version */ 06441 char *subject = "s=session\r\n"; /* Subject of the session */ 06442 char owner[256]; /* Session owner/creator */ 06443 char connection[256]; /* Connection data */ 06444 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06445 char bandwidth[256] = ""; /* Max bitrate */ 06446 char *hold; 06447 char m_audio[256]; /* Media declaration line for audio */ 06448 char m_video[256]; /* Media declaration line for video */ 06449 char a_audio[1024]; /* Attributes for audio */ 06450 char a_video[1024]; /* Attributes for video */ 06451 char *m_audio_next = m_audio; 06452 char *m_video_next = m_video; 06453 size_t m_audio_left = sizeof(m_audio); 06454 size_t m_video_left = sizeof(m_video); 06455 char *a_audio_next = a_audio; 06456 char *a_video_next = a_video; 06457 size_t a_audio_left = sizeof(a_audio); 06458 size_t a_video_left = sizeof(a_video); 06459 06460 int x; 06461 int capability; 06462 int needvideo = FALSE; 06463 int debug = sip_debug_test_pvt(p); 06464 int min_audio_packet_size = 0; 06465 int min_video_packet_size = 0; 06466 06467 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06468 06469 if (!p->rtp) { 06470 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06471 return AST_FAILURE; 06472 } 06473 06474 /* Set RTP Session ID and version */ 06475 if (!p->sessionid) { 06476 p->sessionid = getpid(); 06477 p->sessionversion = p->sessionid; 06478 } else 06479 p->sessionversion++; 06480 06481 /* Get our addresses */ 06482 ast_rtp_get_us(p->rtp, &sin); 06483 if (p->vrtp) 06484 ast_rtp_get_us(p->vrtp, &vsin); 06485 06486 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06487 if (p->redirip.sin_addr.s_addr) { 06488 dest.sin_port = p->redirip.sin_port; 06489 dest.sin_addr = p->redirip.sin_addr; 06490 } else { 06491 dest.sin_addr = p->ourip; 06492 dest.sin_port = sin.sin_port; 06493 } 06494 06495 capability = p->jointcapability; 06496 06497 06498 if (option_debug > 1) { 06499 char codecbuf[SIPBUFSIZE]; 06500 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"); 06501 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06502 } 06503 06504 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06505 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06506 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06507 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06508 } 06509 #endif 06510 06511 /* Check if we need video in this call */ 06512 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06513 if (p->vrtp) { 06514 needvideo = TRUE; 06515 if (option_debug > 1) 06516 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06517 } else if (option_debug > 1) 06518 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06519 } 06520 06521 06522 /* Ok, we need video. Let's add what we need for video and set codecs. 06523 Video is handled differently than audio since we can not transcode. */ 06524 if (needvideo) { 06525 /* Determine video destination */ 06526 if (p->vredirip.sin_addr.s_addr) { 06527 vdest.sin_addr = p->vredirip.sin_addr; 06528 vdest.sin_port = p->vredirip.sin_port; 06529 } else { 06530 vdest.sin_addr = p->ourip; 06531 vdest.sin_port = vsin.sin_port; 06532 } 06533 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06534 06535 /* Build max bitrate string */ 06536 if (p->maxcallbitrate) 06537 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06538 if (debug) 06539 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06540 } 06541 06542 if (debug) 06543 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06544 06545 /* Start building generic SDP headers */ 06546 06547 /* We break with the "recommendation" and send our IP, in order that our 06548 peer doesn't have to ast_gethostbyname() us */ 06549 06550 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06551 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06552 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06553 06554 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06555 hold = "a=recvonly\r\n"; 06556 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06557 hold = "a=inactive\r\n"; 06558 else 06559 hold = "a=sendrecv\r\n"; 06560 06561 /* Now, start adding audio codecs. These are added in this order: 06562 - First what was requested by the calling channel 06563 - Then preferences in order from sip.conf device config for this peer/user 06564 - Then other codecs in capabilities, including video 06565 */ 06566 06567 /* Prefer the audio codec we were requested to use, first, no matter what 06568 Note that p->prefcodec can include video codecs, so mask them out 06569 */ 06570 if (capability & p->prefcodec) { 06571 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06572 06573 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06574 &m_audio_next, &m_audio_left, 06575 &a_audio_next, &a_audio_left, 06576 debug, &min_audio_packet_size); 06577 alreadysent |= codec; 06578 } 06579 06580 /* Start by sending our preferred audio codecs */ 06581 for (x = 0; x < 32; x++) { 06582 int codec; 06583 06584 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06585 break; 06586 06587 if (!(capability & codec)) 06588 continue; 06589 06590 if (alreadysent & codec) 06591 continue; 06592 06593 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06594 &m_audio_next, &m_audio_left, 06595 &a_audio_next, &a_audio_left, 06596 debug, &min_audio_packet_size); 06597 alreadysent |= codec; 06598 } 06599 06600 /* Now send any other common audio and video codecs, and non-codec formats: */ 06601 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06602 if (!(capability & x)) /* Codec not requested */ 06603 continue; 06604 06605 if (alreadysent & x) /* Already added to SDP */ 06606 continue; 06607 06608 if (x <= AST_FORMAT_MAX_AUDIO) 06609 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06610 &m_audio_next, &m_audio_left, 06611 &a_audio_next, &a_audio_left, 06612 debug, &min_audio_packet_size); 06613 else 06614 add_codec_to_sdp(p, x, 90000, 06615 &m_video_next, &m_video_left, 06616 &a_video_next, &a_video_left, 06617 debug, &min_video_packet_size); 06618 } 06619 06620 /* Now add DTMF RFC2833 telephony-event as a codec */ 06621 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06622 if (!(p->jointnoncodeccapability & x)) 06623 continue; 06624 06625 add_noncodec_to_sdp(p, x, 8000, 06626 &m_audio_next, &m_audio_left, 06627 &a_audio_next, &a_audio_left, 06628 debug); 06629 } 06630 06631 if (option_debug > 2) 06632 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06633 06634 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06635 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06636 06637 if (min_audio_packet_size) 06638 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06639 06640 if (min_video_packet_size) 06641 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06642 06643 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06644 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06645 06646 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06647 if (needvideo) 06648 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06649 06650 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06651 if (needvideo) /* only if video response is appropriate */ 06652 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06653 06654 add_header(resp, "Content-Type", "application/sdp"); 06655 add_header_contentLength(resp, len); 06656 add_line(resp, version); 06657 add_line(resp, owner); 06658 add_line(resp, subject); 06659 add_line(resp, connection); 06660 if (needvideo) /* only if video response is appropriate */ 06661 add_line(resp, bandwidth); 06662 add_line(resp, stime); 06663 add_line(resp, m_audio); 06664 add_line(resp, a_audio); 06665 add_line(resp, hold); 06666 if (needvideo) { /* only if video response is appropriate */ 06667 add_line(resp, m_video); 06668 add_line(resp, a_video); 06669 add_line(resp, hold); /* Repeat hold for the video stream */ 06670 } 06671 06672 /* Update lastrtprx when we send our SDP */ 06673 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06674 06675 if (option_debug > 2) { 06676 char buf[SIPBUFSIZE]; 06677 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06678 } 06679 06680 return AST_SUCCESS; 06681 }
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 16212 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.
16213 { 16214 struct domain *d; 16215 16216 if (ast_strlen_zero(domain)) { 16217 ast_log(LOG_WARNING, "Zero length domain.\n"); 16218 return 1; 16219 } 16220 16221 if (!(d = ast_calloc(1, sizeof(*d)))) 16222 return 0; 16223 16224 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16225 16226 if (!ast_strlen_zero(context)) 16227 ast_copy_string(d->context, context, sizeof(d->context)); 16228 16229 d->mode = mode; 16230 16231 AST_LIST_LOCK(&domain_list); 16232 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16233 AST_LIST_UNLOCK(&domain_list); 16234 16235 if (sipdebug) 16236 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16237 16238 return 1; 16239 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6304 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().
06305 { 06306 int len = 0; 06307 int x = 0; 06308 struct sockaddr_in udptlsin; 06309 char v[256] = ""; 06310 char s[256] = ""; 06311 char o[256] = ""; 06312 char c[256] = ""; 06313 char t[256] = ""; 06314 char m_modem[256]; 06315 char a_modem[1024]; 06316 char *m_modem_next = m_modem; 06317 size_t m_modem_left = sizeof(m_modem); 06318 char *a_modem_next = a_modem; 06319 size_t a_modem_left = sizeof(a_modem); 06320 struct sockaddr_in udptldest = { 0, }; 06321 int debug; 06322 06323 debug = sip_debug_test_pvt(p); 06324 len = 0; 06325 if (!p->udptl) { 06326 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06327 return -1; 06328 } 06329 06330 if (!p->sessionid) { 06331 p->sessionid = getpid(); 06332 p->sessionversion = p->sessionid; 06333 } else 06334 p->sessionversion++; 06335 06336 /* Our T.38 end is */ 06337 ast_udptl_get_us(p->udptl, &udptlsin); 06338 06339 /* Determine T.38 UDPTL destination */ 06340 if (p->udptlredirip.sin_addr.s_addr) { 06341 udptldest.sin_port = p->udptlredirip.sin_port; 06342 udptldest.sin_addr = p->udptlredirip.sin_addr; 06343 } else { 06344 udptldest.sin_addr = p->ourip; 06345 udptldest.sin_port = udptlsin.sin_port; 06346 } 06347 06348 if (debug) 06349 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06350 06351 /* We break with the "recommendation" and send our IP, in order that our 06352 peer doesn't have to ast_gethostbyname() us */ 06353 06354 if (debug) { 06355 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06356 p->t38.capability, 06357 p->t38.peercapability, 06358 p->t38.jointcapability); 06359 } 06360 snprintf(v, sizeof(v), "v=0\r\n"); 06361 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06362 snprintf(s, sizeof(s), "s=session\r\n"); 06363 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06364 snprintf(t, sizeof(t), "t=0 0\r\n"); 06365 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06366 06367 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06368 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06369 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06370 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06371 if ((x = t38_get_rate(p->t38.jointcapability))) 06372 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06373 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06374 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06375 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06376 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06377 x = ast_udptl_get_local_max_datagram(p->udptl); 06378 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06379 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06380 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06381 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06382 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06383 add_header(resp, "Content-Type", "application/sdp"); 06384 add_header_contentLength(resp, len); 06385 add_line(resp, v); 06386 add_line(resp, o); 06387 add_line(resp, s); 06388 add_line(resp, c); 06389 add_line(resp, t); 06390 add_line(resp, m_modem); 06391 add_line(resp, a_modem); 06392 06393 /* Update lastrtprx when we send our SDP */ 06394 p->lastrtprx = p->lastrtptx = time(NULL); 06395 06396 return 0; 06397 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6182 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06183 { 06184 /* XXX Convert \n's to \r\n's XXX */ 06185 add_header(req, "Content-Type", "text/plain"); 06186 add_header_contentLength(req, strlen(text)); 06187 add_line(req, text); 06188 return 0; 06189 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6206 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06207 { 06208 const char *xml_is_a_huge_waste_of_space = 06209 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06210 " <media_control>\r\n" 06211 " <vc_primitive>\r\n" 06212 " <to_encoder>\r\n" 06213 " <picture_fast_update>\r\n" 06214 " </picture_fast_update>\r\n" 06215 " </to_encoder>\r\n" 06216 " </vc_primitive>\r\n" 06217 " </media_control>\r\n"; 06218 add_header(req, "Content-Type", "application/media_control+xml"); 06219 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06220 add_line(req, xml_is_a_huge_waste_of_space); 06221 return 0; 06222 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6129 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().
06130 { 06131 char tmpdat[256]; 06132 struct tm tm; 06133 time_t t = time(NULL); 06134 06135 gmtime_r(&t, &tm); 06136 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06137 add_header(req, "Date", tmpdat); 06138 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1874 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01875 { 01876 va_list ap; 01877 01878 if (!p) 01879 return; 01880 01881 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01882 && !recordhistory && !dumphistory) { 01883 return; 01884 } 01885 01886 va_start(ap, fmt); 01887 append_history_va(p, fmt, ap); 01888 va_end(ap); 01889 01890 return; 01891 }
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 1847 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().
01848 { 01849 char buf[80], *c = buf; /* max history length */ 01850 struct sip_history *hist; 01851 int l; 01852 01853 vsnprintf(buf, sizeof(buf), fmt, ap); 01854 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01855 l = strlen(buf) + 1; 01856 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01857 return; 01858 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01859 free(hist); 01860 return; 01861 } 01862 memcpy(hist->event, buf, l); 01863 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01864 struct sip_history *oldest; 01865 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01866 p->history_entries--; 01867 free(oldest); 01868 } 01869 AST_LIST_INSERT_TAIL(p->history, hist, list); 01870 p->history_entries++; 01871 }
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 13235 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().
13236 { 13237 if (chan && chan->_state == AST_STATE_UP) { 13238 if (ast_test_flag(chan, AST_FLAG_MOH)) 13239 ast_moh_stop(chan); 13240 else if (chan->generatordata) 13241 ast_deactivate_generator(chan); 13242 } 13243 }
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 1807 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().
01808 { 01809 struct sockaddr_in theirs, ours; 01810 01811 /* Get our local information */ 01812 ast_ouraddrfor(them, us); 01813 theirs.sin_addr = *them; 01814 ours.sin_addr = *us; 01815 01816 if (localaddr && externip.sin_addr.s_addr && 01817 (ast_apply_ha(localaddr, &theirs)) && 01818 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01819 if (externexpire && time(NULL) >= externexpire) { 01820 struct ast_hostent ahp; 01821 struct hostent *hp; 01822 01823 externexpire = time(NULL) + externrefresh; 01824 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01825 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01826 } else 01827 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01828 } 01829 *us = externip.sin_addr; 01830 if (option_debug) { 01831 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01832 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01833 } 01834 } else if (bindaddr.sin_addr.s_addr) 01835 *us = bindaddr.sin_addr; 01836 return AST_SUCCESS; 01837 }
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 13247 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.
13248 { 13249 int res = 0; 13250 struct ast_channel *peera = NULL, 13251 *peerb = NULL, 13252 *peerc = NULL, 13253 *peerd = NULL; 13254 13255 13256 /* We will try to connect the transferee with the target and hangup 13257 all channels to the transferer */ 13258 if (option_debug > 3) { 13259 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13260 if (transferer->chan1) 13261 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13262 else 13263 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13264 if (target->chan1) 13265 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13266 else 13267 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13268 if (transferer->chan2) 13269 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13270 else 13271 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13272 if (target->chan2) 13273 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)"); 13274 else 13275 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13276 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13277 } 13278 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13279 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13280 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13281 peerc = transferer->chan2; /* Asterisk to Transferee */ 13282 peerd = target->chan2; /* Asterisk to Target */ 13283 if (option_debug > 2) 13284 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13285 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13286 peera = target->chan1; /* Transferer to PBX -> target channel */ 13287 peerb = transferer->chan1; /* Transferer to IVR*/ 13288 peerc = target->chan2; /* Asterisk to Target */ 13289 peerd = transferer->chan2; /* Nothing */ 13290 if (option_debug > 2) 13291 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13292 } 13293 13294 if (peera && peerb && peerc && (peerb != peerc)) { 13295 ast_quiet_chan(peera); /* Stop generators */ 13296 ast_quiet_chan(peerb); 13297 ast_quiet_chan(peerc); 13298 if (peerd) 13299 ast_quiet_chan(peerd); 13300 13301 /* Fix CDRs so they're attached to the remaining channel */ 13302 if (peera->cdr && peerb->cdr) 13303 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13304 else if (peera->cdr) 13305 peerb->cdr = peera->cdr; 13306 peera->cdr = NULL; 13307 13308 if (peerb->cdr && peerc->cdr) 13309 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13310 else if (peerc->cdr) 13311 peerb->cdr = peerc->cdr; 13312 peerc->cdr = NULL; 13313 13314 if (option_debug > 3) 13315 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13316 if (ast_channel_masquerade(peerb, peerc)) { 13317 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13318 res = -1; 13319 } else 13320 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13321 return res; 13322 } else { 13323 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13324 if (transferer->chan1) 13325 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13326 if (target->chan1) 13327 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13328 return -2; 13329 } 13330 return 0; 13331 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2936 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.
02937 { 02938 struct sip_pvt *p = (struct sip_pvt *)nothing; 02939 02940 ast_mutex_lock(&p->lock); 02941 p->initid = -1; 02942 if (p->owner) { 02943 /* XXX fails on possible deadlock */ 02944 if (!ast_channel_trylock(p->owner)) { 02945 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02946 append_history(p, "Cong", "Auto-congesting (timer)"); 02947 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02948 ast_channel_unlock(p->owner); 02949 } 02950 } 02951 ast_mutex_unlock(&p->lock); 02952 return 0; 02953 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4410 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().
04411 { 04412 char buf[33]; 04413 04414 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04415 04416 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04417 04418 }
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 4421 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04422 { 04423 char buf[33]; 04424 04425 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04426 04427 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04428 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6852 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().
06853 { 06854 /* Construct Contact: header */ 06855 if (ourport != STANDARD_SIP_PORT) 06856 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); 06857 else 06858 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06859 }
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 16543 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_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
16544 { 16545 struct sip_peer *peer = NULL; 16546 struct ast_ha *oldha = NULL; 16547 int obproxyfound=0; 16548 int found=0; 16549 int firstpass=1; 16550 int format=0; /* Ama flags */ 16551 time_t regseconds = 0; 16552 char *varname = NULL, *varval = NULL; 16553 struct ast_variable *tmpvar = NULL; 16554 struct ast_flags peerflags[2] = {{(0)}}; 16555 struct ast_flags mask[2] = {{(0)}}; 16556 16557 16558 if (!realtime) 16559 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16560 /* We also use a case-sensitive comparison (unlike find_peer) so 16561 that case changes made to the peer name will be properly handled 16562 during reload 16563 */ 16564 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16565 16566 if (peer) { 16567 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16568 found = 1; 16569 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16570 firstpass = 0; 16571 } else { 16572 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16573 return NULL; 16574 16575 if (realtime) 16576 rpeerobjs++; 16577 else 16578 speerobjs++; 16579 ASTOBJ_INIT(peer); 16580 } 16581 /* Note that our peer HAS had its reference count incrased */ 16582 if (firstpass) { 16583 peer->lastmsgssent = -1; 16584 oldha = peer->ha; 16585 peer->ha = NULL; 16586 set_peer_defaults(peer); /* Set peer defaults */ 16587 } 16588 if (!found && name) 16589 ast_copy_string(peer->name, name, sizeof(peer->name)); 16590 16591 /* If we have channel variables, remove them (reload) */ 16592 if (peer->chanvars) { 16593 ast_variables_destroy(peer->chanvars); 16594 peer->chanvars = NULL; 16595 /* XXX should unregister ? */ 16596 } 16597 16598 /* If we have realm authentication information, remove them (reload) */ 16599 clear_realm_authentication(peer->auth); 16600 peer->auth = NULL; 16601 16602 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16603 if (handle_common_options(&peerflags[0], &mask[0], v)) 16604 continue; 16605 if (realtime && !strcasecmp(v->name, "regseconds")) { 16606 ast_get_time_t(v->value, ®seconds, 0, NULL); 16607 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16608 inet_aton(v->value, &(peer->addr.sin_addr)); 16609 } else if (realtime && !strcasecmp(v->name, "name")) 16610 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16611 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16612 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16613 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16614 } else if (!strcasecmp(v->name, "secret")) 16615 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16616 else if (!strcasecmp(v->name, "md5secret")) 16617 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16618 else if (!strcasecmp(v->name, "auth")) 16619 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16620 else if (!strcasecmp(v->name, "callerid")) { 16621 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16622 } else if (!strcasecmp(v->name, "fullname")) { 16623 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16624 } else if (!strcasecmp(v->name, "cid_number")) { 16625 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16626 } else if (!strcasecmp(v->name, "context")) { 16627 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16628 } else if (!strcasecmp(v->name, "subscribecontext")) { 16629 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16630 } else if (!strcasecmp(v->name, "fromdomain")) { 16631 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16632 } else if (!strcasecmp(v->name, "usereqphone")) { 16633 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16634 } else if (!strcasecmp(v->name, "fromuser")) { 16635 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16636 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16637 if (!strcasecmp(v->value, "dynamic")) { 16638 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16639 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16640 } else { 16641 /* They'll register with us */ 16642 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16643 /* Initialize stuff if this is a new peer, or if it used to be 16644 * non-dynamic before the reload. */ 16645 memset(&peer->addr.sin_addr, 0, 4); 16646 if (peer->addr.sin_port) { 16647 /* If we've already got a port, make it the default rather than absolute */ 16648 peer->defaddr.sin_port = peer->addr.sin_port; 16649 peer->addr.sin_port = 0; 16650 } 16651 } 16652 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16653 } 16654 } else { 16655 /* Non-dynamic. Make sure we become that way if we're not */ 16656 AST_SCHED_DEL(sched, peer->expire); 16657 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16658 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16659 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16660 ASTOBJ_UNREF(peer, sip_destroy_peer); 16661 return NULL; 16662 } 16663 } 16664 if (!strcasecmp(v->name, "outboundproxy")) 16665 obproxyfound=1; 16666 else { 16667 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16668 if (!peer->addr.sin_port) 16669 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16670 } 16671 } 16672 } else if (!strcasecmp(v->name, "defaultip")) { 16673 if (ast_get_ip(&peer->defaddr, v->value)) { 16674 ASTOBJ_UNREF(peer, sip_destroy_peer); 16675 return NULL; 16676 } 16677 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16678 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16679 } else if (!strcasecmp(v->name, "port")) { 16680 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16681 peer->defaddr.sin_port = htons(atoi(v->value)); 16682 else 16683 peer->addr.sin_port = htons(atoi(v->value)); 16684 } else if (!strcasecmp(v->name, "callingpres")) { 16685 peer->callingpres = ast_parse_caller_presentation(v->value); 16686 if (peer->callingpres == -1) 16687 peer->callingpres = atoi(v->value); 16688 } else if (!strcasecmp(v->name, "username")) { 16689 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16690 } else if (!strcasecmp(v->name, "language")) { 16691 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16692 } else if (!strcasecmp(v->name, "regexten")) { 16693 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16694 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16695 peer->call_limit = atoi(v->value); 16696 if (peer->call_limit < 0) 16697 peer->call_limit = 0; 16698 } else if (!strcasecmp(v->name, "amaflags")) { 16699 format = ast_cdr_amaflags2int(v->value); 16700 if (format < 0) { 16701 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16702 } else { 16703 peer->amaflags = format; 16704 } 16705 } else if (!strcasecmp(v->name, "accountcode")) { 16706 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16707 } else if (!strcasecmp(v->name, "mohinterpret") 16708 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16709 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16710 } else if (!strcasecmp(v->name, "mohsuggest")) { 16711 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16712 } else if (!strcasecmp(v->name, "mailbox")) { 16713 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16714 } else if (!strcasecmp(v->name, "subscribemwi")) { 16715 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16716 } else if (!strcasecmp(v->name, "vmexten")) { 16717 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16718 } else if (!strcasecmp(v->name, "callgroup")) { 16719 peer->callgroup = ast_get_group(v->value); 16720 } else if (!strcasecmp(v->name, "allowtransfer")) { 16721 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16722 } else if (!strcasecmp(v->name, "pickupgroup")) { 16723 peer->pickupgroup = ast_get_group(v->value); 16724 } else if (!strcasecmp(v->name, "allow")) { 16725 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16726 } else if (!strcasecmp(v->name, "disallow")) { 16727 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16728 } else if (!strcasecmp(v->name, "autoframing")) { 16729 peer->autoframing = ast_true(v->value); 16730 } else if (!strcasecmp(v->name, "rtptimeout")) { 16731 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16732 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16733 peer->rtptimeout = global_rtptimeout; 16734 } 16735 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16736 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16737 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16738 peer->rtpholdtimeout = global_rtpholdtimeout; 16739 } 16740 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16741 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16742 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16743 peer->rtpkeepalive = global_rtpkeepalive; 16744 } 16745 } else if (!strcasecmp(v->name, "setvar")) { 16746 /* Set peer channel variable */ 16747 varname = ast_strdupa(v->value); 16748 if ((varval = strchr(varname, '='))) { 16749 *varval++ = '\0'; 16750 if ((tmpvar = ast_variable_new(varname, varval))) { 16751 tmpvar->next = peer->chanvars; 16752 peer->chanvars = tmpvar; 16753 } 16754 } 16755 } else if (!strcasecmp(v->name, "qualify")) { 16756 if (!strcasecmp(v->value, "no")) { 16757 peer->maxms = 0; 16758 } else if (!strcasecmp(v->value, "yes")) { 16759 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16760 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16761 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); 16762 peer->maxms = 0; 16763 } 16764 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16765 peer->maxcallbitrate = atoi(v->value); 16766 if (peer->maxcallbitrate < 0) 16767 peer->maxcallbitrate = default_maxcallbitrate; 16768 } 16769 } 16770 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16771 time_t nowtime = time(NULL); 16772 16773 if ((nowtime - regseconds) > 0) { 16774 destroy_association(peer); 16775 memset(&peer->addr, 0, sizeof(peer->addr)); 16776 if (option_debug) 16777 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16778 } 16779 } 16780 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16781 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16782 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16783 global_allowsubscribe = TRUE; /* No global ban any more */ 16784 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16785 reg_source_db(peer); 16786 ASTOBJ_UNMARK(peer); 16787 ast_free_ha(oldha); 16788 return peer; 16789 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11556 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().
11557 { 11558 char a1[256]; 11559 char a2[256]; 11560 char a1_hash[256]; 11561 char a2_hash[256]; 11562 char resp[256]; 11563 char resp_hash[256]; 11564 char uri[256]; 11565 char cnonce[80]; 11566 const char *username; 11567 const char *secret; 11568 const char *md5secret; 11569 struct sip_auth *auth = NULL; /* Realm authentication */ 11570 11571 if (!ast_strlen_zero(p->domain)) 11572 ast_copy_string(uri, p->domain, sizeof(uri)); 11573 else if (!ast_strlen_zero(p->uri)) 11574 ast_copy_string(uri, p->uri, sizeof(uri)); 11575 else 11576 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11577 11578 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11579 11580 /* Check if we have separate auth credentials */ 11581 if ((auth = find_realm_authentication(authl, p->realm))) { 11582 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11583 auth->username, p->peername, p->username); 11584 username = auth->username; 11585 secret = auth->secret; 11586 md5secret = auth->md5secret; 11587 if (sipdebug) 11588 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11589 } else { 11590 /* No authentication, use peer or register= config */ 11591 username = p->authname; 11592 secret = p->peersecret; 11593 md5secret = p->peermd5secret; 11594 } 11595 if (ast_strlen_zero(username)) /* We have no authentication */ 11596 return -1; 11597 11598 /* Calculate SIP digest response */ 11599 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11600 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11601 if (!ast_strlen_zero(md5secret)) 11602 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11603 else 11604 ast_md5_hash(a1_hash,a1); 11605 ast_md5_hash(a2_hash,a2); 11606 11607 p->noncecount++; 11608 if (!ast_strlen_zero(p->qop)) 11609 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11610 else 11611 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11612 ast_md5_hash(resp_hash, resp); 11613 /* XXX We hard code our qop to "auth" for now. XXX */ 11614 if (!ast_strlen_zero(p->qop)) 11615 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount); 11616 else 11617 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque); 11618 11619 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11620 11621 return 0; 11622 }
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 8244 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().
08245 { 08246 struct sip_route *thishop, *head, *tail; 08247 int start = 0; 08248 int len; 08249 const char *rr, *contact, *c; 08250 08251 /* Once a persistant route is set, don't fool with it */ 08252 if (p->route && p->route_persistant) { 08253 if (option_debug) 08254 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08255 return; 08256 } 08257 08258 if (p->route) { 08259 free_old_route(p->route); 08260 p->route = NULL; 08261 } 08262 08263 p->route_persistant = backwards; 08264 08265 /* Build a tailq, then assign it to p->route when done. 08266 * If backwards, we add entries from the head so they end up 08267 * in reverse order. However, we do need to maintain a correct 08268 * tail pointer because the contact is always at the end. 08269 */ 08270 head = NULL; 08271 tail = head; 08272 /* 1st we pass through all the hops in any Record-Route headers */ 08273 for (;;) { 08274 /* Each Record-Route header */ 08275 rr = __get_header(req, "Record-Route", &start); 08276 if (*rr == '\0') 08277 break; 08278 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08279 ++rr; 08280 len = strcspn(rr, ">") + 1; 08281 /* Make a struct route */ 08282 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08283 /* ast_calloc is not needed because all fields are initialized in this block */ 08284 ast_copy_string(thishop->hop, rr, len); 08285 if (option_debug > 1) 08286 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08287 /* Link in */ 08288 if (backwards) { 08289 /* Link in at head so they end up in reverse order */ 08290 thishop->next = head; 08291 head = thishop; 08292 /* If this was the first then it'll be the tail */ 08293 if (!tail) 08294 tail = thishop; 08295 } else { 08296 thishop->next = NULL; 08297 /* Link in at the end */ 08298 if (tail) 08299 tail->next = thishop; 08300 else 08301 head = thishop; 08302 tail = thishop; 08303 } 08304 } 08305 } 08306 } 08307 08308 /* Only append the contact if we are dealing with a strict router */ 08309 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08310 /* 2nd append the Contact: if there is one */ 08311 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08312 contact = get_header(req, "Contact"); 08313 if (!ast_strlen_zero(contact)) { 08314 if (option_debug > 1) 08315 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08316 /* Look for <: delimited address */ 08317 c = strchr(contact, '<'); 08318 if (c) { 08319 /* Take to > */ 08320 ++c; 08321 len = strcspn(c, ">") + 1; 08322 } else { 08323 /* No <> - just take the lot */ 08324 c = contact; 08325 len = strlen(contact) + 1; 08326 } 08327 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08328 /* ast_calloc is not needed because all fields are initialized in this block */ 08329 ast_copy_string(thishop->hop, c, len); 08330 thishop->next = NULL; 08331 /* Goes at the end */ 08332 if (tail) 08333 tail->next = thishop; 08334 else 08335 head = thishop; 08336 } 08337 } 08338 } 08339 08340 /* Store as new route */ 08341 p->route = head; 08342 08343 /* For debugging dump what we ended up with */ 08344 if (sip_debug_test_pvt(p)) 08345 list_route(p->route); 08346 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6862 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().
06863 { 06864 int send_pres_tags = TRUE; 06865 const char *privacy=NULL; 06866 const char *screen=NULL; 06867 char buf[256]; 06868 const char *clid = default_callerid; 06869 const char *clin = NULL; 06870 const char *fromdomain; 06871 06872 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06873 return; 06874 06875 if (p->owner && p->owner->cid.cid_num) 06876 clid = p->owner->cid.cid_num; 06877 if (p->owner && p->owner->cid.cid_name) 06878 clin = p->owner->cid.cid_name; 06879 if (ast_strlen_zero(clin)) 06880 clin = clid; 06881 06882 switch (p->callingpres) { 06883 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06884 privacy = "off"; 06885 screen = "no"; 06886 break; 06887 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06888 privacy = "off"; 06889 screen = "yes"; 06890 break; 06891 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06892 privacy = "off"; 06893 screen = "no"; 06894 break; 06895 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06896 privacy = "off"; 06897 screen = "yes"; 06898 break; 06899 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06900 privacy = "full"; 06901 screen = "no"; 06902 break; 06903 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06904 privacy = "full"; 06905 screen = "yes"; 06906 break; 06907 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06908 privacy = "full"; 06909 screen = "no"; 06910 break; 06911 case AST_PRES_PROHIB_NETWORK_NUMBER: 06912 privacy = "full"; 06913 screen = "yes"; 06914 break; 06915 case AST_PRES_NUMBER_NOT_AVAILABLE: 06916 send_pres_tags = FALSE; 06917 break; 06918 default: 06919 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06920 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06921 privacy = "full"; 06922 else 06923 privacy = "off"; 06924 screen = "no"; 06925 break; 06926 } 06927 06928 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06929 06930 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06931 if (send_pres_tags) 06932 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06933 ast_string_field_set(p, rpid, buf); 06934 06935 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06936 S_OR(p->fromuser, clid), 06937 fromdomain, p->tag); 06938 }
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 16363 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.
16364 { 16365 struct sip_user *user; 16366 int format; 16367 struct ast_ha *oldha = NULL; 16368 char *varname = NULL, *varval = NULL; 16369 struct ast_variable *tmpvar = NULL; 16370 struct ast_flags userflags[2] = {{(0)}}; 16371 struct ast_flags mask[2] = {{(0)}}; 16372 16373 16374 if (!(user = ast_calloc(1, sizeof(*user)))) 16375 return NULL; 16376 16377 suserobjs++; 16378 ASTOBJ_INIT(user); 16379 ast_copy_string(user->name, name, sizeof(user->name)); 16380 oldha = user->ha; 16381 user->ha = NULL; 16382 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16383 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16384 user->capability = global_capability; 16385 user->allowtransfer = global_allowtransfer; 16386 user->maxcallbitrate = default_maxcallbitrate; 16387 user->autoframing = global_autoframing; 16388 user->prefs = default_prefs; 16389 /* set default context */ 16390 strcpy(user->context, default_context); 16391 strcpy(user->language, default_language); 16392 strcpy(user->mohinterpret, default_mohinterpret); 16393 strcpy(user->mohsuggest, default_mohsuggest); 16394 /* First we walk through the v parameters list and then the alt parameters list */ 16395 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16396 if (handle_common_options(&userflags[0], &mask[0], v)) 16397 continue; 16398 16399 if (!strcasecmp(v->name, "context")) { 16400 ast_copy_string(user->context, v->value, sizeof(user->context)); 16401 } else if (!strcasecmp(v->name, "subscribecontext")) { 16402 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16403 } else if (!strcasecmp(v->name, "setvar")) { 16404 varname = ast_strdupa(v->value); 16405 if ((varval = strchr(varname,'='))) { 16406 *varval++ = '\0'; 16407 if ((tmpvar = ast_variable_new(varname, varval))) { 16408 tmpvar->next = user->chanvars; 16409 user->chanvars = tmpvar; 16410 } 16411 } 16412 } else if (!strcasecmp(v->name, "permit") || 16413 !strcasecmp(v->name, "deny")) { 16414 user->ha = ast_append_ha(v->name, v->value, user->ha); 16415 } else if (!strcasecmp(v->name, "allowtransfer")) { 16416 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16417 } else if (!strcasecmp(v->name, "secret")) { 16418 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16419 } else if (!strcasecmp(v->name, "md5secret")) { 16420 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16421 } else if (!strcasecmp(v->name, "callerid")) { 16422 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16423 } else if (!strcasecmp(v->name, "fullname")) { 16424 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16425 } else if (!strcasecmp(v->name, "cid_number")) { 16426 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16427 } else if (!strcasecmp(v->name, "callgroup")) { 16428 user->callgroup = ast_get_group(v->value); 16429 } else if (!strcasecmp(v->name, "pickupgroup")) { 16430 user->pickupgroup = ast_get_group(v->value); 16431 } else if (!strcasecmp(v->name, "language")) { 16432 ast_copy_string(user->language, v->value, sizeof(user->language)); 16433 } else if (!strcasecmp(v->name, "mohinterpret") 16434 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16435 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16436 } else if (!strcasecmp(v->name, "mohsuggest")) { 16437 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16438 } else if (!strcasecmp(v->name, "accountcode")) { 16439 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16440 } else if (!strcasecmp(v->name, "call-limit")) { 16441 user->call_limit = atoi(v->value); 16442 if (user->call_limit < 0) 16443 user->call_limit = 0; 16444 } else if (!strcasecmp(v->name, "amaflags")) { 16445 format = ast_cdr_amaflags2int(v->value); 16446 if (format < 0) { 16447 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16448 } else { 16449 user->amaflags = format; 16450 } 16451 } else if (!strcasecmp(v->name, "allow")) { 16452 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16453 } else if (!strcasecmp(v->name, "disallow")) { 16454 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16455 } else if (!strcasecmp(v->name, "autoframing")) { 16456 user->autoframing = ast_true(v->value); 16457 } else if (!strcasecmp(v->name, "callingpres")) { 16458 user->callingpres = ast_parse_caller_presentation(v->value); 16459 if (user->callingpres == -1) 16460 user->callingpres = atoi(v->value); 16461 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16462 user->maxcallbitrate = atoi(v->value); 16463 if (user->maxcallbitrate < 0) 16464 user->maxcallbitrate = default_maxcallbitrate; 16465 } 16466 /* We can't just report unknown options here because this may be a 16467 * type=friend entry. All user options are valid for a peer, but not 16468 * the other way around. */ 16469 } 16470 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16471 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16472 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16473 global_allowsubscribe = TRUE; /* No global ban any more */ 16474 ast_free_ha(oldha); 16475 return user; 16476 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1791 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
01792 { 01793 /* Work around buggy UNIDEN UIP200 firmware */ 01794 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01795 01796 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01797 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01798 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01799 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8551 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().
08552 { 08553 struct sip_pvt *p = data; 08554 08555 ast_mutex_lock(&p->lock); 08556 08557 switch(state) { 08558 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08559 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08560 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08561 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08562 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08563 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); 08564 p->stateid = -1; 08565 p->subscribed = NONE; 08566 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08567 break; 08568 default: /* Tell user */ 08569 p->laststate = state; 08570 break; 08571 } 08572 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08573 if (!p->pendinginvite) { 08574 transmit_state_notify(p, state, 1, FALSE); 08575 } else { 08576 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08577 if many state changes happen meanwhile, we will only send a notification of the last one */ 08578 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08579 } 08580 } 08581 if (option_verbose > 1) 08582 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, 08583 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08584 08585 08586 ast_mutex_unlock(&p->lock); 08587 08588 return 0; 08589 }
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 4977 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().
04978 { 04979 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04980 sip_peer_hold(dialog, holdstate); 04981 if (global_callevents) 04982 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04983 "Channel: %s\r\n" 04984 "Uniqueid: %s\r\n", 04985 dialog->owner->name, 04986 dialog->owner->uniqueid); 04987 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04988 if (!holdstate) { /* Put off remote hold */ 04989 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04990 return; 04991 } 04992 /* No address for RTP, we're on hold */ 04993 04994 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 04995 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 04996 else if (sendonly == 2) /* Inactive stream */ 04997 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 04998 else 04999 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05000 return; 05001 }
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 8356 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(), key(), 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().
08359 { 08360 const char *response = "407 Proxy Authentication Required"; 08361 const char *reqheader = "Proxy-Authorization"; 08362 const char *respheader = "Proxy-Authenticate"; 08363 const char *authtoken; 08364 char a1_hash[256]; 08365 char resp_hash[256]=""; 08366 char *c; 08367 int wrongnonce = FALSE; 08368 int good_response; 08369 const char *usednonce = p->randdata; 08370 struct ast_dynamic_str *buf; 08371 int res; 08372 08373 /* table of recognised keywords, and their value in the digest */ 08374 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08375 struct x { 08376 const char *key; 08377 const char *s; 08378 } *i, keys[] = { 08379 [K_RESP] = { "response=", "" }, 08380 [K_URI] = { "uri=", "" }, 08381 [K_USER] = { "username=", "" }, 08382 [K_NONCE] = { "nonce=", "" }, 08383 [K_LAST] = { NULL, NULL} 08384 }; 08385 08386 /* Always OK if no secret */ 08387 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08388 return AUTH_SUCCESSFUL; 08389 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08390 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08391 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08392 different circumstances! What a surprise. */ 08393 response = "401 Unauthorized"; 08394 reqheader = "Authorization"; 08395 respheader = "WWW-Authenticate"; 08396 } 08397 authtoken = get_header(req, reqheader); 08398 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08399 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08400 information */ 08401 if (!reliable) { 08402 /* Resend message if this was NOT a reliable delivery. Otherwise the 08403 retransmission should get it */ 08404 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08405 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08406 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08407 } 08408 return AUTH_CHALLENGE_SENT; 08409 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08410 /* We have no auth, so issue challenge and request authentication */ 08411 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08412 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08413 /* Schedule auto destroy in 32 seconds */ 08414 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08415 return AUTH_CHALLENGE_SENT; 08416 } 08417 08418 /* --- We have auth, so check it */ 08419 08420 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08421 an example in the spec of just what it is you're doing a hash on. */ 08422 08423 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08424 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08425 08426 /* Make a copy of the response and parse it */ 08427 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08428 08429 if (res == AST_DYNSTR_BUILD_FAILED) 08430 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08431 08432 c = buf->str; 08433 08434 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08435 for (i = keys; i->key != NULL; i++) { 08436 const char *separator = ","; /* default */ 08437 08438 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08439 continue; 08440 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08441 c += strlen(i->key); 08442 if (*c == '"') { /* in quotes. Skip first and look for last */ 08443 c++; 08444 separator = "\""; 08445 } 08446 i->s = c; 08447 strsep(&c, separator); 08448 break; 08449 } 08450 if (i->key == NULL) /* not found, jump after space or comma */ 08451 strsep(&c, " ,"); 08452 } 08453 08454 /* Verify that digest username matches the username we auth as */ 08455 if (strcmp(username, keys[K_USER].s)) { 08456 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08457 username, keys[K_USER].s); 08458 /* Oops, we're trying something here */ 08459 return AUTH_USERNAME_MISMATCH; 08460 } 08461 08462 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08463 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08464 wrongnonce = TRUE; 08465 usednonce = keys[K_NONCE].s; 08466 } 08467 08468 if (!ast_strlen_zero(md5secret)) 08469 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08470 else { 08471 char a1[256]; 08472 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08473 ast_md5_hash(a1_hash, a1); 08474 } 08475 08476 /* compute the expected response to compare with what we received */ 08477 { 08478 char a2[256]; 08479 char a2_hash[256]; 08480 char resp[256]; 08481 08482 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08483 S_OR(keys[K_URI].s, uri)); 08484 ast_md5_hash(a2_hash, a2); 08485 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08486 ast_md5_hash(resp_hash, resp); 08487 } 08488 08489 good_response = keys[K_RESP].s && 08490 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08491 if (wrongnonce) { 08492 if (good_response) { 08493 if (sipdebug) 08494 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08495 /* We got working auth token, based on stale nonce . */ 08496 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08497 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08498 } else { 08499 /* Everything was wrong, so give the device one more try with a new challenge */ 08500 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08501 if (sipdebug) 08502 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08503 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08504 } else { 08505 if (sipdebug) 08506 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08507 } 08508 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08509 } 08510 08511 /* Schedule auto destroy in 32 seconds */ 08512 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08513 return AUTH_CHALLENGE_SENT; 08514 } 08515 if (good_response) { 08516 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08517 return AUTH_SUCCESSFUL; 08518 } 08519 08520 /* Ok, we have a bad username/secret pair */ 08521 /* Tell the UAS not to re-send this authentication data, because 08522 it will continue to fail 08523 */ 08524 08525 return AUTH_SECRET_FAILED; 08526 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12017 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().
12018 { 12019 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12020 /* if we can't BYE, then this is really a pending CANCEL */ 12021 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12022 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12023 /* Actually don't destroy us yet, wait for the 487 on our original 12024 INVITE, but do set an autodestruct just in case we never get it. */ 12025 else { 12026 /* We have a pending outbound invite, don't send someting 12027 new in-transaction */ 12028 if (p->pendinginvite) 12029 return; 12030 12031 /* Perhaps there is an SD change INVITE outstanding */ 12032 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12033 } 12034 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12035 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12036 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12037 /* if we can't REINVITE, hold it for later */ 12038 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12039 if (option_debug) 12040 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12041 } else { 12042 if (option_debug) 12043 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12044 /* Didn't get to reinvite yet, so do it now */ 12045 transmit_reinvite_with_sdp(p); 12046 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12047 } 12048 } 12049 }
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 16242 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
16243 { 16244 struct domain *d; 16245 int result = 0; 16246 16247 AST_LIST_LOCK(&domain_list); 16248 AST_LIST_TRAVERSE(&domain_list, d, list) { 16249 if (strcasecmp(d->domain, domain)) 16250 continue; 16251 16252 if (len && !ast_strlen_zero(d->context)) 16253 ast_copy_string(context, d->context, len); 16254 16255 result = 1; 16256 break; 16257 } 16258 AST_LIST_UNLOCK(&domain_list); 16259 16260 return result; 16261 }
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 9658 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09659 { 09660 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09661 }
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 9338 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().
09341 { 09342 struct sip_user *user = NULL; 09343 struct sip_peer *peer; 09344 char from[256], *c; 09345 char *of; 09346 char rpid_num[50]; 09347 const char *rpid; 09348 enum check_auth_result res = AUTH_SUCCESSFUL; 09349 char *t; 09350 char calleridname[50]; 09351 int debug=sip_debug_test_addr(sin); 09352 struct ast_variable *tmpvar = NULL, *v = NULL; 09353 char *uri2 = ast_strdupa(uri); 09354 09355 /* Terminate URI */ 09356 t = uri2; 09357 while (*t && *t > 32 && *t != ';') 09358 t++; 09359 *t = '\0'; 09360 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09361 if (pedanticsipchecking) 09362 ast_uri_decode(from); 09363 /* XXX here tries to map the username for invite things */ 09364 memset(calleridname, 0, sizeof(calleridname)); 09365 get_calleridname(from, calleridname, sizeof(calleridname)); 09366 if (calleridname[0]) 09367 ast_string_field_set(p, cid_name, calleridname); 09368 09369 rpid = get_header(req, "Remote-Party-ID"); 09370 memset(rpid_num, 0, sizeof(rpid_num)); 09371 if (!ast_strlen_zero(rpid)) 09372 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09373 09374 of = get_in_brackets(from); 09375 if (ast_strlen_zero(p->exten)) { 09376 t = uri2; 09377 if (!strncasecmp(t, "sip:", 4)) 09378 t+= 4; 09379 ast_string_field_set(p, exten, t); 09380 t = strchr(p->exten, '@'); 09381 if (t) 09382 *t = '\0'; 09383 if (ast_strlen_zero(p->our_contact)) 09384 build_contact(p); 09385 } 09386 /* save the URI part of the From header */ 09387 ast_string_field_set(p, from, of); 09388 if (strncasecmp(of, "sip:", 4)) { 09389 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09390 } else 09391 of += 4; 09392 /* Get just the username part */ 09393 if ((c = strchr(of, '@'))) { 09394 char *tmp; 09395 *c = '\0'; 09396 if ((c = strchr(of, ':'))) 09397 *c = '\0'; 09398 tmp = ast_strdupa(of); 09399 /* We need to be able to handle auth-headers looking like 09400 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09401 */ 09402 tmp = strsep(&tmp, ";"); 09403 if (ast_is_shrinkable_phonenumber(tmp)) 09404 ast_shrink_phone_number(tmp); 09405 ast_string_field_set(p, cid_num, tmp); 09406 } 09407 09408 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09409 user = find_user(of, 1); 09410 09411 /* Find user based on user name in the from header */ 09412 if (user && ast_apply_ha(user->ha, sin)) { 09413 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09414 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09415 /* copy channel vars */ 09416 for (v = user->chanvars ; v ; v = v->next) { 09417 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09418 tmpvar->next = p->chanvars; 09419 p->chanvars = tmpvar; 09420 } 09421 } 09422 p->prefs = user->prefs; 09423 /* Set Frame packetization */ 09424 if (p->rtp) { 09425 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09426 p->autoframing = user->autoframing; 09427 } 09428 /* replace callerid if rpid found, and not restricted */ 09429 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09430 char *tmp; 09431 if (*calleridname) 09432 ast_string_field_set(p, cid_name, calleridname); 09433 tmp = ast_strdupa(rpid_num); 09434 if (ast_is_shrinkable_phonenumber(tmp)) 09435 ast_shrink_phone_number(tmp); 09436 ast_string_field_set(p, cid_num, tmp); 09437 } 09438 09439 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09440 09441 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09442 if (sip_cancel_destroy(p)) 09443 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09444 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09445 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09446 /* Copy SIP extensions profile from INVITE */ 09447 if (p->sipoptions) 09448 user->sipoptions = p->sipoptions; 09449 09450 /* If we have a call limit, set flag */ 09451 if (user->call_limit) 09452 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09453 if (!ast_strlen_zero(user->context)) 09454 ast_string_field_set(p, context, user->context); 09455 if (!ast_strlen_zero(user->cid_num)) { 09456 char *tmp = ast_strdupa(user->cid_num); 09457 if (ast_is_shrinkable_phonenumber(tmp)) 09458 ast_shrink_phone_number(tmp); 09459 ast_string_field_set(p, cid_num, tmp); 09460 } 09461 if (!ast_strlen_zero(user->cid_name)) 09462 ast_string_field_set(p, cid_name, user->cid_name); 09463 ast_string_field_set(p, username, user->name); 09464 ast_string_field_set(p, peername, user->name); 09465 ast_string_field_set(p, peersecret, user->secret); 09466 ast_string_field_set(p, peermd5secret, user->md5secret); 09467 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09468 ast_string_field_set(p, accountcode, user->accountcode); 09469 ast_string_field_set(p, language, user->language); 09470 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09471 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09472 p->allowtransfer = user->allowtransfer; 09473 p->amaflags = user->amaflags; 09474 p->callgroup = user->callgroup; 09475 p->pickupgroup = user->pickupgroup; 09476 if (user->callingpres) /* User callingpres setting will override RPID header */ 09477 p->callingpres = user->callingpres; 09478 09479 /* Set default codec settings for this call */ 09480 p->capability = user->capability; /* User codec choice */ 09481 p->jointcapability = user->capability; /* Our codecs */ 09482 if (p->peercapability) /* AND with peer's codecs */ 09483 p->jointcapability &= p->peercapability; 09484 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09485 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09486 p->noncodeccapability |= AST_RTP_DTMF; 09487 else 09488 p->noncodeccapability &= ~AST_RTP_DTMF; 09489 p->jointnoncodeccapability = p->noncodeccapability; 09490 if (p->t38.peercapability) 09491 p->t38.jointcapability &= p->t38.peercapability; 09492 p->maxcallbitrate = user->maxcallbitrate; 09493 /* If we do not support video, remove video from call structure */ 09494 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09495 ast_rtp_destroy(p->vrtp); 09496 p->vrtp = NULL; 09497 } 09498 } 09499 if (user && debug) 09500 ast_verbose("Found user '%s'\n", user->name); 09501 } else { 09502 if (user) { 09503 if (!authpeer && debug) 09504 ast_verbose("Found user '%s', but fails host access\n", user->name); 09505 ASTOBJ_UNREF(user,sip_destroy_user); 09506 } 09507 user = NULL; 09508 } 09509 09510 if (!user) { 09511 /* If we didn't find a user match, check for peers */ 09512 if (sipmethod == SIP_SUBSCRIBE) 09513 /* For subscribes, match on peer name only */ 09514 peer = find_peer(of, NULL, 1); 09515 else 09516 /* Look for peer based on the IP address we received data from */ 09517 /* If peer is registered from this IP address or have this as a default 09518 IP address, this call is from the peer 09519 */ 09520 peer = find_peer(NULL, &p->recv, 1); 09521 09522 if (peer) { 09523 /* Set Frame packetization */ 09524 if (p->rtp) { 09525 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09526 p->autoframing = peer->autoframing; 09527 } 09528 if (debug) 09529 ast_verbose("Found peer '%s'\n", peer->name); 09530 09531 /* Take the peer */ 09532 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09533 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09534 09535 /* Copy SIP extensions profile to peer */ 09536 if (p->sipoptions) 09537 peer->sipoptions = p->sipoptions; 09538 09539 /* replace callerid if rpid found, and not restricted */ 09540 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09541 char *tmp = ast_strdupa(rpid_num); 09542 if (*calleridname) 09543 ast_string_field_set(p, cid_name, calleridname); 09544 if (ast_is_shrinkable_phonenumber(tmp)) 09545 ast_shrink_phone_number(tmp); 09546 ast_string_field_set(p, cid_num, tmp); 09547 } 09548 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09549 09550 ast_string_field_set(p, peersecret, peer->secret); 09551 ast_string_field_set(p, peermd5secret, peer->md5secret); 09552 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09553 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09554 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09555 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09556 p->callingpres = peer->callingpres; 09557 if (peer->maxms && peer->lastms) 09558 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09559 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09560 /* Pretend there is no required authentication */ 09561 ast_string_field_free(p, peersecret); 09562 ast_string_field_free(p, peermd5secret); 09563 } 09564 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09565 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09566 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09567 /* If we have a call limit, set flag */ 09568 if (peer->call_limit) 09569 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09570 ast_string_field_set(p, peername, peer->name); 09571 ast_string_field_set(p, authname, peer->name); 09572 09573 /* copy channel vars */ 09574 for (v = peer->chanvars ; v ; v = v->next) { 09575 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09576 tmpvar->next = p->chanvars; 09577 p->chanvars = tmpvar; 09578 } 09579 } 09580 if (authpeer) { 09581 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09582 } 09583 09584 if (!ast_strlen_zero(peer->username)) { 09585 ast_string_field_set(p, username, peer->username); 09586 /* Use the default username for authentication on outbound calls */ 09587 /* XXX this takes the name from the caller... can we override ? */ 09588 ast_string_field_set(p, authname, peer->username); 09589 } 09590 if (!ast_strlen_zero(peer->cid_num)) { 09591 char *tmp = ast_strdupa(peer->cid_num); 09592 if (ast_is_shrinkable_phonenumber(tmp)) 09593 ast_shrink_phone_number(tmp); 09594 ast_string_field_set(p, cid_num, tmp); 09595 } 09596 if (!ast_strlen_zero(peer->cid_name)) 09597 ast_string_field_set(p, cid_name, peer->cid_name); 09598 ast_string_field_set(p, fullcontact, peer->fullcontact); 09599 if (!ast_strlen_zero(peer->context)) 09600 ast_string_field_set(p, context, peer->context); 09601 ast_string_field_set(p, peersecret, peer->secret); 09602 ast_string_field_set(p, peermd5secret, peer->md5secret); 09603 ast_string_field_set(p, language, peer->language); 09604 ast_string_field_set(p, accountcode, peer->accountcode); 09605 p->amaflags = peer->amaflags; 09606 p->callgroup = peer->callgroup; 09607 p->pickupgroup = peer->pickupgroup; 09608 p->capability = peer->capability; 09609 p->prefs = peer->prefs; 09610 p->jointcapability = peer->capability; 09611 if (p->peercapability) 09612 p->jointcapability &= p->peercapability; 09613 p->maxcallbitrate = peer->maxcallbitrate; 09614 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09615 ast_rtp_destroy(p->vrtp); 09616 p->vrtp = NULL; 09617 } 09618 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09619 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09620 p->noncodeccapability |= AST_RTP_DTMF; 09621 else 09622 p->noncodeccapability &= ~AST_RTP_DTMF; 09623 p->jointnoncodeccapability = p->noncodeccapability; 09624 if (p->t38.peercapability) 09625 p->t38.jointcapability &= p->t38.peercapability; 09626 } 09627 ASTOBJ_UNREF(peer, sip_destroy_peer); 09628 } else { 09629 if (debug) 09630 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09631 09632 /* do we allow guests? */ 09633 if (!global_allowguest) { 09634 if (global_alwaysauthreject) 09635 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09636 else 09637 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09638 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09639 char *tmp = ast_strdupa(rpid_num); 09640 if (*calleridname) 09641 ast_string_field_set(p, cid_name, calleridname); 09642 if (ast_is_shrinkable_phonenumber(tmp)) 09643 ast_shrink_phone_number(tmp); 09644 ast_string_field_set(p, cid_num, tmp); 09645 } 09646 } 09647 09648 } 09649 09650 if (user) 09651 ASTOBJ_UNREF(user, sip_destroy_user); 09652 return res; 09653 }
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 9206 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().
09207 { 09208 char via[512]; 09209 char *c, *pt; 09210 struct hostent *hp; 09211 struct ast_hostent ahp; 09212 09213 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09214 09215 /* Work on the leftmost value of the topmost Via header */ 09216 c = strchr(via, ','); 09217 if (c) 09218 *c = '\0'; 09219 09220 /* Check for rport */ 09221 c = strstr(via, ";rport"); 09222 if (c && (c[6] != '=')) /* rport query, not answer */ 09223 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09224 09225 c = strchr(via, ';'); 09226 if (c) 09227 *c = '\0'; 09228 09229 c = strchr(via, ' '); 09230 if (c) { 09231 *c = '\0'; 09232 c = ast_skip_blanks(c+1); 09233 if (strcasecmp(via, "SIP/2.0/UDP")) { 09234 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09235 return; 09236 } 09237 pt = strchr(c, ':'); 09238 if (pt) 09239 *pt++ = '\0'; /* remember port pointer */ 09240 hp = ast_gethostbyname(c, &ahp); 09241 if (!hp) { 09242 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09243 return; 09244 } 09245 memset(&p->sa, 0, sizeof(p->sa)); 09246 p->sa.sin_family = AF_INET; 09247 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09248 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09249 09250 if (sip_debug_test_pvt(p)) { 09251 const struct sockaddr_in *dst = sip_real_dst(p); 09252 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09253 } 09254 } 09255 }
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 10102 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
10103 { 10104 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10105 10106 while ((oldcontext = strsep(&old, "&"))) { 10107 stalecontext = '\0'; 10108 ast_copy_string(newlist, new, sizeof(newlist)); 10109 stringp = newlist; 10110 while ((newcontext = strsep(&stringp, "&"))) { 10111 if (strcmp(newcontext, oldcontext) == 0) { 10112 /* This is not the context you're looking for */ 10113 stalecontext = '\0'; 10114 break; 10115 } else if (strcmp(newcontext, oldcontext)) { 10116 stalecontext = oldcontext; 10117 } 10118 10119 } 10120 if (stalecontext) 10121 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10122 } 10123 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16335 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16336 { 16337 struct sip_auth *a = authlist; 16338 struct sip_auth *b; 16339 16340 while (a) { 16341 b = a; 16342 a = a->next; 16343 free(b); 16344 } 16345 16346 return 1; 16347 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16264 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().
16265 { 16266 struct domain *d; 16267 16268 AST_LIST_LOCK(&domain_list); 16269 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16270 free(d); 16271 AST_LIST_UNLOCK(&domain_list); 16272 }
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 10916 of file chan_sip.c.
References complete_sip_peer().
10917 { 10918 if (pos == 3) 10919 return complete_sip_peer(word, state, 0); 10920 10921 return NULL; 10922 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10890 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, and result.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10891 { 10892 char *result = NULL; 10893 int wordlen = strlen(word); 10894 int which = 0; 10895 10896 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10897 /* locking of the object is not required because only the name and flags are being compared */ 10898 if (!strncasecmp(word, iterator->name, wordlen) && 10899 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10900 ++which > state) 10901 result = ast_strdup(iterator->name); 10902 } while(0) ); 10903 return result; 10904 }
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 10984 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10985 { 10986 if (pos == 4) 10987 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10988 return NULL; 10989 }
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 10992 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10993 { 10994 if (pos == 4) 10995 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10996 10997 return NULL; 10998 }
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 10907 of file chan_sip.c.
References complete_sip_peer().
10908 { 10909 if (pos == 3) 10910 return complete_sip_peer(word, state, 0); 10911 10912 return NULL; 10913 }
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 10945 of file chan_sip.c.
References complete_sip_user().
10946 { 10947 if (pos == 3) 10948 return complete_sip_user(word, state, 0); 10949 10950 return NULL; 10951 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10925 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10926 { 10927 char *result = NULL; 10928 int wordlen = strlen(word); 10929 int which = 0; 10930 10931 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10932 /* locking of the object is not required because only the name and flags are being compared */ 10933 if (!strncasecmp(word, iterator->name, wordlen)) { 10934 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10935 continue; 10936 if (++which > state) { 10937 result = ast_strdup(iterator->name); 10938 } 10939 } 10940 } while(0) ); 10941 return result; 10942 }
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 10871 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10872 { 10873 int which=0; 10874 struct sip_pvt *cur; 10875 char *c = NULL; 10876 int wordlen = strlen(word); 10877 10878 ast_mutex_lock(&iflock); 10879 for (cur = iflist; cur; cur = cur->next) { 10880 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10881 c = ast_strdup(cur->callid); 10882 break; 10883 } 10884 } 10885 ast_mutex_unlock(&iflock); 10886 return c; 10887 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10954 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10955 { 10956 char *c = NULL; 10957 10958 if (pos == 2) { 10959 int which = 0; 10960 char *cat = NULL; 10961 int wordlen = strlen(word); 10962 10963 /* do completion for notify type */ 10964 10965 if (!notify_types) 10966 return NULL; 10967 10968 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10969 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10970 c = ast_strdup(cat); 10971 break; 10972 } 10973 } 10974 return c; 10975 } 10976 10977 if (pos > 2) 10978 return complete_sip_peer(word, state, 0); 10979 10980 return NULL; 10981 }
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 5662 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05663 { 05664 int start = 0; 05665 int copied = 0; 05666 for (;;) { 05667 const char *tmp = __get_header(orig, field, &start); 05668 05669 if (ast_strlen_zero(tmp)) 05670 break; 05671 /* Add what we're responding to */ 05672 add_header(req, field, tmp); 05673 copied++; 05674 } 05675 return copied ? 0 : -1; 05676 }
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 5651 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05652 { 05653 const char *tmp = get_header(orig, field); 05654 05655 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05656 return add_header(req, field, tmp); 05657 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05658 return -1; 05659 }
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 6705 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().
06706 { 06707 long offset; 06708 int x; 06709 offset = ((void *)dst) - ((void *)src); 06710 /* First copy stuff */ 06711 memcpy(dst, src, sizeof(*dst)); 06712 /* Now fix pointer arithmetic */ 06713 for (x=0; x < src->headers; x++) 06714 dst->header[x] += offset; 06715 for (x=0; x < src->lines; x++) 06716 dst->line[x] += offset; 06717 dst->rlPart1 += offset; 06718 dst->rlPart2 += offset; 06719 }
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 5684 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().
05685 { 05686 int copied = 0; 05687 int start = 0; 05688 05689 for (;;) { 05690 char new[512]; 05691 const char *oh = __get_header(orig, field, &start); 05692 05693 if (ast_strlen_zero(oh)) 05694 break; 05695 05696 if (!copied) { /* Only check for empty rport in topmost via header */ 05697 char leftmost[512], *others, *rport; 05698 05699 /* Only work on leftmost value */ 05700 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05701 others = strchr(leftmost, ','); 05702 if (others) 05703 *others++ = '\0'; 05704 05705 /* Find ;rport; (empty request) */ 05706 rport = strstr(leftmost, ";rport"); 05707 if (rport && *(rport+6) == '=') 05708 rport = NULL; /* We already have a parameter to rport */ 05709 05710 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05711 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05712 /* We need to add received port - rport */ 05713 char *end; 05714 05715 rport = strstr(leftmost, ";rport"); 05716 05717 if (rport) { 05718 end = strchr(rport + 1, ';'); 05719 if (end) 05720 memmove(rport, end, strlen(end) + 1); 05721 else 05722 *rport = '\0'; 05723 } 05724 05725 /* Add rport to first VIA header if requested */ 05726 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05727 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05728 ntohs(p->recv.sin_port), 05729 others ? "," : "", others ? others : ""); 05730 } else { 05731 /* We should *always* add a received to the topmost via */ 05732 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05733 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05734 others ? "," : "", others ? others : ""); 05735 } 05736 oh = new; /* the header to copy */ 05737 } /* else add the following via headers untouched */ 05738 add_header(req, field, oh); 05739 copied++; 05740 } 05741 if (!copied) { 05742 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05743 return -1; 05744 } 05745 return 0; 05746 }
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 2886 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.
02887 { 02888 struct hostent *hp; 02889 struct ast_hostent ahp; 02890 struct sip_peer *p; 02891 char *port; 02892 int portno; 02893 char host[MAXHOSTNAMELEN], *hostn; 02894 char peer[256]; 02895 02896 ast_copy_string(peer, opeer, sizeof(peer)); 02897 port = strchr(peer, ':'); 02898 if (port) 02899 *port++ = '\0'; 02900 dialog->sa.sin_family = AF_INET; 02901 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02902 p = find_peer(peer, NULL, 1); 02903 02904 if (p) { 02905 int res = create_addr_from_peer(dialog, p); 02906 ASTOBJ_UNREF(p, sip_destroy_peer); 02907 return res; 02908 } 02909 hostn = peer; 02910 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02911 if (srvlookup) { 02912 char service[MAXHOSTNAMELEN]; 02913 int tportno; 02914 int ret; 02915 02916 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02917 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02918 if (ret > 0) { 02919 hostn = host; 02920 portno = tportno; 02921 } 02922 } 02923 hp = ast_gethostbyname(hostn, &ahp); 02924 if (!hp) { 02925 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02926 return -1; 02927 } 02928 ast_string_field_set(dialog, tohost, peer); 02929 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02930 dialog->sa.sin_port = htons(portno); 02931 dialog->recv = dialog->sa; 02932 return 0; 02933 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2778 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02779 { 02780 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02781 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02782 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02783 dialog->recv = dialog->sa; 02784 } else 02785 return -1; 02786 02787 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02788 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02789 dialog->capability = peer->capability; 02790 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02791 ast_rtp_destroy(dialog->vrtp); 02792 dialog->vrtp = NULL; 02793 } 02794 dialog->prefs = peer->prefs; 02795 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02796 dialog->t38.capability = global_t38_capability; 02797 if (dialog->udptl) { 02798 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02799 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02800 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02801 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02802 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02803 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02804 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02805 if (option_debug > 1) 02806 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02807 } 02808 dialog->t38.jointcapability = dialog->t38.capability; 02809 } else if (dialog->udptl) { 02810 ast_udptl_destroy(dialog->udptl); 02811 dialog->udptl = NULL; 02812 } 02813 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02814 02815 if (dialog->rtp) { 02816 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02817 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02818 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02819 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02820 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02821 /* Set Frame packetization */ 02822 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02823 dialog->autoframing = peer->autoframing; 02824 } 02825 if (dialog->vrtp) { 02826 ast_rtp_setdtmf(dialog->vrtp, 0); 02827 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02828 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02829 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02830 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02831 } 02832 02833 ast_string_field_set(dialog, peername, peer->name); 02834 ast_string_field_set(dialog, authname, peer->username); 02835 ast_string_field_set(dialog, username, peer->username); 02836 ast_string_field_set(dialog, peersecret, peer->secret); 02837 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02838 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02839 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02840 ast_string_field_set(dialog, tohost, peer->tohost); 02841 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02842 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02843 char *tmpcall; 02844 char *c; 02845 tmpcall = ast_strdupa(dialog->callid); 02846 c = strchr(tmpcall, '@'); 02847 if (c) { 02848 *c = '\0'; 02849 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02850 } 02851 } 02852 if (ast_strlen_zero(dialog->tohost)) 02853 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02854 if (!ast_strlen_zero(peer->fromdomain)) 02855 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02856 if (!ast_strlen_zero(peer->fromuser)) 02857 ast_string_field_set(dialog, fromuser, peer->fromuser); 02858 if (!ast_strlen_zero(peer->language)) 02859 ast_string_field_set(dialog, language, peer->language); 02860 dialog->maxtime = peer->maxms; 02861 dialog->callgroup = peer->callgroup; 02862 dialog->pickupgroup = peer->pickupgroup; 02863 dialog->allowtransfer = peer->allowtransfer; 02864 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02865 /* Minimum is settable or default to 100 ms */ 02866 if (peer->maxms && peer->lastms) 02867 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02868 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02869 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02870 dialog->noncodeccapability |= AST_RTP_DTMF; 02871 else 02872 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02873 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02874 ast_string_field_set(dialog, context, peer->context); 02875 dialog->rtptimeout = peer->rtptimeout; 02876 if (peer->call_limit) 02877 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02878 dialog->maxcallbitrate = peer->maxcallbitrate; 02879 02880 return 0; 02881 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7886 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().
07887 { 07888 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07889 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07890 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07891 else 07892 ast_db_del("SIP/Registry", peer->name); 07893 } 07894 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6749 of file chan_sip.c.
References ast_log(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06750 { 06751 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06752 06753 if (!*e) 06754 return -1; 06755 req->rlPart1 = e; /* method or protocol */ 06756 e = ast_skip_nonblanks(e); 06757 if (*e) 06758 *e++ = '\0'; 06759 /* Get URI or status code */ 06760 e = ast_skip_blanks(e); 06761 if ( !*e ) 06762 return -1; 06763 ast_trim_blanks(e); 06764 06765 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06766 if (strlen(e) < 3) /* status code is 3 digits */ 06767 return -1; 06768 req->rlPart2 = e; 06769 } else { /* We have a request */ 06770 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06771 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06772 e++; 06773 if (!*e) 06774 return -1; 06775 } 06776 req->rlPart2 = e; /* URI */ 06777 e = ast_skip_nonblanks(e); 06778 if (*e) 06779 *e++ = '\0'; 06780 e = ast_skip_blanks(e); 06781 if (strcasecmp(e, "SIP/2.0") ) { 06782 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06783 return -1; 06784 } 06785 } 06786 return 1; 06787 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15581 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(), FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
15582 { 15583 int res; 15584 struct sip_pvt *sip; 15585 struct sip_peer *peer = NULL; 15586 time_t t; 15587 int fastrestart = FALSE; 15588 int lastpeernum = -1; 15589 int curpeernum; 15590 int reloading; 15591 15592 /* Add an I/O event to our SIP UDP socket */ 15593 if (sipsock > -1) 15594 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15595 15596 /* From here on out, we die whenever asked */ 15597 for(;;) { 15598 /* Check for a reload request */ 15599 ast_mutex_lock(&sip_reload_lock); 15600 reloading = sip_reloading; 15601 sip_reloading = FALSE; 15602 ast_mutex_unlock(&sip_reload_lock); 15603 if (reloading) { 15604 if (option_verbose > 0) 15605 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15606 sip_do_reload(sip_reloadreason); 15607 15608 /* Change the I/O fd of our UDP socket */ 15609 if (sipsock > -1) { 15610 if (sipsock_read_id) 15611 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15612 else 15613 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15614 } else if (sipsock_read_id) { 15615 ast_io_remove(io, sipsock_read_id); 15616 sipsock_read_id = NULL; 15617 } 15618 } 15619 /* Check for interfaces needing to be killed */ 15620 ast_mutex_lock(&iflock); 15621 restartsearch: 15622 t = time(NULL); 15623 /* don't scan the interface list if it hasn't been a reasonable period 15624 of time since the last time we did it (when MWI is being sent, we can 15625 get back to this point every millisecond or less) 15626 */ 15627 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15628 /*! \note If we can't get a lock on an interface, skip it and come 15629 * back later. Note that there is the possibility of a deadlock with 15630 * sip_hangup otherwise, because sip_hangup is called with the channel 15631 * locked first, and the iface lock is attempted second. 15632 */ 15633 if (ast_mutex_trylock(&sip->lock)) 15634 continue; 15635 15636 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15637 if (sip->rtp && sip->owner && 15638 (sip->owner->_state == AST_STATE_UP) && 15639 !sip->redirip.sin_addr.s_addr && 15640 sip->t38.state != T38_ENABLED) { 15641 if (sip->lastrtptx && 15642 ast_rtp_get_rtpkeepalive(sip->rtp) && 15643 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15644 /* Need to send an empty RTP packet */ 15645 sip->lastrtptx = time(NULL); 15646 ast_rtp_sendcng(sip->rtp, 0); 15647 } 15648 if (sip->lastrtprx && 15649 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15650 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15651 /* Might be a timeout now -- see if we're on hold */ 15652 struct sockaddr_in sin; 15653 ast_rtp_get_peer(sip->rtp, &sin); 15654 if (sin.sin_addr.s_addr || 15655 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15656 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15657 /* Needs a hangup */ 15658 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15659 while (sip->owner && ast_channel_trylock(sip->owner)) { 15660 ast_mutex_unlock(&sip->lock); 15661 usleep(1); 15662 ast_mutex_lock(&sip->lock); 15663 } 15664 if (sip->owner) { 15665 ast_log(LOG_NOTICE, 15666 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15667 sip->owner->name, 15668 (long) (t - sip->lastrtprx)); 15669 /* Issue a softhangup */ 15670 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15671 ast_channel_unlock(sip->owner); 15672 /* forget the timeouts for this call, since a hangup 15673 has already been requested and we don't want to 15674 repeatedly request hangups 15675 */ 15676 ast_rtp_set_rtptimeout(sip->rtp, 0); 15677 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15678 if (sip->vrtp) { 15679 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15680 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15681 } 15682 } 15683 } 15684 } 15685 } 15686 } 15687 /* If we have sessions that needs to be destroyed, do it now */ 15688 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15689 !sip->owner) { 15690 ast_mutex_unlock(&sip->lock); 15691 __sip_destroy(sip, 1); 15692 goto restartsearch; 15693 } 15694 ast_mutex_unlock(&sip->lock); 15695 } 15696 ast_mutex_unlock(&iflock); 15697 15698 pthread_testcancel(); 15699 /* Wait for sched or io */ 15700 res = ast_sched_wait(sched); 15701 if ((res < 0) || (res > 1000)) 15702 res = 1000; 15703 /* If we might need to send more mailboxes, don't wait long at all.*/ 15704 if (fastrestart) 15705 res = 1; 15706 res = ast_io_wait(io, res); 15707 if (option_debug && res > 20) 15708 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15709 ast_mutex_lock(&monlock); 15710 if (res >= 0) { 15711 res = ast_sched_runq(sched); 15712 if (option_debug && res >= 20) 15713 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15714 } 15715 15716 /* Send MWI notifications to peers - static and cached realtime peers */ 15717 t = time(NULL); 15718 fastrestart = FALSE; 15719 curpeernum = 0; 15720 peer = NULL; 15721 /* Find next peer that needs mwi */ 15722 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15723 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15724 fastrestart = TRUE; 15725 lastpeernum = curpeernum; 15726 peer = ASTOBJ_REF(iterator); 15727 }; 15728 curpeernum++; 15729 } while (0) 15730 ); 15731 /* Send MWI to the peer */ 15732 if (peer) { 15733 ASTOBJ_WRLOCK(peer); 15734 sip_send_mwi_to_peer(peer); 15735 ASTOBJ_UNLOCK(peer); 15736 ASTOBJ_UNREF(peer,sip_destroy_peer); 15737 } else { 15738 /* Reset where we come from */ 15739 lastpeernum = -1; 15740 } 15741 ast_mutex_unlock(&monlock); 15742 } 15743 /* Never reached */ 15744 return NULL; 15745 15746 }
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 11457 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().
11458 { 11459 char digest[1024]; 11460 11461 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11462 return -2; 11463 11464 p->authtries++; 11465 if (option_debug > 1) 11466 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11467 memset(digest, 0, sizeof(digest)); 11468 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11469 /* No way to authenticate */ 11470 return -1; 11471 } 11472 /* Now we have a reply digest */ 11473 p->options->auth = digest; 11474 p->options->authheader = respheader; 11475 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11476 }
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 11436 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().
11437 { 11438 char digest[1024]; 11439 p->authtries++; 11440 memset(digest,0,sizeof(digest)); 11441 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11442 /* There's nothing to use for authentication */ 11443 /* No digest challenge in request */ 11444 if (sip_debug_test_pvt(p) && p->registry) 11445 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11446 /* No old challenge */ 11447 return -1; 11448 } 11449 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11450 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11451 if (sip_debug_test_pvt(p) && p->registry) 11452 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11453 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11454 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2754 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().
02755 { 02756 const char *mode = natflags ? "On" : "Off"; 02757 02758 if (p->rtp) { 02759 if (option_debug) 02760 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02761 ast_rtp_setnat(p->rtp, natflags); 02762 } 02763 if (p->vrtp) { 02764 if (option_debug) 02765 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02766 ast_rtp_setnat(p->vrtp, natflags); 02767 } 02768 if (p->udptl) { 02769 if (option_debug) 02770 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02771 ast_udptl_setnat(p->udptl, natflags); 02772 } 02773 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15560 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.
15561 { 15562 time_t t = time(NULL); 15563 15564 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15565 !peer->mwipvt) { /* We don't have a subscription */ 15566 peer->lastmsgcheck = t; /* Reset timer */ 15567 return FALSE; 15568 } 15569 15570 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15571 return TRUE; 15572 15573 return FALSE; 15574 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10291 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10292 { 10293 switch (mode) { 10294 case SIP_DOMAIN_AUTO: 10295 return "[Automatic]"; 10296 case SIP_DOMAIN_CONFIG: 10297 return "[Configured]"; 10298 } 10299 10300 return ""; 10301 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10071 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().
10072 { 10073 switch (mode) { 10074 case SIP_DTMF_RFC2833: 10075 return "rfc2833"; 10076 case SIP_DTMF_INFO: 10077 return "info"; 10078 case SIP_DTMF_INBAND: 10079 return "inband"; 10080 case SIP_DTMF_AUTO: 10081 return "auto"; 10082 } 10083 return "<error>"; 10084 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7897 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
07898 { 07899 struct sip_peer *peer = (struct sip_peer *)data; 07900 07901 if (!peer) /* Hmmm. We have no peer. Weird. */ 07902 return 0; 07903 07904 memset(&peer->addr, 0, sizeof(peer->addr)); 07905 07906 destroy_association(peer); /* remove registration data from storage */ 07907 07908 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07909 register_peer_exten(peer, FALSE); /* Remove regexten */ 07910 peer->expire = -1; 07911 ast_device_state_changed("SIP/%s", peer->name); 07912 07913 /* Do we need to release this peer from memory? 07914 Only for realtime peers and autocreated peers 07915 */ 07916 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07917 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07918 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07919 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07920 } 07921 07922 return 0; 07923 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6839 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().
06840 { 06841 char stripped[SIPBUFSIZE]; 06842 char *c; 06843 06844 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06845 c = get_in_brackets(stripped); 06846 c = strsep(&c, ";"); /* trim ; and beyond */ 06847 if (!ast_strlen_zero(c)) 06848 ast_string_field_set(p, uri, c); 06849 }
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 4204 of file chan_sip.c.
References aliases.
04205 { 04206 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04207 static const struct cfalias { 04208 char * const fullname; 04209 char * const shortname; 04210 } aliases[] = { 04211 { "Content-Type", "c" }, 04212 { "Content-Encoding", "e" }, 04213 { "From", "f" }, 04214 { "Call-ID", "i" }, 04215 { "Contact", "m" }, 04216 { "Content-Length", "l" }, 04217 { "Subject", "s" }, 04218 { "To", "t" }, 04219 { "Supported", "k" }, 04220 { "Refer-To", "r" }, 04221 { "Referred-By", "b" }, 04222 { "Allow-Events", "u" }, 04223 { "Event", "o" }, 04224 { "Via", "v" }, 04225 { "Accept-Contact", "a" }, 04226 { "Reject-Contact", "j" }, 04227 { "Request-Disposition", "d" }, 04228 { "Session-Expires", "x" }, 04229 { "Identity", "y" }, 04230 { "Identity-Info", "n" }, 04231 }; 04232 int x; 04233 04234 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04235 if (!strcasecmp(aliases[x].fullname, name)) 04236 return aliases[x].shortname; 04237 04238 return _default; 04239 }
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 4564 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().
04565 { 04566 struct sip_pvt *p = NULL; 04567 char *tag = ""; /* note, tag is never NULL */ 04568 char totag[128]; 04569 char fromtag[128]; 04570 const char *callid = get_header(req, "Call-ID"); 04571 const char *from = get_header(req, "From"); 04572 const char *to = get_header(req, "To"); 04573 const char *cseq = get_header(req, "Cseq"); 04574 04575 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04576 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04577 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04578 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04579 return NULL; /* Invalid packet */ 04580 04581 if (pedanticsipchecking) { 04582 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04583 we need more to identify a branch - so we have to check branch, from 04584 and to tags to identify a call leg. 04585 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04586 in sip.conf 04587 */ 04588 if (gettag(req, "To", totag, sizeof(totag))) 04589 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04590 gettag(req, "From", fromtag, sizeof(fromtag)); 04591 04592 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04593 04594 if (option_debug > 4 ) 04595 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); 04596 } 04597 04598 ast_mutex_lock(&iflock); 04599 for (p = iflist; p; p = p->next) { 04600 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04601 int found = FALSE; 04602 if (ast_strlen_zero(p->callid)) 04603 continue; 04604 if (req->method == SIP_REGISTER) 04605 found = (!strcmp(p->callid, callid)); 04606 else 04607 found = (!strcmp(p->callid, callid) && 04608 (!pedanticsipchecking || ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04609 04610 if (option_debug > 4) 04611 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); 04612 04613 /* If we get a new request within an existing to-tag - check the to tag as well */ 04614 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04615 if (p->tag[0] == '\0' && totag[0]) { 04616 /* We have no to tag, but they have. Wrong dialog */ 04617 found = FALSE; 04618 } else if (totag[0]) { /* Both have tags, compare them */ 04619 if (strcmp(totag, p->tag)) { 04620 found = FALSE; /* This is not our packet */ 04621 } 04622 } 04623 if (!found && option_debug > 4) 04624 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); 04625 } 04626 04627 04628 if (found) { 04629 /* Found the call */ 04630 ast_mutex_unlock(&iflock); 04631 ast_mutex_lock(&p->lock); 04632 return p; 04633 } 04634 } 04635 ast_mutex_unlock(&iflock); 04636 04637 /* See if the method is capable of creating a dialog */ 04638 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04639 if (intended_method == SIP_REFER) { 04640 /* We do support REFER, but not outside of a dialog yet */ 04641 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04642 } else if (intended_method == SIP_NOTIFY) { 04643 /* We do not support out-of-dialog NOTIFY either, 04644 like voicemail notification, so cancel that early */ 04645 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04646 } else { 04647 /* Ok, time to create a new SIP dialog object, a pvt */ 04648 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04649 /* Ok, we've created a dialog, let's go and process it */ 04650 ast_mutex_lock(&p->lock); 04651 } else { 04652 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04653 getting a dialog from sip_alloc. 04654 04655 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04656 send an error message. 04657 04658 Sorry, we apologize for the inconvienience 04659 */ 04660 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04661 if (option_debug > 3) 04662 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04663 } 04664 } 04665 return p; 04666 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04667 /* A method we do not support, let's take it on the volley */ 04668 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04669 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04670 /* This is a request outside of a dialog that we don't know about 04671 ...never reply to an ACK! 04672 */ 04673 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04674 } 04675 /* We do not respond to responses for dialogs that we don't know about, we just drop 04676 the session quickly */ 04677 04678 return p; 04679 }
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 2315 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02316 { 02317 char last_char = '\0'; 02318 const char *s; 02319 for (s = start; *s && s != lim; last_char = *s++) { 02320 if (*s == '"' && last_char != '\\') 02321 break; 02322 } 02323 return s; 02324 }
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 2666 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02667 { 02668 struct sip_peer *p = NULL; 02669 02670 if (peer) 02671 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02672 else 02673 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02674 02675 if (!p && realtime) 02676 p = realtime_peer(peer, sin); 02677 02678 return p; 02679 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 16350 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16351 { 16352 struct sip_auth *a; 16353 16354 for (a = authlist; a; a = a->next) { 16355 if (!strcasecmp(a->realm, realm)) 16356 break; 16357 } 16358 16359 return a; 16360 }
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 4885 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().
04886 { 04887 const char *content_type; 04888 const char *content_length; 04889 const char *search; 04890 char *boundary; 04891 unsigned int x; 04892 int boundaryisquoted = FALSE; 04893 int found_application_sdp = FALSE; 04894 int found_end_of_headers = FALSE; 04895 04896 content_length = get_header(req, "Content-Length"); 04897 04898 if (!ast_strlen_zero(content_length)) { 04899 if (sscanf(content_length, "%ud", &x) != 1) { 04900 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04901 return 0; 04902 } 04903 04904 /* Content-Length of zero means there can't possibly be an 04905 SDP here, even if the Content-Type says there is */ 04906 if (x == 0) 04907 return 0; 04908 } 04909 04910 content_type = get_header(req, "Content-Type"); 04911 04912 /* if the body contains only SDP, this is easy */ 04913 if (!strcasecmp(content_type, "application/sdp")) { 04914 req->sdp_start = 0; 04915 req->sdp_end = req->lines; 04916 return req->lines ? 1 : 0; 04917 } 04918 04919 /* if it's not multipart/mixed, there cannot be an SDP */ 04920 if (strncasecmp(content_type, "multipart/mixed", 15)) 04921 return 0; 04922 04923 /* if there is no boundary marker, it's invalid */ 04924 if ((search = strcasestr(content_type, ";boundary="))) 04925 search += 10; 04926 else if ((search = strcasestr(content_type, "; boundary="))) 04927 search += 11; 04928 else 04929 return 0; 04930 04931 if (ast_strlen_zero(search)) 04932 return 0; 04933 04934 /* If the boundary is quoted with ", remove quote */ 04935 if (*search == '\"') { 04936 search++; 04937 boundaryisquoted = TRUE; 04938 } 04939 04940 /* make a duplicate of the string, with two extra characters 04941 at the beginning */ 04942 boundary = ast_strdupa(search - 2); 04943 boundary[0] = boundary[1] = '-'; 04944 /* Remove final quote */ 04945 if (boundaryisquoted) 04946 boundary[strlen(boundary) - 1] = '\0'; 04947 04948 /* search for the boundary marker, the empty line delimiting headers from 04949 sdp part and the end boundry if it exists */ 04950 04951 for (x = 0; x < (req->lines ); x++) { 04952 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04953 if(found_application_sdp && found_end_of_headers){ 04954 req->sdp_end = x-1; 04955 return 1; 04956 } 04957 found_application_sdp = FALSE; 04958 } 04959 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04960 found_application_sdp = TRUE; 04961 04962 if(strlen(req->line[x]) == 0 ){ 04963 if(found_application_sdp && !found_end_of_headers){ 04964 req->sdp_start = x; 04965 found_end_of_headers = TRUE; 04966 } 04967 } 04968 } 04969 if(found_application_sdp && found_end_of_headers) { 04970 req->sdp_end = x; 04971 return TRUE; 04972 } 04973 return FALSE; 04974 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1677 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01678 { 01679 int i, res = 0; 01680 01681 if (ast_strlen_zero(msg)) 01682 return 0; 01683 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01684 if (method_match(i, msg)) 01685 res = sip_methods[i].id; 01686 } 01687 return res; 01688 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10785 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10786 { 10787 int i; 10788 10789 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10790 if (subscription_types[i].type == subtype) { 10791 return &subscription_types[i]; 10792 } 10793 } 10794 return &subscription_types[0]; 10795 }
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 2745 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02746 { 02747 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02748 if (!u && realtime) 02749 u = realtime_user(name); 02750 return u; 02751 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8221 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08222 { 08223 struct sip_route *next; 08224 08225 while (route) { 08226 next = route->next; 08227 free(route); 08228 route = next; 08229 } 08230 }
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 11783 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), and check_sip_domain().
11784 { 11785 if (ast_strlen_zero(data)) { 11786 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11787 return -1; 11788 } 11789 if (check_sip_domain(data, NULL, 0)) 11790 ast_copy_string(buf, data, len); 11791 else 11792 buf[0] = '\0'; 11793 return 0; 11794 }
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 11719 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.
11720 { 11721 struct sip_pvt *p; 11722 const char *content = NULL; 11723 AST_DECLARE_APP_ARGS(args, 11724 AST_APP_ARG(header); 11725 AST_APP_ARG(number); 11726 ); 11727 int i, number, start = 0; 11728 11729 if (ast_strlen_zero(data)) { 11730 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11731 return -1; 11732 } 11733 11734 ast_channel_lock(chan); 11735 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11736 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11737 ast_channel_unlock(chan); 11738 return -1; 11739 } 11740 11741 AST_STANDARD_APP_ARGS(args, data); 11742 if (!args.number) { 11743 number = 1; 11744 } else { 11745 sscanf(args.number, "%d", &number); 11746 if (number < 1) 11747 number = 1; 11748 } 11749 11750 p = chan->tech_pvt; 11751 11752 /* If there is no private structure, this channel is no longer alive */ 11753 if (!p) { 11754 ast_channel_unlock(chan); 11755 return -1; 11756 } 11757 11758 for (i = 0; i < number; i++) 11759 content = __get_header(&p->initreq, args.header, &start); 11760 11761 if (ast_strlen_zero(content)) { 11762 ast_channel_unlock(chan); 11763 return -1; 11764 } 11765 11766 ast_copy_string(buf, content, len); 11767 ast_channel_unlock(chan); 11768 11769 return 0; 11770 }
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 11898 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.
11899 { 11900 struct sip_pvt *p; 11901 11902 *buf = 0; 11903 11904 if (!data) { 11905 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11906 return -1; 11907 } 11908 11909 ast_channel_lock(chan); 11910 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11911 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11912 ast_channel_unlock(chan); 11913 return -1; 11914 } 11915 11916 p = chan->tech_pvt; 11917 11918 /* If there is no private structure, this channel is no longer alive */ 11919 if (!p) { 11920 ast_channel_unlock(chan); 11921 return -1; 11922 } 11923 11924 if (!strcasecmp(data, "peerip")) { 11925 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11926 } else if (!strcasecmp(data, "recvip")) { 11927 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11928 } else if (!strcasecmp(data, "from")) { 11929 ast_copy_string(buf, p->from, len); 11930 } else if (!strcasecmp(data, "uri")) { 11931 ast_copy_string(buf, p->uri, len); 11932 } else if (!strcasecmp(data, "useragent")) { 11933 ast_copy_string(buf, p->useragent, len); 11934 } else if (!strcasecmp(data, "peername")) { 11935 ast_copy_string(buf, p->peername, len); 11936 } else if (!strcasecmp(data, "t38passthrough")) { 11937 if (p->t38.state == T38_DISABLED) 11938 ast_copy_string(buf, "0", sizeof("0")); 11939 else /* T38 is offered or enabled in this call */ 11940 ast_copy_string(buf, "1", sizeof("1")); 11941 } else { 11942 ast_channel_unlock(chan); 11943 return -1; 11944 } 11945 ast_channel_unlock(chan); 11946 11947 return 0; 11948 }
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 11808 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.
11809 { 11810 struct sip_peer *peer; 11811 char *colname; 11812 11813 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11814 *colname++ = '\0'; 11815 else if ((colname = strchr(data, '|'))) 11816 *colname++ = '\0'; 11817 else 11818 colname = "ip"; 11819 11820 if (!(peer = find_peer(data, NULL, 1))) 11821 return -1; 11822 11823 if (!strcasecmp(colname, "ip")) { 11824 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11825 } else if (!strcasecmp(colname, "status")) { 11826 peer_status(peer, buf, len); 11827 } else if (!strcasecmp(colname, "language")) { 11828 ast_copy_string(buf, peer->language, len); 11829 } else if (!strcasecmp(colname, "regexten")) { 11830 ast_copy_string(buf, peer->regexten, len); 11831 } else if (!strcasecmp(colname, "limit")) { 11832 snprintf(buf, len, "%d", peer->call_limit); 11833 } else if (!strcasecmp(colname, "curcalls")) { 11834 snprintf(buf, len, "%d", peer->inUse); 11835 } else if (!strcasecmp(colname, "accountcode")) { 11836 ast_copy_string(buf, peer->accountcode, len); 11837 } else if (!strcasecmp(colname, "useragent")) { 11838 ast_copy_string(buf, peer->useragent, len); 11839 } else if (!strcasecmp(colname, "mailbox")) { 11840 ast_copy_string(buf, peer->mailbox, len); 11841 } else if (!strcasecmp(colname, "context")) { 11842 ast_copy_string(buf, peer->context, len); 11843 } else if (!strcasecmp(colname, "expire")) { 11844 snprintf(buf, len, "%d", peer->expire); 11845 } else if (!strcasecmp(colname, "dynamic")) { 11846 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11847 } else if (!strcasecmp(colname, "callerid_name")) { 11848 ast_copy_string(buf, peer->cid_name, len); 11849 } else if (!strcasecmp(colname, "callerid_num")) { 11850 ast_copy_string(buf, peer->cid_num, len); 11851 } else if (!strcasecmp(colname, "codecs")) { 11852 ast_getformatname_multiple(buf, len -1, peer->capability); 11853 } else if (!strncasecmp(colname, "codec[", 6)) { 11854 char *codecnum; 11855 int index = 0, codec = 0; 11856 11857 codecnum = colname + 6; /* move past the '[' */ 11858 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11859 index = atoi(codecnum); 11860 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11861 ast_copy_string(buf, ast_getformatname(codec), len); 11862 } 11863 } 11864 11865 ASTOBJ_UNREF(peer, sip_destroy_peer); 11866 11867 return 0; 11868 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4397 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04398 { 04399 long val[4]; 04400 int x; 04401 04402 for (x=0; x<4; x++) 04403 val[x] = ast_random(); 04404 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04405 04406 return buf; 04407 }
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 9146 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().
09147 { 09148 char tmp[256] = "", *c, *a; 09149 struct sip_request *req = oreq ? oreq : &p->initreq; 09150 struct sip_refer *referdata = NULL; 09151 const char *transfer_context = NULL; 09152 09153 if (!p->refer && !sip_refer_allocate(p)) 09154 return -1; 09155 09156 referdata = p->refer; 09157 09158 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09159 c = get_in_brackets(tmp); 09160 09161 if (pedanticsipchecking) 09162 ast_uri_decode(c); 09163 09164 if (strncasecmp(c, "sip:", 4)) { 09165 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09166 return -1; 09167 } 09168 c += 4; 09169 if ((a = strchr(c, ';'))) /* Remove arguments */ 09170 *a = '\0'; 09171 09172 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09173 *a++ = '\0'; 09174 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09175 } 09176 09177 if (sip_debug_test_pvt(p)) 09178 ast_verbose("Looking for %s in %s\n", c, p->context); 09179 09180 if (p->owner) /* Mimic behaviour in res_features.c */ 09181 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09182 09183 /* By default, use the context in the channel sending the REFER */ 09184 if (ast_strlen_zero(transfer_context)) { 09185 transfer_context = S_OR(p->owner->macrocontext, 09186 S_OR(p->context, default_context)); 09187 } 09188 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09189 /* This is a blind transfer */ 09190 if (option_debug) 09191 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09192 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09193 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09194 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09195 referdata->refer_call = NULL; 09196 /* Set new context */ 09197 ast_string_field_set(p, context, transfer_context); 09198 return 0; 09199 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09200 return 1; 09201 } 09202 09203 return -1; 09204 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4188 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04189 { 04190 int x; 04191 int len = strlen(name); 04192 char *r; 04193 04194 for (x = 0; x < req->lines; x++) { 04195 r = get_body_by_line(req->line[x], name, len); 04196 if (r[0] != '\0') 04197 return r; 04198 } 04199 04200 return ""; 04201 }
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 4154 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04155 { 04156 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04157 return ast_skip_blanks(line + nameLen + 1); 04158 04159 return ""; 04160 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9258 of file chan_sip.c.
Referenced by check_user_full().
09259 { 09260 const char *end = strchr(input,'<'); /* first_bracket */ 09261 const char *tmp = strchr(input,'"'); /* first quote */ 09262 int bytes = 0; 09263 int maxbytes = outputsize - 1; 09264 09265 if (!end || end == input) /* we require a part in brackets */ 09266 return NULL; 09267 09268 end--; /* move just before "<" */ 09269 09270 if (tmp && tmp <= end) { 09271 /* The quote (tmp) precedes the bracket (end+1). 09272 * Find the matching quote and return the content. 09273 */ 09274 end = strchr(tmp+1, '"'); 09275 if (!end) 09276 return NULL; 09277 bytes = (int) (end - tmp); 09278 /* protect the output buffer */ 09279 if (bytes > maxbytes) 09280 bytes = maxbytes; 09281 ast_copy_string(output, tmp + 1, bytes); 09282 } else { 09283 /* No quoted string, or it is inside brackets. */ 09284 /* clear the empty characters in the begining*/ 09285 input = ast_skip_blanks(input); 09286 /* clear the empty characters in the end */ 09287 while(*end && *end < 33 && end > input) 09288 end--; 09289 if (end >= input) { 09290 bytes = (int) (end - input) + 2; 09291 /* protect the output buffer */ 09292 if (bytes > maxbytes) 09293 bytes = maxbytes; 09294 ast_copy_string(output, input, bytes); 09295 } else 09296 return NULL; 09297 } 09298 return output; 09299 }
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 8801 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08802 { 08803 char tmp[256] = "", *uri, *a; 08804 char tmpf[256] = "", *from; 08805 struct sip_request *req; 08806 char *colon; 08807 08808 req = oreq; 08809 if (!req) 08810 req = &p->initreq; 08811 08812 /* Find the request URI */ 08813 if (req->rlPart2) 08814 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08815 08816 if (pedanticsipchecking) 08817 ast_uri_decode(tmp); 08818 08819 uri = get_in_brackets(tmp); 08820 08821 if (strncasecmp(uri, "sip:", 4)) { 08822 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08823 return -1; 08824 } 08825 uri += 4; 08826 08827 /* Now find the From: caller ID and name */ 08828 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08829 if (!ast_strlen_zero(tmpf)) { 08830 if (pedanticsipchecking) 08831 ast_uri_decode(tmpf); 08832 from = get_in_brackets(tmpf); 08833 } else { 08834 from = NULL; 08835 } 08836 08837 if (!ast_strlen_zero(from)) { 08838 if (strncasecmp(from, "sip:", 4)) { 08839 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08840 return -1; 08841 } 08842 from += 4; 08843 if ((a = strchr(from, '@'))) 08844 *a++ = '\0'; 08845 else 08846 a = from; /* just a domain */ 08847 from = strsep(&from, ";"); /* Remove userinfo options */ 08848 a = strsep(&a, ";"); /* Remove URI options */ 08849 ast_string_field_set(p, fromdomain, a); 08850 } 08851 08852 /* Skip any options and find the domain */ 08853 08854 /* Get the target domain */ 08855 if ((a = strchr(uri, '@'))) { 08856 *a++ = '\0'; 08857 } else { /* No username part */ 08858 a = uri; 08859 uri = "s"; /* Set extension to "s" */ 08860 } 08861 colon = strchr(a, ':'); /* Remove :port */ 08862 if (colon) 08863 *colon = '\0'; 08864 08865 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08866 a = strsep(&a, ";"); /* Remove URI options */ 08867 08868 ast_string_field_set(p, domain, a); 08869 08870 if (!AST_LIST_EMPTY(&domain_list)) { 08871 char domain_context[AST_MAX_EXTENSION]; 08872 08873 domain_context[0] = '\0'; 08874 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08875 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08876 if (option_debug) 08877 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08878 return -2; 08879 } 08880 } 08881 /* If we have a context defined, overwrite the original context */ 08882 if (!ast_strlen_zero(domain_context)) 08883 ast_string_field_set(p, context, domain_context); 08884 } 08885 08886 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 08887 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 08888 ast_string_field_set(p, context, p->subscribecontext); 08889 08890 if (sip_debug_test_pvt(p)) 08891 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08892 08893 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 08894 if (req->method == SIP_SUBSCRIBE) { 08895 char hint[AST_MAX_EXTENSION]; 08896 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 08897 } else { 08898 /* Check the dialplan for the username part of the request URI, 08899 the domain will be stored in the SIPDOMAIN variable 08900 Since extensions.conf can have unescaped characters, try matching a decoded 08901 uri in addition to the non-decoded uri 08902 Return 0 if we have a matching extension */ 08903 char *decoded_uri = ast_strdupa(uri); 08904 ast_uri_decode(decoded_uri); 08905 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)) || 08906 !strcmp(uri, ast_pickup_ext())) { 08907 if (!oreq) 08908 ast_string_field_set(p, exten, uri); 08909 return 0; 08910 } 08911 } 08912 08913 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08914 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08915 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 08916 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08917 return 1; 08918 } 08919 08920 return -1; 08921 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4277 of file chan_sip.c.
References __get_header().
04278 { 04279 int start = 0; 04280 return __get_header(req, name, &start); 04281 }
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 2337 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().
02338 { 02339 const char *parse = tmp; 02340 char *first_bracket; 02341 02342 /* 02343 * Skip any quoted text until we find the part in brackets. 02344 * On any error give up and return the full string. 02345 */ 02346 while ( (first_bracket = strchr(parse, '<')) ) { 02347 char *first_quote = strchr(parse, '"'); 02348 02349 if (!first_quote || first_quote > first_bracket) 02350 break; /* no need to look at quoted part */ 02351 /* the bracket is within quotes, so ignore it */ 02352 parse = find_closing_quote(first_quote + 1, NULL); 02353 if (!*parse) { /* not found, return full string ? */ 02354 /* XXX or be robust and return in-bracket part ? */ 02355 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02356 break; 02357 } 02358 parse++; 02359 } 02360 if (first_bracket) { 02361 char *second_bracket = strchr(first_bracket + 1, '>'); 02362 if (second_bracket) { 02363 *second_bracket = '\0'; 02364 tmp = first_bracket + 1; 02365 } else { 02366 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02367 } 02368 } 02369 return tmp; 02370 }
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 9664 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09665 { 09666 int x; 09667 int y; 09668 09669 buf[0] = '\0'; 09670 y = len - strlen(buf) - 5; 09671 if (y < 0) 09672 y = 0; 09673 for (x=0;x<req->lines;x++) { 09674 strncat(buf, req->line[x], y); /* safe */ 09675 y -= strlen(req->line[x]) + 1; 09676 if (y < 0) 09677 y = 0; 09678 if (y != 0) 09679 strcat(buf, "\n"); /* safe */ 09680 } 09681 return 0; 09682 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8772 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().
08773 { 08774 char tmp[256], *c, *a; 08775 struct sip_request *req; 08776 08777 req = oreq; 08778 if (!req) 08779 req = &p->initreq; 08780 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08781 if (ast_strlen_zero(tmp)) 08782 return 0; 08783 c = get_in_brackets(tmp); 08784 if (strncasecmp(c, "sip:", 4)) { 08785 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08786 return -1; 08787 } 08788 c += 4; 08789 a = c; 08790 strsep(&a, "@;"); /* trim anything after @ or ; */ 08791 if (sip_debug_test_pvt(p)) 08792 ast_verbose("RDNIS is %s\n", c); 08793 ast_string_field_set(p, rdnis, c); 08794 08795 return 0; 08796 }
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 8980 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().
08981 { 08982 08983 const char *p_referred_by = NULL; 08984 char *h_refer_to = NULL; 08985 char *h_referred_by = NULL; 08986 char *refer_to; 08987 const char *p_refer_to; 08988 char *referred_by_uri = NULL; 08989 char *ptr; 08990 struct sip_request *req = NULL; 08991 const char *transfer_context = NULL; 08992 struct sip_refer *referdata; 08993 08994 08995 req = outgoing_req; 08996 referdata = transferer->refer; 08997 08998 if (!req) 08999 req = &transferer->initreq; 09000 09001 p_refer_to = get_header(req, "Refer-To"); 09002 if (ast_strlen_zero(p_refer_to)) { 09003 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09004 return -2; /* Syntax error */ 09005 } 09006 h_refer_to = ast_strdupa(p_refer_to); 09007 refer_to = get_in_brackets(h_refer_to); 09008 if (pedanticsipchecking) 09009 ast_uri_decode(refer_to); 09010 09011 if (strncasecmp(refer_to, "sip:", 4)) { 09012 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09013 return -3; 09014 } 09015 refer_to += 4; /* Skip sip: */ 09016 09017 /* Get referred by header if it exists */ 09018 p_referred_by = get_header(req, "Referred-By"); 09019 if (!ast_strlen_zero(p_referred_by)) { 09020 char *lessthan; 09021 h_referred_by = ast_strdupa(p_referred_by); 09022 if (pedanticsipchecking) 09023 ast_uri_decode(h_referred_by); 09024 09025 /* Store referrer's caller ID name */ 09026 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09027 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09028 *(lessthan - 1) = '\0'; /* Space */ 09029 } 09030 09031 referred_by_uri = get_in_brackets(h_referred_by); 09032 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09033 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09034 referred_by_uri = (char *) NULL; 09035 } else { 09036 referred_by_uri += 4; /* Skip sip: */ 09037 } 09038 } 09039 09040 /* Check for arguments in the refer_to header */ 09041 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09042 *ptr++ = '\0'; 09043 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09044 char *to = NULL, *from = NULL; 09045 09046 /* This is an attended transfer */ 09047 referdata->attendedtransfer = 1; 09048 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09049 ast_uri_decode(referdata->replaces_callid); 09050 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09051 *ptr++ = '\0'; 09052 } 09053 09054 if (ptr) { 09055 /* Find the different tags before we destroy the string */ 09056 to = strcasestr(ptr, "to-tag="); 09057 from = strcasestr(ptr, "from-tag="); 09058 } 09059 09060 /* Grab the to header */ 09061 if (to) { 09062 ptr = to + 7; 09063 if ((to = strchr(ptr, '&'))) 09064 *to = '\0'; 09065 if ((to = strchr(ptr, ';'))) 09066 *to = '\0'; 09067 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09068 } 09069 09070 if (from) { 09071 ptr = from + 9; 09072 if ((to = strchr(ptr, '&'))) 09073 *to = '\0'; 09074 if ((to = strchr(ptr, ';'))) 09075 *to = '\0'; 09076 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09077 } 09078 09079 if (option_debug > 1) { 09080 if (!pedanticsipchecking) 09081 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09082 else 09083 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>" ); 09084 } 09085 } 09086 } 09087 09088 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09089 char *urioption = NULL, *domain; 09090 *ptr++ = '\0'; 09091 09092 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09093 *urioption++ = '\0'; 09094 09095 domain = ptr; 09096 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09097 *ptr = '\0'; 09098 09099 /* Save the domain for the dial plan */ 09100 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09101 if (urioption) 09102 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09103 } 09104 09105 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09106 *ptr = '\0'; 09107 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09108 09109 if (referred_by_uri) { 09110 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09111 *ptr = '\0'; 09112 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09113 } else { 09114 referdata->referred_by[0] = '\0'; 09115 } 09116 09117 /* Determine transfer context */ 09118 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09119 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09120 09121 /* By default, use the context in the channel sending the REFER */ 09122 if (ast_strlen_zero(transfer_context)) { 09123 transfer_context = S_OR(transferer->owner->macrocontext, 09124 S_OR(transferer->context, default_context)); 09125 } 09126 09127 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09128 09129 /* Either an existing extension or the parking extension */ 09130 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09131 if (sip_debug_test_pvt(transferer)) { 09132 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09133 } 09134 /* We are ready to transfer to the extension */ 09135 return 0; 09136 } 09137 if (sip_debug_test_pvt(transferer)) 09138 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09139 09140 /* Failure, we can't find this extension */ 09141 return -1; 09142 }
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 9305 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09306 { 09307 char *start; 09308 char *end; 09309 09310 start = strchr(input,':'); 09311 if (!start) { 09312 output[0] = '\0'; 09313 return 0; 09314 } 09315 start++; 09316 09317 /* we found "number" */ 09318 ast_copy_string(output,start,maxlen); 09319 output[maxlen-1] = '\0'; 09320 09321 end = strchr(output,'@'); 09322 if (end) 09323 *end = '\0'; 09324 else 09325 output[0] = '\0'; 09326 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09327 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09328 09329 return 0; 09330 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4180 of file chan_sip.c.
References get_sdp_iterate().
04181 { 04182 int dummy = 0; 04183 04184 return get_sdp_iterate(&dummy, req, name); 04185 }
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 4166 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04167 { 04168 int len = strlen(name); 04169 04170 while (*start < req->sdp_end) { 04171 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04172 if (r[0] != '\0') 04173 return r; 04174 } 04175 04176 return ""; 04177 }
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 8928 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, 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().
08929 { 08930 struct sip_pvt *sip_pvt_ptr; 08931 08932 ast_mutex_lock(&iflock); 08933 08934 if (option_debug > 3 && totag) 08935 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08936 08937 /* Search interfaces and find the match */ 08938 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08939 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08940 int match = 1; 08941 char *ourtag = sip_pvt_ptr->tag; 08942 08943 /* Go ahead and lock it (and its owner) before returning */ 08944 ast_mutex_lock(&sip_pvt_ptr->lock); 08945 08946 /* Check if tags match. If not, this is not the call we want 08947 (With a forking SIP proxy, several call legs share the 08948 call id, but have different tags) 08949 */ 08950 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 08951 match = 0; 08952 08953 if (!match) { 08954 ast_mutex_unlock(&sip_pvt_ptr->lock); 08955 continue; 08956 } 08957 08958 if (option_debug > 3 && totag) 08959 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08960 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08961 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08962 08963 /* deadlock avoidance... */ 08964 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08965 ast_mutex_unlock(&sip_pvt_ptr->lock); 08966 usleep(1); 08967 ast_mutex_lock(&sip_pvt_ptr->lock); 08968 } 08969 break; 08970 } 08971 } 08972 ast_mutex_unlock(&iflock); 08973 if (option_debug > 3 && !sip_pvt_ptr) 08974 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08975 return sip_pvt_ptr; 08976 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13338 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13339 { 13340 const char *thetag; 13341 13342 if (!tagbuf) 13343 return NULL; 13344 tagbuf[0] = '\0'; /* reset the buffer */ 13345 thetag = get_header(req, header); 13346 thetag = strcasestr(thetag, ";tag="); 13347 if (thetag) { 13348 thetag += 5; 13349 ast_copy_string(tagbuf, thetag, tagbufsize); 13350 return strsep(&tagbuf, ";"); 13351 } 13352 return NULL; 13353 }
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 16102 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_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().
16103 { 16104 int res = 1; 16105 16106 if (!strcasecmp(v->name, "trustrpid")) { 16107 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16108 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16109 } else if (!strcasecmp(v->name, "sendrpid")) { 16110 ast_set_flag(&mask[0], SIP_SENDRPID); 16111 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16112 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16113 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16114 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16115 } else if (!strcasecmp(v->name, "useclientcode")) { 16116 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16117 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16118 } else if (!strcasecmp(v->name, "dtmfmode")) { 16119 ast_set_flag(&mask[0], SIP_DTMF); 16120 ast_clear_flag(&flags[0], SIP_DTMF); 16121 if (!strcasecmp(v->value, "inband")) 16122 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16123 else if (!strcasecmp(v->value, "rfc2833")) 16124 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16125 else if (!strcasecmp(v->value, "info")) 16126 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16127 else if (!strcasecmp(v->value, "auto")) 16128 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16129 else { 16130 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16131 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16132 } 16133 } else if (!strcasecmp(v->name, "nat")) { 16134 ast_set_flag(&mask[0], SIP_NAT); 16135 ast_clear_flag(&flags[0], SIP_NAT); 16136 if (!strcasecmp(v->value, "never")) 16137 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16138 else if (!strcasecmp(v->value, "route")) 16139 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16140 else if (ast_true(v->value)) 16141 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16142 else 16143 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16144 } else if (!strcasecmp(v->name, "canreinvite")) { 16145 ast_set_flag(&mask[0], SIP_REINVITE); 16146 ast_clear_flag(&flags[0], SIP_REINVITE); 16147 if(ast_true(v->value)) { 16148 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16149 } else if (!ast_false(v->value)) { 16150 char buf[64]; 16151 char *word, *next = buf; 16152 16153 ast_copy_string(buf, v->value, sizeof(buf)); 16154 while ((word = strsep(&next, ","))) { 16155 if(!strcasecmp(word, "update")) { 16156 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16157 } else if(!strcasecmp(word, "nonat")) { 16158 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16159 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16160 } else { 16161 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16162 } 16163 } 16164 } 16165 } else if (!strcasecmp(v->name, "insecure")) { 16166 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16167 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16168 set_insecure_flags(flags, v->value, v->lineno); 16169 } else if (!strcasecmp(v->name, "progressinband")) { 16170 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16171 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16172 if (ast_true(v->value)) 16173 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16174 else if (strcasecmp(v->value, "never")) 16175 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16176 } else if (!strcasecmp(v->name, "promiscredir")) { 16177 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16178 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16179 } else if (!strcasecmp(v->name, "videosupport")) { 16180 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16181 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16182 } else if (!strcasecmp(v->name, "allowoverlap")) { 16183 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16184 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16185 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16186 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16187 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16188 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16189 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16190 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16191 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16192 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16193 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16194 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16195 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16196 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16197 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16198 #endif 16199 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16200 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16201 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16202 } else if (!strcasecmp(v->name, "buggymwi")) { 16203 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16204 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16205 } else 16206 res = 0; 16207 16208 return res; 16209 }
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 13517 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().
13518 { 13519 struct ast_frame *f; 13520 int earlyreplace = 0; 13521 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13522 struct ast_channel *c = p->owner; /* Our incoming call */ 13523 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13524 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13525 13526 /* Check if we're in ring state */ 13527 if (replacecall->_state == AST_STATE_RING) 13528 earlyreplace = 1; 13529 13530 /* Check if we have a bridge */ 13531 if (!(targetcall = ast_bridged_channel(replacecall))) { 13532 /* We have no bridge */ 13533 if (!earlyreplace) { 13534 if (option_debug > 1) 13535 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13536 oneleggedreplace = 1; 13537 } 13538 } 13539 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13540 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13541 13542 if (option_debug > 3) { 13543 if (targetcall) 13544 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); 13545 else 13546 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13547 } 13548 13549 if (ignore) { 13550 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13551 /* We should answer something here. If we are here, the 13552 call we are replacing exists, so an accepted 13553 can't harm */ 13554 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13555 /* Do something more clever here */ 13556 ast_channel_unlock(c); 13557 ast_mutex_unlock(&p->refer->refer_call->lock); 13558 return 1; 13559 } 13560 if (!c) { 13561 /* What to do if no channel ??? */ 13562 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13563 transmit_response_reliable(p, "503 Service Unavailable", req); 13564 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13565 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13566 ast_mutex_unlock(&p->refer->refer_call->lock); 13567 return 1; 13568 } 13569 append_history(p, "Xfer", "INVITE/Replace received"); 13570 /* We have three channels to play with 13571 channel c: New incoming call 13572 targetcall: Call from PBX to target 13573 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13574 replacecall: The owner of the previous 13575 We need to masq C into refer_call to connect to 13576 targetcall; 13577 If we are talking to internal audio stream, target call is null. 13578 */ 13579 13580 /* Fake call progress */ 13581 transmit_response(p, "100 Trying", req); 13582 ast_setstate(c, AST_STATE_RING); 13583 13584 /* Masquerade the new call into the referred call to connect to target call 13585 Targetcall is not touched by the masq */ 13586 13587 /* Answer the incoming call and set channel to UP state */ 13588 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13589 13590 ast_setstate(c, AST_STATE_UP); 13591 13592 /* Stop music on hold and other generators */ 13593 ast_quiet_chan(replacecall); 13594 ast_quiet_chan(targetcall); 13595 if (option_debug > 3) 13596 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13597 /* Unlock clone, but not original (replacecall) */ 13598 if (!oneleggedreplace) 13599 ast_channel_unlock(c); 13600 13601 /* Unlock PVT */ 13602 ast_mutex_unlock(&p->refer->refer_call->lock); 13603 13604 /* Make sure that the masq does not free our PVT for the old call */ 13605 if (! earlyreplace && ! oneleggedreplace ) 13606 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13607 13608 /* Prepare the masquerade - if this does not happen, we will be gone */ 13609 if(ast_channel_masquerade(replacecall, c)) 13610 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13611 else if (option_debug > 3) 13612 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13613 13614 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13615 13616 /* C should now be in place of replacecall */ 13617 /* ast_read needs to lock channel */ 13618 ast_channel_unlock(c); 13619 13620 if (earlyreplace || oneleggedreplace ) { 13621 /* Force the masq to happen */ 13622 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13623 ast_frfree(f); 13624 f = NULL; 13625 if (option_debug > 3) 13626 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13627 } else { 13628 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13629 } 13630 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13631 if (!oneleggedreplace) 13632 ast_channel_unlock(replacecall); 13633 } else { /* Bridged call, UP channel */ 13634 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13635 /* Masq ok */ 13636 ast_frfree(f); 13637 f = NULL; 13638 if (option_debug > 2) 13639 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13640 } else { 13641 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13642 } 13643 ast_channel_unlock(replacecall); 13644 } 13645 ast_mutex_unlock(&p->refer->refer_call->lock); 13646 13647 ast_setstate(c, AST_STATE_DOWN); 13648 if (option_debug > 3) { 13649 struct ast_channel *test; 13650 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13651 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13652 if (replacecall) 13653 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13654 if (p->owner) { 13655 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13656 test = ast_bridged_channel(p->owner); 13657 if (test) 13658 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13659 else 13660 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13661 } else 13662 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13663 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13664 } 13665 13666 ast_channel_unlock(p->owner); /* Unlock new owner */ 13667 if (!oneleggedreplace) 13668 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13669 13670 /* The call should be down with no ast_channel, so hang it up */ 13671 c->tech_pvt = NULL; 13672 ast_hangup(c); 13673 return 0; 13674 }
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 15187 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.
15188 { 15189 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15190 relatively static */ 15191 const char *cmd; 15192 const char *cseq; 15193 const char *useragent; 15194 int seqno; 15195 int len; 15196 int ignore = FALSE; 15197 int respid; 15198 int res = 0; 15199 int debug = sip_debug_test_pvt(p); 15200 char *e; 15201 int error = 0; 15202 15203 /* Get Method and Cseq */ 15204 cseq = get_header(req, "Cseq"); 15205 cmd = req->header[0]; 15206 15207 /* Must have Cseq */ 15208 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15209 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15210 error = 1; 15211 } 15212 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15213 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15214 error = 1; 15215 } 15216 if (error) { 15217 if (!p->initreq.headers) /* New call */ 15218 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15219 return -1; 15220 } 15221 /* Get the command XXX */ 15222 15223 cmd = req->rlPart1; 15224 e = req->rlPart2; 15225 15226 /* Save useragent of the client */ 15227 useragent = get_header(req, "User-Agent"); 15228 if (!ast_strlen_zero(useragent)) 15229 ast_string_field_set(p, useragent, useragent); 15230 15231 /* Find out SIP method for incoming request */ 15232 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15233 /* Response to our request -- Do some sanity checks */ 15234 if (!p->initreq.headers) { 15235 if (option_debug) 15236 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15237 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15238 return 0; 15239 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15240 if (option_debug) 15241 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15242 return -1; 15243 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15244 /* ignore means "don't do anything with it" but still have to 15245 respond appropriately */ 15246 ignore = TRUE; 15247 ast_set_flag(req, SIP_PKT_IGNORE); 15248 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15249 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15250 } else if (e) { 15251 e = ast_skip_blanks(e); 15252 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15253 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15254 } else { 15255 if (respid <= 0) { 15256 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15257 return 0; 15258 } 15259 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15260 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15261 extract_uri(p, req); 15262 handle_response(p, respid, e + len, req, ignore, seqno); 15263 } 15264 } 15265 return 0; 15266 } 15267 15268 /* New SIP request coming in 15269 (could be new request in existing SIP dialog as well...) 15270 */ 15271 15272 p->method = req->method; /* Find out which SIP method they are using */ 15273 if (option_debug > 3) 15274 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15275 15276 if (p->icseq && (p->icseq > seqno) ) { 15277 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15278 if (option_debug > 2) 15279 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15280 } else { 15281 if (option_debug) 15282 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15283 if (req->method != SIP_ACK) 15284 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15285 return -1; 15286 } 15287 } else if (p->icseq && 15288 p->icseq == seqno && 15289 req->method != SIP_ACK && 15290 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15291 /* ignore means "don't do anything with it" but still have to 15292 respond appropriately. We do this if we receive a repeat of 15293 the last sequence number */ 15294 ignore = 2; 15295 ast_set_flag(req, SIP_PKT_IGNORE); 15296 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15297 if (option_debug > 2) 15298 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15299 } 15300 15301 if (seqno >= p->icseq) 15302 /* Next should follow monotonically (but not necessarily 15303 incrementally -- thanks again to the genius authors of SIP -- 15304 increasing */ 15305 p->icseq = seqno; 15306 15307 /* Find their tag if we haven't got it */ 15308 if (ast_strlen_zero(p->theirtag)) { 15309 char tag[128]; 15310 15311 gettag(req, "From", tag, sizeof(tag)); 15312 ast_string_field_set(p, theirtag, tag); 15313 } 15314 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15315 15316 if (pedanticsipchecking) { 15317 /* If this is a request packet without a from tag, it's not 15318 correct according to RFC 3261 */ 15319 /* Check if this a new request in a new dialog with a totag already attached to it, 15320 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15321 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15322 /* If this is a first request and it got a to-tag, it is not for us */ 15323 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15324 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15325 /* Will cease to exist after ACK */ 15326 } else if (req->method != SIP_ACK) { 15327 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15328 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15329 } 15330 return res; 15331 } 15332 } 15333 15334 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15335 transmit_response(p, "400 Bad request", req); 15336 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15337 return -1; 15338 } 15339 15340 /* Handle various incoming SIP methods in requests */ 15341 switch (p->method) { 15342 case SIP_OPTIONS: 15343 res = handle_request_options(p, req); 15344 break; 15345 case SIP_INVITE: 15346 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15347 break; 15348 case SIP_REFER: 15349 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15350 break; 15351 case SIP_CANCEL: 15352 res = handle_request_cancel(p, req); 15353 break; 15354 case SIP_BYE: 15355 res = handle_request_bye(p, req); 15356 break; 15357 case SIP_MESSAGE: 15358 res = handle_request_message(p, req); 15359 break; 15360 case SIP_SUBSCRIBE: 15361 res = handle_request_subscribe(p, req, sin, seqno, e); 15362 break; 15363 case SIP_REGISTER: 15364 res = handle_request_register(p, req, sin, e); 15365 break; 15366 case SIP_INFO: 15367 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15368 ast_verbose("Receiving INFO!\n"); 15369 if (!ignore) 15370 handle_request_info(p, req); 15371 else /* if ignoring, transmit response */ 15372 transmit_response(p, "200 OK", req); 15373 break; 15374 case SIP_NOTIFY: 15375 res = handle_request_notify(p, req, sin, seqno, e); 15376 break; 15377 case SIP_ACK: 15378 /* Make sure we don't ignore this */ 15379 if (seqno == p->pendinginvite) { 15380 p->invitestate = INV_TERMINATED; 15381 p->pendinginvite = 0; 15382 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15383 if (find_sdp(req)) { 15384 if (process_sdp(p, req)) 15385 return -1; 15386 } 15387 check_pendings(p); 15388 } 15389 /* Got an ACK that we did not match. Ignore silently */ 15390 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15391 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15392 break; 15393 default: 15394 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15395 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15396 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15397 /* If this is some new method, and we don't have a call, destroy it now */ 15398 if (!p->initreq.headers) 15399 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15400 break; 15401 } 15402 return res; 15403 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14752 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().
14753 { 14754 struct ast_channel *c=NULL; 14755 int res; 14756 struct ast_channel *bridged_to; 14757 14758 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14759 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14760 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14761 14762 p->invitestate = INV_TERMINATED; 14763 14764 copy_request(&p->initreq, req); 14765 check_via(p, req); 14766 sip_alreadygone(p); 14767 14768 /* Get RTCP quality before end of call */ 14769 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14770 char *audioqos, *videoqos; 14771 if (p->rtp) { 14772 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14773 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14774 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14775 if (p->owner) 14776 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14777 } 14778 if (p->vrtp) { 14779 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14780 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14781 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14782 if (p->owner) 14783 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14784 } 14785 } 14786 14787 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14788 14789 if (!ast_strlen_zero(get_header(req, "Also"))) { 14790 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14791 ast_inet_ntoa(p->recv.sin_addr)); 14792 if (ast_strlen_zero(p->context)) 14793 ast_string_field_set(p, context, default_context); 14794 res = get_also_info(p, req); 14795 if (!res) { 14796 c = p->owner; 14797 if (c) { 14798 bridged_to = ast_bridged_channel(c); 14799 if (bridged_to) { 14800 /* Don't actually hangup here... */ 14801 ast_queue_control(c, AST_CONTROL_UNHOLD); 14802 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14803 } else 14804 ast_queue_hangup(p->owner); 14805 } 14806 } else { 14807 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14808 if (p->owner) 14809 ast_queue_hangup(p->owner); 14810 } 14811 } else if (p->owner) { 14812 ast_queue_hangup(p->owner); 14813 if (option_debug > 2) 14814 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14815 } else { 14816 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14817 if (option_debug > 2) 14818 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14819 } 14820 transmit_response(p, "200 OK", req); 14821 14822 return 1; 14823 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14646 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().
14647 { 14648 14649 check_via(p, req); 14650 sip_alreadygone(p); 14651 14652 /* At this point, we could have cancelled the invite at the same time 14653 as the other side sends a CANCEL. Our final reply with error code 14654 might not have been received by the other side before the CANCEL 14655 was sent, so let's just give up retransmissions and waiting for 14656 ACK on our error code. The call is hanging up any way. */ 14657 if (p->invitestate == INV_TERMINATED) 14658 __sip_pretend_ack(p); 14659 else 14660 p->invitestate = INV_CANCELLED; 14661 14662 if (p->owner && p->owner->_state == AST_STATE_UP) { 14663 /* This call is up, cancel is ignored, we need a bye */ 14664 transmit_response(p, "200 OK", req); 14665 if (option_debug) 14666 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14667 return 0; 14668 } 14669 14670 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14671 update_call_counter(p, DEC_CALL_LIMIT); 14672 14673 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14674 if (p->owner) 14675 ast_queue_hangup(p->owner); 14676 else 14677 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14678 if (p->initreq.len > 0) { 14679 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14680 transmit_response(p, "200 OK", req); 14681 return 1; 14682 } else { 14683 transmit_response(p, "481 Call Leg Does Not Exist", req); 14684 return 0; 14685 } 14686 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11139 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().
11140 { 11141 char buf[1024]; 11142 unsigned int event; 11143 const char *c = get_header(req, "Content-Type"); 11144 11145 /* Need to check the media/type */ 11146 if (!strcasecmp(c, "application/dtmf-relay") || 11147 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11148 unsigned int duration = 0; 11149 11150 /* Try getting the "signal=" part */ 11151 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11152 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11153 transmit_response(p, "200 OK", req); /* Should return error */ 11154 return; 11155 } else { 11156 ast_copy_string(buf, c, sizeof(buf)); 11157 } 11158 11159 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11160 duration = atoi(c); 11161 if (!duration) 11162 duration = 100; /* 100 ms */ 11163 11164 if (!p->owner) { /* not a PBX call */ 11165 transmit_response(p, "481 Call leg/transaction does not exist", req); 11166 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11167 return; 11168 } 11169 11170 if (ast_strlen_zero(buf)) { 11171 transmit_response(p, "200 OK", req); 11172 return; 11173 } 11174 11175 if (buf[0] == '*') 11176 event = 10; 11177 else if (buf[0] == '#') 11178 event = 11; 11179 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11180 event = 12 + buf[0] - 'A'; 11181 else 11182 event = atoi(buf); 11183 if (event == 16) { 11184 /* send a FLASH event */ 11185 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11186 ast_queue_frame(p->owner, &f); 11187 if (sipdebug) 11188 ast_verbose("* DTMF-relay event received: FLASH\n"); 11189 } else { 11190 /* send a DTMF event */ 11191 struct ast_frame f = { AST_FRAME_DTMF, }; 11192 if (event < 10) { 11193 f.subclass = '0' + event; 11194 } else if (event < 11) { 11195 f.subclass = '*'; 11196 } else if (event < 12) { 11197 f.subclass = '#'; 11198 } else if (event < 16) { 11199 f.subclass = 'A' + (event - 12); 11200 } 11201 f.len = duration; 11202 ast_queue_frame(p->owner, &f); 11203 if (sipdebug) 11204 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11205 } 11206 transmit_response(p, "200 OK", req); 11207 return; 11208 } else if (!strcasecmp(c, "application/media_control+xml")) { 11209 /* Eh, we'll just assume it's a fast picture update for now */ 11210 if (p->owner) 11211 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11212 transmit_response(p, "200 OK", req); 11213 return; 11214 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11215 /* Client code (from SNOM phone) */ 11216 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11217 if (p->owner && p->owner->cdr) 11218 ast_cdr_setuserfield(p->owner, c); 11219 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11220 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11221 transmit_response(p, "200 OK", req); 11222 } else { 11223 transmit_response(p, "403 Unauthorized", req); 11224 } 11225 return; 11226 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11227 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11228 transmit_response(p, "200 OK", req); 11229 return; 11230 } 11231 11232 /* Other type of INFO message, not really understood by Asterisk */ 11233 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11234 11235 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11236 transmit_response(p, "415 Unsupported media type", req); 11237 return; 11238 }
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 13683 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_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().
13684 { 13685 int res = 1; 13686 int gotdest; 13687 const char *p_replaces; 13688 char *replace_id = NULL; 13689 const char *required; 13690 unsigned int required_profile = 0; 13691 struct ast_channel *c = NULL; /* New channel */ 13692 int reinvite = 0; 13693 13694 /* Find out what they support */ 13695 if (!p->sipoptions) { 13696 const char *supported = get_header(req, "Supported"); 13697 if (!ast_strlen_zero(supported)) 13698 parse_sip_options(p, supported); 13699 } 13700 13701 /* Find out what they require */ 13702 required = get_header(req, "Require"); 13703 if (!ast_strlen_zero(required)) { 13704 required_profile = parse_sip_options(NULL, required); 13705 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13706 /* At this point we only support REPLACES */ 13707 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13708 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13709 p->invitestate = INV_COMPLETED; 13710 if (!p->lastinvite) 13711 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13712 return -1; 13713 } 13714 } 13715 13716 /* Check if this is a loop */ 13717 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13718 /* This is a call to ourself. Send ourselves an error code and stop 13719 processing immediately, as SIP really has no good mechanism for 13720 being able to call yourself */ 13721 /* If pedantic is on, we need to check the tags. If they're different, this is 13722 in fact a forked call through a SIP proxy somewhere. */ 13723 transmit_response(p, "482 Loop Detected", req); 13724 p->invitestate = INV_COMPLETED; 13725 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13726 return 0; 13727 } 13728 13729 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13730 /* We already have a pending invite. Sorry. You are on hold. */ 13731 transmit_response(p, "491 Request Pending", req); 13732 if (option_debug) 13733 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13734 /* Don't destroy dialog here */ 13735 return 0; 13736 } 13737 13738 p_replaces = get_header(req, "Replaces"); 13739 if (!ast_strlen_zero(p_replaces)) { 13740 /* We have a replaces header */ 13741 char *ptr; 13742 char *fromtag = NULL; 13743 char *totag = NULL; 13744 char *start, *to; 13745 int error = 0; 13746 13747 if (p->owner) { 13748 if (option_debug > 2) 13749 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13750 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13751 /* Do not destroy existing call */ 13752 return -1; 13753 } 13754 13755 if (sipdebug && option_debug > 2) 13756 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13757 /* Create a buffer we can manipulate */ 13758 replace_id = ast_strdupa(p_replaces); 13759 ast_uri_decode(replace_id); 13760 13761 if (!p->refer && !sip_refer_allocate(p)) { 13762 transmit_response(p, "500 Server Internal Error", req); 13763 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13764 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13765 p->invitestate = INV_COMPLETED; 13766 return -1; 13767 } 13768 13769 /* Todo: (When we find phones that support this) 13770 if the replaces header contains ";early-only" 13771 we can only replace the call in early 13772 stage, not after it's up. 13773 13774 If it's not in early mode, 486 Busy. 13775 */ 13776 13777 /* Skip leading whitespace */ 13778 replace_id = ast_skip_blanks(replace_id); 13779 13780 start = replace_id; 13781 while ( (ptr = strsep(&start, ";")) ) { 13782 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13783 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13784 totag = to + 7; /* skip the keyword */ 13785 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13786 fromtag = to + 9; /* skip the keyword */ 13787 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13788 } 13789 } 13790 13791 if (sipdebug && option_debug > 3) 13792 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>"); 13793 13794 13795 /* Try to find call that we are replacing 13796 If we have a Replaces header, we need to cancel that call if we succeed with this call 13797 */ 13798 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13799 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13800 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13801 error = 1; 13802 } 13803 13804 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13805 13806 /* The matched call is the call from the transferer to Asterisk . 13807 We want to bridge the bridged part of the call to the 13808 incoming invite, thus taking over the refered call */ 13809 13810 if (p->refer->refer_call == p) { 13811 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13812 p->refer->refer_call = NULL; 13813 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13814 error = 1; 13815 } 13816 13817 if (!error && !p->refer->refer_call->owner) { 13818 /* Oops, someting wrong anyway, no owner, no call */ 13819 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13820 /* Check for better return code */ 13821 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13822 error = 1; 13823 } 13824 13825 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 ) { 13826 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13827 transmit_response(p, "603 Declined (Replaces)", req); 13828 error = 1; 13829 } 13830 13831 if (error) { /* Give up this dialog */ 13832 append_history(p, "Xfer", "INVITE/Replace Failed."); 13833 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13834 ast_mutex_unlock(&p->lock); 13835 if (p->refer->refer_call) { 13836 ast_mutex_unlock(&p->refer->refer_call->lock); 13837 ast_channel_unlock(p->refer->refer_call->owner); 13838 } 13839 p->invitestate = INV_COMPLETED; 13840 return -1; 13841 } 13842 } 13843 13844 13845 /* Check if this is an INVITE that sets up a new dialog or 13846 a re-invite in an existing dialog */ 13847 13848 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13849 int newcall = (p->initreq.headers ? TRUE : FALSE); 13850 13851 if (sip_cancel_destroy(p)) 13852 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13853 /* This also counts as a pending invite */ 13854 p->pendinginvite = seqno; 13855 check_via(p, req); 13856 13857 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13858 if (!p->owner) { /* Not a re-invite */ 13859 if (debug) 13860 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13861 if (newcall) 13862 append_history(p, "Invite", "New call: %s", p->callid); 13863 parse_ok_contact(p, req); 13864 } else { /* Re-invite on existing call */ 13865 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13866 /* Handle SDP here if we already have an owner */ 13867 if (find_sdp(req)) { 13868 if (process_sdp(p, req)) { 13869 transmit_response(p, "488 Not acceptable here", req); 13870 if (!p->lastinvite) 13871 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13872 return -1; 13873 } 13874 } else { 13875 p->jointcapability = p->capability; 13876 if (option_debug > 2) 13877 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13878 /* Some devices signal they want to be put off hold by sending a re-invite 13879 *without* an SDP, which is supposed to mean "Go back to your state" 13880 and since they put os on remote hold, we go back to off hold */ 13881 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13882 change_hold_state(p, req, FALSE, 0); 13883 } 13884 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13885 append_history(p, "ReInv", "Re-invite received"); 13886 } 13887 } else if (debug) 13888 ast_verbose("Ignoring this INVITE request\n"); 13889 13890 13891 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13892 /* This is a new invite */ 13893 /* Handle authentication if this is our first invite */ 13894 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13895 if (res == AUTH_CHALLENGE_SENT) { 13896 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13897 return 0; 13898 } 13899 if (res < 0) { /* Something failed in authentication */ 13900 if (res == AUTH_FAKE_AUTH) { 13901 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13902 transmit_fake_auth_response(p, req, 1); 13903 } else { 13904 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13905 transmit_response_reliable(p, "403 Forbidden", req); 13906 } 13907 p->invitestate = INV_COMPLETED; 13908 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13909 ast_string_field_free(p, theirtag); 13910 return 0; 13911 } 13912 13913 /* We have a succesful authentication, process the SDP portion if there is one */ 13914 if (find_sdp(req)) { 13915 if (process_sdp(p, req)) { 13916 /* Unacceptable codecs */ 13917 transmit_response_reliable(p, "488 Not acceptable here", req); 13918 p->invitestate = INV_COMPLETED; 13919 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13920 if (option_debug) 13921 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13922 return -1; 13923 } 13924 } else { /* No SDP in invite, call control session */ 13925 p->jointcapability = p->capability; 13926 if (option_debug > 1) 13927 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13928 } 13929 13930 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13931 /* This seems redundant ... see !p-owner above */ 13932 if (p->owner) 13933 ast_queue_frame(p->owner, &ast_null_frame); 13934 13935 13936 /* Initialize the context if it hasn't been already */ 13937 if (ast_strlen_zero(p->context)) 13938 ast_string_field_set(p, context, default_context); 13939 13940 13941 /* Check number of concurrent calls -vs- incoming limit HERE */ 13942 if (option_debug) 13943 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13944 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13945 if (res < 0) { 13946 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13947 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13948 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13949 p->invitestate = INV_COMPLETED; 13950 } 13951 return 0; 13952 } 13953 gotdest = get_destination(p, NULL); /* Get destination right away */ 13954 get_rdnis(p, NULL); /* Get redirect information */ 13955 extract_uri(p, req); /* Get the Contact URI */ 13956 build_contact(p); /* Build our contact header */ 13957 13958 if (p->rtp) { 13959 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13960 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13961 } 13962 13963 if (!replace_id && gotdest) { /* No matching extension found */ 13964 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13965 transmit_response_reliable(p, "484 Address Incomplete", req); 13966 else { 13967 transmit_response_reliable(p, "404 Not Found", req); 13968 ast_log(LOG_NOTICE, "Call from '%s' to extension" 13969 " '%s' rejected because extension not found.\n", 13970 S_OR(p->username, p->peername), p->exten); 13971 } 13972 p->invitestate = INV_COMPLETED; 13973 update_call_counter(p, DEC_CALL_LIMIT); 13974 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13975 return 0; 13976 } else { 13977 /* If no extension was specified, use the s one */ 13978 /* Basically for calling to IP/Host name only */ 13979 if (ast_strlen_zero(p->exten)) 13980 ast_string_field_set(p, exten, "s"); 13981 /* Initialize our tag */ 13982 13983 make_our_tag(p->tag, sizeof(p->tag)); 13984 /* First invitation - create the channel */ 13985 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13986 *recount = 1; 13987 13988 /* Save Record-Route for any later requests we make on this dialogue */ 13989 build_route(p, req, 0); 13990 13991 if (c) { 13992 /* Pre-lock the call */ 13993 ast_channel_lock(c); 13994 } 13995 } 13996 } else { 13997 if (option_debug > 1 && sipdebug) { 13998 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13999 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14000 else 14001 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14002 } 14003 reinvite = 1; 14004 c = p->owner; 14005 } 14006 14007 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14008 p->lastinvite = seqno; 14009 14010 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14011 /* Go and take over the target call */ 14012 if (sipdebug && option_debug > 3) 14013 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14014 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14015 } 14016 14017 14018 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14019 switch(c->_state) { 14020 case AST_STATE_DOWN: 14021 if (option_debug > 1) 14022 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14023 transmit_response(p, "100 Trying", req); 14024 p->invitestate = INV_PROCEEDING; 14025 ast_setstate(c, AST_STATE_RING); 14026 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14027 enum ast_pbx_result res; 14028 14029 res = ast_pbx_start(c); 14030 14031 switch(res) { 14032 case AST_PBX_FAILED: 14033 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14034 p->invitestate = INV_COMPLETED; 14035 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14036 transmit_response(p, "503 Unavailable", req); 14037 else 14038 transmit_response_reliable(p, "503 Unavailable", req); 14039 break; 14040 case AST_PBX_CALL_LIMIT: 14041 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14042 p->invitestate = INV_COMPLETED; 14043 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14044 transmit_response(p, "480 Temporarily Unavailable", req); 14045 else 14046 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14047 break; 14048 case AST_PBX_SUCCESS: 14049 /* nothing to do */ 14050 break; 14051 } 14052 14053 if (res) { 14054 14055 /* Unlock locks so ast_hangup can do its magic */ 14056 ast_mutex_unlock(&c->lock); 14057 ast_mutex_unlock(&p->lock); 14058 ast_hangup(c); 14059 ast_mutex_lock(&p->lock); 14060 c = NULL; 14061 } 14062 } else { /* Pickup call in call group */ 14063 ast_channel_unlock(c); 14064 *nounlock = 1; 14065 if (ast_pickup_call(c)) { 14066 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14067 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14068 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14069 else 14070 transmit_response_reliable(p, "503 Unavailable", req); 14071 sip_alreadygone(p); 14072 /* Unlock locks so ast_hangup can do its magic */ 14073 ast_mutex_unlock(&p->lock); 14074 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14075 } else { 14076 ast_mutex_unlock(&p->lock); 14077 ast_setstate(c, AST_STATE_DOWN); 14078 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14079 } 14080 p->invitestate = INV_COMPLETED; 14081 ast_hangup(c); 14082 ast_mutex_lock(&p->lock); 14083 c = NULL; 14084 } 14085 break; 14086 case AST_STATE_RING: 14087 transmit_response(p, "100 Trying", req); 14088 p->invitestate = INV_PROCEEDING; 14089 break; 14090 case AST_STATE_RINGING: 14091 transmit_response(p, "180 Ringing", req); 14092 p->invitestate = INV_PROCEEDING; 14093 break; 14094 case AST_STATE_UP: 14095 if (option_debug > 1) 14096 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14097 14098 transmit_response(p, "100 Trying", req); 14099 14100 if (p->t38.state == T38_PEER_REINVITE) { 14101 struct ast_channel *bridgepeer = NULL; 14102 struct sip_pvt *bridgepvt = NULL; 14103 14104 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14105 /* 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*/ 14106 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14107 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14108 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14109 if (bridgepvt->t38.state == T38_DISABLED) { 14110 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14111 /* Send re-invite to the bridged channel */ 14112 sip_handle_t38_reinvite(bridgepeer, p, 1); 14113 } else { /* Something is wrong with peers udptl struct */ 14114 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14115 ast_mutex_lock(&bridgepvt->lock); 14116 bridgepvt->t38.state = T38_DISABLED; 14117 ast_mutex_unlock(&bridgepvt->lock); 14118 if (option_debug > 1) 14119 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14120 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14121 transmit_response(p, "488 Not acceptable here", req); 14122 else 14123 transmit_response_reliable(p, "488 Not acceptable here", req); 14124 14125 } 14126 } else { 14127 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14128 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14129 p->t38.state = T38_ENABLED; 14130 if (option_debug) 14131 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14132 } 14133 } else { 14134 /* Other side is not a SIP channel */ 14135 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14136 transmit_response(p, "488 Not acceptable here", req); 14137 else 14138 transmit_response_reliable(p, "488 Not acceptable here", req); 14139 p->t38.state = T38_DISABLED; 14140 if (option_debug > 1) 14141 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14142 14143 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14144 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14145 } 14146 } else { 14147 /* we are not bridged in a call */ 14148 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14149 p->t38.state = T38_ENABLED; 14150 if (option_debug) 14151 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14152 } 14153 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14154 int sendok = TRUE; 14155 14156 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14157 /* so handle it here (re-invite other party to RTP) */ 14158 struct ast_channel *bridgepeer = NULL; 14159 struct sip_pvt *bridgepvt = NULL; 14160 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14161 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14162 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14163 /* Does the bridged peer have T38 ? */ 14164 if (bridgepvt->t38.state == T38_ENABLED) { 14165 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14166 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14167 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14168 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14169 else 14170 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14171 sendok = FALSE; 14172 } 14173 /* No bridged peer with T38 enabled*/ 14174 } 14175 } 14176 /* Respond to normal re-invite */ 14177 if (sendok) 14178 /* If this is not a re-invite or something to ignore - it's critical */ 14179 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14180 } 14181 p->invitestate = INV_TERMINATED; 14182 break; 14183 default: 14184 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14185 transmit_response(p, "100 Trying", req); 14186 break; 14187 } 14188 } else { 14189 if (p && (p->autokillid == -1)) { 14190 const char *msg; 14191 14192 if (!p->jointcapability) 14193 msg = "488 Not Acceptable Here (codec error)"; 14194 else { 14195 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14196 msg = "503 Unavailable"; 14197 } 14198 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14199 transmit_response(p, msg, req); 14200 else 14201 transmit_response_reliable(p, msg, req); 14202 p->invitestate = INV_COMPLETED; 14203 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14204 } 14205 } 14206 return res; 14207 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14826 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().
14827 { 14828 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14829 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14830 ast_verbose("Receiving message!\n"); 14831 receive_message(p, req); 14832 } else 14833 transmit_response(p, "202 Accepted", req); 14834 return 1; 14835 }
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 13356 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().
13357 { 13358 /* This is mostly a skeleton for future improvements */ 13359 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13360 int res = 0; 13361 const char *event = get_header(req, "Event"); 13362 char *eventid = NULL; 13363 char *sep; 13364 13365 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13366 *sep++ = '\0'; 13367 eventid = sep; 13368 } 13369 13370 if (option_debug > 1 && sipdebug) 13371 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13372 13373 if (strcmp(event, "refer")) { 13374 /* We don't understand this event. */ 13375 /* Here's room to implement incoming voicemail notifications :-) */ 13376 transmit_response(p, "489 Bad event", req); 13377 res = -1; 13378 } else { 13379 /* Save nesting depth for now, since there might be other events we will 13380 support in the future */ 13381 13382 /* Handle REFER notifications */ 13383 13384 char buf[1024]; 13385 char *cmd, *code; 13386 int respcode; 13387 int success = TRUE; 13388 13389 /* EventID for each transfer... EventID is basically the REFER cseq 13390 13391 We are getting notifications on a call that we transfered 13392 We should hangup when we are getting a 200 OK in a sipfrag 13393 Check if we have an owner of this event */ 13394 13395 /* Check the content type */ 13396 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13397 /* We need a sipfrag */ 13398 transmit_response(p, "400 Bad request", req); 13399 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13400 return -1; 13401 } 13402 13403 /* Get the text of the attachment */ 13404 if (get_msg_text(buf, sizeof(buf), req)) { 13405 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13406 transmit_response(p, "400 Bad request", req); 13407 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13408 return -1; 13409 } 13410 13411 /* 13412 From the RFC... 13413 A minimal, but complete, implementation can respond with a single 13414 NOTIFY containing either the body: 13415 SIP/2.0 100 Trying 13416 13417 if the subscription is pending, the body: 13418 SIP/2.0 200 OK 13419 if the reference was successful, the body: 13420 SIP/2.0 503 Service Unavailable 13421 if the reference failed, or the body: 13422 SIP/2.0 603 Declined 13423 13424 if the REFER request was accepted before approval to follow the 13425 reference could be obtained and that approval was subsequently denied 13426 (see Section 2.4.7). 13427 13428 If there are several REFERs in the same dialog, we need to 13429 match the ID of the event header... 13430 */ 13431 if (option_debug > 2) 13432 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13433 cmd = ast_skip_blanks(buf); 13434 code = cmd; 13435 /* We are at SIP/2.0 */ 13436 while(*code && (*code > 32)) { /* Search white space */ 13437 code++; 13438 } 13439 *code++ = '\0'; 13440 code = ast_skip_blanks(code); 13441 sep = code; 13442 sep++; 13443 while(*sep && (*sep > 32)) { /* Search white space */ 13444 sep++; 13445 } 13446 *sep++ = '\0'; /* Response string */ 13447 respcode = atoi(code); 13448 switch (respcode) { 13449 case 100: /* Trying: */ 13450 case 101: /* dialog establishment */ 13451 /* Don't do anything yet */ 13452 break; 13453 case 183: /* Ringing: */ 13454 /* Don't do anything yet */ 13455 break; 13456 case 200: /* OK: The new call is up, hangup this call */ 13457 /* Hangup the call that we are replacing */ 13458 break; 13459 case 301: /* Moved permenantly */ 13460 case 302: /* Moved temporarily */ 13461 /* Do we get the header in the packet in this case? */ 13462 success = FALSE; 13463 break; 13464 case 503: /* Service Unavailable: The new call failed */ 13465 /* Cancel transfer, continue the call */ 13466 success = FALSE; 13467 break; 13468 case 603: /* Declined: Not accepted */ 13469 /* Cancel transfer, continue the current call */ 13470 success = FALSE; 13471 break; 13472 } 13473 if (!success) { 13474 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13475 } 13476 13477 /* Confirm that we received this packet */ 13478 transmit_response(p, "200 OK", req); 13479 }; 13480 13481 if (!p->lastinvite) 13482 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13483 13484 return res; 13485 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13488 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().
13489 { 13490 int res; 13491 13492 res = get_destination(p, req); 13493 build_contact(p); 13494 13495 /* XXX Should we authenticate OPTIONS? XXX */ 13496 13497 if (ast_strlen_zero(p->context)) 13498 ast_string_field_set(p, context, default_context); 13499 13500 if (ast_shutting_down()) 13501 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13502 else if (res < 0) 13503 transmit_response_with_allow(p, "404 Not Found", req, 0); 13504 else 13505 transmit_response_with_allow(p, "200 OK", req, 0); 13506 13507 /* Destroy if this OPTIONS was the opening request, but not if 13508 it's in the middle of a normal call flow. */ 13509 if (!p->lastinvite) 13510 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13511 13512 return res; 13513 }
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 14375 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().
14376 { 14377 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14378 /* Chan2: Call between asterisk and transferee */ 14379 14380 int res = 0; 14381 14382 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14383 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"); 14384 14385 if (!p->owner) { 14386 /* This is a REFER outside of an existing SIP dialog */ 14387 /* We can't handle that, so decline it */ 14388 if (option_debug > 2) 14389 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14390 transmit_response(p, "603 Declined (No dialog)", req); 14391 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14392 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14393 sip_alreadygone(p); 14394 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14395 } 14396 return 0; 14397 } 14398 14399 14400 /* Check if transfer is allowed from this device */ 14401 if (p->allowtransfer == TRANSFER_CLOSED ) { 14402 /* Transfer not allowed, decline */ 14403 transmit_response(p, "603 Declined (policy)", req); 14404 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14405 /* Do not destroy SIP session */ 14406 return 0; 14407 } 14408 14409 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14410 /* Already have a pending REFER */ 14411 transmit_response(p, "491 Request pending", req); 14412 append_history(p, "Xfer", "Refer failed. Request pending."); 14413 return 0; 14414 } 14415 14416 /* Allocate memory for call transfer data */ 14417 if (!p->refer && !sip_refer_allocate(p)) { 14418 transmit_response(p, "500 Internal Server Error", req); 14419 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14420 return -3; 14421 } 14422 14423 res = get_refer_info(p, req); /* Extract headers */ 14424 14425 p->refer->status = REFER_SENT; 14426 14427 if (res != 0) { 14428 switch (res) { 14429 case -2: /* Syntax error */ 14430 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14431 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14432 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14433 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14434 break; 14435 case -3: 14436 transmit_response(p, "603 Declined (Non sip: uri)", req); 14437 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14438 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14439 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14440 break; 14441 default: 14442 /* Refer-to extension not found, fake a failed transfer */ 14443 transmit_response(p, "202 Accepted", req); 14444 append_history(p, "Xfer", "Refer failed. Bad extension."); 14445 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14446 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14447 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14448 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14449 break; 14450 } 14451 return 0; 14452 } 14453 if (ast_strlen_zero(p->context)) 14454 ast_string_field_set(p, context, default_context); 14455 14456 /* If we do not support SIP domains, all transfers are local */ 14457 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14458 p->refer->localtransfer = 1; 14459 if (sipdebug && option_debug > 2) 14460 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14461 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14462 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14463 p->refer->localtransfer = 1; 14464 } else if (sipdebug && option_debug > 2) 14465 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14466 14467 /* Is this a repeat of a current request? Ignore it */ 14468 /* Don't know what else to do right now. */ 14469 if (ignore) 14470 return res; 14471 14472 /* If this is a blind transfer, we have the following 14473 channels to work with: 14474 - chan1, chan2: The current call between transferer and transferee (2 channels) 14475 - target_channel: A new call from the transferee to the target (1 channel) 14476 We need to stay tuned to what happens in order to be able 14477 to bring back the call to the transferer */ 14478 14479 /* If this is a attended transfer, we should have all call legs within reach: 14480 - chan1, chan2: The call between the transferer and transferee (2 channels) 14481 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14482 We want to bridge chan2 with targetcall_pvt! 14483 14484 The replaces call id in the refer message points 14485 to the call leg between Asterisk and the transferer. 14486 So we need to connect the target and the transferee channel 14487 and hangup the two other channels silently 14488 14489 If the target is non-local, the call ID could be on a remote 14490 machine and we need to send an INVITE with replaces to the 14491 target. We basically handle this as a blind transfer 14492 and let the sip_call function catch that we need replaces 14493 header in the INVITE. 14494 */ 14495 14496 14497 /* Get the transferer's channel */ 14498 current.chan1 = p->owner; 14499 14500 /* Find the other part of the bridge (2) - transferee */ 14501 current.chan2 = ast_bridged_channel(current.chan1); 14502 14503 if (sipdebug && option_debug > 2) 14504 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>"); 14505 14506 if (!current.chan2 && !p->refer->attendedtransfer) { 14507 /* No bridged channel, propably IVR or echo or similar... */ 14508 /* Guess we should masquerade or something here */ 14509 /* Until we figure it out, refuse transfer of such calls */ 14510 if (sipdebug && option_debug > 2) 14511 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14512 p->refer->status = REFER_FAILED; 14513 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14514 transmit_response(p, "603 Declined", req); 14515 return -1; 14516 } 14517 14518 if (current.chan2) { 14519 if (sipdebug && option_debug > 3) 14520 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14521 14522 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14523 } 14524 14525 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14526 14527 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14528 if (p->refer->attendedtransfer) { 14529 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14530 return res; /* We're done with the transfer */ 14531 /* Fall through for remote transfers that we did not find locally */ 14532 if (sipdebug && option_debug > 3) 14533 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14534 /* Fallthrough if we can't find the call leg internally */ 14535 } 14536 14537 14538 /* Parking a call */ 14539 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14540 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14541 *nounlock = 1; 14542 ast_channel_unlock(current.chan1); 14543 copy_request(¤t.req, req); 14544 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14545 p->refer->status = REFER_200OK; 14546 append_history(p, "Xfer", "REFER to call parking."); 14547 if (sipdebug && option_debug > 3) 14548 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14549 sip_park(current.chan2, current.chan1, req, seqno); 14550 return res; 14551 } 14552 14553 /* Blind transfers and remote attended xfers */ 14554 transmit_response(p, "202 Accepted", req); 14555 14556 if (current.chan1 && current.chan2) { 14557 if (option_debug > 2) 14558 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14559 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14560 } 14561 if (current.chan2) { 14562 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14563 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14564 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14565 /* One for the new channel */ 14566 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14567 /* Attended transfer to remote host, prepare headers for the INVITE */ 14568 if (p->refer->referred_by) 14569 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14570 } 14571 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14572 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14573 char tempheader[SIPBUFSIZE]; 14574 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14575 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14576 p->refer->replaces_callid_totag, 14577 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14578 p->refer->replaces_callid_fromtag); 14579 if (current.chan2) 14580 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14581 } 14582 /* Must release lock now, because it will not longer 14583 be accessible after the transfer! */ 14584 *nounlock = 1; 14585 ast_channel_unlock(current.chan1); 14586 14587 /* Connect the call */ 14588 14589 /* FAKE ringing if not attended transfer */ 14590 if (!p->refer->attendedtransfer) 14591 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14592 14593 /* For blind transfer, this will lead to a new call */ 14594 /* For attended transfer to remote host, this will lead to 14595 a new SIP call with a replaces header, if the dial plan allows it 14596 */ 14597 if (!current.chan2) { 14598 /* We have no bridge, so we're talking with Asterisk somehow */ 14599 /* We need to masquerade this call */ 14600 /* What to do to fix this situation: 14601 * Set up the new call in a new channel 14602 * Let the new channel masq into this channel 14603 Please add that code here :-) 14604 */ 14605 p->refer->status = REFER_FAILED; 14606 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14607 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14608 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14609 return -1; 14610 } 14611 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14612 14613 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14614 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14615 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14616 14617 if (!res) { 14618 /* Success - we have a new channel */ 14619 if (option_debug > 2) 14620 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14621 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14622 if (p->refer->localtransfer) 14623 p->refer->status = REFER_200OK; 14624 if (p->owner) 14625 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14626 append_history(p, "Xfer", "Refer succeeded."); 14627 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14628 /* Do not hangup call, the other side do that when we say 200 OK */ 14629 /* We could possibly implement a timer here, auto congestion */ 14630 res = 0; 14631 } else { 14632 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14633 if (option_debug > 2) 14634 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14635 append_history(p, "Xfer", "Refer failed."); 14636 /* Failure of some kind */ 14637 p->refer->status = REFER_FAILED; 14638 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14639 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14640 res = -1; 14641 } 14642 return res; 14643 }
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 15134 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().
15135 { 15136 enum check_auth_result res; 15137 15138 /* Use this as the basis */ 15139 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15140 ast_verbose("Using latest REGISTER request as basis request\n"); 15141 copy_request(&p->initreq, req); 15142 check_via(p, req); 15143 if ((res = register_verify(p, sin, req, e)) < 0) { 15144 const char *reason; 15145 15146 switch (res) { 15147 case AUTH_SECRET_FAILED: 15148 reason = "Wrong password"; 15149 break; 15150 case AUTH_USERNAME_MISMATCH: 15151 reason = "Username/auth name mismatch"; 15152 break; 15153 case AUTH_NOT_FOUND: 15154 reason = "No matching peer found"; 15155 break; 15156 case AUTH_UNKNOWN_DOMAIN: 15157 reason = "Not a local domain"; 15158 break; 15159 case AUTH_PEER_NOT_DYNAMIC: 15160 reason = "Peer is not supposed to register"; 15161 break; 15162 case AUTH_ACL_FAILED: 15163 reason = "Device does not match ACL"; 15164 break; 15165 default: 15166 reason = "Unknown failure"; 15167 break; 15168 } 15169 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15170 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15171 reason); 15172 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15173 } else 15174 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15175 15176 if (res < 1) { 15177 /* Destroy the session, but keep us around for just a bit in case they don't 15178 get our 200 OK */ 15179 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15180 } 15181 return res; 15182 }
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 14838 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_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().
14839 { 14840 int gotdest; 14841 int res = 0; 14842 int firststate = AST_EXTENSION_REMOVED; 14843 struct sip_peer *authpeer = NULL; 14844 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14845 const char *accept = get_header(req, "Accept"); 14846 int resubscribe = (p->subscribed != NONE); 14847 char *temp, *event; 14848 14849 if (p->initreq.headers) { 14850 /* We already have a dialog */ 14851 if (p->initreq.method != SIP_SUBSCRIBE) { 14852 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14853 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14854 transmit_response(p, "403 Forbidden (within dialog)", req); 14855 /* Do not destroy session, since we will break the call if we do */ 14856 if (option_debug) 14857 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); 14858 return 0; 14859 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14860 if (option_debug) { 14861 if (resubscribe) 14862 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14863 else 14864 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14865 } 14866 } 14867 } 14868 14869 /* Check if we have a global disallow setting on subscriptions. 14870 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14871 */ 14872 if (!global_allowsubscribe) { 14873 transmit_response(p, "403 Forbidden (policy)", req); 14874 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14875 return 0; 14876 } 14877 14878 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14879 const char *to = get_header(req, "To"); 14880 char totag[128]; 14881 14882 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 14883 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 14884 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14885 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 14886 transmit_response(p, "481 Subscription does not exist", req); 14887 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14888 return 0; 14889 } 14890 14891 /* Use this as the basis */ 14892 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14893 ast_verbose("Creating new subscription\n"); 14894 14895 copy_request(&p->initreq, req); 14896 check_via(p, req); 14897 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14898 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14899 14900 /* Find parameters to Event: header value and remove them for now */ 14901 if (ast_strlen_zero(eventheader)) { 14902 transmit_response(p, "489 Bad Event", req); 14903 if (option_debug > 1) 14904 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14905 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14906 return 0; 14907 } 14908 14909 if ( (strchr(eventheader, ';'))) { 14910 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14911 temp = strchr(event, ';'); 14912 *temp = '\0'; /* Remove any options for now */ 14913 /* We might need to use them later :-) */ 14914 } else 14915 event = (char *) eventheader; /* XXX is this legal ? */ 14916 14917 /* Handle authentication */ 14918 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14919 /* if an authentication response was sent, we are done here */ 14920 if (res == AUTH_CHALLENGE_SENT) { 14921 if (authpeer) 14922 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14923 return 0; 14924 } 14925 if (res < 0) { 14926 if (res == AUTH_FAKE_AUTH) { 14927 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14928 transmit_fake_auth_response(p, req, 1); 14929 } else { 14930 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14931 transmit_response_reliable(p, "403 Forbidden", req); 14932 } 14933 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14934 if (authpeer) 14935 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14936 return 0; 14937 } 14938 14939 /* Check if this user/peer is allowed to subscribe at all */ 14940 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14941 transmit_response(p, "403 Forbidden (policy)", req); 14942 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14943 if (authpeer) 14944 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14945 return 0; 14946 } 14947 14948 /* Get destination right away */ 14949 gotdest = get_destination(p, NULL); 14950 14951 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14952 parse_ok_contact(p, req); 14953 14954 build_contact(p); 14955 if (strcmp(event, "message-summary") && gotdest) { 14956 transmit_response(p, "404 Not Found", req); 14957 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14958 if (authpeer) 14959 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14960 return 0; 14961 } 14962 14963 /* Initialize tag for new subscriptions */ 14964 if (ast_strlen_zero(p->tag)) 14965 make_our_tag(p->tag, sizeof(p->tag)); 14966 14967 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14968 if (authpeer) /* No need for authpeer here */ 14969 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14970 14971 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14972 /* Polycom phones only handle xpidf+xml, even if they say they can 14973 handle pidf+xml as well 14974 */ 14975 if (strstr(p->useragent, "Polycom")) { 14976 p->subscribed = XPIDF_XML; 14977 } else if (strstr(accept, "application/pidf+xml")) { 14978 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14979 } else if (strstr(accept, "application/dialog-info+xml")) { 14980 p->subscribed = DIALOG_INFO_XML; 14981 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14982 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14983 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14984 } else if (strstr(accept, "application/xpidf+xml")) { 14985 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14986 } else if (ast_strlen_zero(accept)) { 14987 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14988 transmit_response(p, "489 Bad Event", req); 14989 14990 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14991 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14992 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14993 return 0; 14994 } 14995 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14996 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14997 } else { 14998 /* Can't find a format for events that we know about */ 14999 char mybuf[200]; 15000 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15001 transmit_response(p, mybuf, req); 15002 15003 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15004 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15005 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15006 return 0; 15007 } 15008 } else if (!strcmp(event, "message-summary")) { 15009 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15010 /* Format requested that we do not support */ 15011 transmit_response(p, "406 Not Acceptable", req); 15012 if (option_debug > 1) 15013 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15014 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15015 if (authpeer) /* No need for authpeer here */ 15016 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15017 return 0; 15018 } 15019 /* Looks like they actually want a mailbox status 15020 This version of Asterisk supports mailbox subscriptions 15021 The subscribed URI needs to exist in the dial plan 15022 In most devices, this is configurable to the voicemailmain extension you use 15023 */ 15024 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15025 transmit_response(p, "404 Not found (no mailbox)", req); 15026 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15027 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15028 if (authpeer) /* No need for authpeer here */ 15029 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15030 return 0; 15031 } 15032 15033 p->subscribed = MWI_NOTIFICATION; 15034 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15035 /* We only allow one subscription per peer */ 15036 sip_destroy(authpeer->mwipvt); 15037 authpeer->mwipvt = p; /* Link from peer to pvt */ 15038 p->relatedpeer = authpeer; /* Link from pvt to peer */ 15039 } else { /* At this point, Asterisk does not understand the specified event */ 15040 transmit_response(p, "489 Bad Event", req); 15041 if (option_debug > 1) 15042 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15043 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15044 if (authpeer) /* No need for authpeer here */ 15045 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15046 return 0; 15047 } 15048 15049 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15050 if (p->stateid > -1) 15051 ast_extension_state_del(p->stateid, cb_extensionstate); 15052 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15053 } 15054 15055 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15056 p->lastinvite = seqno; 15057 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15058 p->expiry = atoi(get_header(req, "Expires")); 15059 15060 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15061 if (p->expiry > max_expiry) 15062 p->expiry = max_expiry; 15063 if (p->expiry < min_expiry && p->expiry > 0) 15064 p->expiry = min_expiry; 15065 15066 if (sipdebug || option_debug > 1) { 15067 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15068 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15069 else 15070 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15071 } 15072 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15073 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15074 if (p->expiry > 0) 15075 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15076 15077 if (p->subscribed == MWI_NOTIFICATION) { 15078 transmit_response(p, "200 OK", req); 15079 if (p->relatedpeer) { /* Send first notification */ 15080 ASTOBJ_WRLOCK(p->relatedpeer); 15081 sip_send_mwi_to_peer(p->relatedpeer); 15082 ASTOBJ_UNLOCK(p->relatedpeer); 15083 } 15084 } else { 15085 struct sip_pvt *p_old; 15086 15087 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15088 15089 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)); 15090 transmit_response(p, "404 Not found", req); 15091 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15092 return 0; 15093 } 15094 15095 transmit_response(p, "200 OK", req); 15096 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15097 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15098 /* hide the 'complete' exten/context in the refer_to field for later display */ 15099 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15100 15101 /* remove any old subscription from this peer for the same exten/context, 15102 as the peer has obviously forgotten about it and it's wasteful to wait 15103 for it to expire and send NOTIFY messages to the peer only to have them 15104 ignored (or generate errors) 15105 */ 15106 ast_mutex_lock(&iflock); 15107 for (p_old = iflist; p_old; p_old = p_old->next) { 15108 if (p_old == p) 15109 continue; 15110 if (p_old->initreq.method != SIP_SUBSCRIBE) 15111 continue; 15112 if (p_old->subscribed == NONE) 15113 continue; 15114 ast_mutex_lock(&p_old->lock); 15115 if (!strcmp(p_old->username, p->username)) { 15116 if (!strcmp(p_old->exten, p->exten) && 15117 !strcmp(p_old->context, p->context)) { 15118 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15119 ast_mutex_unlock(&p_old->lock); 15120 break; 15121 } 15122 } 15123 ast_mutex_unlock(&p_old->lock); 15124 } 15125 ast_mutex_unlock(&iflock); 15126 } 15127 if (!p->expiry) 15128 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15129 } 15130 return 1; 15131 }
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 12646 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, 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.
12647 { 12648 struct ast_channel *owner; 12649 int sipmethod; 12650 int res = 1; 12651 const char *c = get_header(req, "Cseq"); 12652 const char *msg = strchr(c, ' '); 12653 12654 if (!msg) 12655 msg = ""; 12656 else 12657 msg++; 12658 sipmethod = find_sip_method(msg); 12659 12660 owner = p->owner; 12661 if (owner) 12662 owner->hangupcause = hangup_sip2cause(resp); 12663 12664 /* Acknowledge whatever it is destined for */ 12665 if ((resp >= 100) && (resp <= 199)) 12666 __sip_semi_ack(p, seqno, 0, sipmethod); 12667 else 12668 __sip_ack(p, seqno, 0, sipmethod); 12669 12670 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12671 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12672 p->pendinginvite = 0; 12673 12674 /* Get their tag if we haven't already */ 12675 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12676 char tag[128]; 12677 12678 gettag(req, "To", tag, sizeof(tag)); 12679 ast_string_field_set(p, theirtag, tag); 12680 } 12681 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12682 /* We don't really care what the response is, just that it replied back. 12683 Well, as long as it's not a 100 response... since we might 12684 need to hang around for something more "definitive" */ 12685 if (resp != 100) 12686 handle_response_peerpoke(p, resp, req); 12687 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12688 switch(resp) { 12689 case 100: /* 100 Trying */ 12690 case 101: /* 101 Dialog establishment */ 12691 if (sipmethod == SIP_INVITE) 12692 handle_response_invite(p, resp, rest, req, seqno); 12693 break; 12694 case 183: /* 183 Session Progress */ 12695 if (sipmethod == SIP_INVITE) 12696 handle_response_invite(p, resp, rest, req, seqno); 12697 break; 12698 case 180: /* 180 Ringing */ 12699 if (sipmethod == SIP_INVITE) 12700 handle_response_invite(p, resp, rest, req, seqno); 12701 break; 12702 case 182: /* 182 Queued */ 12703 if (sipmethod == SIP_INVITE) 12704 handle_response_invite(p, resp, rest, req, seqno); 12705 break; 12706 case 200: /* 200 OK */ 12707 p->authtries = 0; /* Reset authentication counter */ 12708 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12709 /* We successfully transmitted a message 12710 or a video update request in INFO */ 12711 /* Nothing happens here - the message is inside a dialog */ 12712 } else if (sipmethod == SIP_INVITE) { 12713 handle_response_invite(p, resp, rest, req, seqno); 12714 } else if (sipmethod == SIP_NOTIFY) { 12715 /* They got the notify, this is the end */ 12716 if (p->owner) { 12717 if (!p->refer) { 12718 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12719 ast_queue_hangup(p->owner); 12720 } else if (option_debug > 3) 12721 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12722 } else { 12723 if (p->subscribed == NONE) 12724 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12725 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12726 /* Ready to send the next state we have on queue */ 12727 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12728 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 12729 } 12730 } 12731 } else if (sipmethod == SIP_REGISTER) 12732 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12733 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12734 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12735 break; 12736 case 202: /* Transfer accepted */ 12737 if (sipmethod == SIP_REFER) 12738 handle_response_refer(p, resp, rest, req, seqno); 12739 break; 12740 case 401: /* Not www-authorized on SIP method */ 12741 if (sipmethod == SIP_INVITE) 12742 handle_response_invite(p, resp, rest, req, seqno); 12743 else if (sipmethod == SIP_REFER) 12744 handle_response_refer(p, resp, rest, req, seqno); 12745 else if (p->registry && sipmethod == SIP_REGISTER) 12746 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12747 else if (sipmethod == SIP_BYE) { 12748 if (ast_strlen_zero(p->authname)) { 12749 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12750 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12751 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12752 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12753 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12754 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12755 /* We fail to auth bye on our own call, but still needs to tear down the call. 12756 Life, they call it. */ 12757 } 12758 } else { 12759 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12760 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12761 } 12762 break; 12763 case 403: /* Forbidden - we failed authentication */ 12764 if (sipmethod == SIP_INVITE) 12765 handle_response_invite(p, resp, rest, req, seqno); 12766 else if (p->registry && sipmethod == SIP_REGISTER) 12767 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12768 else { 12769 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12770 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12771 } 12772 break; 12773 case 404: /* Not found */ 12774 if (p->registry && sipmethod == SIP_REGISTER) 12775 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12776 else if (sipmethod == SIP_INVITE) 12777 handle_response_invite(p, resp, rest, req, seqno); 12778 else if (owner) 12779 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12780 break; 12781 case 407: /* Proxy auth required */ 12782 if (sipmethod == SIP_INVITE) 12783 handle_response_invite(p, resp, rest, req, seqno); 12784 else if (sipmethod == SIP_REFER) 12785 handle_response_refer(p, resp, rest, req, seqno); 12786 else if (p->registry && sipmethod == SIP_REGISTER) 12787 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12788 else if (sipmethod == SIP_BYE) { 12789 if (ast_strlen_zero(p->authname)) { 12790 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12791 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12792 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12793 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12794 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12795 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12796 } 12797 } else /* We can't handle this, giving up in a bad way */ 12798 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12799 12800 break; 12801 case 408: /* Request timeout - terminate dialog */ 12802 if (sipmethod == SIP_INVITE) 12803 handle_response_invite(p, resp, rest, req, seqno); 12804 else if (sipmethod == SIP_REGISTER) 12805 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12806 else if (sipmethod == SIP_BYE) { 12807 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12808 if (option_debug) 12809 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12810 } else { 12811 if (owner) 12812 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12813 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12814 } 12815 break; 12816 case 481: /* Call leg does not exist */ 12817 if (sipmethod == SIP_INVITE) { 12818 handle_response_invite(p, resp, rest, req, seqno); 12819 } else if (sipmethod == SIP_REFER) { 12820 handle_response_refer(p, resp, rest, req, seqno); 12821 } else if (sipmethod == SIP_BYE) { 12822 /* The other side has no transaction to bye, 12823 just assume it's all right then */ 12824 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12825 } else if (sipmethod == SIP_CANCEL) { 12826 /* The other side has no transaction to cancel, 12827 just assume it's all right then */ 12828 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12829 } else { 12830 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12831 /* Guessing that this is not an important request */ 12832 } 12833 break; 12834 case 487: 12835 if (sipmethod == SIP_INVITE) 12836 handle_response_invite(p, resp, rest, req, seqno); 12837 break; 12838 case 488: /* Not acceptable here - codec error */ 12839 if (sipmethod == SIP_INVITE) 12840 handle_response_invite(p, resp, rest, req, seqno); 12841 break; 12842 case 491: /* Pending */ 12843 if (sipmethod == SIP_INVITE) 12844 handle_response_invite(p, resp, rest, req, seqno); 12845 else { 12846 if (option_debug) 12847 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12848 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12849 } 12850 break; 12851 case 501: /* Not Implemented */ 12852 if (sipmethod == SIP_INVITE) 12853 handle_response_invite(p, resp, rest, req, seqno); 12854 else if (sipmethod == SIP_REFER) 12855 handle_response_refer(p, resp, rest, req, seqno); 12856 else 12857 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12858 break; 12859 case 603: /* Declined transfer */ 12860 if (sipmethod == SIP_REFER) { 12861 handle_response_refer(p, resp, rest, req, seqno); 12862 break; 12863 } 12864 /* Fallthrough */ 12865 default: 12866 if ((resp >= 300) && (resp < 700)) { 12867 /* Fatal response */ 12868 if ((option_verbose > 2) && (resp != 487)) 12869 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12870 12871 if (sipmethod == SIP_INVITE) 12872 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12873 12874 /* XXX Locking issues?? XXX */ 12875 switch(resp) { 12876 case 300: /* Multiple Choices */ 12877 case 301: /* Moved permenantly */ 12878 case 302: /* Moved temporarily */ 12879 case 305: /* Use Proxy */ 12880 parse_moved_contact(p, req); 12881 /* Fall through */ 12882 case 486: /* Busy here */ 12883 case 600: /* Busy everywhere */ 12884 case 603: /* Decline */ 12885 if (p->owner) 12886 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12887 break; 12888 case 482: /* 12889 \note SIP is incapable of performing a hairpin call, which 12890 is yet another failure of not having a layer 2 (again, YAY 12891 IETF for thinking ahead). So we treat this as a call 12892 forward and hope we end up at the right place... */ 12893 if (option_debug) 12894 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12895 if (p->owner) 12896 ast_string_field_build(p->owner, call_forward, 12897 "Local/%s@%s", p->username, p->context); 12898 /* Fall through */ 12899 case 480: /* Temporarily Unavailable */ 12900 case 404: /* Not Found */ 12901 case 410: /* Gone */ 12902 case 400: /* Bad Request */ 12903 case 500: /* Server error */ 12904 if (sipmethod == SIP_REFER) { 12905 handle_response_refer(p, resp, rest, req, seqno); 12906 break; 12907 } 12908 /* Fall through */ 12909 case 503: /* Service Unavailable */ 12910 case 504: /* Server Timeout */ 12911 if (owner) 12912 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12913 break; 12914 default: 12915 /* Send hangup */ 12916 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12917 ast_queue_hangup(p->owner); 12918 break; 12919 } 12920 /* ACK on invite */ 12921 if (sipmethod == SIP_INVITE) 12922 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12923 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12924 sip_alreadygone(p); 12925 if (!p->owner) 12926 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12927 } else if ((resp >= 100) && (resp < 200)) { 12928 if (sipmethod == SIP_INVITE) { 12929 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 12930 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12931 if (find_sdp(req)) 12932 process_sdp(p, req); 12933 if (p->owner) { 12934 /* Queue a progress frame */ 12935 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12936 } 12937 } 12938 } else 12939 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)); 12940 } 12941 } else { 12942 /* Responses to OUTGOING SIP requests on INCOMING calls 12943 get handled here. As well as out-of-call message responses */ 12944 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12945 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12946 12947 if (sipmethod == SIP_INVITE && resp == 200) { 12948 /* Tags in early session is replaced by the tag in 200 OK, which is 12949 the final reply to our INVITE */ 12950 char tag[128]; 12951 12952 gettag(req, "To", tag, sizeof(tag)); 12953 ast_string_field_set(p, theirtag, tag); 12954 } 12955 12956 switch(resp) { 12957 case 200: 12958 if (sipmethod == SIP_INVITE) { 12959 handle_response_invite(p, resp, rest, req, seqno); 12960 } else if (sipmethod == SIP_CANCEL) { 12961 if (option_debug) 12962 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12963 12964 /* Wait for 487, then destroy */ 12965 } else if (sipmethod == SIP_NOTIFY) { 12966 /* They got the notify, this is the end */ 12967 if (p->owner) { 12968 if (p->refer) { 12969 if (option_debug) 12970 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12971 } else 12972 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12973 /* ast_queue_hangup(p->owner); Disabled */ 12974 } else { 12975 if (!p->subscribed && !p->refer) 12976 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12977 } 12978 } else if (sipmethod == SIP_BYE) 12979 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12980 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12981 /* We successfully transmitted a message or 12982 a video update request in INFO */ 12983 ; 12984 else if (sipmethod == SIP_BYE) 12985 /* Ok, we're ready to go */ 12986 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12987 break; 12988 case 202: /* Transfer accepted */ 12989 if (sipmethod == SIP_REFER) 12990 handle_response_refer(p, resp, rest, req, seqno); 12991 break; 12992 case 401: /* www-auth */ 12993 case 407: 12994 if (sipmethod == SIP_REFER) 12995 handle_response_refer(p, resp, rest, req, seqno); 12996 else if (sipmethod == SIP_INVITE) 12997 handle_response_invite(p, resp, rest, req, seqno); 12998 else if (sipmethod == SIP_BYE) { 12999 char *auth, *auth2; 13000 13001 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13002 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13003 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13004 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13005 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13006 } 13007 } 13008 break; 13009 case 481: /* Call leg does not exist */ 13010 if (sipmethod == SIP_INVITE) { 13011 /* Re-invite failed */ 13012 handle_response_invite(p, resp, rest, req, seqno); 13013 } else if (sipmethod == SIP_BYE) { 13014 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13015 } else if (sipdebug) { 13016 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13017 } 13018 break; 13019 case 501: /* Not Implemented */ 13020 if (sipmethod == SIP_INVITE) 13021 handle_response_invite(p, resp, rest, req, seqno); 13022 else if (sipmethod == SIP_REFER) 13023 handle_response_refer(p, resp, rest, req, seqno); 13024 break; 13025 case 603: /* Declined transfer */ 13026 if (sipmethod == SIP_REFER) { 13027 handle_response_refer(p, resp, rest, req, seqno); 13028 break; 13029 } 13030 /* Fallthrough */ 13031 default: /* Errors without handlers */ 13032 if ((resp >= 100) && (resp < 200)) { 13033 if (sipmethod == SIP_INVITE) { /* re-invite */ 13034 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13035 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13036 } 13037 } 13038 if ((resp >= 300) && (resp < 700)) { 13039 if ((option_verbose > 2) && (resp != 487)) 13040 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)); 13041 switch(resp) { 13042 case 488: /* Not acceptable here - codec error */ 13043 case 603: /* Decline */ 13044 case 500: /* Server error */ 13045 case 503: /* Service Unavailable */ 13046 case 504: /* Server timeout */ 13047 13048 /* re-invite failed */ 13049 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13050 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13051 break; 13052 } 13053 } 13054 break; 13055 } 13056 } 13057 }
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 12066 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().
12067 { 12068 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12069 int res = 0; 12070 int xmitres = 0; 12071 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12072 struct ast_channel *bridgepeer = NULL; 12073 12074 if (option_debug > 3) { 12075 if (reinvite) 12076 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12077 else 12078 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12079 } 12080 12081 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12082 if (option_debug) 12083 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12084 return; 12085 } 12086 12087 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12088 /* Don't auto congest anymore since we've gotten something useful back */ 12089 AST_SCHED_DEL(sched, p->initid); 12090 12091 /* RFC3261 says we must treat every 1xx response (but not 100) 12092 that we don't recognize as if it was 183. 12093 */ 12094 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12095 resp = 183; 12096 12097 /* Any response between 100 and 199 is PROCEEDING */ 12098 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12099 p->invitestate = INV_PROCEEDING; 12100 12101 /* Final response, not 200 ? */ 12102 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12103 p->invitestate = INV_COMPLETED; 12104 12105 12106 switch (resp) { 12107 case 100: /* Trying */ 12108 case 101: /* Dialog establishment */ 12109 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12110 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12111 check_pendings(p); 12112 break; 12113 12114 case 180: /* 180 Ringing */ 12115 case 182: /* 182 Queued */ 12116 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12117 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12118 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12119 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12120 if (p->owner->_state != AST_STATE_UP) { 12121 ast_setstate(p->owner, AST_STATE_RINGING); 12122 } 12123 } 12124 if (find_sdp(req)) { 12125 if (p->invitestate != INV_CANCELLED) 12126 p->invitestate = INV_EARLY_MEDIA; 12127 res = process_sdp(p, req); 12128 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12129 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12130 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12131 } 12132 } 12133 check_pendings(p); 12134 break; 12135 12136 case 183: /* Session progress */ 12137 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12138 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12139 /* Ignore 183 Session progress without SDP */ 12140 if (find_sdp(req)) { 12141 if (p->invitestate != INV_CANCELLED) 12142 p->invitestate = INV_EARLY_MEDIA; 12143 res = process_sdp(p, req); 12144 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12145 /* Queue a progress frame */ 12146 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12147 } 12148 } 12149 check_pendings(p); 12150 break; 12151 12152 case 200: /* 200 OK on invite - someone's answering our call */ 12153 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12154 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12155 p->authtries = 0; 12156 if (find_sdp(req)) { 12157 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12158 if (!reinvite) 12159 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12160 /* For re-invites, we try to recover */ 12161 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12162 } 12163 12164 /* Parse contact header for continued conversation */ 12165 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12166 /* This is important when we have a SIP proxy between us and the phone */ 12167 if (outgoing) { 12168 update_call_counter(p, DEC_CALL_RINGING); 12169 parse_ok_contact(p, req); 12170 if(set_address_from_contact(p)) { 12171 /* Bad contact - we don't know how to reach this device */ 12172 /* We need to ACK, but then send a bye */ 12173 /* OEJ: Possible issue that may need a check: 12174 If we have a proxy route between us and the device, 12175 should we care about resolving the contact 12176 or should we just send it? 12177 */ 12178 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12179 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12180 } 12181 12182 /* Save Record-Route for any later requests we make on this dialogue */ 12183 if (!reinvite) 12184 build_route(p, req, 1); 12185 } 12186 12187 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12188 struct sip_pvt *bridgepvt = NULL; 12189 12190 if (!bridgepeer->tech) { 12191 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12192 break; 12193 } 12194 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12195 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12196 if (bridgepvt->udptl) { 12197 if (p->t38.state == T38_PEER_REINVITE) { 12198 sip_handle_t38_reinvite(bridgepeer, p, 0); 12199 ast_rtp_set_rtptimers_onhold(p->rtp); 12200 if (p->vrtp) 12201 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12202 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12203 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12204 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12205 /* XXXX Should we really destroy this session here, without any response at all??? */ 12206 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12207 } 12208 } else { 12209 if (option_debug > 1) 12210 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12211 ast_mutex_lock(&bridgepvt->lock); 12212 bridgepvt->t38.state = T38_DISABLED; 12213 ast_mutex_unlock(&bridgepvt->lock); 12214 if (option_debug) 12215 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12216 p->t38.state = T38_DISABLED; 12217 if (option_debug > 1) 12218 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12219 } 12220 } else { 12221 /* Other side is not a SIP channel */ 12222 if (option_debug > 1) 12223 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12224 p->t38.state = T38_DISABLED; 12225 if (option_debug > 1) 12226 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12227 } 12228 } 12229 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12230 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12231 p->t38.state = T38_ENABLED; 12232 if (option_debug) 12233 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12234 } 12235 12236 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12237 if (!reinvite) { 12238 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12239 } else { /* RE-invite */ 12240 ast_queue_frame(p->owner, &ast_null_frame); 12241 } 12242 } else { 12243 /* It's possible we're getting an 200 OK after we've tried to disconnect 12244 by sending CANCEL */ 12245 /* First send ACK, then send bye */ 12246 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12247 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12248 } 12249 /* If I understand this right, the branch is different for a non-200 ACK only */ 12250 p->invitestate = INV_TERMINATED; 12251 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12252 check_pendings(p); 12253 break; 12254 case 407: /* Proxy authentication */ 12255 case 401: /* Www auth */ 12256 /* First we ACK */ 12257 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12258 if (p->options) 12259 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12260 12261 /* Then we AUTH */ 12262 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12263 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12264 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12265 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12266 if (p->authtries < MAX_AUTHTRIES) 12267 p->invitestate = INV_CALLING; 12268 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12269 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12270 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12271 sip_alreadygone(p); 12272 if (p->owner) 12273 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12274 } 12275 } 12276 break; 12277 12278 case 403: /* Forbidden */ 12279 /* First we ACK */ 12280 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12281 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12282 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12283 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12284 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12285 sip_alreadygone(p); 12286 break; 12287 12288 case 404: /* Not found */ 12289 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12290 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12291 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12292 sip_alreadygone(p); 12293 break; 12294 12295 case 408: /* Request timeout */ 12296 case 481: /* Call leg does not exist */ 12297 /* Could be REFER caused INVITE with replaces */ 12298 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12299 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12300 if (p->owner) 12301 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12302 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12303 break; 12304 case 487: /* Cancelled transaction */ 12305 /* We have sent CANCEL on an outbound INVITE 12306 This transaction is already scheduled to be killed by sip_hangup(). 12307 */ 12308 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12309 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12310 ast_queue_hangup(p->owner); 12311 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12312 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12313 update_call_counter(p, DEC_CALL_LIMIT); 12314 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12315 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12316 sip_alreadygone(p); 12317 } 12318 break; 12319 case 488: /* Not acceptable here */ 12320 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12321 if (reinvite && p->udptl) { 12322 /* If this is a T.38 call, we should go back to 12323 audio. If this is an audio call - something went 12324 terribly wrong since we don't renegotiate codecs, 12325 only IP/port . 12326 */ 12327 p->t38.state = T38_DISABLED; 12328 /* Try to reset RTP timers */ 12329 ast_rtp_set_rtptimers_onhold(p->rtp); 12330 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12331 12332 /*! \bug Is there any way we can go back to the audio call on both 12333 sides here? 12334 */ 12335 /* While figuring that out, hangup the call */ 12336 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12337 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12338 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12339 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12340 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12341 right now we can't fall back to audio so totally abort. 12342 */ 12343 p->t38.state = T38_DISABLED; 12344 /* Try to reset RTP timers */ 12345 ast_rtp_set_rtptimers_onhold(p->rtp); 12346 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12347 12348 /* The dialog is now terminated */ 12349 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12350 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12351 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12352 sip_alreadygone(p); 12353 } else { 12354 /* We can't set up this call, so give up */ 12355 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12356 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12357 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12358 } 12359 break; 12360 case 491: /* Pending */ 12361 /* we really should have to wait a while, then retransmit 12362 * We should support the retry-after at some point 12363 * At this point, we treat this as a congestion if the call is not in UP state 12364 */ 12365 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12366 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12367 if (p->owner->_state != AST_STATE_UP) { 12368 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12369 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12370 } else { 12371 /* This is a re-invite that failed. 12372 * Reset the flag after a while 12373 */ 12374 int wait = 3 + ast_random() % 5; 12375 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12376 if (option_debug > 2) 12377 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12378 } 12379 } 12380 break; 12381 12382 case 501: /* Not implemented */ 12383 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12384 if (p->owner) 12385 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12386 break; 12387 } 12388 if (xmitres == XMIT_ERROR) 12389 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12390 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12587 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, 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_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12588 { 12589 struct sip_peer *peer = p->relatedpeer; 12590 int statechanged, is_reachable, was_reachable; 12591 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12592 12593 /* 12594 * Compute the response time to a ping (goes in peer->lastms.) 12595 * -1 means did not respond, 0 means unknown, 12596 * 1..maxms is a valid response, >maxms means late response. 12597 */ 12598 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12599 pingtime = 1; 12600 12601 /* Now determine new state and whether it has changed. 12602 * Use some helper variables to simplify the writing 12603 * of the expressions. 12604 */ 12605 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12606 is_reachable = pingtime <= peer->maxms; 12607 statechanged = peer->lastms == 0 /* yes, unknown before */ 12608 || was_reachable != is_reachable; 12609 12610 peer->lastms = pingtime; 12611 peer->call = NULL; 12612 if (statechanged) { 12613 const char *s = is_reachable ? "Reachable" : "Lagged"; 12614 12615 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12616 peer->name, s, pingtime, peer->maxms); 12617 ast_device_state_changed("SIP/%s", peer->name); 12618 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12619 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12620 peer->name, s, pingtime); 12621 } 12622 12623 AST_SCHED_DEL(sched, peer->pokeexpire); 12624 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12625 12626 /* Try again eventually */ 12627 peer->pokeexpire = ast_sched_add(sched, 12628 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12629 sip_poke_peer_s, peer); 12630 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12395 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().
12396 { 12397 char *auth = "Proxy-Authenticate"; 12398 char *auth2 = "Proxy-Authorization"; 12399 12400 /* If no refer structure exists, then do nothing */ 12401 if (!p->refer) 12402 return; 12403 12404 switch (resp) { 12405 case 202: /* Transfer accepted */ 12406 /* We need to do something here */ 12407 /* The transferee is now sending INVITE to target */ 12408 p->refer->status = REFER_ACCEPTED; 12409 /* Now wait for next message */ 12410 if (option_debug > 2) 12411 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12412 /* We should hang along, waiting for NOTIFY's here */ 12413 break; 12414 12415 case 401: /* Not www-authorized on SIP method */ 12416 case 407: /* Proxy auth */ 12417 if (ast_strlen_zero(p->authname)) { 12418 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12419 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12420 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12421 } 12422 if (resp == 401) { 12423 auth = "WWW-Authenticate"; 12424 auth2 = "Authorization"; 12425 } 12426 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12427 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12428 p->refer->status = REFER_NOAUTH; 12429 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12430 } 12431 break; 12432 case 481: /* Call leg does not exist */ 12433 12434 /* A transfer with Replaces did not work */ 12435 /* OEJ: We should Set flag, cancel the REFER, go back 12436 to original call - but right now we can't */ 12437 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12438 if (p->owner) 12439 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12440 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12441 break; 12442 12443 case 500: /* Server error */ 12444 case 501: /* Method not implemented */ 12445 /* Return to the current call onhold */ 12446 /* Status flag needed to be reset */ 12447 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12448 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12449 p->refer->status = REFER_FAILED; 12450 break; 12451 case 603: /* Transfer declined */ 12452 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12453 p->refer->status = REFER_FAILED; 12454 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12455 break; 12456 } 12457 }
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 12460 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().
12461 { 12462 int expires, expires_ms; 12463 struct sip_registry *r; 12464 r=p->registry; 12465 12466 switch (resp) { 12467 case 401: /* Unauthorized */ 12468 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12469 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12470 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12471 } 12472 break; 12473 case 403: /* Forbidden */ 12474 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12475 if (global_regattempts_max) 12476 p->registry->regattempts = global_regattempts_max+1; 12477 AST_SCHED_DEL(sched, r->timeout); 12478 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12479 break; 12480 case 404: /* Not found */ 12481 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12482 if (global_regattempts_max) 12483 p->registry->regattempts = global_regattempts_max+1; 12484 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12485 r->call = NULL; 12486 AST_SCHED_DEL(sched, r->timeout); 12487 break; 12488 case 407: /* Proxy auth */ 12489 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12490 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12491 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12492 } 12493 break; 12494 case 408: /* Request timeout */ 12495 if (global_regattempts_max) 12496 p->registry->regattempts = global_regattempts_max+1; 12497 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12498 r->call = NULL; 12499 AST_SCHED_DEL(sched, r->timeout); 12500 break; 12501 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12502 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12503 if (global_regattempts_max) 12504 p->registry->regattempts = global_regattempts_max+1; 12505 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12506 r->call = NULL; 12507 AST_SCHED_DEL(sched, r->timeout); 12508 break; 12509 case 200: /* 200 OK */ 12510 if (!r) { 12511 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12512 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12513 return 0; 12514 } 12515 12516 r->regstate = REG_STATE_REGISTERED; 12517 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12518 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12519 r->regattempts = 0; 12520 if (option_debug) 12521 ast_log(LOG_DEBUG, "Registration successful\n"); 12522 if (r->timeout > -1) { 12523 if (option_debug) 12524 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12525 } 12526 AST_SCHED_DEL(sched, r->timeout); 12527 r->call = NULL; 12528 p->registry = NULL; 12529 /* Let this one hang around until we have all the responses */ 12530 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12531 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12532 12533 /* set us up for re-registering */ 12534 /* figure out how long we got registered for */ 12535 AST_SCHED_DEL(sched, r->expire); 12536 /* according to section 6.13 of RFC, contact headers override 12537 expires headers, so check those first */ 12538 expires = 0; 12539 12540 /* XXX todo: try to save the extra call */ 12541 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12542 const char *contact = NULL; 12543 const char *tmptmp = NULL; 12544 int start = 0; 12545 for(;;) { 12546 contact = __get_header(req, "Contact", &start); 12547 /* this loop ensures we get a contact header about our register request */ 12548 if(!ast_strlen_zero(contact)) { 12549 if( (tmptmp=strstr(contact, p->our_contact))) { 12550 contact=tmptmp; 12551 break; 12552 } 12553 } else 12554 break; 12555 } 12556 tmptmp = strcasestr(contact, "expires="); 12557 if (tmptmp) { 12558 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12559 expires = 0; 12560 } 12561 12562 } 12563 if (!expires) 12564 expires=atoi(get_header(req, "expires")); 12565 if (!expires) 12566 expires=default_expiry; 12567 12568 expires_ms = expires * 1000; 12569 if (expires <= EXPIRY_GUARD_LIMIT) 12570 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12571 else 12572 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12573 if (sipdebug) 12574 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12575 12576 r->refresh= (int) expires_ms / 1000; 12577 12578 /* Schedule re-registration before we expire */ 12579 AST_SCHED_DEL(sched, r->expire); 12580 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12581 ASTOBJ_UNREF(r, sip_registry_destroy); 12582 } 12583 return 1; 12584 }
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 3432 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().
03433 { 03434 switch (cause) { 03435 case AST_CAUSE_UNALLOCATED: /* 1 */ 03436 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03437 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03438 return "404 Not Found"; 03439 case AST_CAUSE_CONGESTION: /* 34 */ 03440 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03441 return "503 Service Unavailable"; 03442 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03443 return "408 Request Timeout"; 03444 case AST_CAUSE_NO_ANSWER: /* 19 */ 03445 return "480 Temporarily unavailable"; 03446 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03447 return "403 Forbidden"; 03448 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03449 return "410 Gone"; 03450 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03451 return "480 Temporarily unavailable"; 03452 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03453 return "484 Address incomplete"; 03454 case AST_CAUSE_USER_BUSY: 03455 return "486 Busy here"; 03456 case AST_CAUSE_FAILURE: 03457 return "500 Server internal failure"; 03458 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03459 return "501 Not Implemented"; 03460 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03461 return "503 Service Unavailable"; 03462 /* Used in chan_iax2 */ 03463 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03464 return "502 Bad Gateway"; 03465 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03466 return "488 Not Acceptable Here"; 03467 03468 case AST_CAUSE_NOTDEFINED: 03469 default: 03470 if (option_debug) 03471 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03472 return NULL; 03473 } 03474 03475 /* Never reached */ 03476 return 0; 03477 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3320 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().
03321 { 03322 /* Possible values taken from causes.h */ 03323 03324 switch(cause) { 03325 case 401: /* Unauthorized */ 03326 return AST_CAUSE_CALL_REJECTED; 03327 case 403: /* Not found */ 03328 return AST_CAUSE_CALL_REJECTED; 03329 case 404: /* Not found */ 03330 return AST_CAUSE_UNALLOCATED; 03331 case 405: /* Method not allowed */ 03332 return AST_CAUSE_INTERWORKING; 03333 case 407: /* Proxy authentication required */ 03334 return AST_CAUSE_CALL_REJECTED; 03335 case 408: /* No reaction */ 03336 return AST_CAUSE_NO_USER_RESPONSE; 03337 case 409: /* Conflict */ 03338 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03339 case 410: /* Gone */ 03340 return AST_CAUSE_UNALLOCATED; 03341 case 411: /* Length required */ 03342 return AST_CAUSE_INTERWORKING; 03343 case 413: /* Request entity too large */ 03344 return AST_CAUSE_INTERWORKING; 03345 case 414: /* Request URI too large */ 03346 return AST_CAUSE_INTERWORKING; 03347 case 415: /* Unsupported media type */ 03348 return AST_CAUSE_INTERWORKING; 03349 case 420: /* Bad extension */ 03350 return AST_CAUSE_NO_ROUTE_DESTINATION; 03351 case 480: /* No answer */ 03352 return AST_CAUSE_NO_ANSWER; 03353 case 481: /* No answer */ 03354 return AST_CAUSE_INTERWORKING; 03355 case 482: /* Loop detected */ 03356 return AST_CAUSE_INTERWORKING; 03357 case 483: /* Too many hops */ 03358 return AST_CAUSE_NO_ANSWER; 03359 case 484: /* Address incomplete */ 03360 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03361 case 485: /* Ambigous */ 03362 return AST_CAUSE_UNALLOCATED; 03363 case 486: /* Busy everywhere */ 03364 return AST_CAUSE_BUSY; 03365 case 487: /* Request terminated */ 03366 return AST_CAUSE_INTERWORKING; 03367 case 488: /* No codecs approved */ 03368 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03369 case 491: /* Request pending */ 03370 return AST_CAUSE_INTERWORKING; 03371 case 493: /* Undecipherable */ 03372 return AST_CAUSE_INTERWORKING; 03373 case 500: /* Server internal failure */ 03374 return AST_CAUSE_FAILURE; 03375 case 501: /* Call rejected */ 03376 return AST_CAUSE_FACILITY_REJECTED; 03377 case 502: 03378 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03379 case 503: /* Service unavailable */ 03380 return AST_CAUSE_CONGESTION; 03381 case 504: /* Gateway timeout */ 03382 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03383 case 505: /* SIP version not supported */ 03384 return AST_CAUSE_INTERWORKING; 03385 case 600: /* Busy everywhere */ 03386 return AST_CAUSE_USER_BUSY; 03387 case 603: /* Decline */ 03388 return AST_CAUSE_CALL_REJECTED; 03389 case 604: /* Does not exist anywhere */ 03390 return AST_CAUSE_UNALLOCATED; 03391 case 606: /* Not acceptable */ 03392 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03393 default: 03394 return AST_CAUSE_NORMAL; 03395 } 03396 /* Never reached */ 03397 return 0; 03398 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5854 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05855 { 05856 /* Initialize a request */ 05857 memset(req, 0, sizeof(*req)); 05858 req->method = sipmethod; 05859 req->header[0] = req->data; 05860 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05861 req->len = strlen(req->header[0]); 05862 req->headers++; 05863 return 0; 05864 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5841 of file chan_sip.c.
References SIP_RESPONSE.
05842 { 05843 /* Initialize a response */ 05844 memset(resp, 0, sizeof(*resp)); 05845 resp->method = SIP_RESPONSE; 05846 resp->header[0] = resp->data; 05847 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05848 resp->len = strlen(resp->header[0]); 05849 resp->headers++; 05850 return 0; 05851 }
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 1641 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().
01642 { 01643 if (p->initreq.headers && option_debug) { 01644 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01645 } 01646 /* Use this as the basis */ 01647 copy_request(&p->initreq, req); 01648 parse_request(&p->initreq); 01649 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01650 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01651 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6941 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().
06942 { 06943 char invite_buf[256] = ""; 06944 char *invite = invite_buf; 06945 size_t invite_max = sizeof(invite_buf); 06946 char from[256]; 06947 char to[256]; 06948 char tmp[SIPBUFSIZE/2]; 06949 char tmp2[SIPBUFSIZE/2]; 06950 const char *l = NULL, *n = NULL; 06951 const char *urioptions = ""; 06952 06953 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06954 const char *s = p->username; /* being a string field, cannot be NULL */ 06955 06956 /* Test p->username against allowed characters in AST_DIGIT_ANY 06957 If it matches the allowed characters list, then sipuser = ";user=phone" 06958 If not, then sipuser = "" 06959 */ 06960 /* + is allowed in first position in a tel: uri */ 06961 if (*s == '+') 06962 s++; 06963 for (; *s; s++) { 06964 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06965 break; 06966 } 06967 /* If we have only digits, add ;user=phone to the uri */ 06968 if (*s) 06969 urioptions = ";user=phone"; 06970 } 06971 06972 06973 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06974 06975 if (p->owner) { 06976 l = p->owner->cid.cid_num; 06977 n = p->owner->cid.cid_name; 06978 } 06979 /* if we are not sending RPID and user wants his callerid restricted */ 06980 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06981 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06982 l = CALLERID_UNKNOWN; 06983 n = l; 06984 } 06985 if (ast_strlen_zero(l)) 06986 l = default_callerid; 06987 if (ast_strlen_zero(n)) 06988 n = l; 06989 /* Allow user to be overridden */ 06990 if (!ast_strlen_zero(p->fromuser)) 06991 l = p->fromuser; 06992 else /* Save for any further attempts */ 06993 ast_string_field_set(p, fromuser, l); 06994 06995 /* Allow user to be overridden */ 06996 if (!ast_strlen_zero(p->fromname)) 06997 n = p->fromname; 06998 else /* Save for any further attempts */ 06999 ast_string_field_set(p, fromname, n); 07000 07001 if (pedanticsipchecking) { 07002 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07003 n = tmp; 07004 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07005 l = tmp2; 07006 } 07007 07008 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07009 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); 07010 else 07011 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07012 07013 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07014 if (!ast_strlen_zero(p->fullcontact)) { 07015 /* If we have full contact, trust it */ 07016 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07017 } else { 07018 /* Otherwise, use the username while waiting for registration */ 07019 ast_build_string(&invite, &invite_max, "sip:"); 07020 if (!ast_strlen_zero(p->username)) { 07021 n = p->username; 07022 if (pedanticsipchecking) { 07023 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07024 n = tmp; 07025 } 07026 ast_build_string(&invite, &invite_max, "%s@", n); 07027 } 07028 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07029 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07030 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07031 ast_build_string(&invite, &invite_max, "%s", urioptions); 07032 } 07033 07034 /* If custom URI options have been provided, append them */ 07035 if (p->options && p->options->uri_options) 07036 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07037 07038 ast_string_field_set(p, uri, invite_buf); 07039 07040 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07041 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07042 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07043 } else if (p->options && p->options->vxml_url) { 07044 /* If there is a VXML URL append it to the SIP URL */ 07045 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07046 } else 07047 snprintf(to, sizeof(to), "<%s>", p->uri); 07048 07049 init_req(req, sipmethod, p->uri); 07050 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07051 07052 add_header(req, "Via", p->via); 07053 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07054 * OTOH, then we won't have anything in p->route anyway */ 07055 /* Build Remote Party-ID and From */ 07056 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07057 build_rpid(p); 07058 add_header(req, "From", p->rpid_from); 07059 } else 07060 add_header(req, "From", from); 07061 add_header(req, "To", to); 07062 ast_string_field_set(p, exten, l); 07063 build_contact(p); 07064 add_header(req, "Contact", p->our_contact); 07065 add_header(req, "Call-ID", p->callid); 07066 add_header(req, "CSeq", tmp); 07067 if (!ast_strlen_zero(global_useragent)) 07068 add_header(req, "User-Agent", global_useragent); 07069 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07070 if (!ast_strlen_zero(p->rpid)) 07071 add_header(req, "Remote-Party-ID", p->rpid); 07072 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10087 of file chan_sip.c.
Referenced by _sip_show_peer().
10088 { 10089 if (port && invite) 10090 return "port,invite"; 10091 else if (port) 10092 return "port"; 10093 else if (invite) 10094 return "invite"; 10095 else 10096 return "no"; 10097 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8233 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08234 { 08235 if (!route) 08236 ast_verbose("list_route: no route\n"); 08237 else { 08238 for (;route; route = route->next) 08239 ast_verbose("list_route: hop: <%s>\n", route->hop); 08240 } 08241 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18019 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.
18020 { 18021 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18022 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18023 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18024 18025 if (!(sched = sched_context_create())) { 18026 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18027 return AST_MODULE_LOAD_FAILURE; 18028 } 18029 18030 if (!(io = io_context_create())) { 18031 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18032 sched_context_destroy(sched); 18033 return AST_MODULE_LOAD_FAILURE; 18034 } 18035 18036 sip_reloadreason = CHANNEL_MODULE_LOAD; 18037 18038 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18039 return AST_MODULE_LOAD_DECLINE; 18040 18041 /* Make sure we can register our sip channel type */ 18042 if (ast_channel_register(&sip_tech)) { 18043 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18044 io_context_destroy(io); 18045 sched_context_destroy(sched); 18046 return AST_MODULE_LOAD_FAILURE; 18047 } 18048 18049 /* Register all CLI functions for SIP */ 18050 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18051 18052 /* Tell the RTP subdriver that we're here */ 18053 ast_rtp_proto_register(&sip_rtp); 18054 18055 /* Tell the UDPTL subdriver that we're here */ 18056 ast_udptl_proto_register(&sip_udptl); 18057 18058 /* Register dialplan applications */ 18059 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18060 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18061 18062 /* Register dialplan functions */ 18063 ast_custom_function_register(&sip_header_function); 18064 ast_custom_function_register(&sippeer_function); 18065 ast_custom_function_register(&sipchaninfo_function); 18066 ast_custom_function_register(&checksipdomain_function); 18067 18068 /* Register manager commands */ 18069 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18070 "List SIP peers (text format)", mandescr_show_peers); 18071 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18072 "Show SIP peer (text format)", mandescr_show_peer); 18073 18074 sip_poke_all_peers(); 18075 sip_send_all_registers(); 18076 18077 /* And start the monitor for the first time */ 18078 restart_monitor(); 18079 18080 return AST_MODULE_LOAD_SUCCESS; 18081 }
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 14211 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().
14212 { 14213 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14214 /* Chan 2: Call from Asterisk to target */ 14215 int res = 0; 14216 struct sip_pvt *targetcall_pvt; 14217 14218 /* Check if the call ID of the replaces header does exist locally */ 14219 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14220 transferer->refer->replaces_callid_fromtag))) { 14221 if (transferer->refer->localtransfer) { 14222 /* We did not find the refered call. Sorry, can't accept then */ 14223 transmit_response(transferer, "202 Accepted", req); 14224 /* Let's fake a response from someone else in order 14225 to follow the standard */ 14226 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14227 append_history(transferer, "Xfer", "Refer failed"); 14228 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14229 transferer->refer->status = REFER_FAILED; 14230 return -1; 14231 } 14232 /* Fall through for remote transfers that we did not find locally */ 14233 if (option_debug > 2) 14234 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14235 return 0; 14236 } 14237 14238 /* Ok, we can accept this transfer */ 14239 transmit_response(transferer, "202 Accepted", req); 14240 append_history(transferer, "Xfer", "Refer accepted"); 14241 if (!targetcall_pvt->owner) { /* No active channel */ 14242 if (option_debug > 3) 14243 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14244 /* Cancel transfer */ 14245 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14246 append_history(transferer, "Xfer", "Refer failed"); 14247 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14248 transferer->refer->status = REFER_FAILED; 14249 ast_mutex_unlock(&targetcall_pvt->lock); 14250 ast_channel_unlock(current->chan1); 14251 return -1; 14252 } 14253 14254 /* We have a channel, find the bridge */ 14255 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14256 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14257 14258 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14259 /* Wrong state of new channel */ 14260 if (option_debug > 3) { 14261 if (target.chan2) 14262 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14263 else if (target.chan1->_state != AST_STATE_RING) 14264 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14265 else 14266 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14267 } 14268 } 14269 14270 /* Transfer */ 14271 if (option_debug > 3 && sipdebug) { 14272 if (current->chan2) /* We have two bridges */ 14273 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14274 else /* One bridge, propably transfer of IVR/voicemail etc */ 14275 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14276 } 14277 14278 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14279 14280 /* Perform the transfer */ 14281 res = attempt_transfer(current, &target); 14282 ast_mutex_unlock(&targetcall_pvt->lock); 14283 if (res) { 14284 /* Failed transfer */ 14285 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14286 append_history(transferer, "Xfer", "Refer failed"); 14287 transferer->refer->status = REFER_FAILED; 14288 if (targetcall_pvt->owner) 14289 ast_channel_unlock(targetcall_pvt->owner); 14290 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14291 if (res != -2) 14292 ast_hangup(transferer->owner); 14293 else 14294 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14295 } else { 14296 /* Transfer succeeded! */ 14297 14298 /* Tell transferer that we're done. */ 14299 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14300 append_history(transferer, "Xfer", "Refer succeeded"); 14301 transferer->refer->status = REFER_200OK; 14302 if (targetcall_pvt->owner) { 14303 if (option_debug) 14304 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14305 ast_channel_unlock(targetcall_pvt->owner); 14306 } 14307 } 14308 return 1; 14309 }
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 4760 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04761 { 04762 int h = 0, t = 0; 04763 int lws = 0; 04764 04765 for (; h < len;) { 04766 /* Eliminate all CRs */ 04767 if (msgbuf[h] == '\r') { 04768 h++; 04769 continue; 04770 } 04771 /* Check for end-of-line */ 04772 if (msgbuf[h] == '\n') { 04773 /* Check for end-of-message */ 04774 if (h + 1 == len) 04775 break; 04776 /* Check for a continuation line */ 04777 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04778 /* Merge continuation line */ 04779 h++; 04780 continue; 04781 } 04782 /* Propagate LF and start new line */ 04783 msgbuf[t++] = msgbuf[h++]; 04784 lws = 0; 04785 continue; 04786 } 04787 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04788 if (lws) { 04789 h++; 04790 continue; 04791 } 04792 msgbuf[t++] = msgbuf[h++]; 04793 lws = 1; 04794 continue; 04795 } 04796 msgbuf[t++] = msgbuf[h++]; 04797 if (lws) 04798 lws = 0; 04799 } 04800 msgbuf[t] = '\0'; 04801 return t; 04802 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4431 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().
04432 { 04433 snprintf(tagbuf, len, "as%08lx", ast_random()); 04434 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10332 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().
10333 { 10334 const char *a[4]; 10335 const char *peer; 10336 int ret; 10337 10338 peer = astman_get_header(m,"Peer"); 10339 if (ast_strlen_zero(peer)) { 10340 astman_send_error(s, m, "Peer: <name> missing.\n"); 10341 return 0; 10342 } 10343 a[0] = "sip"; 10344 a[1] = "show"; 10345 a[2] = "peer"; 10346 a[3] = peer; 10347 10348 ret = _sip_show_peer(1, -1, s, m, 4, a); 10349 astman_append(s, "\r\n\r\n" ); 10350 return ret; 10351 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9883 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().
09884 { 09885 const char *id = astman_get_header(m,"ActionID"); 09886 const char *a[] = {"sip", "show", "peers"}; 09887 char idtext[256] = ""; 09888 int total = 0; 09889 09890 if (!ast_strlen_zero(id)) 09891 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09892 09893 astman_send_ack(s, m, "Peer status list will follow"); 09894 /* List the peers in separate manager events */ 09895 _sip_show_peers(-1, &total, s, m, 3, a); 09896 /* Send final confirmation */ 09897 astman_append(s, 09898 "Event: PeerlistComplete\r\n" 09899 "ListItems: %d\r\n" 09900 "%s" 09901 "\r\n", total, idtext); 09902 return 0; 09903 }
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 1667 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01668 { 01669 int len = strlen(sip_methods[id].text); 01670 int l_name = name ? strlen(name) : 0; 01671 /* true if the string is long enough, and ends with whitespace, and matches */ 01672 return (l_name >= len && name[len] < 33 && 01673 !strncasecmp(sip_methods[id].text, name, len)); 01674 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9786 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().
09787 { 09788 switch(nat) { 09789 case SIP_NAT_NEVER: 09790 return "No"; 09791 case SIP_NAT_ROUTE: 09792 return "Route"; 09793 case SIP_NAT_ALWAYS: 09794 return "Always"; 09795 case SIP_NAT_RFC3581: 09796 return "RFC3581"; 09797 default: 09798 return "Unknown"; 09799 } 09800 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2242 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02243 { 02244 memset(dst, 0, sizeof(*dst)); 02245 memcpy(dst->data, src->data, sizeof(dst->data)); 02246 dst->len = src->len; 02247 parse_request(dst); 02248 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11967 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().
11968 { 11969 char tmp[SIPBUFSIZE]; 11970 char *s, *e, *uri, *t; 11971 char *domain; 11972 11973 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11974 if ((t = strchr(tmp, ','))) 11975 *t = '\0'; 11976 s = get_in_brackets(tmp); 11977 uri = ast_strdupa(s); 11978 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11979 if (!strncasecmp(s, "sip:", 4)) 11980 s += 4; 11981 e = strchr(s, ';'); 11982 if (e) 11983 *e = '\0'; 11984 if (option_debug) 11985 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11986 if (p->owner) 11987 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11988 } else { 11989 e = strchr(tmp, '@'); 11990 if (e) { 11991 *e++ = '\0'; 11992 domain = e; 11993 } else { 11994 /* No username part */ 11995 domain = tmp; 11996 } 11997 e = strchr(s, ';'); /* Strip of parameters in the username part */ 11998 if (e) 11999 *e = '\0'; 12000 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12001 if (e) 12002 *e = '\0'; 12003 12004 if (!strncasecmp(s, "sip:", 4)) 12005 s += 4; 12006 if (option_debug > 1) 12007 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12008 if (p->owner) { 12009 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12010 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12011 ast_string_field_set(p->owner, call_forward, s); 12012 } 12013 } 12014 }
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 7994 of file chan_sip.c.
References ast_string_field_set, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
07995 { 07996 char contact[SIPBUFSIZE]; 07997 char *c; 07998 07999 /* Look for brackets */ 08000 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08001 c = get_in_brackets(contact); 08002 08003 /* Save full contact to call pvt for later bye or re-invite */ 08004 ast_string_field_set(pvt, fullcontact, c); 08005 08006 /* Save URI for later ACKs, BYE or RE-invites */ 08007 ast_string_field_set(pvt, okcontacturi, c); 08008 08009 /* We should return false for URI:s we can't handle, 08010 like sips:, tel:, mailto:,ldap: etc */ 08011 return TRUE; 08012 }
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 8078 of file chan_sip.c.
References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08079 { 08080 char contact[SIPBUFSIZE]; 08081 char data[SIPBUFSIZE]; 08082 const char *expires = get_header(req, "Expires"); 08083 int expiry = atoi(expires); 08084 char *curi, *n, *pt; 08085 int port; 08086 const char *useragent; 08087 struct hostent *hp; 08088 struct ast_hostent ahp; 08089 struct sockaddr_in oldsin; 08090 08091 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08092 08093 if (ast_strlen_zero(expires)) { /* No expires header */ 08094 expires = strcasestr(contact, ";expires="); 08095 if (expires) { 08096 /* XXX bug here, we overwrite the string */ 08097 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08098 if (sscanf(expires + 9, "%d", &expiry) != 1) 08099 expiry = default_expiry; 08100 } else { 08101 /* Nothing has been specified */ 08102 expiry = default_expiry; 08103 } 08104 } 08105 08106 /* Look for brackets */ 08107 curi = contact; 08108 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08109 strsep(&curi, ";"); /* This is Header options, not URI options */ 08110 curi = get_in_brackets(contact); 08111 08112 /* if they did not specify Contact: or Expires:, they are querying 08113 what we currently have stored as their contact address, so return 08114 it 08115 */ 08116 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08117 /* If we have an active registration, tell them when the registration is going to expire */ 08118 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08119 pvt->expiry = ast_sched_when(sched, peer->expire); 08120 return PARSE_REGISTER_QUERY; 08121 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08122 /* This means remove all registrations and return OK */ 08123 memset(&peer->addr, 0, sizeof(peer->addr)); 08124 AST_SCHED_DEL(sched, peer->expire); 08125 08126 destroy_association(peer); 08127 08128 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08129 peer->fullcontact[0] = '\0'; 08130 peer->useragent[0] = '\0'; 08131 peer->sipoptions = 0; 08132 peer->lastms = 0; 08133 08134 if (option_verbose > 2) 08135 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08136 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08137 return PARSE_REGISTER_UPDATE; 08138 } 08139 08140 /* Store whatever we got as a contact from the client */ 08141 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08142 08143 /* For the 200 OK, we should use the received contact */ 08144 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08145 08146 /* Make sure it's a SIP URL */ 08147 if (strncasecmp(curi, "sip:", 4)) { 08148 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08149 } else 08150 curi += 4; 08151 /* Ditch q */ 08152 curi = strsep(&curi, ";"); 08153 /* Grab host */ 08154 n = strchr(curi, '@'); 08155 if (!n) { 08156 n = curi; 08157 curi = NULL; 08158 } else 08159 *n++ = '\0'; 08160 pt = strchr(n, ':'); 08161 if (pt) { 08162 *pt++ = '\0'; 08163 port = atoi(pt); 08164 } else 08165 port = STANDARD_SIP_PORT; 08166 oldsin = peer->addr; 08167 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08168 /* XXX This could block for a long time XXX */ 08169 hp = ast_gethostbyname(n, &ahp); 08170 if (!hp) { 08171 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08172 return PARSE_REGISTER_FAILED; 08173 } 08174 peer->addr.sin_family = AF_INET; 08175 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08176 peer->addr.sin_port = htons(port); 08177 } else { 08178 /* Don't trust the contact field. Just use what they came to us 08179 with */ 08180 peer->addr = pvt->recv; 08181 } 08182 08183 /* Save SIP options profile */ 08184 peer->sipoptions = pvt->sipoptions; 08185 08186 if (curi && ast_strlen_zero(peer->username)) 08187 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08188 08189 AST_SCHED_DEL(sched, peer->expire); 08190 if (expiry > max_expiry) 08191 expiry = max_expiry; 08192 if (expiry < min_expiry) 08193 expiry = min_expiry; 08194 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 08195 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 08196 pvt->expiry = expiry; 08197 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); 08198 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08199 ast_db_put("SIP/Registry", peer->name, data); 08200 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08201 08202 /* Is this a new IP address for us? */ 08203 if (inaddrcmp(&peer->addr, &oldsin)) { 08204 sip_poke_peer(peer); 08205 if (option_verbose > 2) 08206 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); 08207 register_peer_exten(peer, 1); 08208 } 08209 08210 /* Save User agent */ 08211 useragent = get_header(req, "User-Agent"); 08212 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08213 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08214 if (option_verbose > 3) 08215 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08216 } 08217 return PARSE_REGISTER_UPDATE; 08218 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4807 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().
04808 { 04809 /* Divide fields by NULL's */ 04810 char *c; 04811 int f = 0; 04812 04813 c = req->data; 04814 04815 /* First header starts immediately */ 04816 req->header[f] = c; 04817 while(*c) { 04818 if (*c == '\n') { 04819 /* We've got a new header */ 04820 *c = 0; 04821 04822 if (sipdebug && option_debug > 3) 04823 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04824 if (ast_strlen_zero(req->header[f])) { 04825 /* Line by itself means we're now in content */ 04826 c++; 04827 break; 04828 } 04829 if (f >= SIP_MAX_HEADERS - 1) { 04830 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04831 } else 04832 f++; 04833 req->header[f] = c + 1; 04834 } else if (*c == '\r') { 04835 /* Ignore but eliminate \r's */ 04836 *c = 0; 04837 } 04838 c++; 04839 } 04840 /* Check for last header */ 04841 if (!ast_strlen_zero(req->header[f])) { 04842 if (sipdebug && option_debug > 3) 04843 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04844 f++; 04845 } 04846 req->headers = f; 04847 /* Now we process any mime content */ 04848 f = 0; 04849 req->line[f] = c; 04850 while(*c) { 04851 if (*c == '\n') { 04852 /* We've got a new line */ 04853 *c = 0; 04854 if (sipdebug && option_debug > 3) 04855 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04856 if (f >= SIP_MAX_LINES - 1) { 04857 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04858 } else 04859 f++; 04860 req->line[f] = c + 1; 04861 } else if (*c == '\r') { 04862 /* Ignore and eliminate \r's */ 04863 *c = 0; 04864 } 04865 c++; 04866 } 04867 /* Check for last line */ 04868 if (!ast_strlen_zero(req->line[f])) 04869 f++; 04870 req->lines = f; 04871 if (*c) 04872 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04873 /* Split up the first line parts */ 04874 determine_firstline_parts(req); 04875 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1691 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().
01692 { 01693 char *next, *sep; 01694 char *temp; 01695 unsigned int profile = 0; 01696 int i, found; 01697 01698 if (ast_strlen_zero(supported) ) 01699 return 0; 01700 temp = ast_strdupa(supported); 01701 01702 if (option_debug > 2 && sipdebug) 01703 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01704 01705 for (next = temp; next; next = sep) { 01706 found = FALSE; 01707 if ( (sep = strchr(next, ',')) != NULL) 01708 *sep++ = '\0'; 01709 next = ast_skip_blanks(next); 01710 if (option_debug > 2 && sipdebug) 01711 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01712 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01713 if (!strcasecmp(next, sip_options[i].text)) { 01714 profile |= sip_options[i].id; 01715 found = TRUE; 01716 if (option_debug > 2 && sipdebug) 01717 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01718 break; 01719 } 01720 } 01721 if (!found && option_debug > 2 && sipdebug) { 01722 if (!strncasecmp(next, "x-", 2)) 01723 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01724 else 01725 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01726 } 01727 } 01728 01729 if (pvt) 01730 pvt->sipoptions = profile; 01731 return profile; 01732 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9805 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09806 { 09807 int res = 0; 09808 if (peer->maxms) { 09809 if (peer->lastms < 0) { 09810 ast_copy_string(status, "UNREACHABLE", statuslen); 09811 } else if (peer->lastms > peer->maxms) { 09812 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09813 res = 1; 09814 } else if (peer->lastms) { 09815 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09816 res = 1; 09817 } else { 09818 ast_copy_string(status, "UNKNOWN", statuslen); 09819 } 09820 } else { 09821 ast_copy_string(status, "Unmonitored", statuslen); 09822 /* Checking if port is 0 */ 09823 res = -1; 09824 } 09825 return res; 09826 }
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 10273 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().
10274 { 10275 int x, codec; 10276 10277 for(x = 0; x < 32 ; x++) { 10278 codec = ast_codec_pref_index(pref, x); 10279 if (!codec) 10280 break; 10281 ast_cli(fd, "%s", ast_getformatname(codec)); 10282 ast_cli(fd, ":%d", pref->framing[x]); 10283 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10284 ast_cli(fd, ","); 10285 } 10286 if (!x) 10287 ast_cli(fd, "none"); 10288 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10064 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10065 { 10066 char buf[256]; 10067 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10068 }
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 5008 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_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, 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_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, 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.
05009 { 05010 const char *m; /* SDP media offer */ 05011 const char *c; 05012 const char *a; 05013 char host[258]; 05014 int len = -1; 05015 int portno = -1; /*!< RTP Audio port number */ 05016 int vportno = -1; /*!< RTP Video port number */ 05017 int udptlportno = -1; 05018 int peert38capability = 0; 05019 char s[256]; 05020 int old = 0; 05021 05022 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05023 int peercapability = 0, peernoncodeccapability = 0; 05024 int vpeercapability = 0, vpeernoncodeccapability = 0; 05025 struct sockaddr_in sin; /*!< media socket address */ 05026 struct sockaddr_in vsin; /*!< Video socket address */ 05027 05028 const char *codecs; 05029 struct hostent *hp; /*!< RTP Audio host IP */ 05030 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05031 struct ast_hostent audiohp; 05032 struct ast_hostent videohp; 05033 int codec; 05034 int destiterator = 0; 05035 int iterator; 05036 int sendonly = -1; 05037 int numberofports; 05038 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05039 int newjointcapability; /* Negotiated capability */ 05040 int newpeercapability; 05041 int newnoncodeccapability; 05042 int numberofmediastreams = 0; 05043 int debug = sip_debug_test_pvt(p); 05044 05045 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05046 int last_rtpmap_codec=0; 05047 05048 if (!p->rtp) { 05049 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05050 return -1; 05051 } 05052 05053 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05054 newaudiortp = alloca(ast_rtp_alloc_size()); 05055 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05056 ast_rtp_new_init(newaudiortp); 05057 ast_rtp_pt_clear(newaudiortp); 05058 05059 newvideortp = alloca(ast_rtp_alloc_size()); 05060 memset(newvideortp, 0, ast_rtp_alloc_size()); 05061 ast_rtp_new_init(newvideortp); 05062 ast_rtp_pt_clear(newvideortp); 05063 05064 /* Update our last rtprx when we receive an SDP, too */ 05065 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05066 05067 05068 /* Try to find first media stream */ 05069 m = get_sdp(req, "m"); 05070 destiterator = req->sdp_start; 05071 c = get_sdp_iterate(&destiterator, req, "c"); 05072 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05073 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05074 return -1; 05075 } 05076 05077 /* Check for IPv4 address (not IPv6 yet) */ 05078 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05079 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05080 return -1; 05081 } 05082 05083 /* XXX This could block for a long time, and block the main thread! XXX */ 05084 hp = ast_gethostbyname(host, &audiohp); 05085 if (!hp) { 05086 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05087 return -1; 05088 } 05089 vhp = hp; /* Copy to video address as default too */ 05090 05091 iterator = req->sdp_start; 05092 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05093 05094 05095 /* Find media streams in this SDP offer */ 05096 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05097 int x; 05098 int audio = FALSE; 05099 05100 numberofports = 1; 05101 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05102 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05103 audio = TRUE; 05104 numberofmediastreams++; 05105 /* Found audio stream in this media definition */ 05106 portno = x; 05107 /* Scan through the RTP payload types specified in a "m=" line: */ 05108 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05109 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05110 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05111 return -1; 05112 } 05113 if (debug) 05114 ast_verbose("Found RTP audio format %d\n", codec); 05115 ast_rtp_set_m_type(newaudiortp, codec); 05116 } 05117 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05118 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05119 /* If it is not audio - is it video ? */ 05120 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05121 numberofmediastreams++; 05122 vportno = x; 05123 /* Scan through the RTP payload types specified in a "m=" line: */ 05124 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05125 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05126 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05127 return -1; 05128 } 05129 if (debug) 05130 ast_verbose("Found RTP video format %d\n", codec); 05131 ast_rtp_set_m_type(newvideortp, codec); 05132 } 05133 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05134 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05135 if (debug) 05136 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05137 udptlportno = x; 05138 numberofmediastreams++; 05139 05140 if (p->owner && p->lastinvite) { 05141 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05142 if (option_debug > 1) 05143 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05144 } else { 05145 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05146 if (option_debug > 1) 05147 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05148 } 05149 } else 05150 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05151 if (numberofports > 1) 05152 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05153 05154 05155 /* Check for Media-description-level-address for audio */ 05156 c = get_sdp_iterate(&destiterator, req, "c"); 05157 if (!ast_strlen_zero(c)) { 05158 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05159 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05160 } else { 05161 /* XXX This could block for a long time, and block the main thread! XXX */ 05162 if (audio) { 05163 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05164 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05165 return -2; 05166 } 05167 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05168 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05169 return -2; 05170 } 05171 } 05172 05173 } 05174 } 05175 if (portno == -1 && vportno == -1 && udptlportno == -1) 05176 /* No acceptable offer found in SDP - we have no ports */ 05177 /* Do not change RTP or VRTP if this is a re-invite */ 05178 return -2; 05179 05180 if (numberofmediastreams > 2) 05181 /* We have too many fax, audio and/or video media streams, fail this offer */ 05182 return -3; 05183 05184 /* RTP addresses and ports for audio and video */ 05185 sin.sin_family = AF_INET; 05186 vsin.sin_family = AF_INET; 05187 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05188 if (vhp) 05189 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05190 05191 /* Setup UDPTL port number */ 05192 if (p->udptl) { 05193 if (udptlportno > 0) { 05194 sin.sin_port = htons(udptlportno); 05195 ast_udptl_set_peer(p->udptl, &sin); 05196 if (debug) 05197 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05198 } else { 05199 ast_udptl_stop(p->udptl); 05200 if (debug) 05201 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05202 } 05203 } 05204 05205 05206 if (p->rtp) { 05207 if (portno > 0) { 05208 sin.sin_port = htons(portno); 05209 ast_rtp_set_peer(p->rtp, &sin); 05210 if (debug) 05211 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05212 } else { 05213 if (udptlportno > 0) { 05214 if (debug) 05215 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05216 } else { 05217 ast_rtp_stop(p->rtp); 05218 if (debug) 05219 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05220 } 05221 } 05222 } 05223 /* Setup video port number */ 05224 if (vportno != -1) 05225 vsin.sin_port = htons(vportno); 05226 05227 /* Next, scan through each "a=rtpmap:" line, noting each 05228 * specified RTP payload type (with corresponding MIME subtype): 05229 */ 05230 /* XXX This needs to be done per media stream, since it's media stream specific */ 05231 iterator = req->sdp_start; 05232 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05233 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05234 if (option_debug > 1) { 05235 int breakout = FALSE; 05236 05237 /* If we're debugging, check for unsupported sdp options */ 05238 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05239 if (debug) 05240 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05241 breakout = TRUE; 05242 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05243 /* Format parameters: Not supported */ 05244 /* Note: This is used for codec parameters, like bitrate for 05245 G722 and video formats for H263 and H264 05246 See RFC2327 for an example */ 05247 if (debug) 05248 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05249 breakout = TRUE; 05250 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05251 /* Video stuff: Not supported */ 05252 if (debug) 05253 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05254 breakout = TRUE; 05255 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05256 /* Video stuff: Not supported */ 05257 if (debug) 05258 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05259 breakout = TRUE; 05260 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05261 /* SRTP stuff, not yet supported */ 05262 if (debug) 05263 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05264 breakout = TRUE; 05265 } 05266 if (breakout) /* We have a match, skip to next header */ 05267 continue; 05268 } 05269 if (!strcasecmp(a, "sendonly")) { 05270 if (sendonly == -1) 05271 sendonly = 1; 05272 continue; 05273 } else if (!strcasecmp(a, "inactive")) { 05274 if (sendonly == -1) 05275 sendonly = 2; 05276 continue; 05277 } else if (!strcasecmp(a, "sendrecv")) { 05278 if (sendonly == -1) 05279 sendonly = 0; 05280 continue; 05281 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05282 char *tmp = strrchr(a, ':'); 05283 long int framing = 0; 05284 if (tmp) { 05285 tmp++; 05286 framing = strtol(tmp, NULL, 10); 05287 if (framing == LONG_MIN || framing == LONG_MAX) { 05288 framing = 0; 05289 if (option_debug) 05290 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05291 } 05292 } 05293 if (framing && last_rtpmap_codec) { 05294 if (p->autoframing) { 05295 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05296 int codec_n; 05297 int format = 0; 05298 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05299 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05300 if (!format) /* non-codec or not found */ 05301 continue; 05302 if (option_debug) 05303 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05304 ast_codec_pref_setsize(pref, format, framing); 05305 } 05306 ast_rtp_codec_setpref(p->rtp, pref); 05307 } 05308 } 05309 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05310 last_rtpmap_codec = 0; 05311 continue; 05312 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05313 /* We have a rtpmap to handle */ 05314 int found = FALSE; 05315 /* We should propably check if this is an audio or video codec 05316 so we know where to look */ 05317 05318 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05319 /* Note: should really look at the 'freq' and '#chans' params too */ 05320 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05321 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05322 if (debug) 05323 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05324 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05325 last_rtpmap_codec++; 05326 found = TRUE; 05327 05328 } else if (p->vrtp) { 05329 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05330 if (debug) 05331 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05332 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05333 last_rtpmap_codec++; 05334 found = TRUE; 05335 } 05336 } 05337 } else { 05338 if (debug) 05339 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05340 } 05341 05342 if (!found) { 05343 /* Remove this codec since it's an unknown media type for us */ 05344 /* XXX This is buggy since the media line for audio and video can have the 05345 same numbers. We need to check as described above, but for testing this works... */ 05346 ast_rtp_unset_m_type(newaudiortp, codec); 05347 ast_rtp_unset_m_type(newvideortp, codec); 05348 if (debug) 05349 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05350 } 05351 } 05352 } 05353 05354 if (udptlportno != -1) { 05355 int found = 0, x; 05356 05357 old = 0; 05358 05359 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05360 iterator = req->sdp_start; 05361 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05362 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05363 found = 1; 05364 if (option_debug > 2) 05365 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05366 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05367 found = 1; 05368 if (option_debug > 2) 05369 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05370 switch (x) { 05371 case 14400: 05372 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05373 break; 05374 case 12000: 05375 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05376 break; 05377 case 9600: 05378 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05379 break; 05380 case 7200: 05381 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05382 break; 05383 case 4800: 05384 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05385 break; 05386 case 2400: 05387 peert38capability |= T38FAX_RATE_2400; 05388 break; 05389 } 05390 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05391 found = 1; 05392 if (option_debug > 2) 05393 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05394 if (x == 0) 05395 peert38capability |= T38FAX_VERSION_0; 05396 else if (x == 1) 05397 peert38capability |= T38FAX_VERSION_1; 05398 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05399 found = 1; 05400 if (option_debug > 2) 05401 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05402 ast_udptl_set_far_max_datagram(p->udptl, x); 05403 ast_udptl_set_local_max_datagram(p->udptl, x); 05404 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05405 found = 1; 05406 if (option_debug > 2) 05407 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05408 if (x == 1) 05409 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05410 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05411 found = 1; 05412 if (option_debug > 2) 05413 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05414 if (x == 1) 05415 peert38capability |= T38FAX_TRANSCODING_MMR; 05416 } 05417 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05418 found = 1; 05419 if (option_debug > 2) 05420 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05421 if (x == 1) 05422 peert38capability |= T38FAX_TRANSCODING_JBIG; 05423 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05424 found = 1; 05425 if (option_debug > 2) 05426 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05427 if (!strcasecmp(s, "localTCF")) 05428 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05429 else if (!strcasecmp(s, "transferredTCF")) 05430 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05431 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05432 found = 1; 05433 if (option_debug > 2) 05434 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05435 if (!strcasecmp(s, "t38UDPRedundancy")) { 05436 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05437 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05438 } else if (!strcasecmp(s, "t38UDPFEC")) { 05439 peert38capability |= T38FAX_UDP_EC_FEC; 05440 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05441 } else { 05442 peert38capability |= T38FAX_UDP_EC_NONE; 05443 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05444 } 05445 } 05446 } 05447 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05448 p->t38.peercapability = peert38capability; 05449 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05450 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05451 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05452 } 05453 if (debug) 05454 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05455 p->t38.capability, 05456 p->t38.peercapability, 05457 p->t38.jointcapability); 05458 } else { 05459 p->t38.state = T38_DISABLED; 05460 if (option_debug > 2) 05461 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05462 } 05463 05464 /* Now gather all of the codecs that we are asked for: */ 05465 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05466 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05467 05468 newjointcapability = p->capability & (peercapability | vpeercapability); 05469 newpeercapability = (peercapability | vpeercapability); 05470 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05471 05472 05473 if (debug) { 05474 /* shame on whoever coded this.... */ 05475 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05476 05477 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05478 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05479 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05480 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05481 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05482 05483 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05484 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05485 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05486 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05487 } 05488 if (!newjointcapability) { 05489 /* If T.38 was not negotiated either, totally bail out... */ 05490 if (!p->t38.jointcapability || !p->t38.peercapability) { 05491 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05492 /* Do NOT Change current setting */ 05493 return -1; 05494 } else { 05495 if (option_debug > 2) 05496 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05497 return 0; 05498 } 05499 } 05500 05501 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05502 they are acceptable */ 05503 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05504 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05505 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05506 05507 ast_rtp_pt_copy(p->rtp, newaudiortp); 05508 if (p->vrtp) 05509 ast_rtp_pt_copy(p->vrtp, newvideortp); 05510 05511 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05512 ast_clear_flag(&p->flags[0], SIP_DTMF); 05513 if (newnoncodeccapability & AST_RTP_DTMF) { 05514 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05515 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05516 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05517 ast_rtp_setdtmf(p->rtp, 1); 05518 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05519 } else { 05520 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05521 } 05522 } 05523 05524 /* Setup audio port number */ 05525 if (p->rtp && sin.sin_port) { 05526 ast_rtp_set_peer(p->rtp, &sin); 05527 if (debug) 05528 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05529 } 05530 05531 /* Setup video port number */ 05532 if (p->vrtp && vsin.sin_port) { 05533 ast_rtp_set_peer(p->vrtp, &vsin); 05534 if (debug) 05535 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05536 } 05537 05538 /* Ok, we're going with this offer */ 05539 if (option_debug > 1) { 05540 char buf[SIPBUFSIZE]; 05541 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05542 } 05543 05544 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05545 return 0; 05546 05547 if (option_debug > 3) 05548 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05549 05550 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05551 if (debug) { 05552 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05553 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05554 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05555 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05556 } 05557 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05558 ast_set_read_format(p->owner, p->owner->readformat); 05559 ast_set_write_format(p->owner, p->owner->writeformat); 05560 } 05561 05562 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05563 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05564 /* Activate a re-invite */ 05565 ast_queue_frame(p->owner, &ast_null_frame); 05566 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05567 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05568 S_OR(p->mohsuggest, NULL), 05569 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05570 if (sendonly) 05571 ast_rtp_stop(p->rtp); 05572 /* RTCP needs to go ahead, even if we're on hold!!! */ 05573 /* Activate a re-invite */ 05574 ast_queue_frame(p->owner, &ast_null_frame); 05575 } 05576 05577 /* Manager Hold and Unhold events must be generated, if necessary */ 05578 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05579 change_hold_state(p, req, FALSE, sendonly); 05580 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05581 change_hold_state(p, req, TRUE, sendonly); 05582 return 0; 05583 }
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 2516 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.
02517 { 02518 struct sip_peer *peer=NULL; 02519 struct ast_variable *var = NULL; 02520 struct ast_config *peerlist = NULL; 02521 struct ast_variable *tmp; 02522 struct ast_flags flags = {0}; 02523 const char *iabuf = NULL; 02524 char portstring[6]; /*up to five digits plus null terminator*/ 02525 const char *insecure; 02526 char *cat = NULL; 02527 unsigned short portnum; 02528 02529 /* First check on peer name */ 02530 if (newpeername) { 02531 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02532 if (!var && sin) 02533 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02534 if (!var) { 02535 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02536 /*!\note 02537 * If this one loaded something, then we need to ensure that the host 02538 * field matched. The only reason why we can't have this as a criteria 02539 * is because we only have the IP address and the host field might be 02540 * set as a name (and the reverse PTR might not match). 02541 */ 02542 if (var) { 02543 for (tmp = var; tmp; tmp = tmp->next) { 02544 if (!strcasecmp(tmp->name, "host")) { 02545 struct hostent *hp; 02546 struct ast_hostent ahp; 02547 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02548 /* No match */ 02549 ast_variables_destroy(var); 02550 var = NULL; 02551 } 02552 break; 02553 } 02554 } 02555 } 02556 } 02557 } 02558 02559 if (!var && sin) { /* Then check on IP address */ 02560 iabuf = ast_inet_ntoa(sin->sin_addr); 02561 portnum = ntohs(sin->sin_port); 02562 sprintf(portstring, "%d", portnum); 02563 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02564 if (!var) 02565 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02566 if (!var) { 02567 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02568 if(peerlist){ 02569 while((cat = ast_category_browse(peerlist, cat))) 02570 { 02571 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02572 set_insecure_flags(&flags, insecure, -1); 02573 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02574 var = ast_category_root(peerlist, cat); 02575 break; 02576 } 02577 } 02578 } 02579 if(!var) { 02580 ast_config_destroy(peerlist); 02581 peerlist = NULL; /*for safety's sake*/ 02582 cat = NULL; 02583 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02584 if(peerlist) { 02585 while((cat = ast_category_browse(peerlist, cat))) 02586 { 02587 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02588 set_insecure_flags(&flags, insecure, -1); 02589 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02590 var = ast_category_root(peerlist, cat); 02591 break; 02592 } 02593 } 02594 } 02595 } 02596 } 02597 } 02598 02599 if (!var) { 02600 if(peerlist) 02601 ast_config_destroy(peerlist); 02602 return NULL; 02603 } 02604 02605 for (tmp = var; tmp; tmp = tmp->next) { 02606 /* If this is type=user, then skip this object. */ 02607 if (!strcasecmp(tmp->name, "type") && 02608 !strcasecmp(tmp->value, "user")) { 02609 ast_variables_destroy(var); 02610 return NULL; 02611 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02612 newpeername = tmp->value; 02613 } 02614 } 02615 02616 if (!newpeername) { /* Did not find peer in realtime */ 02617 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02618 if(peerlist) 02619 ast_config_destroy(peerlist); 02620 else 02621 ast_variables_destroy(var); 02622 return NULL; 02623 } 02624 02625 /* Peer found in realtime, now build it in memory */ 02626 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02627 if (!peer) { 02628 if(peerlist) 02629 ast_config_destroy(peerlist); 02630 else 02631 ast_variables_destroy(var); 02632 return NULL; 02633 } 02634 02635 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02636 /* Cache peer */ 02637 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02638 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02639 AST_SCHED_DEL(sched, peer->expire); 02640 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02641 } 02642 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02643 } else { 02644 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02645 } 02646 if(peerlist) 02647 ast_config_destroy(peerlist); 02648 else 02649 ast_variables_destroy(var); 02650 return peer; 02651 }
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 2396 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.
02397 { 02398 char port[10]; 02399 char ipaddr[INET_ADDRSTRLEN]; 02400 char regseconds[20]; 02401 02402 char *sysname = ast_config_AST_SYSTEM_NAME; 02403 char *syslabel = NULL; 02404 02405 time_t nowtime = time(NULL) + expirey; 02406 const char *fc = fullcontact ? "fullcontact" : NULL; 02407 02408 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02409 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02410 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02411 02412 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02413 sysname = NULL; 02414 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02415 syslabel = "regserver"; 02416 02417 if (fc) 02418 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02419 "port", port, "regseconds", regseconds, 02420 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02421 else 02422 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02423 "port", port, "regseconds", regseconds, 02424 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02425 }
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 2701 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02702 { 02703 struct ast_variable *var; 02704 struct ast_variable *tmp; 02705 struct sip_user *user = NULL; 02706 02707 var = ast_load_realtime("sipusers", "name", username, NULL); 02708 02709 if (!var) 02710 return NULL; 02711 02712 for (tmp = var; tmp; tmp = tmp->next) { 02713 if (!strcasecmp(tmp->name, "type") && 02714 !strcasecmp(tmp->value, "peer")) { 02715 ast_variables_destroy(var); 02716 return NULL; 02717 } 02718 } 02719 02720 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02721 02722 if (!user) { /* No user found */ 02723 ast_variables_destroy(var); 02724 return NULL; 02725 } 02726 02727 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02728 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02729 suserobjs++; 02730 ASTOBJ_CONTAINER_LINK(&userl,user); 02731 } else { 02732 /* Move counter from s to r... */ 02733 suserobjs--; 02734 ruserobjs++; 02735 ast_set_flag(&user->flags[0], SIP_REALTIME); 02736 } 02737 ast_variables_destroy(var); 02738 return user; 02739 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9688 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().
09689 { 09690 char buf[1024]; 09691 struct ast_frame f; 09692 const char *content_type = get_header(req, "Content-Type"); 09693 09694 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09695 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09696 if (!p->owner) 09697 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09698 return; 09699 } 09700 09701 if (get_msg_text(buf, sizeof(buf), req)) { 09702 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09703 transmit_response(p, "202 Accepted", req); 09704 if (!p->owner) 09705 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09706 return; 09707 } 09708 09709 if (p->owner) { 09710 if (sip_debug_test_pvt(p)) 09711 ast_verbose("Message received: '%s'\n", buf); 09712 memset(&f, 0, sizeof(f)); 09713 f.frametype = AST_FRAME_TEXT; 09714 f.subclass = 0; 09715 f.offset = 0; 09716 f.data = buf; 09717 f.datalen = strlen(buf); 09718 ast_queue_frame(p->owner, &f); 09719 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09720 } else { /* Message outside of a call, we do not support that */ 09721 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); 09722 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09723 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09724 } 09725 return; 09726 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1626 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01627 { 01628 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01629 int x; 01630 01631 for (x = 0; x < i; x++) { 01632 if (referstatusstrings[x].status == rstatus) 01633 return (char *) referstatusstrings[x].text; 01634 } 01635 return ""; 01636 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7936 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, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07937 { 07938 char data[256]; 07939 struct in_addr in; 07940 int expiry; 07941 int port; 07942 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07943 07944 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07945 return; 07946 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07947 return; 07948 07949 scan = data; 07950 addr = strsep(&scan, ":"); 07951 port_str = strsep(&scan, ":"); 07952 expiry_str = strsep(&scan, ":"); 07953 username = strsep(&scan, ":"); 07954 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07955 07956 if (!inet_aton(addr, &in)) 07957 return; 07958 07959 if (port_str) 07960 port = atoi(port_str); 07961 else 07962 return; 07963 07964 if (expiry_str) 07965 expiry = atoi(expiry_str); 07966 else 07967 return; 07968 07969 if (username) 07970 ast_copy_string(peer->username, username, sizeof(peer->username)); 07971 if (contact) 07972 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07973 07974 if (option_debug > 1) 07975 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07976 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07977 07978 memset(&peer->addr, 0, sizeof(peer->addr)); 07979 peer->addr.sin_family = AF_INET; 07980 peer->addr.sin_addr = in; 07981 peer->addr.sin_port = htons(port); 07982 if (sipsock < 0) { 07983 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07984 AST_SCHED_DEL(sched, peer->pokeexpire); 07985 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07986 } else 07987 sip_poke_peer(peer); 07988 AST_SCHED_DEL(sched, peer->expire); 07989 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07990 register_peer_exten(peer, TRUE); 07991 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2428 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().
02429 { 02430 char multi[256]; 02431 char *stringp, *ext, *context; 02432 02433 /* XXX note that global_regcontext is both a global 'enable' flag and 02434 * the name of the global regexten context, if not specified 02435 * individually. 02436 */ 02437 if (ast_strlen_zero(global_regcontext)) 02438 return; 02439 02440 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02441 stringp = multi; 02442 while ((ext = strsep(&stringp, "&"))) { 02443 if ((context = strchr(ext, '@'))) { 02444 *context++ = '\0'; /* split ext@context */ 02445 if (!ast_context_find(context)) { 02446 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02447 continue; 02448 } 02449 } else { 02450 context = global_regcontext; 02451 } 02452 if (onoff) 02453 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02454 ast_strdup(peer->name), ast_free, "SIP"); 02455 else 02456 ast_context_remove_extension(context, ext, 1, NULL); 02457 } 02458 }
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 8605 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.
08607 { 08608 enum check_auth_result res = AUTH_NOT_FOUND; 08609 struct sip_peer *peer; 08610 char tmp[256]; 08611 char *name, *c; 08612 char *t; 08613 char *domain; 08614 08615 /* Terminate URI */ 08616 t = uri; 08617 while(*t && (*t > 32) && (*t != ';')) 08618 t++; 08619 *t = '\0'; 08620 08621 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08622 if (pedanticsipchecking) 08623 ast_uri_decode(tmp); 08624 08625 c = get_in_brackets(tmp); 08626 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08627 08628 if (!strncasecmp(c, "sip:", 4)) { 08629 name = c + 4; 08630 } else { 08631 name = c; 08632 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08633 } 08634 08635 /* Strip off the domain name */ 08636 if ((c = strchr(name, '@'))) { 08637 *c++ = '\0'; 08638 domain = c; 08639 if ((c = strchr(domain, ':'))) /* Remove :port */ 08640 *c = '\0'; 08641 if (!AST_LIST_EMPTY(&domain_list)) { 08642 if (!check_sip_domain(domain, NULL, 0)) { 08643 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08644 return AUTH_UNKNOWN_DOMAIN; 08645 } 08646 } 08647 } 08648 08649 ast_string_field_set(p, exten, name); 08650 build_contact(p); 08651 peer = find_peer(name, NULL, 1); 08652 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08653 /* Peer fails ACL check */ 08654 if (peer) { 08655 ASTOBJ_UNREF(peer, sip_destroy_peer); 08656 peer = NULL; 08657 res = AUTH_ACL_FAILED; 08658 } else 08659 res = AUTH_NOT_FOUND; 08660 } 08661 if (peer) { 08662 /* Set Frame packetization */ 08663 if (p->rtp) { 08664 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08665 p->autoframing = peer->autoframing; 08666 } 08667 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08668 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08669 res = AUTH_PEER_NOT_DYNAMIC; 08670 } else { 08671 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08672 transmit_response(p, "100 Trying", req); 08673 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08674 if (sip_cancel_destroy(p)) 08675 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08676 08677 /* We have a succesful registration attemp with proper authentication, 08678 now, update the peer */ 08679 switch (parse_register_contact(p, peer, req)) { 08680 case PARSE_REGISTER_FAILED: 08681 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08682 transmit_response_with_date(p, "400 Bad Request", req); 08683 peer->lastmsgssent = -1; 08684 res = 0; 08685 break; 08686 case PARSE_REGISTER_QUERY: 08687 transmit_response_with_date(p, "200 OK", req); 08688 peer->lastmsgssent = -1; 08689 res = 0; 08690 break; 08691 case PARSE_REGISTER_UPDATE: 08692 update_peer(peer, p->expiry); 08693 /* Say OK and ask subsystem to retransmit msg counter */ 08694 transmit_response_with_date(p, "200 OK", req); 08695 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08696 peer->lastmsgssent = -1; 08697 res = 0; 08698 break; 08699 } 08700 } 08701 } 08702 } 08703 if (!peer && autocreatepeer) { 08704 /* Create peer if we have autocreate mode enabled */ 08705 peer = temp_peer(name); 08706 if (peer) { 08707 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08708 if (sip_cancel_destroy(p)) 08709 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08710 switch (parse_register_contact(p, peer, req)) { 08711 case PARSE_REGISTER_FAILED: 08712 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08713 transmit_response_with_date(p, "400 Bad Request", req); 08714 peer->lastmsgssent = -1; 08715 res = 0; 08716 break; 08717 case PARSE_REGISTER_QUERY: 08718 transmit_response_with_date(p, "200 OK", req); 08719 peer->lastmsgssent = -1; 08720 res = 0; 08721 break; 08722 case PARSE_REGISTER_UPDATE: 08723 /* Say OK and ask subsystem to retransmit msg counter */ 08724 transmit_response_with_date(p, "200 OK", req); 08725 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08726 peer->lastmsgssent = -1; 08727 res = 0; 08728 break; 08729 } 08730 } 08731 } 08732 if (!res) { 08733 ast_device_state_changed("SIP/%s", peer->name); 08734 } 08735 if (res < 0) { 08736 switch (res) { 08737 case AUTH_SECRET_FAILED: 08738 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08739 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08740 break; 08741 case AUTH_USERNAME_MISMATCH: 08742 /* Username and digest username does not match. 08743 Asterisk uses the From: username for authentication. We need the 08744 users to use the same authentication user name until we support 08745 proper authentication by digest auth name */ 08746 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08747 break; 08748 case AUTH_NOT_FOUND: 08749 case AUTH_PEER_NOT_DYNAMIC: 08750 case AUTH_ACL_FAILED: 08751 if (global_alwaysauthreject) { 08752 transmit_fake_auth_response(p, &p->initreq, 1); 08753 } else { 08754 /* URI not found */ 08755 if (res == AUTH_PEER_NOT_DYNAMIC) 08756 transmit_response(p, "403 Forbidden", &p->initreq); 08757 else 08758 transmit_response(p, "404 Not found", &p->initreq); 08759 } 08760 break; 08761 default: 08762 break; 08763 } 08764 } 08765 if (peer) 08766 ASTOBJ_UNREF(peer, sip_destroy_peer); 08767 08768 return res; 08769 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7433 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.
07434 { 07435 switch(regstate) { 07436 case REG_STATE_FAILED: 07437 return "Failed"; 07438 case REG_STATE_UNREGISTERED: 07439 return "Unregistered"; 07440 case REG_STATE_REGSENT: 07441 return "Request Sent"; 07442 case REG_STATE_AUTHSENT: 07443 return "Auth. Sent"; 07444 case REG_STATE_REGISTERED: 07445 return "Registered"; 07446 case REG_STATE_REJECTED: 07447 return "Rejected"; 07448 case REG_STATE_TIMEOUT: 07449 return "Timeout"; 07450 case REG_STATE_NOAUTH: 07451 return "No Authentication"; 07452 default: 07453 return "Unknown"; 07454 } 07455 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17905 of file chan_sip.c.
References sip_reload().
17906 { 17907 return sip_reload(0, 0, NULL); 17908 }
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 16797 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().
16798 { 16799 struct ast_config *cfg, *ucfg; 16800 struct ast_variable *v; 16801 struct sip_peer *peer; 16802 struct sip_user *user; 16803 struct ast_hostent ahp; 16804 char *cat, *stringp, *context, *oldregcontext; 16805 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16806 struct hostent *hp; 16807 int format; 16808 struct ast_flags dummy[2]; 16809 int auto_sip_domains = FALSE; 16810 struct sockaddr_in old_bindaddr = bindaddr; 16811 int registry_count = 0, peer_count = 0, user_count = 0; 16812 unsigned int temp_tos = 0; 16813 struct ast_flags debugflag = {0}; 16814 16815 cfg = ast_config_load(config); 16816 16817 /* We *must* have a config file otherwise stop immediately */ 16818 if (!cfg) { 16819 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16820 return -1; 16821 } 16822 16823 if (option_debug > 3) 16824 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 16825 16826 clear_realm_authentication(authl); 16827 clear_sip_domains(); 16828 authl = NULL; 16829 16830 /* First, destroy all outstanding registry calls */ 16831 /* This is needed, since otherwise active registry entries will not be destroyed */ 16832 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16833 ASTOBJ_RDLOCK(iterator); 16834 if (iterator->call) { 16835 if (option_debug > 2) 16836 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 16837 /* This will also remove references to the registry */ 16838 sip_destroy(iterator->call); 16839 } 16840 ASTOBJ_UNLOCK(iterator); 16841 16842 } while(0)); 16843 16844 /* Then, actually destroy users and registry */ 16845 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 16846 if (option_debug > 3) 16847 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 16848 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 16849 if (option_debug > 3) 16850 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 16851 ASTOBJ_CONTAINER_MARKALL(&peerl); 16852 16853 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16854 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16855 oldregcontext = oldcontexts; 16856 16857 /* Clear all flags before setting default values */ 16858 /* Preserve debugging settings for console */ 16859 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16860 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16861 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16862 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16863 16864 /* Reset IP addresses */ 16865 memset(&bindaddr, 0, sizeof(bindaddr)); 16866 ast_free_ha(localaddr); 16867 memset(&localaddr, 0, sizeof(localaddr)); 16868 memset(&externip, 0, sizeof(externip)); 16869 memset(&default_prefs, 0 , sizeof(default_prefs)); 16870 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16871 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16872 ourport = STANDARD_SIP_PORT; 16873 srvlookup = DEFAULT_SRVLOOKUP; 16874 global_tos_sip = DEFAULT_TOS_SIP; 16875 global_tos_audio = DEFAULT_TOS_AUDIO; 16876 global_tos_video = DEFAULT_TOS_VIDEO; 16877 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16878 externexpire = 0; /* Expiration for DNS re-issuing */ 16879 externrefresh = 10; 16880 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16881 16882 /* Reset channel settings to default before re-configuring */ 16883 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16884 global_regcontext[0] = '\0'; 16885 expiry = DEFAULT_EXPIRY; 16886 global_notifyringing = DEFAULT_NOTIFYRINGING; 16887 global_limitonpeers = FALSE; 16888 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16889 global_notifyhold = FALSE; 16890 global_alwaysauthreject = 0; 16891 global_allowsubscribe = FALSE; 16892 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16893 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16894 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16895 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16896 else 16897 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16898 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16899 compactheaders = DEFAULT_COMPACTHEADERS; 16900 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16901 global_regattempts_max = 0; 16902 pedanticsipchecking = DEFAULT_PEDANTIC; 16903 global_mwitime = DEFAULT_MWITIME; 16904 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16905 global_autoframing = 0; 16906 global_allowguest = DEFAULT_ALLOWGUEST; 16907 global_rtptimeout = 0; 16908 global_rtpholdtimeout = 0; 16909 global_rtpkeepalive = 0; 16910 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16911 global_rtautoclear = 120; 16912 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16913 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16914 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16915 16916 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16917 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16918 default_subscribecontext[0] = '\0'; 16919 default_language[0] = '\0'; 16920 default_fromdomain[0] = '\0'; 16921 default_qualify = DEFAULT_QUALIFY; 16922 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16923 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16924 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16925 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16926 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16927 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16928 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16929 16930 /* Debugging settings, always default to off */ 16931 dumphistory = FALSE; 16932 recordhistory = FALSE; 16933 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16934 16935 /* Misc settings for the channel */ 16936 global_relaxdtmf = FALSE; 16937 global_callevents = FALSE; 16938 global_t1min = DEFAULT_T1MIN; 16939 16940 global_matchexterniplocally = FALSE; 16941 16942 /* Copy the default jb config over global_jbconf */ 16943 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16944 16945 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16946 16947 /* Read the [general] config section of sip.conf (or from realtime config) */ 16948 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16949 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16950 continue; 16951 /* handle jb conf */ 16952 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16953 continue; 16954 16955 /* Create the interface list */ 16956 if (!strcasecmp(v->name, "context")) { 16957 ast_copy_string(default_context, v->value, sizeof(default_context)); 16958 } else if (!strcasecmp(v->name, "subscribecontext")) { 16959 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 16960 } else if (!strcasecmp(v->name, "allowguest")) { 16961 global_allowguest = ast_true(v->value) ? 1 : 0; 16962 } else if (!strcasecmp(v->name, "realm")) { 16963 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16964 } else if (!strcasecmp(v->name, "useragent")) { 16965 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16966 if (option_debug) 16967 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16968 } else if (!strcasecmp(v->name, "allowtransfer")) { 16969 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16970 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16971 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16972 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16973 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16974 } else if (!strcasecmp(v->name, "rtupdate")) { 16975 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16976 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16977 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16978 } else if (!strcasecmp(v->name, "t1min")) { 16979 global_t1min = atoi(v->value); 16980 } else if (!strcasecmp(v->name, "rtautoclear")) { 16981 int i = atoi(v->value); 16982 if (i > 0) 16983 global_rtautoclear = i; 16984 else 16985 i = 0; 16986 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16987 } else if (!strcasecmp(v->name, "usereqphone")) { 16988 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16989 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16990 global_relaxdtmf = ast_true(v->value); 16991 } else if (!strcasecmp(v->name, "checkmwi")) { 16992 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16993 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16994 global_mwitime = DEFAULT_MWITIME; 16995 } 16996 } else if (!strcasecmp(v->name, "vmexten")) { 16997 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16998 } else if (!strcasecmp(v->name, "rtptimeout")) { 16999 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17000 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17001 global_rtptimeout = 0; 17002 } 17003 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17004 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17005 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17006 global_rtpholdtimeout = 0; 17007 } 17008 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17009 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17010 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17011 global_rtpkeepalive = 0; 17012 } 17013 } else if (!strcasecmp(v->name, "compactheaders")) { 17014 compactheaders = ast_true(v->value); 17015 } else if (!strcasecmp(v->name, "notifymimetype")) { 17016 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17017 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17018 global_limitonpeers = ast_true(v->value); 17019 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17020 global_directrtpsetup = ast_true(v->value); 17021 } else if (!strcasecmp(v->name, "notifyringing")) { 17022 global_notifyringing = ast_true(v->value); 17023 } else if (!strcasecmp(v->name, "notifyhold")) { 17024 global_notifyhold = ast_true(v->value); 17025 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17026 global_alwaysauthreject = ast_true(v->value); 17027 } else if (!strcasecmp(v->name, "mohinterpret") 17028 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17029 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17030 } else if (!strcasecmp(v->name, "mohsuggest")) { 17031 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17032 } else if (!strcasecmp(v->name, "language")) { 17033 ast_copy_string(default_language, v->value, sizeof(default_language)); 17034 } else if (!strcasecmp(v->name, "regcontext")) { 17035 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17036 stringp = newcontexts; 17037 /* Let's remove any contexts that are no longer defined in regcontext */ 17038 cleanup_stale_contexts(stringp, oldregcontext); 17039 /* Create contexts if they don't exist already */ 17040 while ((context = strsep(&stringp, "&"))) { 17041 if (!ast_context_find(context)) 17042 ast_context_create(NULL, context,"SIP"); 17043 } 17044 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17045 } else if (!strcasecmp(v->name, "callerid")) { 17046 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17047 } else if (!strcasecmp(v->name, "fromdomain")) { 17048 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17049 } else if (!strcasecmp(v->name, "outboundproxy")) { 17050 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17051 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17052 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17053 /* Port needs to be after IP */ 17054 sscanf(v->value, "%d", &format); 17055 outboundproxyip.sin_port = htons(format); 17056 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17057 autocreatepeer = ast_true(v->value); 17058 } else if (!strcasecmp(v->name, "srvlookup")) { 17059 srvlookup = ast_true(v->value); 17060 } else if (!strcasecmp(v->name, "pedantic")) { 17061 pedanticsipchecking = ast_true(v->value); 17062 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17063 max_expiry = atoi(v->value); 17064 if (max_expiry < 1) 17065 max_expiry = DEFAULT_MAX_EXPIRY; 17066 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17067 min_expiry = atoi(v->value); 17068 if (min_expiry < 1) 17069 min_expiry = DEFAULT_MIN_EXPIRY; 17070 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17071 default_expiry = atoi(v->value); 17072 if (default_expiry < 1) 17073 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17074 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17075 if (ast_true(v->value)) 17076 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17077 } else if (!strcasecmp(v->name, "dumphistory")) { 17078 dumphistory = ast_true(v->value); 17079 } else if (!strcasecmp(v->name, "recordhistory")) { 17080 recordhistory = ast_true(v->value); 17081 } else if (!strcasecmp(v->name, "registertimeout")) { 17082 global_reg_timeout = atoi(v->value); 17083 if (global_reg_timeout < 1) 17084 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17085 } else if (!strcasecmp(v->name, "registerattempts")) { 17086 global_regattempts_max = atoi(v->value); 17087 } else if (!strcasecmp(v->name, "bindaddr")) { 17088 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17089 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17090 } else { 17091 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17092 } 17093 } else if (!strcasecmp(v->name, "localnet")) { 17094 struct ast_ha *na; 17095 if (!(na = ast_append_ha("d", v->value, localaddr))) 17096 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17097 else 17098 localaddr = na; 17099 } else if (!strcasecmp(v->name, "localmask")) { 17100 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17101 } else if (!strcasecmp(v->name, "externip")) { 17102 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17103 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17104 else 17105 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17106 externexpire = 0; 17107 } else if (!strcasecmp(v->name, "externhost")) { 17108 ast_copy_string(externhost, v->value, sizeof(externhost)); 17109 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17110 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17111 else 17112 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17113 externexpire = time(NULL); 17114 } else if (!strcasecmp(v->name, "externrefresh")) { 17115 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17116 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17117 externrefresh = 10; 17118 } 17119 } else if (!strcasecmp(v->name, "allow")) { 17120 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17121 } else if (!strcasecmp(v->name, "disallow")) { 17122 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17123 } else if (!strcasecmp(v->name, "autoframing")) { 17124 global_autoframing = ast_true(v->value); 17125 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17126 allow_external_domains = ast_true(v->value); 17127 } else if (!strcasecmp(v->name, "autodomain")) { 17128 auto_sip_domains = ast_true(v->value); 17129 } else if (!strcasecmp(v->name, "domain")) { 17130 char *domain = ast_strdupa(v->value); 17131 char *context = strchr(domain, ','); 17132 17133 if (context) 17134 *context++ = '\0'; 17135 17136 if (option_debug && ast_strlen_zero(context)) 17137 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17138 if (ast_strlen_zero(domain)) 17139 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17140 else 17141 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17142 } else if (!strcasecmp(v->name, "register")) { 17143 if (sip_register(v->value, v->lineno) == 0) 17144 registry_count++; 17145 } else if (!strcasecmp(v->name, "tos")) { 17146 if (!ast_str2tos(v->value, &temp_tos)) { 17147 global_tos_sip = temp_tos; 17148 global_tos_audio = temp_tos; 17149 global_tos_video = temp_tos; 17150 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17151 } else 17152 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17153 } else if (!strcasecmp(v->name, "tos_sip")) { 17154 if (ast_str2tos(v->value, &global_tos_sip)) 17155 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17156 } else if (!strcasecmp(v->name, "tos_audio")) { 17157 if (ast_str2tos(v->value, &global_tos_audio)) 17158 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17159 } else if (!strcasecmp(v->name, "tos_video")) { 17160 if (ast_str2tos(v->value, &global_tos_video)) 17161 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17162 } else if (!strcasecmp(v->name, "bindport")) { 17163 if (sscanf(v->value, "%d", &ourport) == 1) { 17164 bindaddr.sin_port = htons(ourport); 17165 } else { 17166 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17167 } 17168 } else if (!strcasecmp(v->name, "qualify")) { 17169 if (!strcasecmp(v->value, "no")) { 17170 default_qualify = 0; 17171 } else if (!strcasecmp(v->value, "yes")) { 17172 default_qualify = DEFAULT_MAXMS; 17173 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17174 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17175 default_qualify = 0; 17176 } 17177 } else if (!strcasecmp(v->name, "callevents")) { 17178 global_callevents = ast_true(v->value); 17179 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17180 default_maxcallbitrate = atoi(v->value); 17181 if (default_maxcallbitrate < 0) 17182 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17183 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17184 global_matchexterniplocally = ast_true(v->value); 17185 } 17186 } 17187 17188 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17189 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17190 allow_external_domains = 1; 17191 } 17192 17193 /* Build list of authentication to various SIP realms, i.e. service providers */ 17194 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17195 /* Format for authentication is auth = username:password@realm */ 17196 if (!strcasecmp(v->name, "auth")) 17197 authl = add_realm_authentication(authl, v->value, v->lineno); 17198 } 17199 17200 ucfg = ast_config_load("users.conf"); 17201 if (ucfg) { 17202 struct ast_variable *gen; 17203 int genhassip, genregistersip; 17204 const char *hassip, *registersip; 17205 17206 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17207 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17208 gen = ast_variable_browse(ucfg, "general"); 17209 cat = ast_category_browse(ucfg, NULL); 17210 while (cat) { 17211 if (strcasecmp(cat, "general")) { 17212 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17213 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17214 if (ast_true(hassip) || (!hassip && genhassip)) { 17215 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17216 if (user) { 17217 ASTOBJ_CONTAINER_LINK(&userl,user); 17218 ASTOBJ_UNREF(user, sip_destroy_user); 17219 user_count++; 17220 } 17221 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17222 if (peer) { 17223 ast_device_state_changed("SIP/%s", peer->name); 17224 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17225 ASTOBJ_UNREF(peer, sip_destroy_peer); 17226 peer_count++; 17227 } 17228 } 17229 if (ast_true(registersip) || (!registersip && genregistersip)) { 17230 char tmp[256]; 17231 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17232 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17233 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17234 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17235 if (!host) 17236 host = ast_variable_retrieve(ucfg, "general", "host"); 17237 if (!username) 17238 username = ast_variable_retrieve(ucfg, "general", "username"); 17239 if (!secret) 17240 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17241 if (!contact) 17242 contact = "s"; 17243 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17244 if (!ast_strlen_zero(secret)) 17245 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17246 else 17247 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17248 if (sip_register(tmp, 0) == 0) 17249 registry_count++; 17250 } 17251 } 17252 } 17253 cat = ast_category_browse(ucfg, cat); 17254 } 17255 ast_config_destroy(ucfg); 17256 } 17257 17258 17259 /* Load peers, users and friends */ 17260 cat = NULL; 17261 while ( (cat = ast_category_browse(cfg, cat)) ) { 17262 const char *utype; 17263 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17264 continue; 17265 utype = ast_variable_retrieve(cfg, cat, "type"); 17266 if (!utype) { 17267 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17268 continue; 17269 } else { 17270 int is_user = 0, is_peer = 0; 17271 if (!strcasecmp(utype, "user")) 17272 is_user = 1; 17273 else if (!strcasecmp(utype, "friend")) 17274 is_user = is_peer = 1; 17275 else if (!strcasecmp(utype, "peer")) 17276 is_peer = 1; 17277 else { 17278 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17279 continue; 17280 } 17281 if (is_user) { 17282 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17283 if (user) { 17284 ASTOBJ_CONTAINER_LINK(&userl,user); 17285 ASTOBJ_UNREF(user, sip_destroy_user); 17286 user_count++; 17287 } 17288 } 17289 if (is_peer) { 17290 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17291 if (peer) { 17292 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17293 ASTOBJ_UNREF(peer, sip_destroy_peer); 17294 peer_count++; 17295 } 17296 } 17297 } 17298 } 17299 if (ast_find_ourip(&__ourip, bindaddr)) { 17300 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17301 ast_config_destroy(cfg); 17302 return 0; 17303 } 17304 if (!ntohs(bindaddr.sin_port)) 17305 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17306 bindaddr.sin_family = AF_INET; 17307 ast_mutex_lock(&netlock); 17308 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17309 close(sipsock); 17310 sipsock = -1; 17311 } 17312 if (sipsock < 0) { 17313 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17314 if (sipsock < 0) { 17315 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17316 ast_config_destroy(cfg); 17317 return -1; 17318 } else { 17319 /* Allow SIP clients on the same host to access us: */ 17320 const int reuseFlag = 1; 17321 17322 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17323 (const char*)&reuseFlag, 17324 sizeof reuseFlag); 17325 17326 ast_enable_packet_fragmentation(sipsock); 17327 17328 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17329 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17330 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17331 strerror(errno)); 17332 close(sipsock); 17333 sipsock = -1; 17334 } else { 17335 if (option_verbose > 1) { 17336 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17337 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17338 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17339 } 17340 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17341 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17342 } 17343 } 17344 } 17345 ast_mutex_unlock(&netlock); 17346 17347 /* Add default domains - host name, IP address and IP:port */ 17348 /* Only do this if user added any sip domain with "localdomains" */ 17349 /* In order to *not* break backwards compatibility */ 17350 /* Some phones address us at IP only, some with additional port number */ 17351 if (auto_sip_domains) { 17352 char temp[MAXHOSTNAMELEN]; 17353 17354 /* First our default IP address */ 17355 if (bindaddr.sin_addr.s_addr) 17356 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17357 else 17358 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17359 17360 /* Our extern IP address, if configured */ 17361 if (externip.sin_addr.s_addr) 17362 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17363 17364 /* Extern host name (NAT traversal support) */ 17365 if (!ast_strlen_zero(externhost)) 17366 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17367 17368 /* Our host name */ 17369 if (!gethostname(temp, sizeof(temp))) 17370 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17371 } 17372 17373 /* Release configuration from memory */ 17374 ast_config_destroy(cfg); 17375 17376 /* Load the list of manual NOTIFY types to support */ 17377 if (notify_types) 17378 ast_config_destroy(notify_types); 17379 notify_types = ast_config_load(notify_config); 17380 17381 /* Done, tell the manager */ 17382 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); 17383 17384 return 0; 17385 }
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 11482 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(), key(), keys, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11483 { 11484 char tmp[512]; 11485 char *c; 11486 char oldnonce[256]; 11487 11488 /* table of recognised keywords, and places where they should be copied */ 11489 const struct x { 11490 const char *key; 11491 int field_index; 11492 } *i, keys[] = { 11493 { "realm=", ast_string_field_index(p, realm) }, 11494 { "nonce=", ast_string_field_index(p, nonce) }, 11495 { "opaque=", ast_string_field_index(p, opaque) }, 11496 { "qop=", ast_string_field_index(p, qop) }, 11497 { "domain=", ast_string_field_index(p, domain) }, 11498 { NULL, 0 }, 11499 }; 11500 11501 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11502 if (ast_strlen_zero(tmp)) 11503 return -1; 11504 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11505 ast_log(LOG_WARNING, "missing Digest.\n"); 11506 return -1; 11507 } 11508 c = tmp + strlen("Digest "); 11509 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11510 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11511 for (i = keys; i->key != NULL; i++) { 11512 char *src, *separator; 11513 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11514 continue; 11515 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11516 c += strlen(i->key); 11517 if (*c == '"') { 11518 src = ++c; 11519 separator = "\""; 11520 } else { 11521 src = c; 11522 separator = ","; 11523 } 11524 strsep(&c, separator); /* clear separator and move ptr */ 11525 ast_string_field_index_set(p, i->field_index, src); 11526 break; 11527 } 11528 if (i->key == NULL) /* not found, try ',' */ 11529 strsep(&c, ","); 11530 } 11531 /* Reset nonce count */ 11532 if (strcmp(p->nonce, oldnonce)) 11533 p->noncecount = 0; 11534 11535 /* Save auth data for following registrations */ 11536 if (p->registry) { 11537 struct sip_registry *r = p->registry; 11538 11539 if (strcmp(r->nonce, p->nonce)) { 11540 ast_string_field_set(r, realm, p->realm); 11541 ast_string_field_set(r, nonce, p->nonce); 11542 ast_string_field_set(r, domain, p->domain); 11543 ast_string_field_set(r, opaque, p->opaque); 11544 ast_string_field_set(r, qop, p->qop); 11545 r->noncecount = 0; 11546 } 11547 } 11548 return build_reply_digest(p, sipmethod, digest, digest_len); 11549 }
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 5916 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.
05917 { 05918 struct sip_request *orig = &p->initreq; 05919 char stripped[80]; 05920 char tmp[80]; 05921 char newto[256]; 05922 const char *c; 05923 const char *ot, *of; 05924 int is_strict = FALSE; /*!< Strict routing flag */ 05925 05926 memset(req, 0, sizeof(struct sip_request)); 05927 05928 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05929 05930 if (!seqno) { 05931 p->ocseq++; 05932 seqno = p->ocseq; 05933 } 05934 05935 if (newbranch) { 05936 p->branch ^= ast_random(); 05937 build_via(p); 05938 } 05939 05940 /* Check for strict or loose router */ 05941 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05942 is_strict = TRUE; 05943 if (sipdebug) 05944 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05945 } 05946 05947 if (sipmethod == SIP_CANCEL) 05948 c = p->initreq.rlPart2; /* Use original URI */ 05949 else if (sipmethod == SIP_ACK) { 05950 /* Use URI from Contact: in 200 OK (if INVITE) 05951 (we only have the contacturi on INVITEs) */ 05952 if (!ast_strlen_zero(p->okcontacturi)) 05953 c = is_strict ? p->route->hop : p->okcontacturi; 05954 else 05955 c = p->initreq.rlPart2; 05956 } else if (!ast_strlen_zero(p->okcontacturi)) 05957 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05958 else if (!ast_strlen_zero(p->uri)) 05959 c = p->uri; 05960 else { 05961 char *n; 05962 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05963 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05964 sizeof(stripped)); 05965 n = get_in_brackets(stripped); 05966 c = strsep(&n, ";"); /* trim ; and beyond */ 05967 } 05968 init_req(req, sipmethod, c); 05969 05970 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05971 05972 add_header(req, "Via", p->via); 05973 if (p->route) { 05974 set_destination(p, p->route->hop); 05975 add_route(req, is_strict ? p->route->next : p->route); 05976 } 05977 05978 ot = get_header(orig, "To"); 05979 of = get_header(orig, "From"); 05980 05981 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05982 as our original request, including tag (or presumably lack thereof) */ 05983 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05984 /* Add the proper tag if we don't have it already. If they have specified 05985 their tag, use it. Otherwise, use our own tag */ 05986 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05987 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05988 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05989 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05990 else 05991 snprintf(newto, sizeof(newto), "%s", ot); 05992 ot = newto; 05993 } 05994 05995 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05996 add_header(req, "From", of); 05997 add_header(req, "To", ot); 05998 } else { 05999 add_header(req, "From", ot); 06000 add_header(req, "To", of); 06001 } 06002 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06003 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06004 add_header(req, "Contact", p->our_contact); 06005 06006 copy_header(req, orig, "Call-ID"); 06007 add_header(req, "CSeq", tmp); 06008 06009 if (!ast_strlen_zero(global_useragent)) 06010 add_header(req, "User-Agent", global_useragent); 06011 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06012 06013 if (!ast_strlen_zero(p->rpid)) 06014 add_header(req, "Remote-Party-ID", p->rpid); 06015 06016 return 0; 06017 }
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 5868 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.
05869 { 05870 char newto[256]; 05871 const char *ot; 05872 05873 init_resp(resp, msg); 05874 copy_via_headers(p, resp, req, "Via"); 05875 if (msg[0] == '1' || msg[0] == '2') 05876 copy_all_header(resp, req, "Record-Route"); 05877 copy_header(resp, req, "From"); 05878 ot = get_header(req, "To"); 05879 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05880 /* Add the proper tag if we don't have it already. If they have specified 05881 their tag, use it. Otherwise, use our own tag */ 05882 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05883 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05884 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05885 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05886 else 05887 ast_copy_string(newto, ot, sizeof(newto)); 05888 ot = newto; 05889 } 05890 add_header(resp, "To", ot); 05891 copy_header(resp, req, "Call-ID"); 05892 copy_header(resp, req, "CSeq"); 05893 if (!ast_strlen_zero(global_useragent)) 05894 add_header(resp, "User-Agent", global_useragent); 05895 add_header(resp, "Allow", ALLOWED_METHODS); 05896 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05897 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05898 /* For registration responses, we also need expiry and 05899 contact info */ 05900 char tmp[256]; 05901 05902 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05903 add_header(resp, "Expires", tmp); 05904 if (p->expiry) { /* Only add contact if we have an expiry time */ 05905 char contact[SIPBUFSIZE]; 05906 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05907 add_header(resp, "Contact", contact); /* Not when we unregister */ 05908 } 05909 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05910 add_header(resp, "Contact", p->our_contact); 05911 } 05912 return 0; 05913 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15749 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.
15750 { 15751 /* If we're supposed to be stopped -- stay stopped */ 15752 if (monitor_thread == AST_PTHREADT_STOP) 15753 return 0; 15754 ast_mutex_lock(&monlock); 15755 if (monitor_thread == pthread_self()) { 15756 ast_mutex_unlock(&monlock); 15757 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15758 return -1; 15759 } 15760 if (monitor_thread != AST_PTHREADT_NULL) { 15761 /* Wake up the thread */ 15762 pthread_kill(monitor_thread, SIGURG); 15763 } else { 15764 /* Start a new monitor */ 15765 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15766 ast_mutex_unlock(&monlock); 15767 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15768 return -1; 15769 } 15770 } 15771 ast_mutex_unlock(&monlock); 15772 return 0; 15773 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1894 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, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01895 { 01896 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01897 int reschedule = DEFAULT_RETRANS; 01898 int xmitres = 0; 01899 01900 /* Lock channel PVT */ 01901 ast_mutex_lock(&pkt->owner->lock); 01902 01903 if (pkt->retrans < MAX_RETRANS) { 01904 pkt->retrans++; 01905 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01906 if (sipdebug && option_debug > 3) 01907 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); 01908 } else { 01909 int siptimer_a; 01910 01911 if (sipdebug && option_debug > 3) 01912 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01913 if (!pkt->timer_a) 01914 pkt->timer_a = 2 ; 01915 else 01916 pkt->timer_a = 2 * pkt->timer_a; 01917 01918 /* For non-invites, a maximum of 4 secs */ 01919 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01920 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01921 siptimer_a = 4000; 01922 01923 /* Reschedule re-transmit */ 01924 reschedule = siptimer_a; 01925 if (option_debug > 3) 01926 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); 01927 } 01928 01929 if (sip_debug_test_pvt(pkt->owner)) { 01930 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01931 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01932 pkt->retrans, sip_nat_mode(pkt->owner), 01933 ast_inet_ntoa(dst->sin_addr), 01934 ntohs(dst->sin_port), pkt->data); 01935 } 01936 01937 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01938 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01939 ast_mutex_unlock(&pkt->owner->lock); 01940 if (xmitres == XMIT_ERROR) 01941 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01942 else 01943 return reschedule; 01944 } 01945 /* Too many retries */ 01946 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01947 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01948 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request"); 01949 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01950 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01951 } 01952 if (xmitres == XMIT_ERROR) { 01953 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01954 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01955 } else 01956 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01957 01958 pkt->retransid = -1; 01959 01960 if (ast_test_flag(pkt, FLAG_FATAL)) { 01961 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01962 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01963 usleep(1); 01964 ast_mutex_lock(&pkt->owner->lock); 01965 } 01966 01967 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01968 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01969 01970 if (pkt->owner->owner) { 01971 sip_alreadygone(pkt->owner); 01972 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01973 ast_queue_hangup(pkt->owner->owner); 01974 ast_channel_unlock(pkt->owner->owner); 01975 } else { 01976 /* If no channel owner, destroy now */ 01977 01978 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01979 if (pkt->method != SIP_OPTIONS) { 01980 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01981 sip_alreadygone(pkt->owner); 01982 if (option_debug) 01983 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01984 } 01985 } 01986 } 01987 01988 if (pkt->method == SIP_BYE) { 01989 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01990 if (pkt->owner->owner) 01991 ast_channel_unlock(pkt->owner->owner); 01992 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01993 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01994 } 01995 01996 /* In any case, go ahead and remove the packet */ 01997 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01998 if (cur == pkt) 01999 break; 02000 } 02001 if (cur) { 02002 if (prev) 02003 prev->next = cur->next; 02004 else 02005 pkt->owner->packets = cur->next; 02006 ast_mutex_unlock(&pkt->owner->lock); 02007 free(cur); 02008 pkt = NULL; 02009 } else 02010 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02011 if (pkt) 02012 ast_mutex_unlock(&pkt->owner->lock); 02013 return 0; 02014 }
static int send_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
enum xmittype | reliable, | |||
int | seqno | |||
) | [static] |
Send SIP Request to the other part of the dialogue.
Definition at line 2289 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.
02290 { 02291 int res; 02292 02293 add_blank(req); 02294 if (sip_debug_test_pvt(p)) { 02295 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02296 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); 02297 else 02298 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); 02299 } 02300 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02301 struct sip_request tmp; 02302 parse_copy(&tmp, req); 02303 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02304 } 02305 res = (reliable) ? 02306 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02307 __sip_xmit(p, req->data, req->len); 02308 return res; 02309 }
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 2261 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.
02262 { 02263 int res; 02264 02265 add_blank(req); 02266 if (sip_debug_test_pvt(p)) { 02267 const struct sockaddr_in *dst = sip_real_dst(p); 02268 02269 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02270 reliable ? "Reliably " : "", sip_nat_mode(p), 02271 ast_inet_ntoa(dst->sin_addr), 02272 ntohs(dst->sin_port), req->data); 02273 } 02274 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02275 struct sip_request tmp; 02276 parse_copy(&tmp, req); 02277 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02278 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02279 } 02280 res = (reliable) ? 02281 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02282 __sip_xmit(p, req->data, req->len); 02283 if (res > 0) 02284 return 0; 02285 return res; 02286 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8015 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().
08016 { 08017 struct hostent *hp; 08018 struct ast_hostent ahp; 08019 int port; 08020 char *c, *host, *pt; 08021 char contact_buf[256]; 08022 char *contact; 08023 08024 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08025 /* NAT: Don't trust the contact field. Just use what they came to us 08026 with. */ 08027 pvt->sa = pvt->recv; 08028 return 0; 08029 } 08030 08031 /* Work on a copy */ 08032 ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf)); 08033 contact = contact_buf; 08034 08035 /* Make sure it's a SIP URL */ 08036 if (strncasecmp(contact, "sip:", 4)) { 08037 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08038 } else 08039 contact += 4; 08040 08041 /* Ditch arguments */ 08042 /* XXX this code is replicated also shortly below */ 08043 08044 /* Grab host */ 08045 host = strchr(contact, '@'); 08046 if (!host) { /* No username part */ 08047 host = contact; 08048 c = NULL; 08049 } else { 08050 *host++ = '\0'; 08051 } 08052 pt = strchr(host, ':'); 08053 if (pt) { 08054 *pt++ = '\0'; 08055 port = atoi(pt); 08056 } else 08057 port = STANDARD_SIP_PORT; 08058 08059 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08060 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08061 08062 /* XXX This could block for a long time XXX */ 08063 /* We should only do this if it's a name, not an IP */ 08064 hp = ast_gethostbyname(host, &ahp); 08065 if (!hp) { 08066 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08067 return -1; 08068 } 08069 pvt->sa.sin_family = AF_INET; 08070 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08071 pvt->sa.sin_port = htons(port); 08072 08073 return 0; 08074 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5777 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().
05778 { 05779 char *h, *maddr, hostname[256]; 05780 int port, hn; 05781 struct hostent *hp; 05782 struct ast_hostent ahp; 05783 int debug=sip_debug_test_pvt(p); 05784 05785 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05786 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05787 05788 if (debug) 05789 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05790 05791 /* Find and parse hostname */ 05792 h = strchr(uri, '@'); 05793 if (h) 05794 ++h; 05795 else { 05796 h = uri; 05797 if (strncasecmp(h, "sip:", 4) == 0) 05798 h += 4; 05799 else if (strncasecmp(h, "sips:", 5) == 0) 05800 h += 5; 05801 } 05802 hn = strcspn(h, ":;>") + 1; 05803 if (hn > sizeof(hostname)) 05804 hn = sizeof(hostname); 05805 ast_copy_string(hostname, h, hn); 05806 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05807 h += hn - 1; 05808 05809 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05810 if (*h == ':') { 05811 /* Parse port */ 05812 ++h; 05813 port = strtol(h, &h, 10); 05814 } 05815 else 05816 port = STANDARD_SIP_PORT; 05817 05818 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05819 maddr = strstr(h, "maddr="); 05820 if (maddr) { 05821 maddr += 6; 05822 hn = strspn(maddr, "0123456789.") + 1; 05823 if (hn > sizeof(hostname)) 05824 hn = sizeof(hostname); 05825 ast_copy_string(hostname, maddr, hn); 05826 } 05827 05828 hp = ast_gethostbyname(hostname, &ahp); 05829 if (hp == NULL) { 05830 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05831 return; 05832 } 05833 p->sa.sin_family = AF_INET; 05834 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05835 p->sa.sin_port = htons(port); 05836 if (debug) 05837 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05838 }
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 16051 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().
16052 { 16053 static int dep_insecure_very = 0; 16054 static int dep_insecure_yes = 0; 16055 16056 if (ast_strlen_zero(value)) 16057 return; 16058 16059 if (!strcasecmp(value, "very")) { 16060 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16061 if(!dep_insecure_very) { 16062 if(lineno != -1) 16063 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16064 else 16065 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16066 dep_insecure_very = 1; 16067 } 16068 } 16069 else if (ast_true(value)) { 16070 ast_set_flag(flags, SIP_INSECURE_PORT); 16071 if(!dep_insecure_yes) { 16072 if(lineno != -1) 16073 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16074 else 16075 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16076 dep_insecure_yes = 1; 16077 } 16078 } 16079 else if (!ast_false(value)) { 16080 char buf[64]; 16081 char *word, *next; 16082 ast_copy_string(buf, value, sizeof(buf)); 16083 next = buf; 16084 while ((word = strsep(&next, ","))) { 16085 if (!strcasecmp(word, "port")) 16086 ast_set_flag(flags, SIP_INSECURE_PORT); 16087 else if (!strcasecmp(word, "invite")) 16088 ast_set_flag(flags, SIP_INSECURE_INVITE); 16089 else 16090 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16091 } 16092 } 16093 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16479 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().
16480 { 16481 if (peer->expire == 0) { 16482 /* Don't reset expire or port time during reload 16483 if we have an active registration 16484 */ 16485 peer->expire = -1; 16486 peer->pokeexpire = -1; 16487 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16488 } 16489 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16490 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16491 strcpy(peer->context, default_context); 16492 strcpy(peer->subscribecontext, default_subscribecontext); 16493 strcpy(peer->language, default_language); 16494 strcpy(peer->mohinterpret, default_mohinterpret); 16495 strcpy(peer->mohsuggest, default_mohsuggest); 16496 peer->addr.sin_family = AF_INET; 16497 peer->defaddr.sin_family = AF_INET; 16498 peer->capability = global_capability; 16499 peer->maxcallbitrate = default_maxcallbitrate; 16500 peer->rtptimeout = global_rtptimeout; 16501 peer->rtpholdtimeout = global_rtpholdtimeout; 16502 peer->rtpkeepalive = global_rtpkeepalive; 16503 peer->allowtransfer = global_allowtransfer; 16504 peer->autoframing = global_autoframing; 16505 strcpy(peer->vmexten, default_vmexten); 16506 peer->secret[0] = '\0'; 16507 peer->md5secret[0] = '\0'; 16508 peer->cid_num[0] = '\0'; 16509 peer->cid_name[0] = '\0'; 16510 peer->fromdomain[0] = '\0'; 16511 peer->fromuser[0] = '\0'; 16512 peer->regexten[0] = '\0'; 16513 peer->mailbox[0] = '\0'; 16514 peer->callgroup = 0; 16515 peer->pickupgroup = 0; 16516 peer->maxms = default_qualify; 16517 peer->prefs = default_prefs; 16518 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17724 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().
17725 { 17726 int no = 0; 17727 int ok = FALSE; 17728 char varbuf[30]; 17729 char *inbuf = (char *) data; 17730 17731 if (ast_strlen_zero(inbuf)) { 17732 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17733 return 0; 17734 } 17735 ast_channel_lock(chan); 17736 17737 /* Check for headers */ 17738 while (!ok && no <= 50) { 17739 no++; 17740 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17741 17742 /* Compare without the leading underscore */ 17743 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17744 ok = TRUE; 17745 } 17746 if (ok) { 17747 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17748 if (sipdebug) 17749 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17750 } else { 17751 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17752 } 17753 ast_channel_unlock(chan); 17754 return 0; 17755 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2654 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02655 { 02656 /* We know name is the first field, so we can cast */ 02657 struct sip_peer *p = (struct sip_peer *) name; 02658 return !(!inaddrcmp(&p->addr, sin) || 02659 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02660 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02661 }
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 4437 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_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().
04439 { 04440 struct sip_pvt *p; 04441 04442 if (!(p = ast_calloc(1, sizeof(*p)))) 04443 return NULL; 04444 04445 if (ast_string_field_init(p, 512)) { 04446 free(p); 04447 return NULL; 04448 } 04449 04450 ast_mutex_init(&p->lock); 04451 04452 p->method = intended_method; 04453 p->initid = -1; 04454 p->waitid = -1; 04455 p->autokillid = -1; 04456 p->subscribed = NONE; 04457 p->stateid = -1; 04458 p->prefs = default_prefs; /* Set default codecs for this call */ 04459 04460 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04461 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04462 04463 if (sin) { 04464 p->sa = *sin; 04465 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04466 p->ourip = __ourip; 04467 } else 04468 p->ourip = __ourip; 04469 04470 /* Copy global flags to this PVT at setup. */ 04471 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04472 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04473 04474 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04475 04476 p->branch = ast_random(); 04477 make_our_tag(p->tag, sizeof(p->tag)); 04478 p->ocseq = INITIAL_CSEQ; 04479 04480 if (sip_methods[intended_method].need_rtp) { 04481 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04482 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04483 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04484 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04485 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04486 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04487 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04488 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04489 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04490 ast_mutex_destroy(&p->lock); 04491 if (p->chanvars) { 04492 ast_variables_destroy(p->chanvars); 04493 p->chanvars = NULL; 04494 } 04495 free(p); 04496 return NULL; 04497 } 04498 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04499 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04500 ast_rtp_settos(p->rtp, global_tos_audio); 04501 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04502 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04503 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04504 if (p->vrtp) { 04505 ast_rtp_settos(p->vrtp, global_tos_video); 04506 ast_rtp_setdtmf(p->vrtp, 0); 04507 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04508 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04509 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04510 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04511 } 04512 if (p->udptl) 04513 ast_udptl_settos(p->udptl, global_tos_audio); 04514 p->maxcallbitrate = default_maxcallbitrate; 04515 } 04516 04517 if (useglobal_nat && sin) { 04518 /* Setup NAT structure according to global settings if we have an address */ 04519 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04520 p->recv = *sin; 04521 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04522 } 04523 04524 if (p->method != SIP_REGISTER) 04525 ast_string_field_set(p, fromdomain, default_fromdomain); 04526 build_via(p); 04527 if (!callid) 04528 build_callid_pvt(p); 04529 else 04530 ast_string_field_set(p, callid, callid); 04531 /* Assign default music on hold class */ 04532 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04533 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04534 p->capability = global_capability; 04535 p->allowtransfer = global_allowtransfer; 04536 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04537 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04538 p->noncodeccapability |= AST_RTP_DTMF; 04539 if (p->udptl) { 04540 p->t38.capability = global_t38_capability; 04541 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04542 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04543 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04544 p->t38.capability |= T38FAX_UDP_EC_FEC; 04545 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04546 p->t38.capability |= T38FAX_UDP_EC_NONE; 04547 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04548 p->t38.jointcapability = p->t38.capability; 04549 } 04550 ast_string_field_set(p, context, default_context); 04551 04552 /* Add to active dialog list */ 04553 ast_mutex_lock(&iflock); 04554 p->next = iflist; 04555 iflist = p; 04556 ast_mutex_unlock(&iflock); 04557 if (option_debug) 04558 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"); 04559 return p; 04560 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1653 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().
01654 { 01655 if (option_debug > 2) 01656 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01657 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01658 }
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 3667 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.
03668 { 03669 int res = 0; 03670 struct sip_pvt *p = ast->tech_pvt; 03671 03672 ast_mutex_lock(&p->lock); 03673 if (ast->_state != AST_STATE_UP) { 03674 try_suggested_sip_codec(p); 03675 03676 ast_setstate(ast, AST_STATE_UP); 03677 if (option_debug) 03678 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03679 if (p->t38.state == T38_PEER_DIRECT) { 03680 p->t38.state = T38_ENABLED; 03681 if (option_debug > 1) 03682 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03683 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03684 } else { 03685 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03686 } 03687 } 03688 ast_mutex_unlock(&p->lock); 03689 return res; 03690 }
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 2958 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.
02959 { 02960 int res, xmitres = 0; 02961 struct sip_pvt *p; 02962 struct varshead *headp; 02963 struct ast_var_t *current; 02964 const char *referer = NULL; /* SIP refererer */ 02965 02966 p = ast->tech_pvt; 02967 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02968 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02969 return -1; 02970 } 02971 02972 /* Check whether there is vxml_url, distinctive ring variables */ 02973 headp=&ast->varshead; 02974 AST_LIST_TRAVERSE(headp,current,entries) { 02975 /* Check whether there is a VXML_URL variable */ 02976 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02977 p->options->vxml_url = ast_var_value(current); 02978 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02979 p->options->uri_options = ast_var_value(current); 02980 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02981 /* Check whether there is a ALERT_INFO variable */ 02982 p->options->distinctive_ring = ast_var_value(current); 02983 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02984 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02985 p->options->addsipheaders = 1; 02986 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02987 /* This is a transfered call */ 02988 p->options->transfer = 1; 02989 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02990 /* This is the referer */ 02991 referer = ast_var_value(current); 02992 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02993 /* We're replacing a call. */ 02994 p->options->replaces = ast_var_value(current); 02995 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02996 p->t38.state = T38_LOCAL_DIRECT; 02997 if (option_debug) 02998 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02999 } 03000 03001 } 03002 03003 res = 0; 03004 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03005 03006 if (p->options->transfer) { 03007 char buf[SIPBUFSIZE/2]; 03008 03009 if (referer) { 03010 if (sipdebug && option_debug > 2) 03011 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03012 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03013 } else 03014 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03015 ast_string_field_set(p, cid_name, buf); 03016 } 03017 if (option_debug) 03018 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03019 03020 res = update_call_counter(p, INC_CALL_RINGING); 03021 if ( res != -1 ) { 03022 p->callingpres = ast->cid.cid_pres; 03023 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03024 p->jointnoncodeccapability = p->noncodeccapability; 03025 03026 /* If there are no audio formats left to offer, punt */ 03027 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03028 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03029 res = -1; 03030 } else { 03031 p->t38.jointcapability = p->t38.capability; 03032 if (option_debug > 1) 03033 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03034 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03035 if (xmitres == XMIT_ERROR) 03036 return -1; /* Transmission error */ 03037 03038 p->invitestate = INV_CALLING; 03039 03040 /* Initialize auto-congest time */ 03041 AST_SCHED_DEL(sched, p->initid); 03042 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03043 } 03044 } 03045 return res; 03046 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2129 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02130 { 02131 int res = 0; 02132 if (p->autokillid > -1) { 02133 if (!(res = ast_sched_del(sched, p->autokillid))) { 02134 append_history(p, "CancelDestroy", ""); 02135 p->autokillid = -1; 02136 } 02137 } 02138 return res; 02139 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1735 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01736 { 01737 if (!sipdebug) 01738 return 0; 01739 if (debugaddr.sin_addr.s_addr) { 01740 if (((ntohs(debugaddr.sin_port) != 0) 01741 && (debugaddr.sin_port != addr->sin_port)) 01742 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01743 return 0; 01744 } 01745 return 1; 01746 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1761 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().
01762 { 01763 if (!sipdebug) 01764 return 0; 01765 return sip_debug_test_addr(sip_real_dst(p)); 01766 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3310 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().
03311 { 03312 ast_mutex_lock(&iflock); 03313 if (option_debug > 2) 03314 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03315 __sip_destroy(p, 1); 03316 ast_mutex_unlock(&iflock); 03317 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2461 of file chan_sip.c.
References ast_free_ha(), ast_log(), AST_SCHED_DEL, ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_prune_realtime(), unload_module(), and update_call_counter().
02462 { 02463 if (option_debug > 2) 02464 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02465 02466 /* Delete it, it needs to disappear */ 02467 if (peer->call) 02468 sip_destroy(peer->call); 02469 02470 if (peer->mwipvt) /* We have an active subscription, delete it */ 02471 sip_destroy(peer->mwipvt); 02472 02473 if (peer->chanvars) { 02474 ast_variables_destroy(peer->chanvars); 02475 peer->chanvars = NULL; 02476 } 02477 02478 /* If the schedule delete fails, that means the schedule is currently 02479 * running, which means we should wait for that thread to complete. 02480 * Otherwise, there's a crashable race condition. 02481 * 02482 * NOTE: once peer is refcounted, this probably is no longer necessary. 02483 */ 02484 AST_SCHED_DEL(sched, peer->expire); 02485 AST_SCHED_DEL(sched, peer->pokeexpire); 02486 02487 register_peer_exten(peer, FALSE); 02488 ast_free_ha(peer->ha); 02489 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02490 apeerobjs--; 02491 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02492 rpeerobjs--; 02493 else 02494 speerobjs--; 02495 clear_realm_authentication(peer->auth); 02496 peer->auth = NULL; 02497 free(peer); 02498 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2682 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().
02683 { 02684 if (option_debug > 2) 02685 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02686 ast_free_ha(user->ha); 02687 if (user->chanvars) { 02688 ast_variables_destroy(user->chanvars); 02689 user->chanvars = NULL; 02690 } 02691 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02692 ruserobjs--; 02693 else 02694 suserobjs--; 02695 free(user); 02696 }
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 15893 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().
15894 { 15895 char *host; 15896 char *tmp; 15897 15898 struct hostent *hp; 15899 struct ast_hostent ahp; 15900 struct sip_peer *p; 15901 15902 int res = AST_DEVICE_INVALID; 15903 15904 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15905 host = ast_strdupa(data ? data : ""); 15906 if ((tmp = strchr(host, '@'))) 15907 host = tmp + 1; 15908 15909 if (option_debug > 2) 15910 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15911 15912 if ((p = find_peer(host, NULL, 1))) { 15913 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15914 /* we have an address for the peer */ 15915 15916 /* Check status in this order 15917 - Hold 15918 - Ringing 15919 - Busy (enforced only by call limit) 15920 - Inuse (we have a call) 15921 - Unreachable (qualify) 15922 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15923 for registered devices */ 15924 15925 if (p->onHold) 15926 /* First check for hold or ring states */ 15927 res = AST_DEVICE_ONHOLD; 15928 else if (p->inRinging) { 15929 if (p->inRinging == p->inUse) 15930 res = AST_DEVICE_RINGING; 15931 else 15932 res = AST_DEVICE_RINGINUSE; 15933 } else if (p->call_limit && (p->inUse == p->call_limit)) 15934 /* check call limit */ 15935 res = AST_DEVICE_BUSY; 15936 else if (p->call_limit && p->inUse) 15937 /* Not busy, but we do have a call */ 15938 res = AST_DEVICE_INUSE; 15939 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 15940 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15941 res = AST_DEVICE_UNAVAILABLE; 15942 else /* Default reply if we're registered and have no other data */ 15943 res = AST_DEVICE_NOT_INUSE; 15944 } else { 15945 /* there is no address, it's unavailable */ 15946 res = AST_DEVICE_UNAVAILABLE; 15947 } 15948 ASTOBJ_UNREF(p,sip_destroy_peer); 15949 } else { 15950 char *port = strchr(host, ':'); 15951 if (port) 15952 *port = '\0'; 15953 hp = ast_gethostbyname(host, &ahp); 15954 if (hp) 15955 res = AST_DEVICE_UNKNOWN; 15956 } 15957 15958 return res; 15959 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11295 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.
11296 { 11297 int oldsipdebug = sipdebug_console; 11298 if (argc != 3) { 11299 if (argc != 5) 11300 return RESULT_SHOWUSAGE; 11301 else if (strcmp(argv[3], "ip") == 0) 11302 return sip_do_debug_ip(fd, argc, argv); 11303 else if (strcmp(argv[3], "peer") == 0) 11304 return sip_do_debug_peer(fd, argc, argv); 11305 else 11306 return RESULT_SHOWUSAGE; 11307 } 11308 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11309 memset(&debugaddr, 0, sizeof(debugaddr)); 11310 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11311 return RESULT_SUCCESS; 11312 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11314 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.
11315 { 11316 int oldsipdebug = sipdebug_console; 11317 char *newargv[6] = { "sip", "set", "debug", NULL }; 11318 if (argc != 2) { 11319 if (argc != 4) 11320 return RESULT_SHOWUSAGE; 11321 else if (strcmp(argv[2], "ip") == 0) { 11322 newargv[3] = argv[2]; 11323 newargv[4] = argv[3]; 11324 return sip_do_debug_ip(fd, argc + 1, newargv); 11325 } else if (strcmp(argv[2], "peer") == 0) { 11326 newargv[3] = argv[2]; 11327 newargv[4] = argv[3]; 11328 return sip_do_debug_peer(fd, argc + 1, newargv); 11329 } else 11330 return RESULT_SHOWUSAGE; 11331 } 11332 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11333 memset(&debugaddr, 0, sizeof(debugaddr)); 11334 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11335 return RESULT_SUCCESS; 11336 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11241 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().
11242 { 11243 struct hostent *hp; 11244 struct ast_hostent ahp; 11245 int port = 0; 11246 char *p, *arg; 11247 11248 /* sip set debug ip <ip> */ 11249 if (argc != 5) 11250 return RESULT_SHOWUSAGE; 11251 p = arg = argv[4]; 11252 strsep(&p, ":"); 11253 if (p) 11254 port = atoi(p); 11255 hp = ast_gethostbyname(arg, &ahp); 11256 if (hp == NULL) 11257 return RESULT_SHOWUSAGE; 11258 11259 debugaddr.sin_family = AF_INET; 11260 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11261 debugaddr.sin_port = htons(port); 11262 if (port == 0) 11263 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11264 else 11265 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11266 11267 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11268 11269 return RESULT_SUCCESS; 11270 }
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 11273 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().
11274 { 11275 struct sip_peer *peer; 11276 if (argc != 5) 11277 return RESULT_SHOWUSAGE; 11278 peer = find_peer(argv[4], NULL, 1); 11279 if (peer) { 11280 if (peer->addr.sin_addr.s_addr) { 11281 debugaddr.sin_family = AF_INET; 11282 debugaddr.sin_addr = peer->addr.sin_addr; 11283 debugaddr.sin_port = peer->addr.sin_port; 11284 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11285 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11286 } else 11287 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11288 ASTOBJ_UNREF(peer,sip_destroy_peer); 11289 } else 11290 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11291 return RESULT_SUCCESS; 11292 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11414 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11415 { 11416 if (argc != 2) { 11417 return RESULT_SHOWUSAGE; 11418 } 11419 recordhistory = TRUE; 11420 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11421 return RESULT_SUCCESS; 11422 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17864 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().
17865 { 17866 reload_config(reason); 17867 17868 /* Prune peers who still are supposed to be deleted */ 17869 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17870 if (option_debug > 3) 17871 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17872 17873 /* Send qualify (OPTIONS) to all peers */ 17874 sip_poke_all_peers(); 17875 17876 /* Register with all services */ 17877 sip_send_all_registers(); 17878 17879 if (option_debug > 3) 17880 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17881 17882 return 0; 17883 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17669 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().
17670 { 17671 struct sip_pvt *p; 17672 char *mode; 17673 if (data) 17674 mode = (char *)data; 17675 else { 17676 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17677 return 0; 17678 } 17679 ast_channel_lock(chan); 17680 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17681 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17682 ast_channel_unlock(chan); 17683 return 0; 17684 } 17685 p = chan->tech_pvt; 17686 if (!p) { 17687 ast_channel_unlock(chan); 17688 return 0; 17689 } 17690 ast_mutex_lock(&p->lock); 17691 if (!strcasecmp(mode,"info")) { 17692 ast_clear_flag(&p->flags[0], SIP_DTMF); 17693 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17694 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17695 } else if (!strcasecmp(mode,"rfc2833")) { 17696 ast_clear_flag(&p->flags[0], SIP_DTMF); 17697 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17698 p->jointnoncodeccapability |= AST_RTP_DTMF; 17699 } else if (!strcasecmp(mode,"inband")) { 17700 ast_clear_flag(&p->flags[0], SIP_DTMF); 17701 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17702 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17703 } else 17704 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17705 if (p->rtp) 17706 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17707 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17708 if (!p->vad) { 17709 p->vad = ast_dsp_new(); 17710 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17711 } 17712 } else { 17713 if (p->vad) { 17714 ast_dsp_free(p->vad); 17715 p->vad = NULL; 17716 } 17717 } 17718 ast_mutex_unlock(&p->lock); 17719 ast_channel_unlock(chan); 17720 return 0; 17721 }
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 11106 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().
11107 { 11108 int x = 0; 11109 struct sip_history *hist; 11110 static int errmsg = 0; 11111 11112 if (!dialog) 11113 return; 11114 11115 if (!option_debug && !sipdebug) { 11116 if (!errmsg) { 11117 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11118 errmsg = 1; 11119 } 11120 return; 11121 } 11122 11123 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11124 if (dialog->subscribed) 11125 ast_log(LOG_DEBUG, " * Subscription\n"); 11126 else 11127 ast_log(LOG_DEBUG, " * SIP Call\n"); 11128 if (dialog->history) 11129 AST_LIST_TRAVERSE(dialog->history, hist, list) 11130 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11131 if (!x) 11132 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11133 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11134 }
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 3773 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, and ast_channel::tech_pvt.
03774 { 03775 int ret = -1; 03776 struct sip_pvt *p; 03777 03778 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03779 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03780 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03781 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03782 03783 if (!newchan || !newchan->tech_pvt) { 03784 if (!newchan) 03785 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03786 else 03787 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03788 return -1; 03789 } 03790 p = newchan->tech_pvt; 03791 03792 if (!p) { 03793 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03794 return -1; 03795 } 03796 03797 ast_mutex_lock(&p->lock); 03798 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03799 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03800 if (p->owner != oldchan) 03801 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03802 else { 03803 p->owner = newchan; 03804 ret = 0; 03805 } 03806 if (option_debug > 2) 03807 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03808 03809 ast_mutex_unlock(&p->lock); 03810 return ret; 03811 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17815 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17816 { 17817 struct sip_pvt *p = chan->tech_pvt; 17818 return p->peercapability ? p->peercapability : p->capability; 17819 }
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 17522 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.
17523 { 17524 struct sip_pvt *p = NULL; 17525 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17526 17527 if (!(p = chan->tech_pvt)) 17528 return AST_RTP_GET_FAILED; 17529 17530 ast_mutex_lock(&p->lock); 17531 if (!(p->rtp)) { 17532 ast_mutex_unlock(&p->lock); 17533 return AST_RTP_GET_FAILED; 17534 } 17535 17536 *rtp = p->rtp; 17537 17538 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17539 res = AST_RTP_TRY_PARTIAL; 17540 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17541 res = AST_RTP_TRY_NATIVE; 17542 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17543 res = AST_RTP_GET_FAILED; 17544 17545 ast_mutex_unlock(&p->lock); 17546 17547 return res; 17548 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 17387 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.
17388 { 17389 struct sip_pvt *p; 17390 struct ast_udptl *udptl = NULL; 17391 17392 p = chan->tech_pvt; 17393 if (!p) 17394 return NULL; 17395 17396 ast_mutex_lock(&p->lock); 17397 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17398 udptl = p->udptl; 17399 ast_mutex_unlock(&p->lock); 17400 return udptl; 17401 }
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 17551 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.
17552 { 17553 struct sip_pvt *p = NULL; 17554 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17555 17556 if (!(p = chan->tech_pvt)) 17557 return AST_RTP_GET_FAILED; 17558 17559 ast_mutex_lock(&p->lock); 17560 if (!(p->vrtp)) { 17561 ast_mutex_unlock(&p->lock); 17562 return AST_RTP_GET_FAILED; 17563 } 17564 17565 *rtp = p->vrtp; 17566 17567 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17568 res = AST_RTP_TRY_NATIVE; 17569 17570 ast_mutex_unlock(&p->lock); 17571 17572 return res; 17573 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 17439 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().
17440 { 17441 struct sip_pvt *p; 17442 int flag = 0; 17443 17444 p = chan->tech_pvt; 17445 if (!p || !pvt->udptl) 17446 return -1; 17447 17448 /* Setup everything on the other side like offered/responded from first side */ 17449 ast_mutex_lock(&p->lock); 17450 17451 /*! \todo check if this is not set earlier when setting up the PVT. If not 17452 maybe it should move there. */ 17453 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17454 17455 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17456 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17457 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17458 17459 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17460 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17461 not really T38 re-invites which are different. In this 17462 case it's used properly, to see if we can reinvite over 17463 NAT 17464 */ 17465 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17466 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17467 flag =1; 17468 } else { 17469 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17470 } 17471 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17472 if (!p->pendinginvite) { 17473 if (option_debug > 2) { 17474 if (flag) 17475 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)); 17476 else 17477 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)); 17478 } 17479 transmit_reinvite_with_t38_sdp(p); 17480 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17481 if (option_debug > 2) { 17482 if (flag) 17483 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)); 17484 else 17485 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)); 17486 } 17487 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17488 } 17489 } 17490 /* Reset lastrtprx timer */ 17491 p->lastrtprx = p->lastrtptx = time(NULL); 17492 ast_mutex_unlock(&p->lock); 17493 return 0; 17494 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17495 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17496 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17497 flag = 1; 17498 } else { 17499 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17500 } 17501 if (option_debug > 2) { 17502 if (flag) 17503 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)); 17504 else 17505 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)); 17506 } 17507 pvt->t38.state = T38_ENABLED; 17508 p->t38.state = T38_ENABLED; 17509 if (option_debug > 1) { 17510 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17511 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17512 } 17513 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17514 p->lastrtprx = p->lastrtptx = time(NULL); 17515 ast_mutex_unlock(&p->lock); 17516 return 0; 17517 } 17518 }
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 3482 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.
03483 { 03484 struct sip_pvt *p = ast->tech_pvt; 03485 int needcancel = FALSE; 03486 int needdestroy = 0; 03487 struct ast_channel *oldowner = ast; 03488 03489 if (!p) { 03490 if (option_debug) 03491 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03492 return 0; 03493 } 03494 03495 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03496 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03497 if (option_debug && sipdebug) 03498 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03499 update_call_counter(p, DEC_CALL_LIMIT); 03500 } 03501 if (option_debug >3) 03502 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03503 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03504 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03505 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03506 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03507 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03508 p->owner->tech_pvt = NULL; 03509 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03510 return 0; 03511 } 03512 if (option_debug) { 03513 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03514 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03515 else { 03516 if (option_debug) 03517 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03518 } 03519 } 03520 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03521 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03522 03523 ast_mutex_lock(&p->lock); 03524 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03525 if (option_debug && sipdebug) 03526 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03527 update_call_counter(p, DEC_CALL_LIMIT); 03528 } 03529 03530 /* Determine how to disconnect */ 03531 if (p->owner != ast) { 03532 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03533 ast_mutex_unlock(&p->lock); 03534 return 0; 03535 } 03536 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03537 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03538 needcancel = TRUE; 03539 if (option_debug > 3) 03540 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03541 } 03542 03543 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03544 03545 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03546 03547 /* Disconnect */ 03548 if (p->vad) 03549 ast_dsp_free(p->vad); 03550 03551 p->owner = NULL; 03552 ast->tech_pvt = NULL; 03553 03554 ast_module_unref(ast_module_info->self); 03555 03556 /* Do not destroy this pvt until we have timeout or 03557 get an answer to the BYE or INVITE/CANCEL 03558 If we get no answer during retransmit period, drop the call anyway. 03559 (Sorry, mother-in-law, you can't deny a hangup by sending 03560 603 declined to BYE...) 03561 */ 03562 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03563 needdestroy = 1; /* Set destroy flag at end of this function */ 03564 else if (p->invitestate != INV_CALLING) 03565 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03566 03567 /* Start the process if it's not already started */ 03568 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03569 if (needcancel) { /* Outgoing call, not up */ 03570 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03571 /* stop retransmitting an INVITE that has not received a response */ 03572 __sip_pretend_ack(p); 03573 p->invitestate = INV_CANCELLED; 03574 03575 /* if we can't send right now, mark it pending */ 03576 if (p->invitestate == INV_CALLING) { 03577 /* We can't send anything in CALLING state */ 03578 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03579 /* 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. */ 03580 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03581 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03582 } else { 03583 /* Send a new request: CANCEL */ 03584 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03585 /* Actually don't destroy us yet, wait for the 487 on our original 03586 INVITE, but do set an autodestruct just in case we never get it. */ 03587 needdestroy = 0; 03588 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03589 } 03590 if ( p->initid != -1 ) { 03591 /* channel still up - reverse dec of inUse counter 03592 only if the channel is not auto-congested */ 03593 update_call_counter(p, INC_CALL_LIMIT); 03594 } 03595 } else { /* Incoming call, not up */ 03596 const char *res; 03597 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03598 transmit_response_reliable(p, res, &p->initreq); 03599 else 03600 transmit_response_reliable(p, "603 Declined", &p->initreq); 03601 p->invitestate = INV_TERMINATED; 03602 } 03603 } else { /* Call is in UP state, send BYE */ 03604 if (!p->pendinginvite) { 03605 char *audioqos = ""; 03606 char *videoqos = ""; 03607 if (p->rtp) 03608 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03609 if (p->vrtp) 03610 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03611 /* Send a hangup */ 03612 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03613 03614 /* Get RTCP quality before end of call */ 03615 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03616 if (p->rtp) 03617 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03618 if (p->vrtp) 03619 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03620 } 03621 if (p->rtp && oldowner) 03622 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03623 if (p->vrtp && oldowner) 03624 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03625 } else { 03626 /* Note we will need a BYE when this all settles out 03627 but we can't send one while we have "INVITE" outstanding. */ 03628 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03629 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03630 AST_SCHED_DEL(sched, p->waitid); 03631 if (sip_cancel_destroy(p)) 03632 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03633 } 03634 } 03635 } 03636 if (needdestroy) 03637 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03638 ast_mutex_unlock(&p->lock); 03639 return 0; 03640 }
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 3882 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.
03883 { 03884 struct sip_pvt *p = ast->tech_pvt; 03885 int res = 0; 03886 03887 ast_mutex_lock(&p->lock); 03888 switch(condition) { 03889 case AST_CONTROL_RINGING: 03890 if (ast->_state == AST_STATE_RING) { 03891 p->invitestate = INV_EARLY_MEDIA; 03892 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03893 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03894 /* Send 180 ringing if out-of-band seems reasonable */ 03895 transmit_response(p, "180 Ringing", &p->initreq); 03896 ast_set_flag(&p->flags[0], SIP_RINGING); 03897 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03898 break; 03899 } else { 03900 /* Well, if it's not reasonable, just send in-band */ 03901 } 03902 } 03903 res = -1; 03904 break; 03905 case AST_CONTROL_BUSY: 03906 if (ast->_state != AST_STATE_UP) { 03907 transmit_response(p, "486 Busy Here", &p->initreq); 03908 p->invitestate = INV_COMPLETED; 03909 sip_alreadygone(p); 03910 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03911 break; 03912 } 03913 res = -1; 03914 break; 03915 case AST_CONTROL_CONGESTION: 03916 if (ast->_state != AST_STATE_UP) { 03917 transmit_response(p, "503 Service Unavailable", &p->initreq); 03918 p->invitestate = INV_COMPLETED; 03919 sip_alreadygone(p); 03920 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03921 break; 03922 } 03923 res = -1; 03924 break; 03925 case AST_CONTROL_PROCEEDING: 03926 if ((ast->_state != AST_STATE_UP) && 03927 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03928 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03929 transmit_response(p, "100 Trying", &p->initreq); 03930 p->invitestate = INV_PROCEEDING; 03931 break; 03932 } 03933 res = -1; 03934 break; 03935 case AST_CONTROL_PROGRESS: 03936 if ((ast->_state != AST_STATE_UP) && 03937 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03938 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03939 p->invitestate = INV_EARLY_MEDIA; 03940 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03941 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03942 break; 03943 } 03944 res = -1; 03945 break; 03946 case AST_CONTROL_HOLD: 03947 ast_rtp_new_source(p->rtp); 03948 ast_moh_start(ast, data, p->mohinterpret); 03949 break; 03950 case AST_CONTROL_UNHOLD: 03951 ast_rtp_new_source(p->rtp); 03952 ast_moh_stop(ast); 03953 break; 03954 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03955 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03956 transmit_info_with_vidupdate(p); 03957 /* ast_rtcp_send_h261fur(p->vrtp); */ 03958 } else 03959 res = -1; 03960 break; 03961 case AST_CONTROL_SRCUPDATE: 03962 ast_rtp_new_source(p->rtp); 03963 break; 03964 case -1: 03965 res = -1; 03966 break; 03967 default: 03968 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03969 res = -1; 03970 break; 03971 } 03972 ast_mutex_unlock(&p->lock); 03973 return res; 03974 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1755 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().
01756 { 01757 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01758 }
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 3982 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
03983 { 03984 struct ast_channel *tmp; 03985 struct ast_variable *v = NULL; 03986 int fmt; 03987 int what; 03988 int needvideo = 0, video = 0; 03989 char *decoded_exten; 03990 { 03991 const char *my_name; /* pick a good name */ 03992 03993 if (title) 03994 my_name = title; 03995 else if ( (my_name = strchr(i->fromdomain,':')) ) 03996 my_name++; /* skip ':' */ 03997 else 03998 my_name = i->fromdomain; 03999 04000 ast_mutex_unlock(&i->lock); 04001 /* Don't hold a sip pvt lock while we allocate a channel */ 04002 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); 04003 04004 } 04005 if (!tmp) { 04006 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04007 ast_mutex_lock(&i->lock); 04008 return NULL; 04009 } 04010 ast_mutex_lock(&i->lock); 04011 04012 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04013 tmp->tech = &sip_tech_info; 04014 else 04015 tmp->tech = &sip_tech; 04016 04017 /* Select our native format based on codec preference until we receive 04018 something from another device to the contrary. */ 04019 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04020 what = i->jointcapability; 04021 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04022 } else if (i->capability) { /* Our configured capability for this peer */ 04023 what = i->capability; 04024 video = i->capability & AST_FORMAT_VIDEO_MASK; 04025 } else { 04026 what = global_capability; /* Global codec support */ 04027 video = global_capability & AST_FORMAT_VIDEO_MASK; 04028 } 04029 04030 /* Set the native formats for audio and merge in video */ 04031 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04032 if (option_debug > 2) { 04033 char buf[SIPBUFSIZE]; 04034 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04035 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04036 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04037 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04038 if (i->prefcodec) 04039 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04040 } 04041 04042 /* XXX Why are we choosing a codec from the native formats?? */ 04043 fmt = ast_best_codec(tmp->nativeformats); 04044 04045 /* If we have a prefcodec setting, we have an inbound channel that set a 04046 preferred format for this call. Otherwise, we check the jointcapability 04047 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04048 */ 04049 if (i->vrtp) { 04050 if (i->prefcodec) 04051 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04052 else 04053 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04054 } 04055 04056 if (option_debug > 2) { 04057 if (needvideo) 04058 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04059 else 04060 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04061 } 04062 04063 04064 04065 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04066 i->vad = ast_dsp_new(); 04067 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04068 if (global_relaxdtmf) 04069 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04070 } 04071 if (i->rtp) { 04072 tmp->fds[0] = ast_rtp_fd(i->rtp); 04073 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04074 } 04075 if (needvideo && i->vrtp) { 04076 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04077 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04078 } 04079 if (i->udptl) { 04080 tmp->fds[5] = ast_udptl_fd(i->udptl); 04081 } 04082 if (state == AST_STATE_RING) 04083 tmp->rings = 1; 04084 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04085 tmp->writeformat = fmt; 04086 tmp->rawwriteformat = fmt; 04087 tmp->readformat = fmt; 04088 tmp->rawreadformat = fmt; 04089 tmp->tech_pvt = i; 04090 04091 tmp->callgroup = i->callgroup; 04092 tmp->pickupgroup = i->pickupgroup; 04093 tmp->cid.cid_pres = i->callingpres; 04094 if (!ast_strlen_zero(i->accountcode)) 04095 ast_string_field_set(tmp, accountcode, i->accountcode); 04096 if (i->amaflags) 04097 tmp->amaflags = i->amaflags; 04098 if (!ast_strlen_zero(i->language)) 04099 ast_string_field_set(tmp, language, i->language); 04100 i->owner = tmp; 04101 ast_module_ref(ast_module_info->self); 04102 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04103 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04104 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04105 * structure so that there aren't issues when forming URI's 04106 */ 04107 decoded_exten = ast_strdupa(i->exten); 04108 ast_uri_decode(decoded_exten); 04109 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04110 04111 /* Don't use ast_set_callerid() here because it will 04112 * generate an unnecessary NewCallerID event */ 04113 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04114 if (!ast_strlen_zero(i->rdnis)) 04115 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04116 04117 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04118 tmp->cid.cid_dnid = ast_strdup(i->exten); 04119 04120 tmp->priority = 1; 04121 if (!ast_strlen_zero(i->uri)) 04122 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04123 if (!ast_strlen_zero(i->domain)) 04124 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04125 if (!ast_strlen_zero(i->useragent)) 04126 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04127 if (!ast_strlen_zero(i->callid)) 04128 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04129 if (i->rtp) 04130 ast_jb_configure(tmp, &global_jbconf); 04131 04132 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04133 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04134 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04135 04136 /* Set channel variables for this call from configuration */ 04137 for (v = i->chanvars ; v ; v = v->next) 04138 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04139 04140 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04141 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04142 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04143 ast_hangup(tmp); 04144 tmp = NULL; 04145 } 04146 04147 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04148 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04149 04150 return tmp; 04151 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11395 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11396 { 11397 if (argc != 4) 11398 return RESULT_SHOWUSAGE; 11399 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11400 ast_cli(fd, "SIP Debugging Disabled\n"); 11401 return RESULT_SUCCESS; 11402 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11404 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11405 { 11406 if (argc != 3) 11407 return RESULT_SHOWUSAGE; 11408 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11409 ast_cli(fd, "SIP Debugging Disabled\n"); 11410 return RESULT_SUCCESS; 11411 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11425 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11426 { 11427 if (argc != 3) { 11428 return RESULT_SHOWUSAGE; 11429 } 11430 recordhistory = FALSE; 11431 ast_cli(fd, "SIP History Recording Disabled\n"); 11432 return RESULT_SUCCESS; 11433 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11339 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.
11340 { 11341 struct ast_variable *varlist; 11342 int i; 11343 11344 if (argc < 4) 11345 return RESULT_SHOWUSAGE; 11346 11347 if (!notify_types) { 11348 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11349 return RESULT_FAILURE; 11350 } 11351 11352 varlist = ast_variable_browse(notify_types, argv[2]); 11353 11354 if (!varlist) { 11355 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11356 return RESULT_FAILURE; 11357 } 11358 11359 for (i = 3; i < argc; i++) { 11360 struct sip_pvt *p; 11361 struct sip_request req; 11362 struct ast_variable *var; 11363 11364 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11365 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11366 return RESULT_FAILURE; 11367 } 11368 11369 if (create_addr(p, argv[i])) { 11370 /* Maybe they're not registered, etc. */ 11371 sip_destroy(p); 11372 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11373 continue; 11374 } 11375 11376 initreqprep(&req, p, SIP_NOTIFY); 11377 11378 for (var = varlist; var; var = var->next) 11379 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11380 11381 /* Recalculate our side, and recalculate Call ID */ 11382 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11383 p->ourip = __ourip; 11384 build_via(p); 11385 build_callid_pvt(p); 11386 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11387 transmit_sip_request(p, &req); 11388 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11389 } 11390 11391 return RESULT_SUCCESS; 11392 }
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 13132 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_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), 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().
13133 { 13134 struct sip_dual *d; 13135 struct ast_channel *transferee, *transferer; 13136 /* Chan2m: The transferer, chan1m: The transferee */ 13137 pthread_t th; 13138 13139 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13140 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13141 if ((!transferer) || (!transferee)) { 13142 if (transferee) { 13143 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13144 ast_hangup(transferee); 13145 } 13146 if (transferer) { 13147 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13148 ast_hangup(transferer); 13149 } 13150 return -1; 13151 } 13152 13153 /* Make formats okay */ 13154 transferee->readformat = chan1->readformat; 13155 transferee->writeformat = chan1->writeformat; 13156 13157 /* Prepare for taking over the channel */ 13158 ast_channel_masquerade(transferee, chan1); 13159 13160 /* Setup the extensions and such */ 13161 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13162 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13163 transferee->priority = chan1->priority; 13164 13165 /* We make a clone of the peer channel too, so we can play 13166 back the announcement */ 13167 13168 /* Make formats okay */ 13169 transferer->readformat = chan2->readformat; 13170 transferer->writeformat = chan2->writeformat; 13171 13172 /* Prepare for taking over the channel. Go ahead and grab this channel 13173 * lock here to avoid a deadlock with callbacks into the channel driver 13174 * that hold the channel lock and want the pvt lock. */ 13175 while (ast_channel_trylock(chan2)) { 13176 struct sip_pvt *pvt = chan2->tech_pvt; 13177 ast_mutex_unlock(&pvt->lock); 13178 usleep(1); 13179 ast_mutex_lock(&pvt->lock); 13180 } 13181 ast_channel_masquerade(transferer, chan2); 13182 ast_channel_unlock(chan2); 13183 13184 /* Setup the extensions and such */ 13185 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13186 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13187 transferer->priority = chan2->priority; 13188 13189 ast_channel_lock(transferer); 13190 if (ast_do_masquerade(transferer)) { 13191 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13192 ast_channel_unlock(transferer); 13193 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13194 ast_hangup(transferer); 13195 return -1; 13196 } 13197 ast_channel_unlock(transferer); 13198 if (!transferer || !transferee) { 13199 if (!transferer) { 13200 if (option_debug) 13201 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13202 } 13203 if (!transferee) { 13204 if (option_debug) 13205 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13206 } 13207 return -1; 13208 } 13209 if ((d = ast_calloc(1, sizeof(*d)))) { 13210 pthread_attr_t attr; 13211 13212 pthread_attr_init(&attr); 13213 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13214 13215 /* Save original request for followup */ 13216 copy_request(&d->req, req); 13217 d->chan1 = transferee; /* Transferee */ 13218 d->chan2 = transferer; /* Transferer */ 13219 d->seqno = seqno; 13220 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13221 /* Could not start thread */ 13222 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13223 by sip_park_thread() */ 13224 pthread_attr_destroy(&attr); 13225 return 0; 13226 } 13227 pthread_attr_destroy(&attr); 13228 } 13229 return -1; 13230 }
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 13065 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().
13066 { 13067 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13068 struct sip_dual *d; 13069 struct sip_request req; 13070 int ext; 13071 int res; 13072 13073 d = stuff; 13074 transferee = d->chan1; 13075 transferer = d->chan2; 13076 copy_request(&req, &d->req); 13077 free(d); 13078 13079 if (!transferee || !transferer) { 13080 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13081 return NULL; 13082 } 13083 if (option_debug > 3) 13084 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13085 13086 ast_channel_lock(transferee); 13087 if (ast_do_masquerade(transferee)) { 13088 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13089 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13090 ast_channel_unlock(transferee); 13091 return NULL; 13092 } 13093 ast_channel_unlock(transferee); 13094 13095 res = ast_park_call(transferee, transferer, 0, &ext); 13096 13097 13098 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13099 if (!res) { 13100 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13101 } else { 13102 /* Then tell the transferer what happened */ 13103 sprintf(buf, "Call parked on extension '%d'", ext); 13104 transmit_message_with_text(transferer->tech_pvt, buf); 13105 } 13106 #endif 13107 13108 /* Any way back to the current call??? */ 13109 /* Transmit response to the REFER request */ 13110 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13111 if (!res) { 13112 /* Transfer succeeded */ 13113 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13114 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13115 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13116 ast_hangup(transferer); /* This will cause a BYE */ 13117 if (option_debug) 13118 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13119 } else { 13120 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13121 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13122 if (option_debug) 13123 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13124 /* Do not hangup call */ 13125 } 13126 return NULL; 13127 }
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 8529 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().
08530 { 08531 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08532 08533 if (!peer) 08534 return; 08535 08536 /* If they put someone on hold, increment the value... otherwise decrement it */ 08537 if (hold) 08538 peer->onHold++; 08539 else 08540 peer->onHold--; 08541 08542 /* Request device state update */ 08543 ast_device_state_changed("SIP/%s", peer->name); 08544 08545 return; 08546 }
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 17825 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, sched, and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
17826 { 17827 int ms = 0; 17828 17829 if (!speerobjs) /* No peers, just give up */ 17830 return; 17831 17832 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17833 ASTOBJ_WRLOCK(iterator); 17834 AST_SCHED_DEL(sched, iterator->pokeexpire); 17835 ms += 100; 17836 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17837 ASTOBJ_UNLOCK(iterator); 17838 } while (0) 17839 ); 17840 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15776 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sched, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15777 { 15778 struct sip_peer *peer = (struct sip_peer *)data; 15779 15780 peer->pokeexpire = -1; 15781 if (peer->lastms > -1) { 15782 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15783 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15784 } 15785 if (peer->call) 15786 sip_destroy(peer->call); 15787 peer->call = NULL; 15788 peer->lastms = -1; 15789 ast_device_state_changed("SIP/%s", peer->name); 15790 /* Try again quickly */ 15791 AST_SCHED_DEL(sched, peer->pokeexpire); 15792 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15793 return 0; 15794 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15799 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(), 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_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15800 { 15801 struct sip_pvt *p; 15802 int xmitres = 0; 15803 15804 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15805 /* IF we have no IP, or this isn't to be monitored, return 15806 imeediately after clearing things out */ 15807 AST_SCHED_DEL(sched, peer->pokeexpire); 15808 peer->lastms = 0; 15809 peer->call = NULL; 15810 return 0; 15811 } 15812 if (peer->call) { 15813 if (sipdebug) 15814 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15815 sip_destroy(peer->call); 15816 } 15817 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15818 return -1; 15819 15820 p->sa = peer->addr; 15821 p->recv = peer->addr; 15822 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15823 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15824 15825 /* Send OPTIONs to peer's fullcontact */ 15826 if (!ast_strlen_zero(peer->fullcontact)) 15827 ast_string_field_set(p, fullcontact, peer->fullcontact); 15828 15829 if (!ast_strlen_zero(peer->tohost)) 15830 ast_string_field_set(p, tohost, peer->tohost); 15831 else 15832 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15833 15834 /* Recalculate our side, and recalculate Call ID */ 15835 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15836 p->ourip = __ourip; 15837 build_via(p); 15838 build_callid_pvt(p); 15839 15840 AST_SCHED_DEL(sched, peer->pokeexpire); 15841 p->relatedpeer = peer; 15842 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15843 #ifdef VOCAL_DATA_HACK 15844 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15845 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15846 #else 15847 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15848 #endif 15849 gettimeofday(&peer->ps, NULL); 15850 if (xmitres == XMIT_ERROR) 15851 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 15852 else { 15853 AST_SCHED_DEL(sched, peer->pokeexpire); 15854 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, peer); 15855 } 15856 15857 return 0; 15858 }
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 7926 of file chan_sip.c.
References sip_peer::pokeexpire, and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
07927 { 07928 struct sip_peer *peer = (struct sip_peer *)data; 07929 07930 peer->pokeexpire = -1; 07931 sip_poke_peer(peer); 07932 return 0; 07933 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10126 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.
10127 { 10128 struct sip_peer *peer; 10129 struct sip_user *user; 10130 int pruneuser = FALSE; 10131 int prunepeer = FALSE; 10132 int multi = FALSE; 10133 char *name = NULL; 10134 regex_t regexbuf; 10135 10136 switch (argc) { 10137 case 4: 10138 if (!strcasecmp(argv[3], "user")) 10139 return RESULT_SHOWUSAGE; 10140 if (!strcasecmp(argv[3], "peer")) 10141 return RESULT_SHOWUSAGE; 10142 if (!strcasecmp(argv[3], "like")) 10143 return RESULT_SHOWUSAGE; 10144 if (!strcasecmp(argv[3], "all")) { 10145 multi = TRUE; 10146 pruneuser = prunepeer = TRUE; 10147 } else { 10148 pruneuser = prunepeer = TRUE; 10149 name = argv[3]; 10150 } 10151 break; 10152 case 5: 10153 if (!strcasecmp(argv[4], "like")) 10154 return RESULT_SHOWUSAGE; 10155 if (!strcasecmp(argv[3], "all")) 10156 return RESULT_SHOWUSAGE; 10157 if (!strcasecmp(argv[3], "like")) { 10158 multi = TRUE; 10159 name = argv[4]; 10160 pruneuser = prunepeer = TRUE; 10161 } else if (!strcasecmp(argv[3], "user")) { 10162 pruneuser = TRUE; 10163 if (!strcasecmp(argv[4], "all")) 10164 multi = TRUE; 10165 else 10166 name = argv[4]; 10167 } else if (!strcasecmp(argv[3], "peer")) { 10168 prunepeer = TRUE; 10169 if (!strcasecmp(argv[4], "all")) 10170 multi = TRUE; 10171 else 10172 name = argv[4]; 10173 } else 10174 return RESULT_SHOWUSAGE; 10175 break; 10176 case 6: 10177 if (strcasecmp(argv[4], "like")) 10178 return RESULT_SHOWUSAGE; 10179 if (!strcasecmp(argv[3], "user")) { 10180 pruneuser = TRUE; 10181 name = argv[5]; 10182 } else if (!strcasecmp(argv[3], "peer")) { 10183 prunepeer = TRUE; 10184 name = argv[5]; 10185 } else 10186 return RESULT_SHOWUSAGE; 10187 break; 10188 default: 10189 return RESULT_SHOWUSAGE; 10190 } 10191 10192 if (multi && name) { 10193 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10194 return RESULT_SHOWUSAGE; 10195 } 10196 10197 if (multi) { 10198 if (prunepeer) { 10199 int pruned = 0; 10200 10201 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10202 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10203 ASTOBJ_RDLOCK(iterator); 10204 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10205 ASTOBJ_UNLOCK(iterator); 10206 continue; 10207 }; 10208 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10209 ASTOBJ_MARK(iterator); 10210 pruned++; 10211 } 10212 ASTOBJ_UNLOCK(iterator); 10213 } while (0) ); 10214 if (pruned) { 10215 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10216 ast_cli(fd, "%d peers pruned.\n", pruned); 10217 } else 10218 ast_cli(fd, "No peers found to prune.\n"); 10219 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10220 } 10221 if (pruneuser) { 10222 int pruned = 0; 10223 10224 ASTOBJ_CONTAINER_WRLOCK(&userl); 10225 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10226 ASTOBJ_RDLOCK(iterator); 10227 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10228 ASTOBJ_UNLOCK(iterator); 10229 continue; 10230 }; 10231 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10232 ASTOBJ_MARK(iterator); 10233 pruned++; 10234 } 10235 ASTOBJ_UNLOCK(iterator); 10236 } while (0) ); 10237 if (pruned) { 10238 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10239 ast_cli(fd, "%d users pruned.\n", pruned); 10240 } else 10241 ast_cli(fd, "No users found to prune.\n"); 10242 ASTOBJ_CONTAINER_UNLOCK(&userl); 10243 } 10244 } else { 10245 if (prunepeer) { 10246 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10247 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10248 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10249 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10250 } else 10251 ast_cli(fd, "Peer '%s' pruned.\n", name); 10252 ASTOBJ_UNREF(peer, sip_destroy_peer); 10253 } else 10254 ast_cli(fd, "Peer '%s' not found.\n", name); 10255 } 10256 if (pruneuser) { 10257 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10258 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10259 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10260 ASTOBJ_CONTAINER_LINK(&userl, user); 10261 } else 10262 ast_cli(fd, "User '%s' pruned.\n", name); 10263 ASTOBJ_UNREF(user, sip_destroy_user); 10264 } else 10265 ast_cli(fd, "User '%s' not found.\n", name); 10266 } 10267 } 10268 10269 return RESULT_SUCCESS; 10270 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4354 of file chan_sip.c.
References ast_bridged_channel(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, FALSE, sip_pvt::flags, 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().
04355 { 04356 struct ast_frame *fr; 04357 struct sip_pvt *p; 04358 04359 if( ast == NULL ) 04360 return NULL; 04361 04362 p = ast->tech_pvt; 04363 int faxdetected = FALSE; 04364 04365 if( p == NULL ) 04366 return NULL; 04367 04368 ast_mutex_lock(&p->lock); 04369 fr = sip_rtp_read(ast, p, &faxdetected); 04370 p->lastrtprx = time(NULL); 04371 04372 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04373 /* 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 */ 04374 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04375 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04376 if (!p->pendinginvite) { 04377 if (option_debug > 2) 04378 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04379 p->t38.state = T38_LOCAL_REINVITE; 04380 transmit_reinvite_with_t38_sdp(p); 04381 if (option_debug > 1) 04382 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04383 } 04384 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04385 if (option_debug > 2) 04386 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04387 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04388 } 04389 } 04390 04391 ast_mutex_unlock(&p->lock); 04392 return fr; 04393 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1749 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().
01750 { 01751 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01752 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7735 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().
07736 { 07737 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07738 return p->refer ? 1 : 0; 07739 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7490 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().
07491 { 07492 07493 /* if we are here, our registration timed out, so we'll just do it over */ 07494 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07495 struct sip_pvt *p; 07496 int res; 07497 07498 /* if we couldn't get a reference to the registry object, punt */ 07499 if (!r) 07500 return 0; 07501 07502 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07503 if (r->call) { 07504 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07505 in the single SIP manager thread. */ 07506 p = r->call; 07507 ast_mutex_lock(&p->lock); 07508 if (p->registry) 07509 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07510 r->call = NULL; 07511 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07512 /* Pretend to ACK anything just in case */ 07513 __sip_pretend_ack(p); 07514 ast_mutex_unlock(&p->lock); 07515 } 07516 /* If we have a limit, stop registration and give up */ 07517 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07518 /* Ok, enough is enough. Don't try any more */ 07519 /* We could add an external notification here... 07520 steal it from app_voicemail :-) */ 07521 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07522 r->regstate = REG_STATE_FAILED; 07523 } else { 07524 r->regstate = REG_STATE_UNREGISTERED; 07525 r->timeout = -1; 07526 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07527 } 07528 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)); 07529 ASTOBJ_UNREF(r, sip_registry_destroy); 07530 return 0; 07531 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4682 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.
04683 { 04684 struct sip_registry *reg; 04685 int portnum = 0; 04686 char username[256] = ""; 04687 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04688 char *porta=NULL; 04689 char *contact=NULL; 04690 04691 if (!value) 04692 return -1; 04693 ast_copy_string(username, value, sizeof(username)); 04694 /* First split around the last '@' then parse the two components. */ 04695 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04696 if (hostname) 04697 *hostname++ = '\0'; 04698 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04699 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04700 return -1; 04701 } 04702 /* split user[:secret[:authuser]] */ 04703 secret = strchr(username, ':'); 04704 if (secret) { 04705 *secret++ = '\0'; 04706 authuser = strchr(secret, ':'); 04707 if (authuser) 04708 *authuser++ = '\0'; 04709 } 04710 /* split host[:port][/contact] */ 04711 contact = strchr(hostname, '/'); 04712 if (contact) 04713 *contact++ = '\0'; 04714 if (ast_strlen_zero(contact)) 04715 contact = "s"; 04716 porta = strchr(hostname, ':'); 04717 if (porta) { 04718 *porta++ = '\0'; 04719 portnum = atoi(porta); 04720 if (portnum == 0) { 04721 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04722 return -1; 04723 } 04724 } 04725 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04726 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04727 return -1; 04728 } 04729 04730 if (ast_string_field_init(reg, 256)) { 04731 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04732 free(reg); 04733 return -1; 04734 } 04735 04736 regobjs++; 04737 ASTOBJ_INIT(reg); 04738 ast_string_field_set(reg, contact, contact); 04739 if (!ast_strlen_zero(username)) 04740 ast_string_field_set(reg, username, username); 04741 if (hostname) 04742 ast_string_field_set(reg, hostname, hostname); 04743 if (authuser) 04744 ast_string_field_set(reg, authuser, authuser); 04745 if (secret) 04746 ast_string_field_set(reg, secret, secret); 04747 reg->expire = -1; 04748 reg->timeout = -1; 04749 reg->refresh = default_expiry; 04750 reg->portno = portnum; 04751 reg->callid_valid = FALSE; 04752 reg->ocseq = INITIAL_CSEQ; 04753 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04754 ASTOBJ_UNREF(reg,sip_registry_destroy); 04755 return 0; 04756 }
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 3050 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().
03051 { 03052 /* Really delete */ 03053 if (option_debug > 2) 03054 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03055 03056 if (reg->call) { 03057 /* Clear registry before destroying to ensure 03058 we don't get reentered trying to grab the registry lock */ 03059 reg->call->registry = NULL; 03060 if (option_debug > 2) 03061 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03062 sip_destroy(reg->call); 03063 } 03064 AST_SCHED_DEL(sched, reg->expire); 03065 AST_SCHED_DEL(sched, reg->timeout); 03066 ast_string_field_free_memory(reg); 03067 regobjs--; 03068 free(reg); 03069 03070 }
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 12055 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12056 { 12057 struct sip_pvt *p = (struct sip_pvt *) data; 12058 12059 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12060 p->waitid = -1; 12061 return 0; 12062 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17886 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().
17887 { 17888 ast_mutex_lock(&sip_reload_lock); 17889 if (sip_reloading) 17890 ast_verbose("Previous SIP reload not yet done\n"); 17891 else { 17892 sip_reloading = TRUE; 17893 if (fd) 17894 sip_reloadreason = CHANNEL_CLI_RELOAD; 17895 else 17896 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17897 } 17898 ast_mutex_unlock(&sip_reload_lock); 17899 restart_monitor(); 17900 17901 return 0; 17902 }
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 15963 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.
15964 { 15965 int oldformat; 15966 struct sip_pvt *p; 15967 struct ast_channel *tmpc = NULL; 15968 char *ext, *host; 15969 char tmp[256]; 15970 char *dest = data; 15971 15972 oldformat = format; 15973 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15974 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)); 15975 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15976 return NULL; 15977 } 15978 if (option_debug) 15979 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15980 15981 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15982 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15983 *cause = AST_CAUSE_SWITCH_CONGESTION; 15984 return NULL; 15985 } 15986 15987 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15988 15989 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15990 sip_destroy(p); 15991 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15992 *cause = AST_CAUSE_SWITCH_CONGESTION; 15993 return NULL; 15994 } 15995 15996 ast_copy_string(tmp, dest, sizeof(tmp)); 15997 host = strchr(tmp, '@'); 15998 if (host) { 15999 *host++ = '\0'; 16000 ext = tmp; 16001 } else { 16002 ext = strchr(tmp, '/'); 16003 if (ext) 16004 *ext++ = '\0'; 16005 host = tmp; 16006 } 16007 16008 if (create_addr(p, host)) { 16009 *cause = AST_CAUSE_UNREGISTERED; 16010 if (option_debug > 2) 16011 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16012 sip_destroy(p); 16013 return NULL; 16014 } 16015 if (ast_strlen_zero(p->peername) && ext) 16016 ast_string_field_set(p, peername, ext); 16017 /* Recalculate our side, and recalculate Call ID */ 16018 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16019 p->ourip = __ourip; 16020 build_via(p); 16021 build_callid_pvt(p); 16022 16023 /* We have an extension to call, don't use the full contact here */ 16024 /* This to enable dialing registered peers with extension dialling, 16025 like SIP/peername/extension 16026 SIP/peername will still use the full contact */ 16027 if (ext) { 16028 ast_string_field_set(p, username, ext); 16029 ast_string_field_free(p, fullcontact); 16030 } 16031 #if 0 16032 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16033 #endif 16034 p->prefcodec = oldformat; /* Format for this call */ 16035 ast_mutex_lock(&p->lock); 16036 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16037 ast_mutex_unlock(&p->lock); 16038 if (!tmpc) 16039 sip_destroy(p); 16040 ast_update_use_count(); 16041 restart_monitor(); 16042 return tmpc; 16043 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7458 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().
07459 { 07460 /* if we are here, we know that we need to reregister. */ 07461 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07462 07463 /* if we couldn't get a reference to the registry object, punt */ 07464 if (!r) 07465 return 0; 07466 07467 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07468 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07469 /* Since registry's are only added/removed by the the monitor thread, this 07470 may be overkill to reference/dereference at all here */ 07471 if (sipdebug) 07472 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07473 07474 r->expire = -1; 07475 __sip_do_register(r); 07476 ASTOBJ_UNREF(r, sip_registry_destroy); 07477 return 0; 07478 }
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 4284 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().
04285 { 04286 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04287 struct ast_frame *f; 04288 04289 if (!p->rtp) { 04290 /* We have no RTP allocated for this channel */ 04291 return &ast_null_frame; 04292 } 04293 04294 switch(ast->fdno) { 04295 case 0: 04296 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04297 break; 04298 case 1: 04299 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04300 break; 04301 case 2: 04302 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04303 break; 04304 case 3: 04305 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04306 break; 04307 case 5: 04308 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04309 break; 04310 default: 04311 f = &ast_null_frame; 04312 } 04313 /* Don't forward RFC2833 if we're not supposed to */ 04314 if (f && (f->frametype == AST_FRAME_DTMF) && 04315 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04316 return &ast_null_frame; 04317 04318 /* We already hold the channel lock */ 04319 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04320 return f; 04321 04322 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04323 if (!(f->subclass & p->jointcapability)) { 04324 if (option_debug) { 04325 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04326 ast_getformatname(f->subclass), p->owner->name); 04327 } 04328 return &ast_null_frame; 04329 } 04330 if (option_debug) 04331 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04332 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04333 ast_set_read_format(p->owner, p->owner->readformat); 04334 ast_set_write_format(p->owner, p->owner->writeformat); 04335 } 04336 04337 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04338 f = ast_dsp_process(p->owner, p->vad, f); 04339 if (f && f->frametype == AST_FRAME_DTMF) { 04340 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04341 if (option_debug) 04342 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04343 *faxdetect = 1; 04344 } else if (option_debug) { 04345 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04346 } 04347 } 04348 } 04349 04350 return f; 04351 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2112 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02113 { 02114 if (ms < 0) { 02115 if (p->timer_t1 == 0) 02116 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02117 ms = p->timer_t1 * 64; 02118 } 02119 if (sip_debug_test_pvt(p)) 02120 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02121 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02122 append_history(p, "SchedDestroy", "%d ms", ms); 02123 02124 AST_SCHED_DEL(sched, p->autokillid); 02125 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02126 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17843 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().
17844 { 17845 int ms; 17846 int regspacing; 17847 if (!regobjs) 17848 return; 17849 regspacing = default_expiry * 1000/regobjs; 17850 if (regspacing > 100) 17851 regspacing = 100; 17852 ms = regspacing; 17853 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17854 ASTOBJ_WRLOCK(iterator); 17855 AST_SCHED_DEL(sched, iterator->expire); 17856 ms += regspacing; 17857 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17858 ASTOBJ_UNLOCK(iterator); 17859 } while (0) 17860 ); 17861 }
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 15510 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().
15511 { 15512 /* Called with peerl lock, but releases it */ 15513 struct sip_pvt *p; 15514 int newmsgs, oldmsgs; 15515 15516 /* Do we have an IP address? If not, skip this peer */ 15517 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15518 return 0; 15519 15520 /* Check for messages */ 15521 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15522 15523 peer->lastmsgcheck = time(NULL); 15524 15525 /* Return now if it's the same thing we told them last time */ 15526 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15527 return 0; 15528 } 15529 15530 15531 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15532 15533 if (peer->mwipvt) { 15534 /* Base message on subscription */ 15535 p = peer->mwipvt; 15536 } else { 15537 /* Build temporary dialog for this message */ 15538 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15539 return -1; 15540 if (create_addr_from_peer(p, peer)) { 15541 /* Maybe they're not registered, etc. */ 15542 sip_destroy(p); 15543 return 0; 15544 } 15545 /* Recalculate our side, and recalculate Call ID */ 15546 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15547 p->ourip = __ourip; 15548 build_via(p); 15549 build_callid_pvt(p); 15550 /* Destroy this session after 32 secs */ 15551 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15552 } 15553 /* Send MWI */ 15554 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15555 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15556 return 0; 15557 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3813 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.
03814 { 03815 struct sip_pvt *p = ast->tech_pvt; 03816 int res = 0; 03817 03818 ast_mutex_lock(&p->lock); 03819 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03820 case SIP_DTMF_INBAND: 03821 res = -1; /* Tell Asterisk to generate inband indications */ 03822 break; 03823 case SIP_DTMF_RFC2833: 03824 if (p->rtp) 03825 ast_rtp_senddigit_begin(p->rtp, digit); 03826 break; 03827 default: 03828 break; 03829 } 03830 ast_mutex_unlock(&p->lock); 03831 03832 return res; 03833 }
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 3837 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().
03838 { 03839 struct sip_pvt *p = ast->tech_pvt; 03840 int res = 0; 03841 03842 ast_mutex_lock(&p->lock); 03843 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03844 case SIP_DTMF_INFO: 03845 transmit_info_with_digit(p, digit, duration); 03846 break; 03847 case SIP_DTMF_RFC2833: 03848 if (p->rtp) 03849 ast_rtp_senddigit_end(p->rtp, digit); 03850 break; 03851 case SIP_DTMF_INBAND: 03852 res = -1; /* Tell Asterisk to stop inband indications */ 03853 break; 03854 } 03855 ast_mutex_unlock(&p->lock); 03856 03857 return res; 03858 }
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 2374 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().
02375 { 02376 struct sip_pvt *p = ast->tech_pvt; 02377 int debug = sip_debug_test_pvt(p); 02378 02379 if (debug) 02380 ast_verbose("Sending text %s on %s\n", text, ast->name); 02381 if (!p) 02382 return -1; 02383 if (ast_strlen_zero(text)) 02384 return 0; 02385 if (debug) 02386 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02387 transmit_message_with_text(p, text); 02388 return 0; 02389 }
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 17576 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.
17577 { 17578 struct sip_pvt *p; 17579 int changed = 0; 17580 17581 p = chan->tech_pvt; 17582 if (!p) 17583 return -1; 17584 17585 /* Disable early RTP bridge */ 17586 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17587 return 0; 17588 17589 ast_mutex_lock(&p->lock); 17590 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17591 /* If we're destroyed, don't bother */ 17592 ast_mutex_unlock(&p->lock); 17593 return 0; 17594 } 17595 17596 /* if this peer cannot handle reinvites of the media stream to devices 17597 that are known to be behind a NAT, then stop the process now 17598 */ 17599 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17600 ast_mutex_unlock(&p->lock); 17601 return 0; 17602 } 17603 17604 if (rtp) { 17605 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17606 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17607 memset(&p->redirip, 0, sizeof(p->redirip)); 17608 changed = 1; 17609 } 17610 if (vrtp) { 17611 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17612 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17613 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17614 changed = 1; 17615 } 17616 if (codecs) { 17617 if ((p->redircodecs != codecs)) { 17618 p->redircodecs = codecs; 17619 changed = 1; 17620 } 17621 if ((p->capability & codecs) != p->capability) { 17622 p->jointcapability &= codecs; 17623 p->capability &= codecs; 17624 changed = 1; 17625 } 17626 } 17627 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17628 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17629 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17630 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17631 if (option_debug) 17632 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)); 17633 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17634 if (option_debug > 2) { 17635 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)); 17636 } 17637 transmit_reinvite_with_sdp(p); 17638 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17639 if (option_debug > 2) { 17640 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)); 17641 } 17642 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17643 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17644 } 17645 } 17646 /* Reset lastrtprx timer */ 17647 p->lastrtprx = p->lastrtptx = time(NULL); 17648 ast_mutex_unlock(&p->lock); 17649 return 0; 17650 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17403 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.
17404 { 17405 struct sip_pvt *p; 17406 17407 p = chan->tech_pvt; 17408 if (!p) 17409 return -1; 17410 ast_mutex_lock(&p->lock); 17411 if (udptl) 17412 ast_udptl_get_peer(udptl, &p->udptlredirip); 17413 else 17414 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17415 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17416 if (!p->pendinginvite) { 17417 if (option_debug > 2) { 17418 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); 17419 } 17420 transmit_reinvite_with_t38_sdp(p); 17421 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17422 if (option_debug > 2) { 17423 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); 17424 } 17425 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17426 } 17427 } 17428 /* Reset lastrtprx timer */ 17429 p->lastrtprx = p->lastrtptx = time(NULL); 17430 ast_mutex_unlock(&p->lock); 17431 return 0; 17432 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11001 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().
11002 { 11003 struct sip_pvt *cur; 11004 size_t len; 11005 int found = 0; 11006 11007 if (argc != 4) 11008 return RESULT_SHOWUSAGE; 11009 len = strlen(argv[3]); 11010 ast_mutex_lock(&iflock); 11011 for (cur = iflist; cur; cur = cur->next) { 11012 if (!strncasecmp(cur->callid, argv[3], len)) { 11013 char formatbuf[SIPBUFSIZE/2]; 11014 ast_cli(fd,"\n"); 11015 if (cur->subscribed != NONE) 11016 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11017 else 11018 ast_cli(fd, " * SIP Call\n"); 11019 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11020 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11021 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11022 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11023 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11024 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11025 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11026 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11027 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11028 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11029 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11030 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11031 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11032 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)" ); 11033 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11034 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11035 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11036 if (!ast_strlen_zero(cur->username)) 11037 ast_cli(fd, " Username: %s\n", cur->username); 11038 if (!ast_strlen_zero(cur->peername)) 11039 ast_cli(fd, " Peername: %s\n", cur->peername); 11040 if (!ast_strlen_zero(cur->uri)) 11041 ast_cli(fd, " Original uri: %s\n", cur->uri); 11042 if (!ast_strlen_zero(cur->cid_num)) 11043 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11044 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11045 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11046 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11047 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11048 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11049 ast_cli(fd, " SIP Options: "); 11050 if (cur->sipoptions) { 11051 int x; 11052 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11053 if (cur->sipoptions & sip_options[x].id) 11054 ast_cli(fd, "%s ", sip_options[x].text); 11055 } 11056 } else 11057 ast_cli(fd, "(none)\n"); 11058 ast_cli(fd, "\n\n"); 11059 found++; 11060 } 11061 } 11062 ast_mutex_unlock(&iflock); 11063 if (!found) 11064 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11065 return RESULT_SUCCESS; 11066 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10798 of file chan_sip.c.
References __sip_show_channels().
10799 { 10800 return __sip_show_channels(fd, argc, argv, 0); 10801 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10304 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.
10305 { 10306 struct domain *d; 10307 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10308 10309 if (AST_LIST_EMPTY(&domain_list)) { 10310 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10311 return RESULT_SUCCESS; 10312 } else { 10313 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10314 AST_LIST_LOCK(&domain_list); 10315 AST_LIST_TRAVERSE(&domain_list, d, list) 10316 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10317 domain_mode_to_text(d->mode)); 10318 AST_LIST_UNLOCK(&domain_list); 10319 ast_cli(fd, "\n"); 10320 return RESULT_SUCCESS; 10321 } 10322 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11069 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.
11070 { 11071 struct sip_pvt *cur; 11072 size_t len; 11073 int found = 0; 11074 11075 if (argc != 4) 11076 return RESULT_SHOWUSAGE; 11077 if (!recordhistory) 11078 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11079 len = strlen(argv[3]); 11080 ast_mutex_lock(&iflock); 11081 for (cur = iflist; cur; cur = cur->next) { 11082 if (!strncasecmp(cur->callid, argv[3], len)) { 11083 struct sip_history *hist; 11084 int x = 0; 11085 11086 ast_cli(fd,"\n"); 11087 if (cur->subscribed != NONE) 11088 ast_cli(fd, " * Subscription\n"); 11089 else 11090 ast_cli(fd, " * SIP Call\n"); 11091 if (cur->history) 11092 AST_LIST_TRAVERSE(cur->history, hist, list) 11093 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11094 if (x == 0) 11095 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11096 found++; 11097 } 11098 } 11099 ast_mutex_unlock(&iflock); 11100 if (!found) 11101 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11102 return RESULT_SUCCESS; 11103 }
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 9729 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.
09730 { 09731 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09732 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09733 char ilimits[40]; 09734 char iused[40]; 09735 int showall = FALSE; 09736 09737 if (argc < 3) 09738 return RESULT_SHOWUSAGE; 09739 09740 if (argc == 4 && !strcmp(argv[3],"all")) 09741 showall = TRUE; 09742 09743 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09744 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09745 ASTOBJ_RDLOCK(iterator); 09746 if (iterator->call_limit) 09747 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09748 else 09749 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09750 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09751 if (showall || iterator->call_limit) 09752 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09753 ASTOBJ_UNLOCK(iterator); 09754 } while (0) ); 09755 09756 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09757 09758 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09759 ASTOBJ_RDLOCK(iterator); 09760 if (iterator->call_limit) 09761 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09762 else 09763 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09764 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09765 if (showall || iterator->call_limit) 09766 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09767 ASTOBJ_UNLOCK(iterator); 09768 } while (0) ); 09769 09770 return RESULT_SUCCESS; 09771 #undef FORMAT 09772 #undef FORMAT2 09773 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10050 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10051 { 10052 char tmp[256]; 10053 if (argc != 3) 10054 return RESULT_SHOWUSAGE; 10055 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10056 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10057 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10058 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10059 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10060 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10061 return RESULT_SUCCESS; 10062 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10356 of file chan_sip.c.
References _sip_show_peer().
10357 { 10358 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10359 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9906 of file chan_sip.c.
References _sip_show_peers().
09907 { 09908 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09909 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10629 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.
10630 { 10631 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10632 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10633 char host[80]; 10634 char tmpdat[256]; 10635 struct tm tm; 10636 10637 10638 if (argc != 3) 10639 return RESULT_SHOWUSAGE; 10640 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10641 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10642 ASTOBJ_RDLOCK(iterator); 10643 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10644 if (iterator->regtime) { 10645 ast_localtime(&iterator->regtime, &tm, NULL); 10646 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10647 } else { 10648 tmpdat[0] = 0; 10649 } 10650 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10651 ASTOBJ_UNLOCK(iterator); 10652 } while(0)); 10653 return RESULT_SUCCESS; 10654 #undef FORMAT 10655 #undef FORMAT2 10656 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10659 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_jb_conf::resync_threshold, 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().
10660 { 10661 int realtimepeers; 10662 int realtimeusers; 10663 char codec_buf[SIPBUFSIZE]; 10664 10665 realtimepeers = ast_check_realtime("sippeers"); 10666 realtimeusers = ast_check_realtime("sipusers"); 10667 10668 if (argc != 3) 10669 return RESULT_SHOWUSAGE; 10670 ast_cli(fd, "\n\nGlobal Settings:\n"); 10671 ast_cli(fd, "----------------\n"); 10672 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10673 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10674 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10675 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10676 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10677 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10678 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10679 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10680 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10681 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10682 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10683 ast_cli(fd, " Our auth realm %s\n", global_realm); 10684 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10685 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10686 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10687 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10688 ast_cli(fd, " User Agent: %s\n", global_useragent); 10689 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10690 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10691 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10692 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10693 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10694 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10695 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10696 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10697 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10698 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10699 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10700 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10701 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10702 #endif 10703 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10704 ast_cli(fd, " Jitterbuffer enabled: %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"); 10705 ast_cli(fd, " Jitterbuffer forced: %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"); 10706 ast_cli(fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 10707 ast_cli(fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 10708 ast_cli(fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 10709 ast_cli(fd, " Jitterbuffer log: %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"); 10710 if (!realtimepeers && !realtimeusers) 10711 ast_cli(fd, " SIP realtime: Disabled\n" ); 10712 else 10713 ast_cli(fd, " SIP realtime: Enabled\n" ); 10714 10715 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10716 ast_cli(fd, "---------------------------\n"); 10717 ast_cli(fd, " Codecs: "); 10718 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10719 ast_cli(fd, "%s\n", codec_buf); 10720 ast_cli(fd, " Codec Order: "); 10721 print_codec_to_cli(fd, &default_prefs); 10722 ast_cli(fd, "\n"); 10723 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10724 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10725 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10726 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10727 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10728 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10729 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10730 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10731 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10732 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10733 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10734 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10735 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10736 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10737 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10738 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10739 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10740 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10741 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10742 ast_cli(fd, "\nDefault Settings:\n"); 10743 ast_cli(fd, "-----------------\n"); 10744 ast_cli(fd, " Context: %s\n", default_context); 10745 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10746 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10747 ast_cli(fd, " Qualify: %d\n", default_qualify); 10748 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10749 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" ); 10750 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10751 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10752 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10753 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10754 10755 10756 if (realtimepeers || realtimeusers) { 10757 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10758 ast_cli(fd, "----------------------\n"); 10759 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10760 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10761 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10762 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10763 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10764 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10765 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10766 } 10767 ast_cli(fd, "\n----\n"); 10768 return RESULT_SUCCESS; 10769 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10804 of file chan_sip.c.
References __sip_show_channels().
10805 { 10806 return __sip_show_channels(fd, argc, argv, 1); 10807 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10574 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.
10575 { 10576 char cbuf[256]; 10577 struct sip_user *user; 10578 struct ast_variable *v; 10579 int load_realtime; 10580 10581 if (argc < 4) 10582 return RESULT_SHOWUSAGE; 10583 10584 /* Load from realtime storage? */ 10585 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10586 10587 user = find_user(argv[3], load_realtime); 10588 if (user) { 10589 ast_cli(fd,"\n\n"); 10590 ast_cli(fd, " * Name : %s\n", user->name); 10591 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10592 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10593 ast_cli(fd, " Context : %s\n", user->context); 10594 ast_cli(fd, " Language : %s\n", user->language); 10595 if (!ast_strlen_zero(user->accountcode)) 10596 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10597 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10598 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10599 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10600 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10601 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10602 ast_cli(fd, " Callgroup : "); 10603 print_group(fd, user->callgroup, 0); 10604 ast_cli(fd, " Pickupgroup : "); 10605 print_group(fd, user->pickupgroup, 0); 10606 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10607 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10608 ast_cli(fd, " Codec Order : ("); 10609 print_codec_to_cli(fd, &user->prefs); 10610 ast_cli(fd, ")\n"); 10611 10612 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10613 if (user->chanvars) { 10614 ast_cli(fd, " Variables :\n"); 10615 for (v = user->chanvars ; v ; v = v->next) 10616 ast_cli(fd, " %s = %s\n", v->name, v->value); 10617 } 10618 ast_cli(fd,"\n"); 10619 ASTOBJ_UNREF(user,sip_destroy_user); 10620 } else { 10621 ast_cli(fd,"User %s not found.\n", argv[3]); 10622 ast_cli(fd,"\n"); 10623 } 10624 10625 return RESULT_SUCCESS; 10626 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9829 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.
09830 { 09831 regex_t regexbuf; 09832 int havepattern = FALSE; 09833 09834 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09835 09836 switch (argc) { 09837 case 5: 09838 if (!strcasecmp(argv[3], "like")) { 09839 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09840 return RESULT_SHOWUSAGE; 09841 havepattern = TRUE; 09842 } else 09843 return RESULT_SHOWUSAGE; 09844 case 3: 09845 break; 09846 default: 09847 return RESULT_SHOWUSAGE; 09848 } 09849 09850 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09851 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09852 ASTOBJ_RDLOCK(iterator); 09853 09854 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09855 ASTOBJ_UNLOCK(iterator); 09856 continue; 09857 } 09858 09859 ast_cli(fd, FORMAT, iterator->name, 09860 iterator->secret, 09861 iterator->accountcode, 09862 iterator->context, 09863 iterator->ha ? "Yes" : "No", 09864 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09865 ASTOBJ_UNLOCK(iterator); 09866 } while (0) 09867 ); 09868 09869 if (havepattern) 09870 regfree(®exbuf); 09871 09872 return RESULT_SUCCESS; 09873 #undef FORMAT 09874 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17763 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().
17764 { 17765 char *cdest; 17766 char *extension, *host, *port; 17767 char tmp[80]; 17768 17769 cdest = ast_strdupa(dest); 17770 17771 extension = strsep(&cdest, "@"); 17772 host = strsep(&cdest, ":"); 17773 port = strsep(&cdest, ":"); 17774 if (ast_strlen_zero(extension)) { 17775 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17776 return 0; 17777 } 17778 17779 /* we'll issue the redirect message here */ 17780 if (!host) { 17781 char *localtmp; 17782 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17783 if (ast_strlen_zero(tmp)) { 17784 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17785 return 0; 17786 } 17787 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17788 char lhost[80], lport[80]; 17789 memset(lhost, 0, sizeof(lhost)); 17790 memset(lport, 0, sizeof(lport)); 17791 localtmp++; 17792 /* This is okey because lhost and lport are as big as tmp */ 17793 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17794 if (ast_strlen_zero(lhost)) { 17795 ast_log(LOG_ERROR, "Can't find the host address\n"); 17796 return 0; 17797 } 17798 host = ast_strdupa(lhost); 17799 if (!ast_strlen_zero(lport)) { 17800 port = ast_strdupa(lport); 17801 } 17802 } 17803 } 17804 17805 sip_alreadygone(p); 17806 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17807 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17808 17809 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17810 sip_alreadygone(p); 17811 return 0; 17812 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3861 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().
03862 { 03863 struct sip_pvt *p = ast->tech_pvt; 03864 int res; 03865 03866 if (dest == NULL) /* functions below do not take a NULL */ 03867 dest = ""; 03868 ast_mutex_lock(&p->lock); 03869 if (ast->_state == AST_STATE_RING) 03870 res = sip_sipredirect(p, dest); 03871 else 03872 res = transmit_refer(p, dest); 03873 ast_mutex_unlock(&p->lock); 03874 return res; 03875 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3693 of file chan_sip.c.
References ast_channel::_state, ast_backtrace(), AST_FORMAT_AUDIO_MASK, ast_frame_dump(), 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.
03694 { 03695 struct sip_pvt *p = ast->tech_pvt; 03696 int res = 0; 03697 03698 switch (frame->frametype) { 03699 case AST_FRAME_VOICE: 03700 if (!(frame->subclass & ast->nativeformats)) { 03701 char s1[512], s2[512], s3[512]; 03702 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03703 frame->subclass, 03704 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03705 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03706 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03707 ast->readformat, 03708 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03709 ast->writeformat); 03710 ast_frame_dump(ast->name, frame, "<<"); 03711 ast_backtrace(); 03712 return 0; 03713 } 03714 if (p) { 03715 ast_mutex_lock(&p->lock); 03716 if (p->rtp) { 03717 /* If channel is not up, activate early media session */ 03718 if ((ast->_state != AST_STATE_UP) && 03719 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03720 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03721 ast_rtp_new_source(p->rtp); 03722 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03723 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03724 } 03725 p->lastrtptx = time(NULL); 03726 res = ast_rtp_write(p->rtp, frame); 03727 } 03728 ast_mutex_unlock(&p->lock); 03729 } 03730 break; 03731 case AST_FRAME_VIDEO: 03732 if (p) { 03733 ast_mutex_lock(&p->lock); 03734 if (p->vrtp) { 03735 /* Activate video early media */ 03736 if ((ast->_state != AST_STATE_UP) && 03737 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03738 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03739 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03740 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03741 } 03742 p->lastrtptx = time(NULL); 03743 res = ast_rtp_write(p->vrtp, frame); 03744 } 03745 ast_mutex_unlock(&p->lock); 03746 } 03747 break; 03748 case AST_FRAME_IMAGE: 03749 return 0; 03750 break; 03751 case AST_FRAME_MODEM: 03752 if (p) { 03753 ast_mutex_lock(&p->lock); 03754 /* UDPTL requires two-way communication, so early media is not needed here. 03755 we simply forget the frames if we get modem frames before the bridge is up. 03756 Fax will re-transmit. 03757 */ 03758 if (p->udptl && ast->_state == AST_STATE_UP) 03759 res = ast_udptl_write(p->udptl, frame); 03760 ast_mutex_unlock(&p->lock); 03761 } 03762 break; 03763 default: 03764 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03765 return 0; 03766 } 03767 03768 return res; 03769 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15410 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15411 { 15412 struct sip_request req; 15413 struct sockaddr_in sin = { 0, }; 15414 struct sip_pvt *p; 15415 int res; 15416 socklen_t len = sizeof(sin); 15417 int nounlock; 15418 int recount = 0; 15419 int lockretry; 15420 15421 memset(&req, 0, sizeof(req)); 15422 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15423 if (res < 0) { 15424 #if !defined(__FreeBSD__) 15425 if (errno == EAGAIN) 15426 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15427 else 15428 #endif 15429 if (errno != ECONNREFUSED) 15430 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15431 return 1; 15432 } 15433 if (option_debug && res == sizeof(req.data) - 1) 15434 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15435 15436 req.data[res] = '\0'; 15437 req.len = res; 15438 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15439 ast_set_flag(&req, SIP_PKT_DEBUG); 15440 if (pedanticsipchecking) 15441 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15442 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15443 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15444 15445 parse_request(&req); 15446 req.method = find_sip_method(req.rlPart1); 15447 15448 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15449 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15450 15451 if (req.headers < 2) /* Must have at least two headers */ 15452 return 1; 15453 15454 /* Process request, with netlock held, and with usual deadlock avoidance */ 15455 for (lockretry = 100; lockretry > 0; lockretry--) { 15456 ast_mutex_lock(&netlock); 15457 15458 /* Find the active SIP dialog or create a new one */ 15459 p = find_call(&req, &sin, req.method); /* returns p locked */ 15460 if (p == NULL) { 15461 if (option_debug) 15462 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15463 ast_mutex_unlock(&netlock); 15464 return 1; 15465 } 15466 /* Go ahead and lock the owner if it has one -- we may need it */ 15467 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15468 if (!p->owner || !ast_channel_trylock(p->owner)) 15469 break; /* locking succeeded */ 15470 if (option_debug) 15471 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15472 ast_mutex_unlock(&p->lock); 15473 ast_mutex_unlock(&netlock); 15474 /* Sleep for a very short amount of time */ 15475 usleep(1); 15476 } 15477 p->recv = sin; 15478 15479 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15480 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15481 15482 if (!lockretry) { 15483 if (p->owner) 15484 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15485 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15486 if (req.method != SIP_ACK) 15487 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15488 /* XXX We could add retry-after to make sure they come back */ 15489 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15490 return 1; 15491 } 15492 nounlock = 0; 15493 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15494 /* Request failed */ 15495 if (option_debug) 15496 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15497 } 15498 15499 if (p->owner && !nounlock) 15500 ast_channel_unlock(p->owner); 15501 ast_mutex_unlock(&p->lock); 15502 ast_mutex_unlock(&netlock); 15503 if (recount) 15504 ast_update_use_count(); 15505 15506 return 1; 15507 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12633 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().
12634 { 12635 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12636 if (p->rtp) 12637 ast_rtp_stop(p->rtp); 12638 if (p->vrtp) 12639 ast_rtp_stop(p->vrtp); 12640 if (p->udptl) 12641 ast_udptl_stop(p->udptl); 12642 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10772 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10773 { 10774 int i; 10775 10776 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10777 if (subscription_types[i].type == subtype) { 10778 return subscription_types[i].text; 10779 } 10780 } 10781 return subscription_types[0].text; 10782 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6268 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().
06269 { 06270 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06271 06272 if (maxrate & T38FAX_RATE_14400) { 06273 if (option_debug > 1) 06274 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06275 return 14400; 06276 } else if (maxrate & T38FAX_RATE_12000) { 06277 if (option_debug > 1) 06278 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06279 return 12000; 06280 } else if (maxrate & T38FAX_RATE_9600) { 06281 if (option_debug > 1) 06282 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06283 return 9600; 06284 } else if (maxrate & T38FAX_RATE_7200) { 06285 if (option_debug > 1) 06286 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06287 return 7200; 06288 } else if (maxrate & T38FAX_RATE_4800) { 06289 if (option_debug > 1) 06290 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06291 return 4800; 06292 } else if (maxrate & T38FAX_RATE_2400) { 06293 if (option_debug > 1) 06294 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06295 return 2400; 06296 } else { 06297 if (option_debug > 1) 06298 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06299 return 0; 06300 } 06301 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16521 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().
16522 { 16523 struct sip_peer *peer; 16524 16525 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16526 return NULL; 16527 16528 apeerobjs++; 16529 ASTOBJ_INIT(peer); 16530 set_peer_defaults(peer); 16531 16532 ast_copy_string(peer->name, name, sizeof(peer->name)); 16533 16534 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16535 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16536 peer->prefs = default_prefs; 16537 reg_source_db(peer); 16538 16539 return peer; 16540 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6043 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06044 { 06045 struct sip_pvt *p = data; 06046 06047 ast_string_field_free_memory(p); 06048 06049 free(data); 06050 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9776 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().
09777 { 09778 if (mode == TRANSFER_OPENFORALL) 09779 return "open"; 09780 else if (mode == TRANSFER_CLOSED) 09781 return "closed"; 09782 return "strict"; 09783 }
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 8594 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().
08595 { 08596 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08597 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08598 }
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 7817 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07818 { 07819 struct sip_request req; 07820 07821 reqprep(&req, p, SIP_INFO, 0, 1); 07822 add_digit(&req, digit, duration); 07823 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07824 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7827 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07828 { 07829 struct sip_request req; 07830 07831 reqprep(&req, p, SIP_INFO, 0, 1); 07832 add_vidupdate(&req); 07833 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07834 }
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 7075 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().
07076 { 07077 struct sip_request req; 07078 07079 req.method = sipmethod; 07080 if (init) { /* Seems like init always is 2 */ 07081 /* Bump branch even on initial requests */ 07082 p->branch ^= ast_random(); 07083 build_via(p); 07084 if (init > 1) 07085 initreqprep(&req, p, sipmethod); 07086 else 07087 reqprep(&req, p, sipmethod, 0, 1); 07088 } else 07089 reqprep(&req, p, sipmethod, 0, 1); 07090 07091 if (p->options && p->options->auth) 07092 add_header(&req, p->options->authheader, p->options->auth); 07093 append_date(&req); 07094 if (sipmethod == SIP_REFER) { /* Call transfer */ 07095 if (p->refer) { 07096 char buf[SIPBUFSIZE]; 07097 if (!ast_strlen_zero(p->refer->refer_to)) 07098 add_header(&req, "Refer-To", p->refer->refer_to); 07099 if (!ast_strlen_zero(p->refer->referred_by)) { 07100 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07101 add_header(&req, "Referred-By", buf); 07102 } 07103 } 07104 } 07105 /* This new INVITE is part of an attended transfer. Make sure that the 07106 other end knows and replace the current call with this new call */ 07107 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07108 add_header(&req, "Replaces", p->options->replaces); 07109 add_header(&req, "Require", "replaces"); 07110 } 07111 07112 add_header(&req, "Allow", ALLOWED_METHODS); 07113 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07114 if (p->options && p->options->addsipheaders && p->owner) { 07115 struct ast_channel *chan = p->owner; /* The owner channel */ 07116 struct varshead *headp; 07117 07118 ast_channel_lock(chan); 07119 07120 headp = &chan->varshead; 07121 07122 if (!headp) 07123 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07124 else { 07125 const struct ast_var_t *current; 07126 AST_LIST_TRAVERSE(headp, current, entries) { 07127 /* SIPADDHEADER: Add SIP header to outgoing call */ 07128 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07129 char *content, *end; 07130 const char *header = ast_var_value(current); 07131 char *headdup = ast_strdupa(header); 07132 07133 /* Strip of the starting " (if it's there) */ 07134 if (*headdup == '"') 07135 headdup++; 07136 if ((content = strchr(headdup, ':'))) { 07137 *content++ = '\0'; 07138 content = ast_skip_blanks(content); /* Skip white space */ 07139 /* Strip the ending " (if it's there) */ 07140 end = content + strlen(content) -1; 07141 if (*end == '"') 07142 *end = '\0'; 07143 07144 add_header(&req, headdup, content); 07145 if (sipdebug) 07146 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07147 } 07148 } 07149 } 07150 } 07151 07152 ast_channel_unlock(chan); 07153 } 07154 if (sdp) { 07155 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07156 ast_udptl_offered_from_local(p->udptl, 1); 07157 if (option_debug) 07158 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07159 add_t38_sdp(&req, p); 07160 } else if (p->rtp) 07161 add_sdp(&req, p); 07162 } else { 07163 add_header_contentLength(&req, 0); 07164 } 07165 07166 if (!p->initreq.headers) 07167 initialize_initreq(p, &req); 07168 p->lastinvite = p->ocseq; 07169 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07170 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7725 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().
07726 { 07727 struct sip_request req; 07728 07729 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07730 add_text(&req, text); 07731 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07732 }
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 7361 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().
07362 { 07363 struct sip_request req; 07364 char tmp[500]; 07365 char *t = tmp; 07366 size_t maxbytes = sizeof(tmp); 07367 07368 initreqprep(&req, p, SIP_NOTIFY); 07369 add_header(&req, "Event", "message-summary"); 07370 add_header(&req, "Content-Type", default_notifymime); 07371 07372 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07373 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07374 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07375 /* Cisco has a bug in the SIP stack where it can't accept the 07376 (0/0) notification. This can temporarily be disabled in 07377 sip.conf with the "buggymwi" option */ 07378 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)")); 07379 07380 if (p->subscribed) { 07381 if (p->expiry) 07382 add_header(&req, "Subscription-State", "active"); 07383 else /* Expired */ 07384 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07385 } 07386 07387 if (t > tmp + sizeof(tmp)) 07388 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07389 07390 add_header_contentLength(&req, strlen(tmp)); 07391 add_line(&req, tmp); 07392 07393 if (!p->initreq.headers) 07394 initialize_initreq(p, &req); 07395 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07396 }
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 7407 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().
07408 { 07409 struct sip_request req; 07410 char tmp[SIPBUFSIZE/2]; 07411 07412 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07413 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07414 add_header(&req, "Event", tmp); 07415 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07416 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07417 add_header(&req, "Allow", ALLOWED_METHODS); 07418 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07419 07420 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07421 add_header_contentLength(&req, strlen(tmp)); 07422 add_line(&req, tmp); 07423 07424 if (!p->initreq.headers) 07425 initialize_initreq(p, &req); 07426 07427 p->lastnoninvite = p->ocseq; 07428 07429 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07430 }
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 7746 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, DEFAULT_MAX_FORWARDS, 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().
07747 { 07748 struct sip_request req = { 07749 .headers = 0, 07750 }; 07751 char from[256]; 07752 const char *of; 07753 char *c; 07754 char referto[256]; 07755 char *ttag, *ftag; 07756 char *theirtag = ast_strdupa(p->theirtag); 07757 07758 if (option_debug || sipdebug) 07759 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07760 07761 /* Are we transfering an inbound or outbound call ? */ 07762 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07763 of = get_header(&p->initreq, "To"); 07764 ttag = theirtag; 07765 ftag = p->tag; 07766 } else { 07767 of = get_header(&p->initreq, "From"); 07768 ftag = theirtag; 07769 ttag = p->tag; 07770 } 07771 07772 ast_copy_string(from, of, sizeof(from)); 07773 of = get_in_brackets(from); 07774 ast_string_field_set(p, from, of); 07775 if (strncasecmp(of, "sip:", 4)) 07776 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07777 else 07778 of += 4; 07779 /* Get just the username part */ 07780 if ((c = strchr(dest, '@'))) 07781 c = NULL; 07782 else if ((c = strchr(of, '@'))) 07783 *c++ = '\0'; 07784 if (c) 07785 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07786 else 07787 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07788 07789 /* save in case we get 407 challenge */ 07790 sip_refer_allocate(p); 07791 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07792 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07793 p->refer->status = REFER_SENT; /* Set refer status */ 07794 07795 reqprep(&req, p, SIP_REFER, 0, 1); 07796 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07797 07798 add_header(&req, "Refer-To", referto); 07799 add_header(&req, "Allow", ALLOWED_METHODS); 07800 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07801 if (!ast_strlen_zero(p->our_contact)) 07802 add_header(&req, "Referred-By", p->our_contact); 07803 07804 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07805 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07806 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07807 07808 /*! \todo In theory, we should hang around and wait for a reply, before 07809 returning to the dial plan here. Don't know really how that would 07810 affect the transfer() app or the pbx, but, well, to make this 07811 useful we should have a STATUS code on transfer(). 07812 */ 07813 }
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 7534 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().
07535 { 07536 struct sip_request req; 07537 char from[256]; 07538 char to[256]; 07539 char tmp[80]; 07540 char addr[80]; 07541 struct sip_pvt *p; 07542 07543 /* exit if we are already in process with this registrar ?*/ 07544 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07545 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07546 return 0; 07547 } 07548 07549 if (r->call) { /* We have a registration */ 07550 if (!auth) { 07551 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07552 return 0; 07553 } else { 07554 p = r->call; 07555 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07556 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07557 } 07558 } else { 07559 /* Build callid for registration if we haven't registered before */ 07560 if (!r->callid_valid) { 07561 build_callid_registry(r, __ourip, default_fromdomain); 07562 r->callid_valid = TRUE; 07563 } 07564 /* Allocate SIP packet for registration */ 07565 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07566 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07567 return 0; 07568 } 07569 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07570 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07571 /* Find address to hostname */ 07572 if (create_addr(p, r->hostname)) { 07573 /* we have what we hope is a temporary network error, 07574 * probably DNS. We need to reschedule a registration try */ 07575 sip_destroy(p); 07576 07577 if (r->timeout > -1) 07578 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07579 else 07580 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); 07581 07582 AST_SCHED_DEL(sched, r->timeout); 07583 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07584 r->regattempts++; 07585 return 0; 07586 } 07587 /* Copy back Call-ID in case create_addr changed it */ 07588 ast_string_field_set(r, callid, p->callid); 07589 if (r->portno) { 07590 p->sa.sin_port = htons(r->portno); 07591 p->recv.sin_port = htons(r->portno); 07592 } else /* Set registry port to the port set from the peer definition/srv or default */ 07593 r->portno = ntohs(p->sa.sin_port); 07594 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07595 r->call=p; /* Save pointer to SIP packet */ 07596 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07597 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07598 ast_string_field_set(p, peersecret, r->secret); 07599 if (!ast_strlen_zero(r->md5secret)) 07600 ast_string_field_set(p, peermd5secret, r->md5secret); 07601 /* User name in this realm 07602 - if authuser is set, use that, otherwise use username */ 07603 if (!ast_strlen_zero(r->authuser)) { 07604 ast_string_field_set(p, peername, r->authuser); 07605 ast_string_field_set(p, authname, r->authuser); 07606 } else if (!ast_strlen_zero(r->username)) { 07607 ast_string_field_set(p, peername, r->username); 07608 ast_string_field_set(p, authname, r->username); 07609 ast_string_field_set(p, fromuser, r->username); 07610 } 07611 if (!ast_strlen_zero(r->username)) 07612 ast_string_field_set(p, username, r->username); 07613 /* Save extension in packet */ 07614 ast_string_field_set(p, exten, r->contact); 07615 07616 /* 07617 check which address we should use in our contact header 07618 based on whether the remote host is on the external or 07619 internal network so we can register through nat 07620 */ 07621 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07622 p->ourip = bindaddr.sin_addr; 07623 build_contact(p); 07624 } 07625 07626 /* set up a timeout */ 07627 if (auth == NULL) { 07628 if (r->timeout > -1) 07629 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07630 AST_SCHED_DEL(sched, r->timeout); 07631 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07632 if (option_debug) 07633 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07634 } 07635 07636 if (strchr(r->username, '@')) { 07637 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07638 if (!ast_strlen_zero(p->theirtag)) 07639 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07640 else 07641 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07642 } else { 07643 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07644 if (!ast_strlen_zero(p->theirtag)) 07645 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07646 else 07647 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07648 } 07649 07650 /* Fromdomain is what we are registering to, regardless of actual 07651 host name from SRV */ 07652 if (!ast_strlen_zero(p->fromdomain)) { 07653 if (r->portno && r->portno != STANDARD_SIP_PORT) 07654 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07655 else 07656 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07657 } else { 07658 if (r->portno && r->portno != STANDARD_SIP_PORT) 07659 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07660 else 07661 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07662 } 07663 ast_string_field_set(p, uri, addr); 07664 07665 p->branch ^= ast_random(); 07666 07667 init_req(&req, sipmethod, addr); 07668 07669 /* Add to CSEQ */ 07670 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07671 p->ocseq = r->ocseq; 07672 07673 build_via(p); 07674 add_header(&req, "Via", p->via); 07675 add_header(&req, "From", from); 07676 add_header(&req, "To", to); 07677 add_header(&req, "Call-ID", p->callid); 07678 add_header(&req, "CSeq", tmp); 07679 if (!ast_strlen_zero(global_useragent)) 07680 add_header(&req, "User-Agent", global_useragent); 07681 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07682 07683 07684 if (auth) /* Add auth header */ 07685 add_header(&req, authheader, auth); 07686 else if (!ast_strlen_zero(r->nonce)) { 07687 char digest[1024]; 07688 07689 /* We have auth data to reuse, build a digest header! */ 07690 if (sipdebug) 07691 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07692 ast_string_field_set(p, realm, r->realm); 07693 ast_string_field_set(p, nonce, r->nonce); 07694 ast_string_field_set(p, domain, r->domain); 07695 ast_string_field_set(p, opaque, r->opaque); 07696 ast_string_field_set(p, qop, r->qop); 07697 r->noncecount++; 07698 p->noncecount = r->noncecount; 07699 07700 memset(digest,0,sizeof(digest)); 07701 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07702 add_header(&req, "Authorization", digest); 07703 else 07704 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07705 07706 } 07707 07708 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07709 add_header(&req, "Expires", tmp); 07710 add_header(&req, "Contact", p->our_contact); 07711 add_header(&req, "Event", "registration"); 07712 add_header_contentLength(&req, 0); 07713 07714 initialize_initreq(p, &req); 07715 if (sip_debug_test_pvt(p)) 07716 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07717 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07718 r->regattempts++; /* Another attempt */ 07719 if (option_debug > 3) 07720 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07721 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07722 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6795 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().
06796 { 06797 struct sip_request req; 06798 06799 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06800 06801 add_header(&req, "Allow", ALLOWED_METHODS); 06802 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06803 if (sipdebug) 06804 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06805 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06806 append_history(p, "ReInv", "Re-invite sent"); 06807 add_sdp(&req, p); 06808 /* Use this as the basis */ 06809 initialize_initreq(p, &req); 06810 p->lastinvite = p->ocseq; 06811 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06812 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06813 }
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 6819 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().
06820 { 06821 struct sip_request req; 06822 06823 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06824 06825 add_header(&req, "Allow", ALLOWED_METHODS); 06826 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06827 if (sipdebug) 06828 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06829 ast_udptl_offered_from_local(p->udptl, 1); 06830 add_t38_sdp(&req, p); 06831 /* Use this as the basis */ 06832 initialize_initreq(p, &req); 06833 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06834 p->lastinvite = p->ocseq; 06835 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06836 }
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 7839 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().
07840 { 07841 struct sip_request resp; 07842 07843 if (sipmethod == SIP_ACK) 07844 p->invitestate = INV_CONFIRMED; 07845 07846 reqprep(&resp, p, sipmethod, seqno, newbranch); 07847 add_header_contentLength(&resp, 0); 07848 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07849 }
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 7852 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().
07853 { 07854 struct sip_request resp; 07855 07856 reqprep(&resp, p, sipmethod, seqno, newbranch); 07857 if (!ast_strlen_zero(p->realm)) { 07858 char digest[1024]; 07859 07860 memset(digest, 0, sizeof(digest)); 07861 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07862 if (p->options && p->options->auth_type == PROXY_AUTH) 07863 add_header(&resp, "Proxy-Authorization", digest); 07864 else if (p->options && p->options->auth_type == WWW_AUTH) 07865 add_header(&resp, "Authorization", digest); 07866 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07867 add_header(&resp, "Proxy-Authorization", digest); 07868 } else 07869 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07870 } 07871 /* If we are hanging up and know a cause for that, send it in clear text to make 07872 debugging easier. */ 07873 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07874 char buf[10]; 07875 07876 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07877 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07878 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07879 } 07880 07881 add_header_contentLength(&resp, 0); 07882 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07883 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6104 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06105 { 06106 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06107 }
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 6123 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().
06124 { 06125 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06126 }
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 6053 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.
06054 { 06055 struct sip_pvt *p = NULL; 06056 06057 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06058 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06059 return -1; 06060 } 06061 06062 /* if the structure was just allocated, initialize it */ 06063 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06064 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06065 if (ast_string_field_init(p, 512)) 06066 return -1; 06067 } 06068 06069 /* Initialize the bare minimum */ 06070 p->method = intended_method; 06071 06072 if (sin) { 06073 p->sa = *sin; 06074 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06075 p->ourip = __ourip; 06076 } else 06077 p->ourip = __ourip; 06078 06079 p->branch = ast_random(); 06080 make_our_tag(p->tag, sizeof(p->tag)); 06081 p->ocseq = INITIAL_CSEQ; 06082 06083 if (useglobal_nat && sin) { 06084 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06085 p->recv = *sin; 06086 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06087 } 06088 check_via(p, req); 06089 06090 ast_string_field_set(p, fromdomain, default_fromdomain); 06091 build_via(p); 06092 ast_string_field_set(p, callid, callid); 06093 06094 /* Use this temporary pvt structure to send the message */ 06095 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06096 06097 /* Free the string fields, but not the pool space */ 06098 ast_string_field_reset_all(p); 06099 06100 return 0; 06101 }
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 6151 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06152 { 06153 struct sip_request resp; 06154 respprep(&resp, p, msg, req); 06155 add_header(&resp, "Accept", "application/sdp"); 06156 add_header_contentLength(&resp, 0); 06157 return send_response(p, &resp, reliable, 0); 06158 }
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 6161 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().
06162 { 06163 struct sip_request resp; 06164 char tmp[512]; 06165 int seqno = 0; 06166 06167 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06168 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06169 return -1; 06170 } 06171 /* Stale means that they sent us correct authentication, but 06172 based it on an old challenge (nonce) */ 06173 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06174 respprep(&resp, p, msg, req); 06175 add_header(&resp, header, tmp); 06176 add_header_contentLength(&resp, 0); 06177 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06178 return send_response(p, &resp, reliable, seqno); 06179 }
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 6141 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06142 { 06143 struct sip_request resp; 06144 respprep(&resp, p, msg, req); 06145 append_date(&resp); 06146 add_header_contentLength(&resp, 0); 06147 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06148 }
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 6724 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().
06725 { 06726 struct sip_request resp; 06727 int seqno; 06728 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06729 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06730 return -1; 06731 } 06732 respprep(&resp, p, msg, req); 06733 if (p->rtp) { 06734 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06735 if (option_debug) 06736 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06737 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06738 } 06739 try_suggested_sip_codec(p); 06740 add_sdp(&resp, p); 06741 } else 06742 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06743 if (reliable && !p->pendinginvite) 06744 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06745 return send_response(p, &resp, reliable, seqno); 06746 }
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 6684 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().
06685 { 06686 struct sip_request resp; 06687 int seqno; 06688 06689 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06690 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06691 return -1; 06692 } 06693 respprep(&resp, p, msg, req); 06694 if (p->udptl) { 06695 ast_udptl_offered_from_local(p->udptl, 0); 06696 add_t38_sdp(&resp, p); 06697 } else 06698 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06699 if (retrans && !p->pendinginvite) 06700 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06701 return send_response(p, &resp, retrans, seqno); 06702 }
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 6110 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06111 { 06112 struct sip_request resp; 06113 respprep(&resp, p, msg, req); 06114 append_date(&resp); 06115 add_header(&resp, "Unsupported", unsupported); 06116 add_header_contentLength(&resp, 0); 06117 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06118 }
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 7399 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().
07400 { 07401 if (!p->initreq.headers) /* Initialize first request before sending */ 07402 initialize_initreq(p, req); 07403 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07404 }
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 7173 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().
07174 { 07175 char tmp[4000], from[256], to[256]; 07176 char *t = tmp, *c, *mfrom, *mto; 07177 size_t maxbytes = sizeof(tmp); 07178 struct sip_request req; 07179 char hint[AST_MAX_EXTENSION]; 07180 char *statestring = "terminated"; 07181 const struct cfsubscription_types *subscriptiontype; 07182 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07183 char *pidfstate = "--"; 07184 char *pidfnote= "Ready"; 07185 07186 memset(from, 0, sizeof(from)); 07187 memset(to, 0, sizeof(to)); 07188 memset(tmp, 0, sizeof(tmp)); 07189 07190 switch (state) { 07191 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07192 statestring = (global_notifyringing) ? "early" : "confirmed"; 07193 local_state = NOTIFY_INUSE; 07194 pidfstate = "busy"; 07195 pidfnote = "Ringing"; 07196 break; 07197 case AST_EXTENSION_RINGING: 07198 statestring = "early"; 07199 local_state = NOTIFY_INUSE; 07200 pidfstate = "busy"; 07201 pidfnote = "Ringing"; 07202 break; 07203 case AST_EXTENSION_INUSE: 07204 statestring = "confirmed"; 07205 local_state = NOTIFY_INUSE; 07206 pidfstate = "busy"; 07207 pidfnote = "On the phone"; 07208 break; 07209 case AST_EXTENSION_BUSY: 07210 statestring = "confirmed"; 07211 local_state = NOTIFY_CLOSED; 07212 pidfstate = "busy"; 07213 pidfnote = "On the phone"; 07214 break; 07215 case AST_EXTENSION_UNAVAILABLE: 07216 statestring = "terminated"; 07217 local_state = NOTIFY_CLOSED; 07218 pidfstate = "away"; 07219 pidfnote = "Unavailable"; 07220 break; 07221 case AST_EXTENSION_ONHOLD: 07222 statestring = "confirmed"; 07223 local_state = NOTIFY_CLOSED; 07224 pidfstate = "busy"; 07225 pidfnote = "On Hold"; 07226 break; 07227 case AST_EXTENSION_NOT_INUSE: 07228 default: 07229 /* Default setting */ 07230 break; 07231 } 07232 07233 subscriptiontype = find_subscription_type(p->subscribed); 07234 07235 /* Check which device/devices we are watching and if they are registered */ 07236 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07237 char *hint2 = hint, *individual_hint = NULL; 07238 int hint_count = 0, unavailable_count = 0; 07239 07240 while ((individual_hint = strsep(&hint2, "&"))) { 07241 hint_count++; 07242 07243 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07244 unavailable_count++; 07245 } 07246 07247 /* If none of the hinted devices are registered, we will 07248 * override notification and show no availability. 07249 */ 07250 if (hint_count > 0 && hint_count == unavailable_count) { 07251 local_state = NOTIFY_CLOSED; 07252 pidfstate = "away"; 07253 pidfnote = "Not online"; 07254 } 07255 } 07256 07257 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07258 c = get_in_brackets(from); 07259 if (strncasecmp(c, "sip:", 4)) { 07260 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07261 return -1; 07262 } 07263 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07264 07265 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07266 c = get_in_brackets(to); 07267 if (strncasecmp(c, "sip:", 4)) { 07268 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07269 return -1; 07270 } 07271 mto = strsep(&c, ";"); /* trim ; and beyond */ 07272 07273 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07274 07275 07276 add_header(&req, "Event", subscriptiontype->event); 07277 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07278 switch(state) { 07279 case AST_EXTENSION_DEACTIVATED: 07280 if (timeout) 07281 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07282 else { 07283 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07284 add_header(&req, "Retry-After", "60"); 07285 } 07286 break; 07287 case AST_EXTENSION_REMOVED: 07288 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07289 break; 07290 default: 07291 if (p->expiry) 07292 add_header(&req, "Subscription-State", "active"); 07293 else /* Expired */ 07294 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07295 } 07296 switch (p->subscribed) { 07297 case XPIDF_XML: 07298 case CPIM_PIDF_XML: 07299 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07300 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07301 ast_build_string(&t, &maxbytes, "<presence>\n"); 07302 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07303 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07304 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07305 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07306 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07307 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07308 break; 07309 case PIDF_XML: /* Eyebeam supports this format */ 07310 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07311 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); 07312 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07313 if (pidfstate[0] != '-') 07314 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07315 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07316 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07317 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07318 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07319 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07320 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07321 else 07322 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07323 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07324 break; 07325 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07326 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07327 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); 07328 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07329 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07330 else 07331 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07332 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07333 if (state == AST_EXTENSION_ONHOLD) { 07334 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07335 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07336 "</target>\n</local>\n", mto); 07337 } 07338 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07339 break; 07340 case NONE: 07341 default: 07342 break; 07343 } 07344 07345 if (t > tmp + sizeof(tmp)) 07346 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07347 07348 add_header_contentLength(&req, strlen(tmp)); 07349 add_line(&req, tmp); 07350 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07351 07352 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07353 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3643 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().
03644 { 03645 int fmt; 03646 const char *codec; 03647 03648 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03649 if (!codec) 03650 return; 03651 03652 fmt = ast_getformatbyname(codec); 03653 if (fmt) { 03654 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03655 if (p->jointcapability & fmt) { 03656 p->jointcapability &= fmt; 03657 p->capability &= fmt; 03658 } else 03659 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03660 } else 03661 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03662 return; 03663 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18084 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
18085 { 18086 struct sip_pvt *p, *pl; 18087 18088 /* First, take us out of the channel type list */ 18089 ast_channel_unregister(&sip_tech); 18090 18091 /* Unregister dial plan functions */ 18092 ast_custom_function_unregister(&sipchaninfo_function); 18093 ast_custom_function_unregister(&sippeer_function); 18094 ast_custom_function_unregister(&sip_header_function); 18095 ast_custom_function_unregister(&checksipdomain_function); 18096 18097 /* Unregister dial plan applications */ 18098 ast_unregister_application(app_dtmfmode); 18099 ast_unregister_application(app_sipaddheader); 18100 18101 /* Unregister CLI commands */ 18102 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18103 18104 /* Disconnect from the RTP subsystem */ 18105 ast_rtp_proto_unregister(&sip_rtp); 18106 18107 /* Disconnect from UDPTL */ 18108 ast_udptl_proto_unregister(&sip_udptl); 18109 18110 /* Unregister AMI actions */ 18111 ast_manager_unregister("SIPpeers"); 18112 ast_manager_unregister("SIPshowpeer"); 18113 18114 ast_mutex_lock(&iflock); 18115 /* Hangup all interfaces if they have an owner */ 18116 for (p = iflist; p ; p = p->next) { 18117 if (p->owner) 18118 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18119 } 18120 ast_mutex_unlock(&iflock); 18121 18122 ast_mutex_lock(&monlock); 18123 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18124 pthread_cancel(monitor_thread); 18125 pthread_kill(monitor_thread, SIGURG); 18126 pthread_join(monitor_thread, NULL); 18127 } 18128 monitor_thread = AST_PTHREADT_STOP; 18129 ast_mutex_unlock(&monlock); 18130 18131 ast_mutex_lock(&iflock); 18132 /* Destroy all the interfaces and free their memory */ 18133 p = iflist; 18134 while (p) { 18135 pl = p; 18136 p = p->next; 18137 __sip_destroy(pl, TRUE); 18138 } 18139 iflist = NULL; 18140 ast_mutex_unlock(&iflock); 18141 18142 /* Free memory for local network address mask */ 18143 ast_free_ha(localaddr); 18144 18145 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18146 ASTOBJ_CONTAINER_DESTROY(&userl); 18147 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18148 ASTOBJ_CONTAINER_DESTROY(&peerl); 18149 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18150 ASTOBJ_CONTAINER_DESTROY(®l); 18151 18152 clear_realm_authentication(authl); 18153 clear_sip_domains(); 18154 close(sipsock); 18155 sched_context_destroy(sched); 18156 18157 return 0; 18158 }
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 3196 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().
03197 { 03198 char name[256]; 03199 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03200 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03201 struct sip_user *u = NULL; 03202 struct sip_peer *p = NULL; 03203 03204 if (option_debug > 2) 03205 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03206 03207 /* Test if we need to check call limits, in order to avoid 03208 realtime lookups if we do not need it */ 03209 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03210 return 0; 03211 03212 ast_copy_string(name, fup->username, sizeof(name)); 03213 03214 /* Check the list of users only for incoming calls */ 03215 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03216 inuse = &u->inUse; 03217 call_limit = &u->call_limit; 03218 inringing = NULL; 03219 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03220 inuse = &p->inUse; 03221 call_limit = &p->call_limit; 03222 inringing = &p->inRinging; 03223 ast_copy_string(name, fup->peername, sizeof(name)); 03224 } 03225 if (!p && !u) { 03226 if (option_debug > 1) 03227 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03228 return 0; 03229 } 03230 03231 switch(event) { 03232 /* incoming and outgoing affects the inUse counter */ 03233 case DEC_CALL_LIMIT: 03234 if ( *inuse > 0 ) { 03235 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03236 (*inuse)--; 03237 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03238 } 03239 } else { 03240 *inuse = 0; 03241 } 03242 if (inringing) { 03243 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03244 if (*inringing > 0) 03245 (*inringing)--; 03246 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03247 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03248 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03249 } 03250 } 03251 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03252 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03253 sip_peer_hold(fup, 0); 03254 } 03255 if (option_debug > 1 || sipdebug) { 03256 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03257 } 03258 break; 03259 03260 case INC_CALL_RINGING: 03261 case INC_CALL_LIMIT: 03262 if (*call_limit > 0 ) { 03263 if (*inuse >= *call_limit) { 03264 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); 03265 if (u) 03266 ASTOBJ_UNREF(u, sip_destroy_user); 03267 else 03268 ASTOBJ_UNREF(p, sip_destroy_peer); 03269 return -1; 03270 } 03271 } 03272 if (inringing && (event == INC_CALL_RINGING)) { 03273 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03274 (*inringing)++; 03275 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03276 } 03277 } 03278 /* Continue */ 03279 (*inuse)++; 03280 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03281 if (option_debug > 1 || sipdebug) { 03282 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03283 } 03284 break; 03285 03286 case DEC_CALL_RINGING: 03287 if (inringing) { 03288 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03289 if (*inringing > 0) 03290 (*inringing)--; 03291 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03292 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03293 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03294 } 03295 } 03296 break; 03297 03298 default: 03299 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03300 } 03301 if (p) { 03302 ast_device_state_changed("SIP/%s", p->name); 03303 ASTOBJ_UNREF(p, sip_destroy_peer); 03304 } else /* u must be set */ 03305 ASTOBJ_UNREF(u, sip_destroy_user); 03306 return 0; 03307 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2501 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().
02502 { 02503 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02504 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02505 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02506 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02507 } 02508 }
struct in_addr __ourip [static] |
Definition at line 1208 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 566 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 582 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17654 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17656 of file chan_sip.c.
Definition at line 1197 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 546 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1202 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 17910 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 17915 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 560 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 232 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11680 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1211 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 223 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 525 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 534 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 531 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 532 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 528 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 535 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 529 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 524 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 530 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17653 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17659 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 562 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1205 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 1204 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 1203 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 553 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 554 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 570 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 543 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 569 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 567 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 538 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 585 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 230 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 539 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 572 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 556 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 542 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 541 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 563 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 551 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 552 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 564 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 547 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 540 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 549 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 550 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 548 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 568 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 558 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 559 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 565 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11697 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
struct io_context* io [static] |
The IO context
Definition at line 606 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1207 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 10325 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 9876 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 192 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 191 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 600 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 11689 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 11693 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 233 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1213 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 11629 of file chan_sip.c.
int ourport [static] |
Definition at line 1210 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1209 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 545 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 11671 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 561 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 583 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 581 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 579 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 605 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 11653 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 11649 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 11624 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 11657 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 11644 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 11710 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 11666 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 11661 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 11676 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 11714 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 11706 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 11639 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 11634 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 11702 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 602 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 603 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 1610 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 1552 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 1578 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 1619 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 11951 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 11871 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1201 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 607 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 580 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 544 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 578 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17652 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17657 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.