#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 "asterisk/dnsmgr.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) (x == AST_FORMAT_G722) ? 16000 : 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_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 | 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. | |
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 maybe the lock on p is not strictly necessary but there might be a race. | |
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, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, 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 void | 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 *dest, const char *text, int ispdu) |
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, int sipmethod, struct sip_request *req, enum xmittype reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
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 |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
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 [] |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
struct ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
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 475 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1840 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 367 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 8284 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 608 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 610 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
#define DEFAULT_ALLOWGUEST TRUE |
#define DEFAULT_AUTOCREATEPEER FALSE |
#define DEFAULT_CALLERID "asterisk" |
#define DEFAULT_COMPACTHEADERS FALSE |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 188 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 203 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 202 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
#define DEFAULT_MAX_EXPIRY 3600 |
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 175 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 201 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
#define DEFAULT_MOHINTERPRET "default" |
#define DEFAULT_MOHSUGGEST "" |
#define DEFAULT_MWITIME 10 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_NOTIFYRINGING TRUE |
#define DEFAULT_PEDANTIC FALSE |
#define DEFAULT_QUALIFY FALSE |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 205 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 513 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 505 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 504 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 506 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 210 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 516 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_VMEXTEN "asterisk" |
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 180 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 182 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 186 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 179 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 155 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1024 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 609 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 219 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 166 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 196 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 211 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1022 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 206 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 235 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 408 of file chan_sip.c.
#define RTP 1 |
Definition at line 234 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 217 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | (x == AST_FORMAT_G722) ? 16000 : 8000 |
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 715 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 756 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 744 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 745 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 730 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 731 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 735 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 733 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 734 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 732 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 761 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 729 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 759 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 722 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 758 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 749 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 748 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), realtime_peer(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 213 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 214 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 215 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 737 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 741 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 738 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 739 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 740 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 716 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 720 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 755 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 717 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 411 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 412 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 728 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 782 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 781 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 794 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 789 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 792 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 791 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 775 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 777 of file chan_sip.c.
Referenced by reload_config(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 778 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 797 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 774 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 784 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 795 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 793 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 771 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
Definition at line 770 of file chan_sip.c.
Referenced by expire_register(), realtime_peer(), and reload_config().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 768 of file chan_sip.c.
Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 772 of file chan_sip.c.
Referenced by realtime_update_peer(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 769 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 779 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 783 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 785 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 787 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 788 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 786 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 780 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), reload_config(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 721 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 802 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 804 of file chan_sip.c.
Referenced by check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and transmit_fake_auth_response().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 803 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 751 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 753 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 754 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 719 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 723 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 726 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 746 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 757 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 207 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 724 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 727 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 725 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), reload_config(), and sip_show_settings().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 834 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 835 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 836 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 481 of file chan_sip.c.
Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), reload_config(), set_address_from_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 407 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 478 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 809 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 828 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 829 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 824 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 825 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 826 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 827 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 814 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 813 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 811 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 810 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 817 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 816 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 818 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 820 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 821 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 822 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 159 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1601 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 164 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 162 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 343 of file chan_sip.c.
00343 { 00344 AUTH_SUCCESSFUL = 0, 00345 AUTH_CHALLENGE_SENT = 1, 00346 AUTH_SECRET_FAILED = -1, 00347 AUTH_USERNAME_MISMATCH = -2, 00348 AUTH_NOT_FOUND = -3, 00349 AUTH_FAKE_AUTH = -4, 00350 AUTH_UNKNOWN_DOMAIN = -5, 00351 AUTH_PEER_NOT_DYNAMIC = -6, 00352 AUTH_ACL_FAILED = -7, 00353 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 678 of file chan_sip.c.
00678 { 00679 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00680 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00681 };
enum invitestates |
States for the INVITE transaction, not the dialog.
INV_NONE | No state at all, maybe not an INVITE dialog |
INV_CALLING | Invite sent, no answer |
INV_PROCEEDING | We got/sent 1xx message |
INV_EARLY_MEDIA | We got 18x message with to-tag back |
INV_COMPLETED | Got final response with error. Wait for ACK, then CONFIRMED |
INV_CONFIRMED | Confirmed response - we've got an ack (Incoming calls only) |
INV_TERMINATED | Transaction done - either successful (AST_STATE_UP) or failed, but done The only way out of this is a BYE from one side |
INV_CANCELLED | Transaction cancelled by client or server in non-terminated state |
Definition at line 254 of file chan_sip.c.
00254 { 00255 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00256 INV_CALLING = 1, /*!< Invite sent, no answer */ 00257 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00258 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00259 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00260 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00261 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00262 The only way out of this is a BYE from one side */ 00263 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00264 };
Definition at line 281 of file chan_sip.c.
00281 { 00282 PARSE_REGISTER_FAILED, 00283 PARSE_REGISTER_UPDATE, 00284 PARSE_REGISTER_QUERY, 00285 };
enum referstatus |
Parameters to know status of transfer.
REFER_IDLE | No REFER is in progress |
REFER_SENT | Sent REFER to transferee |
REFER_RECEIVED | Received REFER from transferer |
REFER_CONFIRMED | Refer confirmed with a 100 TRYING |
REFER_ACCEPTED | Accepted by transferee |
REFER_RINGING | Target Ringing |
REFER_200OK | Answered by transfer target |
REFER_FAILED | REFER declined - go on |
REFER_NOAUTH | We had no auth for REFER |
Definition at line 858 of file chan_sip.c.
00858 { 00859 REFER_IDLE, /*!< No REFER is in progress */ 00860 REFER_SENT, /*!< Sent REFER to transferee */ 00861 REFER_RECEIVED, /*!< Received REFER from transferer */ 00862 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00863 REFER_ACCEPTED, /*!< Accepted by transferee */ 00864 REFER_RINGING, /*!< Target Ringing */ 00865 REFER_200OK, /*!< Answered by transfer target */ 00866 REFER_FAILED, /*!< REFER declined - go on */ 00867 REFER_NOAUTH /*!< We had no auth for REFER */ 00868 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 337 of file chan_sip.c.
00337 { 00338 PROXY_AUTH, 00339 WWW_AUTH, 00340 };
enum sip_result |
Definition at line 246 of file chan_sip.c.
00246 { 00247 AST_SUCCESS = 0, 00248 AST_FAILURE = -1, 00249 };
enum sipmethod |
SIP Request methods known by Asterisk.
SIP_UNKNOWN | |
SIP_RESPONSE | |
SIP_REGISTER | |
SIP_OPTIONS | |
SIP_NOTIFY | |
SIP_INVITE | |
SIP_ACK | |
SIP_PRACK | |
SIP_BYE | |
SIP_REFER | |
SIP_SUBSCRIBE | |
SIP_MESSAGE | |
SIP_UPDATE | |
SIP_INFO | |
SIP_CANCEL | |
SIP_PUBLISH | |
SIP_PING |
Definition at line 312 of file chan_sip.c.
00312 { 00313 SIP_UNKNOWN, /* Unknown response */ 00314 SIP_RESPONSE, /* Not request, response to outbound request */ 00315 SIP_REGISTER, 00316 SIP_OPTIONS, 00317 SIP_NOTIFY, 00318 SIP_INVITE, 00319 SIP_ACK, 00320 SIP_PRACK, /* Not supported at all */ 00321 SIP_BYE, 00322 SIP_REFER, 00323 SIP_SUBSCRIBE, 00324 SIP_MESSAGE, 00325 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00326 SIP_INFO, 00327 SIP_CANCEL, 00328 SIP_PUBLISH, /* Not supported at all */ 00329 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00330 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 356 of file chan_sip.c.
00356 { 00357 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00358 REG_STATE_REGSENT, /*!< Registration request sent */ 00359 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00360 REG_STATE_REGISTERED, /*!< Registred and done */ 00361 REG_STATE_REJECTED, /*!< Registration rejected */ 00362 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00363 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00364 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00365 };
enum subscriptiontype |
Definition at line 287 of file chan_sip.c.
00287 { 00288 NONE = 0, 00289 XPIDF_XML, 00290 DIALOG_INFO_XML, 00291 CPIM_PIDF_XML, 00292 PIDF_XML, 00293 MWI_NOTIFICATION 00294 };
enum t38state |
T38 States for a call.
Definition at line 839 of file chan_sip.c.
00839 { 00840 T38_DISABLED = 0, /*!< Not enabled */ 00841 T38_LOCAL_DIRECT, /*!< Offered from local */ 00842 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00843 T38_PEER_DIRECT, /*!< Offered from peer */ 00844 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00845 T38_ENABLED /*!< Negotiated (enabled) */ 00846 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 240 of file chan_sip.c.
00240 { 00241 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00242 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00243 };
enum xmittype |
XMIT_CRITICAL | Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session |
XMIT_RELIABLE | Transmit SIP message reliably, with re-transmits |
XMIT_UNRELIABLE | Transmit SIP message without bothering with re-transmits |
Definition at line 274 of file chan_sip.c.
00274 { 00275 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00276 If it fails, it's critical and will cause a teardown of the session */ 00277 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00278 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00279 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4203 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04204 { 04205 int pass; 04206 04207 /* 04208 * Technically you can place arbitrary whitespace both before and after the ':' in 04209 * a header, although RFC3261 clearly says you shouldn't before, and place just 04210 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04211 * a good idea to say you can do it, and if you can do it, why in the hell would. 04212 * you say you shouldn't. 04213 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04214 * and we always allow spaces after that for compatibility. 04215 */ 04216 for (pass = 0; name && pass < 2;pass++) { 04217 int x, len = strlen(name); 04218 for (x=*start; x<req->headers; x++) { 04219 if (!strncasecmp(req->header[x], name, len)) { 04220 char *r = req->header[x] + len; /* skip name */ 04221 if (pedanticsipchecking) 04222 r = ast_skip_blanks(r); 04223 04224 if (*r == ':') { 04225 *start = x+1; 04226 return ast_skip_blanks(r+1); 04227 } 04228 } 04229 } 04230 if (pass == 0) /* Try aliases */ 04231 name = find_alias(name, NULL); 04232 } 04233 04234 /* Don't return NULL, so get_header is always a valid pointer */ 04235 return ""; 04236 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission.
Definition at line 2138 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, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02139 { 02140 struct sip_pkt *cur, *prev = NULL; 02141 02142 /* Just in case... */ 02143 char *msg; 02144 int res = FALSE; 02145 02146 msg = sip_methods[sipmethod].text; 02147 02148 ast_mutex_lock(&p->lock); 02149 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02150 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02151 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02152 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02153 if (!resp && (seqno == p->pendinginvite)) { 02154 if (option_debug) 02155 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02156 p->pendinginvite = 0; 02157 } 02158 /* this is our baby */ 02159 res = TRUE; 02160 UNLINK(cur, p->packets, prev); 02161 if (cur->retransid > -1) { 02162 if (sipdebug && option_debug > 3) 02163 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02164 ast_sched_del(sched, cur->retransid); 02165 cur->retransid = -1; 02166 } 02167 free(cur); 02168 break; 02169 } 02170 } 02171 ast_mutex_unlock(&p->lock); 02172 if (option_debug) 02173 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02174 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2064 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, MWI_NOTIFICATION, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02065 { 02066 struct sip_pvt *p = (struct sip_pvt *)data; 02067 02068 /* If this is a subscription, tell the phone that we got a timeout */ 02069 if (p->subscribed) { 02070 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02071 p->subscribed = NONE; 02072 append_history(p, "Subscribestatus", "timeout"); 02073 if (option_debug > 2) 02074 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02075 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02076 } 02077 02078 /* If there are packets still waiting for delivery, delay the destruction */ 02079 if (p->packets) { 02080 if (option_debug > 2) 02081 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02082 append_history(p, "ReliableXmit", "timeout"); 02083 return 10000; 02084 } 02085 02086 /* If we're destroying a subscription, dereference peer object too */ 02087 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02088 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02089 02090 /* Reset schedule ID */ 02091 p->autokillid = -1; 02092 02093 if (option_debug) 02094 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02095 append_history(p, "AutoDestroy", "%s", p->callid); 02096 if (p->owner) { 02097 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02098 ast_queue_hangup(p->owner); 02099 } else if (p->refer) { 02100 if (option_debug > 2) 02101 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02102 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02103 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02104 } else 02105 sip_destroy(p); 02106 return 0; 02107 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3052 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_rtp_destroy(), ast_sched_del(), ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::autokillid, sip_registry::call, sip_pvt::chanvars, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), sip_pvt::history, sip_pvt::history_entries, iflist, sip_pvt::initid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pkt::next, sip_pvt::next, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::route, sip_pvt::rtp, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, cfsip_methods::text, sip_pvt::udptl, UNLINK, update_call_counter(), sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03053 { 03054 struct sip_pvt *cur, *prev = NULL; 03055 struct sip_pkt *cp; 03056 03057 if (sip_debug_test_pvt(p) || option_debug > 2) 03058 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03059 03060 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03061 update_call_counter(p, DEC_CALL_LIMIT); 03062 if (option_debug > 1) 03063 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03064 } 03065 03066 /* Remove link from peer to subscription of MWI */ 03067 if (p->relatedpeer && p->relatedpeer->mwipvt) 03068 p->relatedpeer->mwipvt = NULL; 03069 03070 if (dumphistory) 03071 sip_dump_history(p); 03072 03073 if (p->options) 03074 free(p->options); 03075 03076 if (p->stateid > -1) 03077 ast_extension_state_del(p->stateid, NULL); 03078 if (p->initid > -1) 03079 ast_sched_del(sched, p->initid); 03080 if (p->waitid > -1) 03081 ast_sched_del(sched, p->waitid); 03082 if (p->autokillid > -1) 03083 ast_sched_del(sched, p->autokillid); 03084 03085 if (p->rtp) 03086 ast_rtp_destroy(p->rtp); 03087 if (p->vrtp) 03088 ast_rtp_destroy(p->vrtp); 03089 if (p->udptl) 03090 ast_udptl_destroy(p->udptl); 03091 if (p->refer) 03092 free(p->refer); 03093 if (p->route) { 03094 free_old_route(p->route); 03095 p->route = NULL; 03096 } 03097 if (p->registry) { 03098 if (p->registry->call == p) 03099 p->registry->call = NULL; 03100 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03101 } 03102 03103 /* Unlink us from the owner if we have one */ 03104 if (p->owner) { 03105 if (lockowner) 03106 ast_channel_lock(p->owner); 03107 if (option_debug) 03108 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03109 p->owner->tech_pvt = NULL; 03110 if (lockowner) 03111 ast_channel_unlock(p->owner); 03112 } 03113 /* Clear history */ 03114 if (p->history) { 03115 struct sip_history *hist; 03116 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03117 free(hist); 03118 p->history_entries--; 03119 } 03120 free(p->history); 03121 p->history = NULL; 03122 } 03123 03124 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03125 if (cur == p) { 03126 UNLINK(cur, iflist, prev); 03127 break; 03128 } 03129 } 03130 if (!cur) { 03131 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03132 return; 03133 } 03134 03135 /* remove all current packets in this dialog */ 03136 while((cp = p->packets)) { 03137 p->packets = p->packets->next; 03138 if (cp->retransid > -1) 03139 ast_sched_del(sched, cp->retransid); 03140 free(cp); 03141 } 03142 if (p->chanvars) { 03143 ast_variables_destroy(p->chanvars); 03144 p->chanvars = NULL; 03145 } 03146 ast_mutex_destroy(&p->lock); 03147 03148 ast_string_field_free_memory(p); 03149 03150 free(p); 03151 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7410 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07411 { 07412 int res; 07413 07414 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07415 return res; 07416 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race.
Definition at line 2178 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().
02179 { 02180 struct sip_pkt *cur = NULL; 02181 02182 while (p->packets) { 02183 int method; 02184 if (cur == p->packets) { 02185 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02186 return; 02187 } 02188 cur = p->packets; 02189 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02190 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02191 } 02192 }
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 2018 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_sched_del(), ast_set_flag, AST_SUCCESS, ast_test_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sipdebug, sip_pvt::timer_t1, sip_pkt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02019 { 02020 struct sip_pkt *pkt; 02021 int siptimer_a = DEFAULT_RETRANS; 02022 int xmitres = 0; 02023 02024 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02025 return AST_FAILURE; 02026 memcpy(pkt->data, data, len); 02027 pkt->method = sipmethod; 02028 pkt->packetlen = len; 02029 pkt->next = p->packets; 02030 pkt->owner = p; 02031 pkt->seqno = seqno; 02032 if (resp) 02033 ast_set_flag(pkt, FLAG_RESPONSE); 02034 pkt->data[len] = '\0'; 02035 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02036 if (fatal) 02037 ast_set_flag(pkt, FLAG_FATAL); 02038 if (pkt->timer_t1) 02039 siptimer_a = pkt->timer_t1 * 2; 02040 02041 /* Schedule retransmission */ 02042 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 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->next = p->packets; 02046 p->packets = pkt; 02047 if (sipmethod == SIP_INVITE) { 02048 /* Note this is a pending invite */ 02049 p->pendinginvite = seqno; 02050 } 02051 02052 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02053 02054 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02055 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02056 ast_sched_del(sched, pkt->retransid); /* No more retransmission */ 02057 pkt->retransid = -1; 02058 return AST_FAILURE; 02059 } else 02060 return AST_SUCCESS; 02061 }
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 2195 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02196 { 02197 struct sip_pkt *cur; 02198 int res = -1; 02199 02200 for (cur = p->packets; cur; cur = cur->next) { 02201 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02202 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02203 /* this is our baby */ 02204 if (cur->retransid > -1) { 02205 if (option_debug > 3 && sipdebug) 02206 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02207 ast_sched_del(sched, cur->retransid); 02208 cur->retransid = -1; 02209 } 02210 res = 0; 02211 break; 02212 } 02213 } 02214 if (option_debug) 02215 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02216 return res; 02217 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10812 of file chan_sip.c.
References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, sip_peer::mailbox, MWI_NOTIFICATION, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_refer::status, sip_pvt::subscribed, and subscription_type2str().
Referenced by sip_show_channels(), and sip_show_subscriptions().
10813 { 10814 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10815 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10816 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10817 struct sip_pvt *cur; 10818 int numchans = 0; 10819 char *referstatus = NULL; 10820 10821 if (argc != 3) 10822 return RESULT_SHOWUSAGE; 10823 ast_mutex_lock(&iflock); 10824 cur = iflist; 10825 if (!subscriptions) 10826 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10827 else 10828 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10829 for (; cur; cur = cur->next) { 10830 referstatus = ""; 10831 if (cur->refer) { /* SIP transfer in progress */ 10832 referstatus = referstatus2str(cur->refer->status); 10833 } 10834 if (cur->subscribed == NONE && !subscriptions) { 10835 char formatbuf[BUFSIZ/2]; 10836 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10837 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10838 cur->callid, 10839 cur->ocseq, cur->icseq, 10840 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10841 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10842 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10843 cur->lastmsg , 10844 referstatus 10845 ); 10846 numchans++; 10847 } 10848 if (cur->subscribed != NONE && subscriptions) { 10849 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10850 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10851 cur->callid, 10852 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10853 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10854 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10855 subscription_type2str(cur->subscribed), 10856 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10857 ); 10858 numchans++; 10859 } 10860 } 10861 ast_mutex_unlock(&iflock); 10862 if (!subscriptions) 10863 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10864 else 10865 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10866 return RESULT_SUCCESS; 10867 #undef FORMAT 10868 #undef FORMAT2 10869 #undef FORMAT3 10870 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1768 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().
01769 { 01770 int res; 01771 const struct sockaddr_in *dst = sip_real_dst(p); 01772 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01773 01774 if (res == -1) { 01775 switch (errno) { 01776 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01777 case EHOSTUNREACH: /* Host can't be reached */ 01778 case ENETDOWN: /* Inteface down */ 01779 case ENETUNREACH: /* Network failure */ 01780 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01781 } 01782 } 01783 if (res != len) 01784 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)); 01785 return res; 01786 }
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 5956 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
05957 { 05958 struct sip_request resp; 05959 int seqno = 0; 05960 05961 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05962 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05963 return -1; 05964 } 05965 respprep(&resp, p, msg, req); 05966 add_header_contentLength(&resp, 0); 05967 /* If we are cancelling an incoming invite for some reason, add information 05968 about the reason why we are doing this in clear text */ 05969 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05970 char buf[10]; 05971 05972 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05973 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05974 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05975 } 05976 return send_response(p, &resp, reliable, seqno); 05977 }
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 10370 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10371 { 10372 char status[30] = ""; 10373 char cbuf[256]; 10374 struct sip_peer *peer; 10375 char codec_buf[512]; 10376 struct ast_codec_pref *pref; 10377 struct ast_variable *v; 10378 struct sip_auth *auth; 10379 int x = 0, codec = 0, load_realtime; 10380 int realtimepeers; 10381 10382 realtimepeers = ast_check_realtime("sippeers"); 10383 10384 if (argc < 4) 10385 return RESULT_SHOWUSAGE; 10386 10387 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10388 peer = find_peer(argv[3], NULL, load_realtime); 10389 if (s) { /* Manager */ 10390 if (peer) { 10391 const char *id = astman_get_header(m,"ActionID"); 10392 10393 astman_append(s, "Response: Success\r\n"); 10394 if (!ast_strlen_zero(id)) 10395 astman_append(s, "ActionID: %s\r\n",id); 10396 } else { 10397 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10398 astman_send_error(s, m, cbuf); 10399 return 0; 10400 } 10401 } 10402 if (peer && type==0 ) { /* Normal listing */ 10403 ast_cli(fd,"\n\n"); 10404 ast_cli(fd, " * Name : %s\n", peer->name); 10405 if (realtimepeers) { /* Realtime is enabled */ 10406 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10407 } 10408 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10409 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10410 for (auth = peer->auth; auth; auth = auth->next) { 10411 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10412 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10413 } 10414 ast_cli(fd, " Context : %s\n", peer->context); 10415 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10416 ast_cli(fd, " Language : %s\n", peer->language); 10417 if (!ast_strlen_zero(peer->accountcode)) 10418 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10419 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10420 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10421 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10422 if (!ast_strlen_zero(peer->fromuser)) 10423 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10424 if (!ast_strlen_zero(peer->fromdomain)) 10425 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10426 ast_cli(fd, " Callgroup : "); 10427 print_group(fd, peer->callgroup, 0); 10428 ast_cli(fd, " Pickupgroup : "); 10429 print_group(fd, peer->pickupgroup, 0); 10430 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10431 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10432 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10433 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10434 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10435 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10436 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10437 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10438 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))); 10439 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10440 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10441 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10442 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10443 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10444 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10445 #endif 10446 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10447 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10448 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10449 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10450 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10451 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10452 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10453 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10454 10455 /* - is enumerated */ 10456 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10457 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10458 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10459 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)); 10460 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10461 if (!ast_strlen_zero(global_regcontext)) 10462 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10463 ast_cli(fd, " Def. Username: %s\n", peer->username); 10464 ast_cli(fd, " SIP Options : "); 10465 if (peer->sipoptions) { 10466 int lastoption = -1; 10467 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10468 if (sip_options[x].id != lastoption) { 10469 if (peer->sipoptions & sip_options[x].id) 10470 ast_cli(fd, "%s ", sip_options[x].text); 10471 lastoption = x; 10472 } 10473 } 10474 } else 10475 ast_cli(fd, "(none)"); 10476 10477 ast_cli(fd, "\n"); 10478 ast_cli(fd, " Codecs : "); 10479 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10480 ast_cli(fd, "%s\n", codec_buf); 10481 ast_cli(fd, " Codec Order : ("); 10482 print_codec_to_cli(fd, &peer->prefs); 10483 ast_cli(fd, ")\n"); 10484 10485 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10486 ast_cli(fd, " Status : "); 10487 peer_status(peer, status, sizeof(status)); 10488 ast_cli(fd, "%s\n",status); 10489 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10490 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10491 if (peer->chanvars) { 10492 ast_cli(fd, " Variables :\n"); 10493 for (v = peer->chanvars ; v ; v = v->next) 10494 ast_cli(fd, " %s = %s\n", v->name, v->value); 10495 } 10496 ast_cli(fd,"\n"); 10497 ASTOBJ_UNREF(peer,sip_destroy_peer); 10498 } else if (peer && type == 1) { /* manager listing */ 10499 char buf[256]; 10500 astman_append(s, "Channeltype: SIP\r\n"); 10501 astman_append(s, "ObjectName: %s\r\n", peer->name); 10502 astman_append(s, "ChanObjectType: peer\r\n"); 10503 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10504 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10505 astman_append(s, "Context: %s\r\n", peer->context); 10506 astman_append(s, "Language: %s\r\n", peer->language); 10507 if (!ast_strlen_zero(peer->accountcode)) 10508 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10509 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10510 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10511 if (!ast_strlen_zero(peer->fromuser)) 10512 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10513 if (!ast_strlen_zero(peer->fromdomain)) 10514 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10515 astman_append(s, "Callgroup: "); 10516 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10517 astman_append(s, "Pickupgroup: "); 10518 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10519 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10520 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10521 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10522 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10523 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10524 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10525 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10526 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10527 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))); 10528 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10529 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10530 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10531 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10532 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10533 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10534 10535 /* - is enumerated */ 10536 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10537 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10538 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10539 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)); 10540 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)); 10541 astman_append(s, "Default-Username: %s\r\n", peer->username); 10542 if (!ast_strlen_zero(global_regcontext)) 10543 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10544 astman_append(s, "Codecs: "); 10545 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10546 astman_append(s, "%s\r\n", codec_buf); 10547 astman_append(s, "CodecOrder: "); 10548 pref = &peer->prefs; 10549 for(x = 0; x < 32 ; x++) { 10550 codec = ast_codec_pref_index(pref,x); 10551 if (!codec) 10552 break; 10553 astman_append(s, "%s", ast_getformatname(codec)); 10554 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10555 astman_append(s, ","); 10556 } 10557 10558 astman_append(s, "\r\n"); 10559 astman_append(s, "Status: "); 10560 peer_status(peer, status, sizeof(status)); 10561 astman_append(s, "%s\r\n", status); 10562 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10563 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10564 if (peer->chanvars) { 10565 for (v = peer->chanvars ; v ; v = v->next) { 10566 astman_append(s, "ChanVariable:\n"); 10567 astman_append(s, " %s,%s\r\n", v->name, v->value); 10568 } 10569 } 10570 10571 ASTOBJ_UNREF(peer,sip_destroy_peer); 10572 10573 } else { 10574 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10575 ast_cli(fd,"\n"); 10576 } 10577 10578 return RESULT_SUCCESS; 10579 }
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 9920 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09921 { 09922 regex_t regexbuf; 09923 int havepattern = FALSE; 09924 09925 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09926 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09927 09928 char name[256]; 09929 int total_peers = 0; 09930 int peers_mon_online = 0; 09931 int peers_mon_offline = 0; 09932 int peers_unmon_offline = 0; 09933 int peers_unmon_online = 0; 09934 const char *id; 09935 char idtext[256] = ""; 09936 int realtimepeers; 09937 09938 realtimepeers = ast_check_realtime("sippeers"); 09939 09940 if (s) { /* Manager - get ActionID */ 09941 id = astman_get_header(m,"ActionID"); 09942 if (!ast_strlen_zero(id)) 09943 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09944 } 09945 09946 switch (argc) { 09947 case 5: 09948 if (!strcasecmp(argv[3], "like")) { 09949 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09950 return RESULT_SHOWUSAGE; 09951 havepattern = TRUE; 09952 } else 09953 return RESULT_SHOWUSAGE; 09954 case 3: 09955 break; 09956 default: 09957 return RESULT_SHOWUSAGE; 09958 } 09959 09960 if (!s) /* Normal list */ 09961 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09962 09963 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09964 char status[20] = ""; 09965 char srch[2000]; 09966 char pstatus; 09967 09968 ASTOBJ_RDLOCK(iterator); 09969 09970 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09971 ASTOBJ_UNLOCK(iterator); 09972 continue; 09973 } 09974 09975 if (!ast_strlen_zero(iterator->username) && !s) 09976 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09977 else 09978 ast_copy_string(name, iterator->name, sizeof(name)); 09979 09980 pstatus = peer_status(iterator, status, sizeof(status)); 09981 if (pstatus == 1) 09982 peers_mon_online++; 09983 else if (pstatus == 0) 09984 peers_mon_offline++; 09985 else { 09986 if (iterator->addr.sin_port == 0) 09987 peers_unmon_offline++; 09988 else 09989 peers_unmon_online++; 09990 } 09991 09992 snprintf(srch, sizeof(srch), FORMAT, name, 09993 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09994 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09995 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09996 iterator->ha ? " A " : " ", /* permit/deny */ 09997 ntohs(iterator->addr.sin_port), status, 09998 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09999 10000 if (!s) {/* Normal CLI list */ 10001 ast_cli(fd, FORMAT, name, 10002 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10003 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10004 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10005 iterator->ha ? " A " : " ", /* permit/deny */ 10006 10007 ntohs(iterator->addr.sin_port), status, 10008 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10009 } else { /* Manager format */ 10010 /* The names here need to be the same as other channels */ 10011 astman_append(s, 10012 "Event: PeerEntry\r\n%s" 10013 "Channeltype: SIP\r\n" 10014 "ObjectName: %s\r\n" 10015 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10016 "IPaddress: %s\r\n" 10017 "IPport: %d\r\n" 10018 "Dynamic: %s\r\n" 10019 "Natsupport: %s\r\n" 10020 "VideoSupport: %s\r\n" 10021 "ACL: %s\r\n" 10022 "Status: %s\r\n" 10023 "RealtimeDevice: %s\r\n\r\n", 10024 idtext, 10025 iterator->name, 10026 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10027 ntohs(iterator->addr.sin_port), 10028 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10029 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10030 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10031 iterator->ha ? "yes" : "no", /* permit/deny */ 10032 status, 10033 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10034 } 10035 10036 ASTOBJ_UNLOCK(iterator); 10037 10038 total_peers++; 10039 } while(0) ); 10040 10041 if (!s) 10042 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10043 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10044 10045 if (havepattern) 10046 regfree(®exbuf); 10047 10048 if (total) 10049 *total = total_peers; 10050 10051 10052 return RESULT_SUCCESS; 10053 #undef FORMAT 10054 #undef FORMAT2 10055 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14686 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, LOG_ERROR, LOG_WARNING, parse(), ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, sip_pvt::rtp, ast_rtp_quality::rtt, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14687 { 14688 struct ast_rtp_quality qos; 14689 struct sip_pvt *p = chan->tech_pvt; 14690 char *all = "", *parse = ast_strdupa(preparse); 14691 AST_DECLARE_APP_ARGS(args, 14692 AST_APP_ARG(param); 14693 AST_APP_ARG(type); 14694 AST_APP_ARG(field); 14695 ); 14696 AST_STANDARD_APP_ARGS(args, parse); 14697 14698 /* Sanity check */ 14699 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14700 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14701 return 0; 14702 } 14703 14704 if (strcasecmp(args.param, "rtpqos")) 14705 return 0; 14706 14707 /* Default arguments of audio,all */ 14708 if (ast_strlen_zero(args.type)) 14709 args.type = "audio"; 14710 if (ast_strlen_zero(args.field)) 14711 args.field = "all"; 14712 14713 memset(buf, 0, buflen); 14714 memset(&qos, 0, sizeof(qos)); 14715 14716 if (strcasecmp(args.type, "AUDIO") == 0) { 14717 all = ast_rtp_get_quality(p->rtp, &qos); 14718 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14719 all = ast_rtp_get_quality(p->vrtp, &qos); 14720 } 14721 14722 if (strcasecmp(args.field, "local_ssrc") == 0) 14723 snprintf(buf, buflen, "%u", qos.local_ssrc); 14724 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14725 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14726 else if (strcasecmp(args.field, "local_jitter") == 0) 14727 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14728 else if (strcasecmp(args.field, "local_count") == 0) 14729 snprintf(buf, buflen, "%u", qos.local_count); 14730 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14731 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14732 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14733 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14734 else if (strcasecmp(args.field, "remote_jitter") == 0) 14735 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14736 else if (strcasecmp(args.field, "remote_count") == 0) 14737 snprintf(buf, buflen, "%u", qos.remote_count); 14738 else if (strcasecmp(args.field, "rtt") == 0) 14739 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14740 else if (strcasecmp(args.field, "all") == 0) 14741 ast_copy_string(buf, all, buflen); 14742 else { 14743 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14744 return -1; 14745 } 14746 return 0; 14747 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2230 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02231 { 02232 if (!req->lines) { 02233 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02234 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02235 req->len += strlen(req->data + req->len); 02236 } 02237 }
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 6160 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06163 { 06164 int rtp_code; 06165 struct ast_format_list fmt; 06166 06167 06168 if (debug) 06169 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06170 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06171 return; 06172 06173 if (p->rtp) { 06174 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06175 fmt = ast_codec_pref_getsize(pref, codec); 06176 } 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 */ 06177 return; 06178 ast_build_string(m_buf, m_size, " %d", rtp_code); 06179 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06180 ast_rtp_lookup_mime_subtype(1, codec, 06181 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06182 sample_rate); 06183 if (codec == AST_FORMAT_G729A) { 06184 /* Indicate that we don't support VAD (G.729 annex B) */ 06185 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06186 } else if (codec == AST_FORMAT_G723_1) { 06187 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06188 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06189 } else if (codec == AST_FORMAT_ILBC) { 06190 /* Add information about us using only 20/30 ms packetization */ 06191 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06192 } 06193 06194 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06195 *min_packet_size = fmt.cur_ms; 06196 06197 /* Our first codec packetization processed cannot be less than zero */ 06198 if ((*min_packet_size) == 0 && fmt.cur_ms) 06199 *min_packet_size = fmt.cur_ms; 06200 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6128 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06129 { 06130 char tmp[256]; 06131 06132 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06133 add_header(req, "Content-Type", "application/dtmf-relay"); 06134 add_header_contentLength(req, strlen(tmp)); 06135 add_line(req, tmp); 06136 return 0; 06137 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5523 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
05524 { 05525 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05526 05527 if (req->headers == SIP_MAX_HEADERS) { 05528 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05529 return -1; 05530 } 05531 05532 if (req->lines) { 05533 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05534 return -1; 05535 } 05536 05537 if (maxlen <= 0) { 05538 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05539 return -1; 05540 } 05541 05542 req->header[req->headers] = req->data + req->len; 05543 05544 if (compactheaders) 05545 var = find_alias(var, var); 05546 05547 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05548 req->len += strlen(req->header[req->headers]); 05549 req->headers++; 05550 05551 return 0; 05552 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5555 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().
05556 { 05557 char clen[10]; 05558 05559 snprintf(clen, sizeof(clen), "%d", len); 05560 return add_header(req, "Content-Length", clen); 05561 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5564 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.
05565 { 05566 if (req->lines == SIP_MAX_LINES) { 05567 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05568 return -1; 05569 } 05570 if (!req->lines) { 05571 /* Add extra empty return */ 05572 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05573 req->len += strlen(req->data + req->len); 05574 } 05575 if (req->len >= sizeof(req->data) - 4) { 05576 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05577 return -1; 05578 } 05579 req->line[req->lines] = req->data + req->len; 05580 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05581 req->len += strlen(req->line[req->lines]); 05582 req->lines++; 05583 return 0; 05584 }
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 6336 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().
06339 { 06340 int rtp_code; 06341 06342 if (debug) 06343 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06344 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06345 return; 06346 06347 ast_build_string(m_buf, m_size, " %d", rtp_code); 06348 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06349 ast_rtp_lookup_mime_subtype(0, format, 0), 06350 sample_rate); 06351 if (format == AST_RTP_DTMF) 06352 /* Indicate we support DTMF and FLASH... */ 06353 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06354 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static, read] |
Add realm authentication in list.
Definition at line 16260 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, sip_auth::secret, secret, strsep(), sip_auth::username, and username.
Referenced by build_peer(), and reload_config().
16261 { 16262 char authcopy[256]; 16263 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16264 char *stringp; 16265 struct sip_auth *a, *b, *auth; 16266 16267 if (ast_strlen_zero(configuration)) 16268 return authlist; 16269 16270 if (option_debug) 16271 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16272 16273 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16274 stringp = authcopy; 16275 16276 username = stringp; 16277 realm = strrchr(stringp, '@'); 16278 if (realm) 16279 *realm++ = '\0'; 16280 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16281 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16282 return authlist; 16283 } 16284 stringp = username; 16285 username = strsep(&stringp, ":"); 16286 if (username) { 16287 secret = strsep(&stringp, ":"); 16288 if (!secret) { 16289 stringp = username; 16290 md5secret = strsep(&stringp,"#"); 16291 } 16292 } 16293 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16294 return authlist; 16295 16296 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16297 ast_copy_string(auth->username, username, sizeof(auth->username)); 16298 if (secret) 16299 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16300 if (md5secret) 16301 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16302 16303 /* find the end of the list */ 16304 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16305 ; 16306 if (b) 16307 b->next = auth; /* Add structure add end of list */ 16308 else 16309 authlist = auth; 16310 16311 if (option_verbose > 2) 16312 ast_verbose("Added authentication for realm %s\n", realm); 16313 16314 return authlist; 16315 16316 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5685 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05686 { 05687 char r[BUFSIZ*2], *p; 05688 int n, rem = sizeof(r); 05689 05690 if (!route) 05691 return; 05692 05693 p = r; 05694 for (;route ; route = route->next) { 05695 n = strlen(route->hop); 05696 if (rem < n+3) /* we need room for ",<route>" */ 05697 break; 05698 if (p != r) { /* add a separator after fist route */ 05699 *p++ = ','; 05700 --rem; 05701 } 05702 *p++ = '<'; 05703 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05704 p += n; 05705 *p++ = '>'; 05706 rem -= (n+2); 05707 } 05708 *p = '\0'; 05709 add_header(req, "Route", r); 05710 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6359 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06360 { 06361 int len = 0; 06362 int alreadysent = 0; 06363 06364 struct sockaddr_in sin; 06365 struct sockaddr_in vsin; 06366 struct sockaddr_in dest; 06367 struct sockaddr_in vdest = { 0, }; 06368 06369 /* SDP fields */ 06370 char *version = "v=0\r\n"; /* Protocol version */ 06371 char *subject = "s=session\r\n"; /* Subject of the session */ 06372 char owner[256]; /* Session owner/creator */ 06373 char connection[256]; /* Connection data */ 06374 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06375 char bandwidth[256] = ""; /* Max bitrate */ 06376 char *hold; 06377 char m_audio[256]; /* Media declaration line for audio */ 06378 char m_video[256]; /* Media declaration line for video */ 06379 char a_audio[1024]; /* Attributes for audio */ 06380 char a_video[1024]; /* Attributes for video */ 06381 char *m_audio_next = m_audio; 06382 char *m_video_next = m_video; 06383 size_t m_audio_left = sizeof(m_audio); 06384 size_t m_video_left = sizeof(m_video); 06385 char *a_audio_next = a_audio; 06386 char *a_video_next = a_video; 06387 size_t a_audio_left = sizeof(a_audio); 06388 size_t a_video_left = sizeof(a_video); 06389 06390 int x; 06391 int capability; 06392 int needvideo = FALSE; 06393 int debug = sip_debug_test_pvt(p); 06394 int min_audio_packet_size = 0; 06395 int min_video_packet_size = 0; 06396 06397 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06398 06399 if (!p->rtp) { 06400 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06401 return AST_FAILURE; 06402 } 06403 06404 /* Set RTP Session ID and version */ 06405 if (!p->sessionid) { 06406 p->sessionid = getpid(); 06407 p->sessionversion = p->sessionid; 06408 } else 06409 p->sessionversion++; 06410 06411 /* Get our addresses */ 06412 ast_rtp_get_us(p->rtp, &sin); 06413 if (p->vrtp) 06414 ast_rtp_get_us(p->vrtp, &vsin); 06415 06416 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06417 if (p->redirip.sin_addr.s_addr) { 06418 dest.sin_port = p->redirip.sin_port; 06419 dest.sin_addr = p->redirip.sin_addr; 06420 } else { 06421 dest.sin_addr = p->ourip; 06422 dest.sin_port = sin.sin_port; 06423 } 06424 06425 capability = p->jointcapability; 06426 06427 06428 if (option_debug > 1) { 06429 char codecbuf[BUFSIZ]; 06430 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"); 06431 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06432 } 06433 06434 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06435 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06436 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06437 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06438 } 06439 #endif 06440 06441 /* Check if we need video in this call */ 06442 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06443 if (p->vrtp) { 06444 needvideo = TRUE; 06445 if (option_debug > 1) 06446 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06447 } else if (option_debug > 1) 06448 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06449 } 06450 06451 06452 /* Ok, we need video. Let's add what we need for video and set codecs. 06453 Video is handled differently than audio since we can not transcode. */ 06454 if (needvideo) { 06455 /* Determine video destination */ 06456 if (p->vredirip.sin_addr.s_addr) { 06457 vdest.sin_addr = p->vredirip.sin_addr; 06458 vdest.sin_port = p->vredirip.sin_port; 06459 } else { 06460 vdest.sin_addr = p->ourip; 06461 vdest.sin_port = vsin.sin_port; 06462 } 06463 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06464 06465 /* Build max bitrate string */ 06466 if (p->maxcallbitrate) 06467 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06468 if (debug) 06469 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06470 } 06471 06472 if (debug) 06473 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06474 06475 /* Start building generic SDP headers */ 06476 06477 /* We break with the "recommendation" and send our IP, in order that our 06478 peer doesn't have to ast_gethostbyname() us */ 06479 06480 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06481 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06482 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06483 06484 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06485 hold = "a=recvonly\r\n"; 06486 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06487 hold = "a=inactive\r\n"; 06488 else 06489 hold = "a=sendrecv\r\n"; 06490 06491 /* Now, start adding audio codecs. These are added in this order: 06492 - First what was requested by the calling channel 06493 - Then preferences in order from sip.conf device config for this peer/user 06494 - Then other codecs in capabilities, including video 06495 */ 06496 06497 /* Prefer the audio codec we were requested to use, first, no matter what 06498 Note that p->prefcodec can include video codecs, so mask them out 06499 */ 06500 if (capability & p->prefcodec) { 06501 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06502 06503 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06504 &m_audio_next, &m_audio_left, 06505 &a_audio_next, &a_audio_left, 06506 debug, &min_audio_packet_size); 06507 alreadysent |= codec; 06508 } 06509 06510 /* Start by sending our preferred audio codecs */ 06511 for (x = 0; x < 32; x++) { 06512 int codec; 06513 06514 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06515 break; 06516 06517 if (!(capability & codec)) 06518 continue; 06519 06520 if (alreadysent & codec) 06521 continue; 06522 06523 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06524 &m_audio_next, &m_audio_left, 06525 &a_audio_next, &a_audio_left, 06526 debug, &min_audio_packet_size); 06527 alreadysent |= codec; 06528 } 06529 06530 /* Now send any other common audio and video codecs, and non-codec formats: */ 06531 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06532 if (!(capability & x)) /* Codec not requested */ 06533 continue; 06534 06535 if (alreadysent & x) /* Already added to SDP */ 06536 continue; 06537 06538 if (x <= AST_FORMAT_MAX_AUDIO) 06539 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06540 &m_audio_next, &m_audio_left, 06541 &a_audio_next, &a_audio_left, 06542 debug, &min_audio_packet_size); 06543 else 06544 add_codec_to_sdp(p, x, 90000, 06545 &m_video_next, &m_video_left, 06546 &a_video_next, &a_video_left, 06547 debug, &min_video_packet_size); 06548 } 06549 06550 /* Now add DTMF RFC2833 telephony-event as a codec */ 06551 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06552 if (!(p->jointnoncodeccapability & x)) 06553 continue; 06554 06555 add_noncodec_to_sdp(p, x, 8000, 06556 &m_audio_next, &m_audio_left, 06557 &a_audio_next, &a_audio_left, 06558 debug); 06559 } 06560 06561 if (option_debug > 2) 06562 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06563 06564 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06565 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06566 06567 if (min_audio_packet_size) 06568 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06569 06570 if (min_video_packet_size) 06571 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06572 06573 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06574 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06575 06576 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06577 if (needvideo) 06578 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06579 06580 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06581 if (needvideo) /* only if video response is appropriate */ 06582 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06583 06584 add_header(resp, "Content-Type", "application/sdp"); 06585 add_header_contentLength(resp, len); 06586 add_line(resp, version); 06587 add_line(resp, owner); 06588 add_line(resp, subject); 06589 add_line(resp, connection); 06590 if (needvideo) /* only if video response is appropriate */ 06591 add_line(resp, bandwidth); 06592 add_line(resp, stime); 06593 add_line(resp, m_audio); 06594 add_line(resp, a_audio); 06595 add_line(resp, hold); 06596 if (needvideo) { /* only if video response is appropriate */ 06597 add_line(resp, m_video); 06598 add_line(resp, a_video); 06599 add_line(resp, hold); /* Repeat hold for the video stream */ 06600 } 06601 06602 /* Update lastrtprx when we send our SDP */ 06603 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06604 06605 if (option_debug > 2) { 06606 char buf[BUFSIZ]; 06607 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06608 } 06609 06610 return AST_SUCCESS; 06611 }
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 16196 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::context, domain::domain, LOG_DEBUG, LOG_WARNING, domain::mode, and sipdebug.
Referenced by reload_config().
16197 { 16198 struct domain *d; 16199 16200 if (ast_strlen_zero(domain)) { 16201 ast_log(LOG_WARNING, "Zero length domain.\n"); 16202 return 1; 16203 } 16204 16205 if (!(d = ast_calloc(1, sizeof(*d)))) 16206 return 0; 16207 16208 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16209 16210 if (!ast_strlen_zero(context)) 16211 ast_copy_string(d->context, context, sizeof(d->context)); 16212 16213 d->mode = mode; 16214 16215 AST_LIST_LOCK(&domain_list); 16216 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16217 AST_LIST_UNLOCK(&domain_list); 16218 16219 if (sipdebug) 16220 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16221 16222 return 1; 16223 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6239 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06240 { 06241 int len = 0; 06242 int x = 0; 06243 struct sockaddr_in udptlsin; 06244 char v[256] = ""; 06245 char s[256] = ""; 06246 char o[256] = ""; 06247 char c[256] = ""; 06248 char t[256] = ""; 06249 char m_modem[256]; 06250 char a_modem[1024]; 06251 char *m_modem_next = m_modem; 06252 size_t m_modem_left = sizeof(m_modem); 06253 char *a_modem_next = a_modem; 06254 size_t a_modem_left = sizeof(a_modem); 06255 struct sockaddr_in udptldest = { 0, }; 06256 int debug; 06257 06258 debug = sip_debug_test_pvt(p); 06259 len = 0; 06260 if (!p->udptl) { 06261 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06262 return -1; 06263 } 06264 06265 if (!p->sessionid) { 06266 p->sessionid = getpid(); 06267 p->sessionversion = p->sessionid; 06268 } else 06269 p->sessionversion++; 06270 06271 /* Our T.38 end is */ 06272 ast_udptl_get_us(p->udptl, &udptlsin); 06273 06274 /* Determine T.38 UDPTL destination */ 06275 if (p->udptlredirip.sin_addr.s_addr) { 06276 udptldest.sin_port = p->udptlredirip.sin_port; 06277 udptldest.sin_addr = p->udptlredirip.sin_addr; 06278 } else { 06279 udptldest.sin_addr = p->ourip; 06280 udptldest.sin_port = udptlsin.sin_port; 06281 } 06282 06283 if (debug) 06284 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06285 06286 /* We break with the "recommendation" and send our IP, in order that our 06287 peer doesn't have to ast_gethostbyname() us */ 06288 06289 if (debug) { 06290 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06291 p->t38.capability, 06292 p->t38.peercapability, 06293 p->t38.jointcapability); 06294 } 06295 snprintf(v, sizeof(v), "v=0\r\n"); 06296 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06297 snprintf(s, sizeof(s), "s=session\r\n"); 06298 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06299 snprintf(t, sizeof(t), "t=0 0\r\n"); 06300 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06301 06302 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06303 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06304 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06305 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06306 if ((x = t38_get_rate(p->t38.jointcapability))) 06307 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06308 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06309 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06310 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06311 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06312 x = ast_udptl_get_local_max_datagram(p->udptl); 06313 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06314 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06315 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06316 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06317 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06318 add_header(resp, "Content-Type", "application/sdp"); 06319 add_header_contentLength(resp, len); 06320 add_line(resp, v); 06321 add_line(resp, o); 06322 add_line(resp, s); 06323 add_line(resp, c); 06324 add_line(resp, t); 06325 add_line(resp, m_modem); 06326 add_line(resp, a_modem); 06327 06328 /* Update lastrtprx when we send our SDP */ 06329 p->lastrtprx = p->lastrtptx = time(NULL); 06330 06331 return 0; 06332 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6117 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06118 { 06119 /* XXX Convert \n's to \r\n's XXX */ 06120 add_header(req, "Content-Type", "text/plain"); 06121 add_header_contentLength(req, strlen(text)); 06122 add_line(req, text); 06123 return 0; 06124 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6141 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06142 { 06143 const char *xml_is_a_huge_waste_of_space = 06144 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06145 " <media_control>\r\n" 06146 " <vc_primitive>\r\n" 06147 " <to_encoder>\r\n" 06148 " <picture_fast_update>\r\n" 06149 " </picture_fast_update>\r\n" 06150 " </to_encoder>\r\n" 06151 " </vc_primitive>\r\n" 06152 " </media_control>\r\n"; 06153 add_header(req, "Content-Type", "application/media_control+xml"); 06154 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06155 add_line(req, xml_is_a_huge_waste_of_space); 06156 return 0; 06157 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6064 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().
06065 { 06066 char tmpdat[256]; 06067 struct tm tm; 06068 time_t t = time(NULL); 06069 06070 gmtime_r(&t, &tm); 06071 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06072 add_header(req, "Date", tmpdat); 06073 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1873 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01874 { 01875 va_list ap; 01876 01877 if (!p) 01878 return; 01879 01880 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01881 && !recordhistory && !dumphistory) { 01882 return; 01883 } 01884 01885 va_start(ap, fmt); 01886 append_history_va(p, fmt, ap); 01887 va_end(ap); 01888 01889 return; 01890 }
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 1846 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().
01847 { 01848 char buf[80], *c = buf; /* max history length */ 01849 struct sip_history *hist; 01850 int l; 01851 01852 vsnprintf(buf, sizeof(buf), fmt, ap); 01853 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01854 l = strlen(buf) + 1; 01855 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01856 return; 01857 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01858 free(hist); 01859 return; 01860 } 01861 memcpy(hist->event, buf, l); 01862 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01863 struct sip_history *oldest; 01864 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01865 p->history_entries--; 01866 free(oldest); 01867 } 01868 AST_LIST_INSERT_TAIL(p->history, hist, list); 01869 p->history_entries++; 01870 }
AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
sip_history | ||||
) |
history list, entry in sip_pvt
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Session Initiation Protocol (SIP)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 13235 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
13236 { 13237 if (chan && chan->_state == AST_STATE_UP) { 13238 if (chan->generatordata) 13239 ast_deactivate_generator(chan); 13240 } 13241 }
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 1806 of file chan_sip.c.
References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01807 { 01808 struct sockaddr_in theirs, ours; 01809 01810 /* Get our local information */ 01811 ast_ouraddrfor(them, us); 01812 theirs.sin_addr = *them; 01813 ours.sin_addr = *us; 01814 01815 if (localaddr && externip.sin_addr.s_addr && 01816 (ast_apply_ha(localaddr, &theirs)) && 01817 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01818 if (externexpire && time(NULL) >= externexpire) { 01819 struct ast_hostent ahp; 01820 struct hostent *hp; 01821 01822 externexpire = time(NULL) + externrefresh; 01823 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01824 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01825 } else 01826 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01827 } 01828 *us = externip.sin_addr; 01829 if (option_debug) { 01830 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01831 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01832 } 01833 } else if (bindaddr.sin_addr.s_addr) 01834 *us = bindaddr.sin_addr; 01835 return AST_SUCCESS; 01836 }
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 13245 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), ast_channel::cdr, sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
13246 { 13247 int res = 0; 13248 struct ast_channel *peera = NULL, 13249 *peerb = NULL, 13250 *peerc = NULL, 13251 *peerd = NULL; 13252 13253 13254 /* We will try to connect the transferee with the target and hangup 13255 all channels to the transferer */ 13256 if (option_debug > 3) { 13257 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13258 if (transferer->chan1) 13259 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13260 else 13261 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13262 if (target->chan1) 13263 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13264 else 13265 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13266 if (transferer->chan2) 13267 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13268 else 13269 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13270 if (target->chan2) 13271 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)"); 13272 else 13273 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13274 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13275 } 13276 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13277 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13278 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13279 peerc = transferer->chan2; /* Asterisk to Transferee */ 13280 peerd = target->chan2; /* Asterisk to Target */ 13281 if (option_debug > 2) 13282 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13283 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13284 peera = target->chan1; /* Transferer to PBX -> target channel */ 13285 peerb = transferer->chan1; /* Transferer to IVR*/ 13286 peerc = target->chan2; /* Asterisk to Target */ 13287 peerd = transferer->chan2; /* Nothing */ 13288 if (option_debug > 2) 13289 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13290 } 13291 13292 if (peera && peerb && peerc && (peerb != peerc)) { 13293 ast_quiet_chan(peera); /* Stop generators */ 13294 ast_quiet_chan(peerb); 13295 ast_quiet_chan(peerc); 13296 if (peerd) 13297 ast_quiet_chan(peerd); 13298 13299 /* Fix CDRs so they're attached to the remaining channel */ 13300 if (peera->cdr && peerb->cdr) 13301 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13302 else if (peera->cdr) 13303 peerb->cdr = peera->cdr; 13304 peera->cdr = NULL; 13305 13306 if (peerb->cdr && peerc->cdr) 13307 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13308 else if (peerc->cdr) 13309 peerb->cdr = peerc->cdr; 13310 peerc->cdr = NULL; 13311 13312 if (option_debug > 3) 13313 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13314 if (ast_channel_masquerade(peerb, peerc)) { 13315 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13316 res = -1; 13317 } else 13318 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13319 return res; 13320 } else { 13321 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13322 if (transferer->chan1) 13323 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13324 if (target->chan1) 13325 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13326 return -2; 13327 } 13328 return 0; 13329 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2912 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.
02913 { 02914 struct sip_pvt *p = (struct sip_pvt *)nothing; 02915 02916 ast_mutex_lock(&p->lock); 02917 p->initid = -1; 02918 if (p->owner) { 02919 /* XXX fails on possible deadlock */ 02920 if (!ast_channel_trylock(p->owner)) { 02921 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02922 append_history(p, "Cong", "Auto-congesting (timer)"); 02923 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02924 ast_channel_unlock(p->owner); 02925 } 02926 } 02927 ast_mutex_unlock(&p->lock); 02928 return 0; 02929 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4364 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().
04365 { 04366 char buf[33]; 04367 04368 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04369 04370 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04371 04372 }
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 4375 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04376 { 04377 char buf[33]; 04378 04379 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04380 04381 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04382 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6782 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::ourip, ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06783 { 06784 /* Construct Contact: header */ 06785 if (ourport != STANDARD_SIP_PORT) 06786 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); 06787 else 06788 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06789 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 16526 of file chan_sip.c.
References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_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.
16527 { 16528 struct sip_peer *peer = NULL; 16529 struct ast_ha *oldha = NULL; 16530 int obproxyfound=0; 16531 int found=0; 16532 int firstpass=1; 16533 int format=0; /* Ama flags */ 16534 time_t regseconds = 0; 16535 char *varname = NULL, *varval = NULL; 16536 struct ast_variable *tmpvar = NULL; 16537 struct ast_flags peerflags[2] = {{(0)}}; 16538 struct ast_flags mask[2] = {{(0)}}; 16539 16540 16541 if (!realtime) 16542 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16543 /* We also use a case-sensitive comparison (unlike find_peer) so 16544 that case changes made to the peer name will be properly handled 16545 during reload 16546 */ 16547 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16548 16549 if (peer) { 16550 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16551 found = 1; 16552 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16553 firstpass = 0; 16554 } else { 16555 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16556 return NULL; 16557 16558 if (realtime) 16559 rpeerobjs++; 16560 else 16561 speerobjs++; 16562 ASTOBJ_INIT(peer); 16563 } 16564 /* Note that our peer HAS had its reference count incrased */ 16565 if (firstpass) { 16566 peer->lastmsgssent = -1; 16567 oldha = peer->ha; 16568 peer->ha = NULL; 16569 set_peer_defaults(peer); /* Set peer defaults */ 16570 } 16571 if (!found && name) 16572 ast_copy_string(peer->name, name, sizeof(peer->name)); 16573 16574 /* If we have channel variables, remove them (reload) */ 16575 if (peer->chanvars) { 16576 ast_variables_destroy(peer->chanvars); 16577 peer->chanvars = NULL; 16578 /* XXX should unregister ? */ 16579 } 16580 16581 /* If we have realm authentication information, remove them (reload) */ 16582 clear_realm_authentication(peer->auth); 16583 peer->auth = NULL; 16584 16585 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16586 if (handle_common_options(&peerflags[0], &mask[0], v)) 16587 continue; 16588 if (realtime && !strcasecmp(v->name, "regseconds")) { 16589 ast_get_time_t(v->value, ®seconds, 0, NULL); 16590 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16591 inet_aton(v->value, &(peer->addr.sin_addr)); 16592 } else if (realtime && !strcasecmp(v->name, "name")) 16593 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16594 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16595 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16596 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16597 } else if (!strcasecmp(v->name, "secret")) 16598 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16599 else if (!strcasecmp(v->name, "md5secret")) 16600 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16601 else if (!strcasecmp(v->name, "auth")) 16602 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16603 else if (!strcasecmp(v->name, "callerid")) { 16604 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16605 } else if (!strcasecmp(v->name, "fullname")) { 16606 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16607 } else if (!strcasecmp(v->name, "cid_number")) { 16608 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16609 } else if (!strcasecmp(v->name, "context")) { 16610 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16611 } else if (!strcasecmp(v->name, "subscribecontext")) { 16612 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16613 } else if (!strcasecmp(v->name, "fromdomain")) { 16614 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16615 } else if (!strcasecmp(v->name, "usereqphone")) { 16616 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16617 } else if (!strcasecmp(v->name, "fromuser")) { 16618 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16619 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16620 if (!strcasecmp(v->value, "dynamic")) { 16621 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16622 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16623 } else { 16624 /* They'll register with us */ 16625 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16626 /* Initialize stuff if this is a new peer, or if it used to be 16627 * non-dynamic before the reload. */ 16628 memset(&peer->addr.sin_addr, 0, 4); 16629 if (peer->addr.sin_port) { 16630 /* If we've already got a port, make it the default rather than absolute */ 16631 peer->defaddr.sin_port = peer->addr.sin_port; 16632 peer->addr.sin_port = 0; 16633 } 16634 } 16635 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16636 } 16637 } else { 16638 /* Non-dynamic. Make sure we become that way if we're not */ 16639 if (peer->expire > -1) 16640 ast_sched_del(sched, peer->expire); 16641 peer->expire = -1; 16642 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16643 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16644 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16645 ASTOBJ_UNREF(peer, sip_destroy_peer); 16646 return NULL; 16647 } 16648 } 16649 if (!strcasecmp(v->name, "outboundproxy")) 16650 obproxyfound=1; 16651 else { 16652 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16653 if (!peer->addr.sin_port) 16654 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16655 } 16656 } 16657 } else if (!strcasecmp(v->name, "defaultip")) { 16658 if (ast_get_ip(&peer->defaddr, v->value)) { 16659 ASTOBJ_UNREF(peer, sip_destroy_peer); 16660 return NULL; 16661 } 16662 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16663 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16664 } else if (!strcasecmp(v->name, "port")) { 16665 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16666 peer->defaddr.sin_port = htons(atoi(v->value)); 16667 else 16668 peer->addr.sin_port = htons(atoi(v->value)); 16669 } else if (!strcasecmp(v->name, "callingpres")) { 16670 peer->callingpres = ast_parse_caller_presentation(v->value); 16671 if (peer->callingpres == -1) 16672 peer->callingpres = atoi(v->value); 16673 } else if (!strcasecmp(v->name, "username")) { 16674 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16675 } else if (!strcasecmp(v->name, "language")) { 16676 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16677 } else if (!strcasecmp(v->name, "regexten")) { 16678 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16679 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16680 peer->call_limit = atoi(v->value); 16681 if (peer->call_limit < 0) 16682 peer->call_limit = 0; 16683 } else if (!strcasecmp(v->name, "amaflags")) { 16684 format = ast_cdr_amaflags2int(v->value); 16685 if (format < 0) { 16686 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16687 } else { 16688 peer->amaflags = format; 16689 } 16690 } else if (!strcasecmp(v->name, "accountcode")) { 16691 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16692 } else if (!strcasecmp(v->name, "mohinterpret") 16693 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16694 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16695 } else if (!strcasecmp(v->name, "mohsuggest")) { 16696 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16697 } else if (!strcasecmp(v->name, "mailbox")) { 16698 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16699 } else if (!strcasecmp(v->name, "subscribemwi")) { 16700 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16701 } else if (!strcasecmp(v->name, "vmexten")) { 16702 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16703 } else if (!strcasecmp(v->name, "callgroup")) { 16704 peer->callgroup = ast_get_group(v->value); 16705 } else if (!strcasecmp(v->name, "allowtransfer")) { 16706 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16707 } else if (!strcasecmp(v->name, "pickupgroup")) { 16708 peer->pickupgroup = ast_get_group(v->value); 16709 } else if (!strcasecmp(v->name, "allow")) { 16710 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16711 } else if (!strcasecmp(v->name, "disallow")) { 16712 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16713 } else if (!strcasecmp(v->name, "autoframing")) { 16714 peer->autoframing = ast_true(v->value); 16715 } else if (!strcasecmp(v->name, "rtptimeout")) { 16716 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16717 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16718 peer->rtptimeout = global_rtptimeout; 16719 } 16720 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16721 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16722 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16723 peer->rtpholdtimeout = global_rtpholdtimeout; 16724 } 16725 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16726 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16727 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16728 peer->rtpkeepalive = global_rtpkeepalive; 16729 } 16730 } else if (!strcasecmp(v->name, "setvar")) { 16731 /* Set peer channel variable */ 16732 varname = ast_strdupa(v->value); 16733 if ((varval = strchr(varname, '='))) { 16734 *varval++ = '\0'; 16735 if ((tmpvar = ast_variable_new(varname, varval))) { 16736 tmpvar->next = peer->chanvars; 16737 peer->chanvars = tmpvar; 16738 } 16739 } 16740 } else if (!strcasecmp(v->name, "qualify")) { 16741 if (!strcasecmp(v->value, "no")) { 16742 peer->maxms = 0; 16743 } else if (!strcasecmp(v->value, "yes")) { 16744 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16745 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16746 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); 16747 peer->maxms = 0; 16748 } 16749 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16750 peer->maxcallbitrate = atoi(v->value); 16751 if (peer->maxcallbitrate < 0) 16752 peer->maxcallbitrate = default_maxcallbitrate; 16753 } 16754 } 16755 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16756 time_t nowtime = time(NULL); 16757 16758 if ((nowtime - regseconds) > 0) { 16759 destroy_association(peer); 16760 memset(&peer->addr, 0, sizeof(peer->addr)); 16761 if (option_debug) 16762 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16763 } 16764 } 16765 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16766 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16767 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16768 global_allowsubscribe = TRUE; /* No global ban any more */ 16769 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16770 reg_source_db(peer); 16771 ASTOBJ_UNMARK(peer); 16772 ast_free_ha(oldha); 16773 return peer; 16774 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11558 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11559 { 11560 char a1[256]; 11561 char a2[256]; 11562 char a1_hash[256]; 11563 char a2_hash[256]; 11564 char resp[256]; 11565 char resp_hash[256]; 11566 char uri[256]; 11567 char cnonce[80]; 11568 const char *username; 11569 const char *secret; 11570 const char *md5secret; 11571 struct sip_auth *auth = NULL; /* Realm authentication */ 11572 11573 if (!ast_strlen_zero(p->domain)) 11574 ast_copy_string(uri, p->domain, sizeof(uri)); 11575 else if (!ast_strlen_zero(p->uri)) 11576 ast_copy_string(uri, p->uri, sizeof(uri)); 11577 else 11578 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11579 11580 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11581 11582 /* Check if we have separate auth credentials */ 11583 if ((auth = find_realm_authentication(authl, p->realm))) { 11584 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11585 auth->username, p->peername, p->username); 11586 username = auth->username; 11587 secret = auth->secret; 11588 md5secret = auth->md5secret; 11589 if (sipdebug) 11590 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11591 } else { 11592 /* No authentication, use peer or register= config */ 11593 username = p->authname; 11594 secret = p->peersecret; 11595 md5secret = p->peermd5secret; 11596 } 11597 if (ast_strlen_zero(username)) /* We have no authentication */ 11598 return -1; 11599 11600 /* Calculate SIP digest response */ 11601 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11602 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11603 if (!ast_strlen_zero(md5secret)) 11604 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11605 else 11606 ast_md5_hash(a1_hash,a1); 11607 ast_md5_hash(a2_hash,a2); 11608 11609 p->noncecount++; 11610 if (!ast_strlen_zero(p->qop)) 11611 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11612 else 11613 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11614 ast_md5_hash(resp_hash, resp); 11615 /* XXX We hard code our qop to "auth" for now. XXX */ 11616 if (!ast_strlen_zero(p->qop)) 11617 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); 11618 else 11619 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); 11620 11621 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11622 11623 return 0; 11624 }
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 8179 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().
08180 { 08181 struct sip_route *thishop, *head, *tail; 08182 int start = 0; 08183 int len; 08184 const char *rr, *contact, *c; 08185 08186 /* Once a persistant route is set, don't fool with it */ 08187 if (p->route && p->route_persistant) { 08188 if (option_debug) 08189 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08190 return; 08191 } 08192 08193 if (p->route) { 08194 free_old_route(p->route); 08195 p->route = NULL; 08196 } 08197 08198 p->route_persistant = backwards; 08199 08200 /* Build a tailq, then assign it to p->route when done. 08201 * If backwards, we add entries from the head so they end up 08202 * in reverse order. However, we do need to maintain a correct 08203 * tail pointer because the contact is always at the end. 08204 */ 08205 head = NULL; 08206 tail = head; 08207 /* 1st we pass through all the hops in any Record-Route headers */ 08208 for (;;) { 08209 /* Each Record-Route header */ 08210 rr = __get_header(req, "Record-Route", &start); 08211 if (*rr == '\0') 08212 break; 08213 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08214 ++rr; 08215 len = strcspn(rr, ">") + 1; 08216 /* Make a struct route */ 08217 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08218 /* ast_calloc is not needed because all fields are initialized in this block */ 08219 ast_copy_string(thishop->hop, rr, len); 08220 if (option_debug > 1) 08221 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08222 /* Link in */ 08223 if (backwards) { 08224 /* Link in at head so they end up in reverse order */ 08225 thishop->next = head; 08226 head = thishop; 08227 /* If this was the first then it'll be the tail */ 08228 if (!tail) 08229 tail = thishop; 08230 } else { 08231 thishop->next = NULL; 08232 /* Link in at the end */ 08233 if (tail) 08234 tail->next = thishop; 08235 else 08236 head = thishop; 08237 tail = thishop; 08238 } 08239 } 08240 } 08241 } 08242 08243 /* Only append the contact if we are dealing with a strict router */ 08244 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08245 /* 2nd append the Contact: if there is one */ 08246 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08247 contact = get_header(req, "Contact"); 08248 if (!ast_strlen_zero(contact)) { 08249 if (option_debug > 1) 08250 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08251 /* Look for <: delimited address */ 08252 c = strchr(contact, '<'); 08253 if (c) { 08254 /* Take to > */ 08255 ++c; 08256 len = strcspn(c, ">") + 1; 08257 } else { 08258 /* No <> - just take the lot */ 08259 c = contact; 08260 len = strlen(contact) + 1; 08261 } 08262 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08263 /* ast_calloc is not needed because all fields are initialized in this block */ 08264 ast_copy_string(thishop->hop, c, len); 08265 thishop->next = NULL; 08266 /* Goes at the end */ 08267 if (tail) 08268 tail->next = thishop; 08269 else 08270 head = thishop; 08271 } 08272 } 08273 } 08274 08275 /* Store as new route */ 08276 p->route = head; 08277 08278 /* For debugging dump what we ended up with */ 08279 if (sip_debug_test_pvt(p)) 08280 list_route(p->route); 08281 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6792 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06793 { 06794 int send_pres_tags = TRUE; 06795 const char *privacy=NULL; 06796 const char *screen=NULL; 06797 char buf[256]; 06798 const char *clid = default_callerid; 06799 const char *clin = NULL; 06800 const char *fromdomain; 06801 06802 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06803 return; 06804 06805 if (p->owner && p->owner->cid.cid_num) 06806 clid = p->owner->cid.cid_num; 06807 if (p->owner && p->owner->cid.cid_name) 06808 clin = p->owner->cid.cid_name; 06809 if (ast_strlen_zero(clin)) 06810 clin = clid; 06811 06812 switch (p->callingpres) { 06813 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06814 privacy = "off"; 06815 screen = "no"; 06816 break; 06817 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06818 privacy = "off"; 06819 screen = "yes"; 06820 break; 06821 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06822 privacy = "off"; 06823 screen = "no"; 06824 break; 06825 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06826 privacy = "off"; 06827 screen = "yes"; 06828 break; 06829 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06830 privacy = "full"; 06831 screen = "no"; 06832 break; 06833 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06834 privacy = "full"; 06835 screen = "yes"; 06836 break; 06837 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06838 privacy = "full"; 06839 screen = "no"; 06840 break; 06841 case AST_PRES_PROHIB_NETWORK_NUMBER: 06842 privacy = "full"; 06843 screen = "yes"; 06844 break; 06845 case AST_PRES_NUMBER_NOT_AVAILABLE: 06846 send_pres_tags = FALSE; 06847 break; 06848 default: 06849 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06850 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06851 privacy = "full"; 06852 else 06853 privacy = "off"; 06854 screen = "no"; 06855 break; 06856 } 06857 06858 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06859 06860 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06861 if (send_pres_tags) 06862 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06863 ast_string_field_set(p, rpid, buf); 06864 06865 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06866 S_OR(p->fromuser, clid), 06867 fromdomain, p->tag); 06868 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static, read] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 16347 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
16348 { 16349 struct sip_user *user; 16350 int format; 16351 struct ast_ha *oldha = NULL; 16352 char *varname = NULL, *varval = NULL; 16353 struct ast_variable *tmpvar = NULL; 16354 struct ast_flags userflags[2] = {{(0)}}; 16355 struct ast_flags mask[2] = {{(0)}}; 16356 16357 16358 if (!(user = ast_calloc(1, sizeof(*user)))) 16359 return NULL; 16360 16361 suserobjs++; 16362 ASTOBJ_INIT(user); 16363 ast_copy_string(user->name, name, sizeof(user->name)); 16364 oldha = user->ha; 16365 user->ha = NULL; 16366 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16367 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16368 user->capability = global_capability; 16369 user->allowtransfer = global_allowtransfer; 16370 user->maxcallbitrate = default_maxcallbitrate; 16371 user->autoframing = global_autoframing; 16372 user->prefs = default_prefs; 16373 /* set default context */ 16374 strcpy(user->context, default_context); 16375 strcpy(user->language, default_language); 16376 strcpy(user->mohinterpret, default_mohinterpret); 16377 strcpy(user->mohsuggest, default_mohsuggest); 16378 for (; v; v = v->next) { 16379 if (handle_common_options(&userflags[0], &mask[0], v)) 16380 continue; 16381 16382 if (!strcasecmp(v->name, "context")) { 16383 ast_copy_string(user->context, v->value, sizeof(user->context)); 16384 } else if (!strcasecmp(v->name, "subscribecontext")) { 16385 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16386 } else if (!strcasecmp(v->name, "setvar")) { 16387 varname = ast_strdupa(v->value); 16388 if ((varval = strchr(varname,'='))) { 16389 *varval++ = '\0'; 16390 if ((tmpvar = ast_variable_new(varname, varval))) { 16391 tmpvar->next = user->chanvars; 16392 user->chanvars = tmpvar; 16393 } 16394 } 16395 } else if (!strcasecmp(v->name, "permit") || 16396 !strcasecmp(v->name, "deny")) { 16397 user->ha = ast_append_ha(v->name, v->value, user->ha); 16398 } else if (!strcasecmp(v->name, "allowtransfer")) { 16399 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16400 } else if (!strcasecmp(v->name, "secret")) { 16401 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16402 } else if (!strcasecmp(v->name, "md5secret")) { 16403 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16404 } else if (!strcasecmp(v->name, "callerid")) { 16405 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16406 } else if (!strcasecmp(v->name, "fullname")) { 16407 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16408 } else if (!strcasecmp(v->name, "cid_number")) { 16409 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16410 } else if (!strcasecmp(v->name, "callgroup")) { 16411 user->callgroup = ast_get_group(v->value); 16412 } else if (!strcasecmp(v->name, "pickupgroup")) { 16413 user->pickupgroup = ast_get_group(v->value); 16414 } else if (!strcasecmp(v->name, "language")) { 16415 ast_copy_string(user->language, v->value, sizeof(user->language)); 16416 } else if (!strcasecmp(v->name, "mohinterpret") 16417 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16418 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16419 } else if (!strcasecmp(v->name, "mohsuggest")) { 16420 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16421 } else if (!strcasecmp(v->name, "accountcode")) { 16422 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16423 } else if (!strcasecmp(v->name, "call-limit")) { 16424 user->call_limit = atoi(v->value); 16425 if (user->call_limit < 0) 16426 user->call_limit = 0; 16427 } else if (!strcasecmp(v->name, "amaflags")) { 16428 format = ast_cdr_amaflags2int(v->value); 16429 if (format < 0) { 16430 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16431 } else { 16432 user->amaflags = format; 16433 } 16434 } else if (!strcasecmp(v->name, "allow")) { 16435 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16436 } else if (!strcasecmp(v->name, "disallow")) { 16437 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16438 } else if (!strcasecmp(v->name, "autoframing")) { 16439 user->autoframing = ast_true(v->value); 16440 } else if (!strcasecmp(v->name, "callingpres")) { 16441 user->callingpres = ast_parse_caller_presentation(v->value); 16442 if (user->callingpres == -1) 16443 user->callingpres = atoi(v->value); 16444 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16445 user->maxcallbitrate = atoi(v->value); 16446 if (user->maxcallbitrate < 0) 16447 user->maxcallbitrate = default_maxcallbitrate; 16448 } 16449 /* We can't just report unknown options here because this may be a 16450 * type=friend entry. All user options are valid for a peer, but not 16451 * the other way around. */ 16452 } 16453 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16454 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16455 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16456 global_allowsubscribe = TRUE; /* No global ban any more */ 16457 ast_free_ha(oldha); 16458 return user; 16459 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1790 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().
01791 { 01792 /* Work around buggy UNIDEN UIP200 firmware */ 01793 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01794 01795 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01796 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01797 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01798 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data, | |||
char * | cid_num, | |||
char * | cid_name | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8476 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe().
08477 { 08478 struct sip_pvt *p = data; 08479 08480 ast_mutex_lock(&p->lock); 08481 08482 switch(state) { 08483 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08484 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08485 if (p->autokillid > -1) 08486 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08487 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08488 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); 08489 p->stateid = -1; 08490 p->subscribed = NONE; 08491 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08492 break; 08493 default: /* Tell user */ 08494 p->laststate = state; 08495 break; 08496 } 08497 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08498 transmit_state_notify(p, state, 1, FALSE); 08499 08500 if (option_verbose > 1) 08501 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08502 08503 ast_mutex_unlock(&p->lock); 08504 08505 return 0; 08506 }
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 4913 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), sip_pvt::owner, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
04914 { 04915 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04916 sip_peer_hold(dialog, holdstate); 04917 if (global_callevents) 04918 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04919 "Channel: %s\r\n" 04920 "Uniqueid: %s\r\n", 04921 dialog->owner->name, 04922 dialog->owner->uniqueid); 04923 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04924 if (!holdstate) { /* Put off remote hold */ 04925 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04926 return; 04927 } 04928 /* No address for RTP, we're on hold */ 04929 04930 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 04931 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 04932 else if (sendonly == 2) /* Inactive stream */ 04933 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 04934 else 04935 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 04936 return; 04937 }
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
Definition at line 8291 of file chan_sip.c.
References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), 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, LOG_WARNING, s, S_OR, sip_methods, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08294 { 08295 const char *response = "407 Proxy Authentication Required"; 08296 const char *reqheader = "Proxy-Authorization"; 08297 const char *respheader = "Proxy-Authenticate"; 08298 const char *authtoken; 08299 char a1_hash[256]; 08300 char resp_hash[256]=""; 08301 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08302 char *c; 08303 int wrongnonce = FALSE; 08304 int good_response; 08305 const char *usednonce = p->randdata; 08306 struct ast_dynamic_str *buf; 08307 08308 /* table of recognised keywords, and their value in the digest */ 08309 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08310 struct x { 08311 const char *key; 08312 const char *s; 08313 } *i, keys[] = { 08314 [K_RESP] = { "response=", "" }, 08315 [K_URI] = { "uri=", "" }, 08316 [K_USER] = { "username=", "" }, 08317 [K_NONCE] = { "nonce=", "" }, 08318 [K_LAST] = { NULL, NULL} 08319 }; 08320 08321 /* Always OK if no secret */ 08322 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08323 return AUTH_SUCCESSFUL; 08324 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08325 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08326 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08327 different circumstances! What a surprise. */ 08328 response = "401 Unauthorized"; 08329 reqheader = "Authorization"; 08330 respheader = "WWW-Authenticate"; 08331 } 08332 authtoken = get_header(req, reqheader); 08333 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08334 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08335 information */ 08336 if (!reliable) { 08337 /* Resend message if this was NOT a reliable delivery. Otherwise the 08338 retransmission should get it */ 08339 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08340 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08341 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08342 } 08343 return AUTH_CHALLENGE_SENT; 08344 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08345 /* We have no auth, so issue challenge and request authentication */ 08346 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08347 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08348 /* Schedule auto destroy in 32 seconds */ 08349 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08350 return AUTH_CHALLENGE_SENT; 08351 } 08352 08353 /* --- We have auth, so check it */ 08354 08355 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08356 an example in the spec of just what it is you're doing a hash on. */ 08357 08358 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08359 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08360 08361 /* Make a copy of the response and parse it */ 08362 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08363 c = tmp; 08364 08365 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08366 for (i = keys; i->key != NULL; i++) { 08367 const char *separator = ","; /* default */ 08368 08369 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08370 continue; 08371 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08372 c += strlen(i->key); 08373 if (*c == '"') { /* in quotes. Skip first and look for last */ 08374 c++; 08375 separator = "\""; 08376 } 08377 i->s = c; 08378 strsep(&c, separator); 08379 break; 08380 } 08381 if (i->key == NULL) /* not found, jump after space or comma */ 08382 strsep(&c, " ,"); 08383 } 08384 08385 /* Verify that digest username matches the username we auth as */ 08386 if (strcmp(username, keys[K_USER].s)) { 08387 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08388 username, keys[K_USER].s); 08389 /* Oops, we're trying something here */ 08390 return AUTH_USERNAME_MISMATCH; 08391 } 08392 08393 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08394 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08395 wrongnonce = TRUE; 08396 usednonce = keys[K_NONCE].s; 08397 } 08398 08399 if (!ast_strlen_zero(md5secret)) 08400 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08401 else { 08402 char a1[256]; 08403 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08404 ast_md5_hash(a1_hash, a1); 08405 } 08406 08407 /* compute the expected response to compare with what we received */ 08408 { 08409 char a2[256]; 08410 char a2_hash[256]; 08411 char resp[256]; 08412 08413 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08414 S_OR(keys[K_URI].s, uri)); 08415 ast_md5_hash(a2_hash, a2); 08416 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08417 ast_md5_hash(resp_hash, resp); 08418 } 08419 08420 good_response = keys[K_RESP].s && 08421 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08422 if (wrongnonce) { 08423 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08424 if (good_response) { 08425 if (sipdebug) 08426 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08427 /* We got working auth token, based on stale nonce . */ 08428 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08429 } else { 08430 /* Everything was wrong, so give the device one more try with a new challenge */ 08431 if (sipdebug) 08432 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08433 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08434 } 08435 08436 /* Schedule auto destroy in 32 seconds */ 08437 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08438 return AUTH_CHALLENGE_SENT; 08439 } 08440 if (good_response) { 08441 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08442 return AUTH_SUCCESSFUL; 08443 } 08444 08445 /* Ok, we have a bad username/secret pair */ 08446 /* Tell the UAS not to re-send this authentication data, because 08447 it will continue to fail 08448 */ 08449 08450 return AUTH_SECRET_FAILED; 08451 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12019 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, sip_pvt::ocseq, 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().
12020 { 12021 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12022 /* if we can't BYE, then this is really a pending CANCEL */ 12023 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12024 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 12025 /* Actually don't destroy us yet, wait for the 487 on our original 12026 INVITE, but do set an autodestruct just in case we never get it. */ 12027 else { 12028 /* We have a pending outbound invite, don't send someting 12029 new in-transaction */ 12030 if (p->pendinginvite) 12031 return; 12032 12033 /* Perhaps there is an SD change INVITE outstanding */ 12034 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12035 } 12036 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12037 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12038 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12039 /* if we can't REINVITE, hold it for later */ 12040 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12041 if (option_debug) 12042 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12043 } else { 12044 if (option_debug) 12045 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12046 /* Didn't get to reinvite yet, so do it now */ 12047 transmit_reinvite_with_sdp(p); 12048 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12049 } 12050 } 12051 }
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 16226 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
16227 { 16228 struct domain *d; 16229 int result = 0; 16230 16231 AST_LIST_LOCK(&domain_list); 16232 AST_LIST_TRAVERSE(&domain_list, d, list) { 16233 if (strcasecmp(d->domain, domain)) 16234 continue; 16235 16236 if (len && !ast_strlen_zero(d->context)) 16237 ast_copy_string(context, d->context, len); 16238 16239 result = 1; 16240 break; 16241 } 16242 AST_LIST_UNLOCK(&domain_list); 16243 16244 return result; 16245 }
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 9666 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09667 { 09668 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09669 }
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 9347 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_pvt::allowtransfer, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, sip_pvt::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, domain::context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_pvt::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_pvt::t38, sip_pvt::timer_t1, sip_peer::username, username, and sip_pvt::vrtp.
Referenced by check_user(), and handle_request_subscribe().
09350 { 09351 struct sip_user *user = NULL; 09352 struct sip_peer *peer; 09353 char from[256], *c; 09354 char *of; 09355 char rpid_num[50]; 09356 const char *rpid; 09357 enum check_auth_result res = AUTH_SUCCESSFUL; 09358 char *t; 09359 char calleridname[50]; 09360 int debug=sip_debug_test_addr(sin); 09361 struct ast_variable *tmpvar = NULL, *v = NULL; 09362 char *uri2 = ast_strdupa(uri); 09363 09364 /* Terminate URI */ 09365 t = uri2; 09366 while (*t && *t > 32 && *t != ';') 09367 t++; 09368 *t = '\0'; 09369 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09370 if (pedanticsipchecking) 09371 ast_uri_decode(from); 09372 /* XXX here tries to map the username for invite things */ 09373 memset(calleridname, 0, sizeof(calleridname)); 09374 get_calleridname(from, calleridname, sizeof(calleridname)); 09375 if (calleridname[0]) 09376 ast_string_field_set(p, cid_name, calleridname); 09377 09378 rpid = get_header(req, "Remote-Party-ID"); 09379 memset(rpid_num, 0, sizeof(rpid_num)); 09380 if (!ast_strlen_zero(rpid)) 09381 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09382 09383 of = get_in_brackets(from); 09384 if (ast_strlen_zero(p->exten)) { 09385 t = uri2; 09386 if (!strncasecmp(t, "sip:", 4)) 09387 t+= 4; 09388 ast_string_field_set(p, exten, t); 09389 t = strchr(p->exten, '@'); 09390 if (t) 09391 *t = '\0'; 09392 if (ast_strlen_zero(p->our_contact)) 09393 build_contact(p); 09394 } 09395 /* save the URI part of the From header */ 09396 ast_string_field_set(p, from, of); 09397 if (strncasecmp(of, "sip:", 4)) { 09398 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09399 } else 09400 of += 4; 09401 /* Get just the username part */ 09402 if ((c = strchr(of, '@'))) { 09403 char *tmp; 09404 *c = '\0'; 09405 if ((c = strchr(of, ':'))) 09406 *c = '\0'; 09407 tmp = ast_strdupa(of); 09408 /* We need to be able to handle auth-headers looking like 09409 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09410 */ 09411 tmp = strsep(&tmp, ";"); 09412 if (ast_is_shrinkable_phonenumber(tmp)) 09413 ast_shrink_phone_number(tmp); 09414 ast_string_field_set(p, cid_num, tmp); 09415 } 09416 09417 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09418 user = find_user(of, 1); 09419 09420 /* Find user based on user name in the from header */ 09421 if (user && ast_apply_ha(user->ha, sin)) { 09422 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09423 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09424 /* copy channel vars */ 09425 for (v = user->chanvars ; v ; v = v->next) { 09426 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09427 tmpvar->next = p->chanvars; 09428 p->chanvars = tmpvar; 09429 } 09430 } 09431 p->prefs = user->prefs; 09432 /* Set Frame packetization */ 09433 if (p->rtp) { 09434 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09435 p->autoframing = user->autoframing; 09436 } 09437 /* replace callerid if rpid found, and not restricted */ 09438 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09439 char *tmp; 09440 if (*calleridname) 09441 ast_string_field_set(p, cid_name, calleridname); 09442 tmp = ast_strdupa(rpid_num); 09443 if (ast_is_shrinkable_phonenumber(tmp)) 09444 ast_shrink_phone_number(tmp); 09445 ast_string_field_set(p, cid_num, tmp); 09446 } 09447 09448 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09449 09450 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09451 sip_cancel_destroy(p); 09452 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09453 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09454 /* Copy SIP extensions profile from INVITE */ 09455 if (p->sipoptions) 09456 user->sipoptions = p->sipoptions; 09457 09458 /* If we have a call limit, set flag */ 09459 if (user->call_limit) 09460 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09461 if (!ast_strlen_zero(user->context)) 09462 ast_string_field_set(p, context, user->context); 09463 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09464 char *tmp = ast_strdupa(user->cid_num); 09465 if (ast_is_shrinkable_phonenumber(tmp)) 09466 ast_shrink_phone_number(tmp); 09467 ast_string_field_set(p, cid_num, tmp); 09468 } 09469 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09470 ast_string_field_set(p, cid_name, user->cid_name); 09471 ast_string_field_set(p, username, user->name); 09472 ast_string_field_set(p, peername, user->name); 09473 ast_string_field_set(p, peersecret, user->secret); 09474 ast_string_field_set(p, peermd5secret, user->md5secret); 09475 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09476 ast_string_field_set(p, accountcode, user->accountcode); 09477 ast_string_field_set(p, language, user->language); 09478 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09479 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09480 p->allowtransfer = user->allowtransfer; 09481 p->amaflags = user->amaflags; 09482 p->callgroup = user->callgroup; 09483 p->pickupgroup = user->pickupgroup; 09484 if (user->callingpres) /* User callingpres setting will override RPID header */ 09485 p->callingpres = user->callingpres; 09486 09487 /* Set default codec settings for this call */ 09488 p->capability = user->capability; /* User codec choice */ 09489 p->jointcapability = user->capability; /* Our codecs */ 09490 if (p->peercapability) /* AND with peer's codecs */ 09491 p->jointcapability &= p->peercapability; 09492 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09493 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09494 p->noncodeccapability |= AST_RTP_DTMF; 09495 else 09496 p->noncodeccapability &= ~AST_RTP_DTMF; 09497 p->jointnoncodeccapability = p->noncodeccapability; 09498 if (p->t38.peercapability) 09499 p->t38.jointcapability &= p->t38.peercapability; 09500 p->maxcallbitrate = user->maxcallbitrate; 09501 /* If we do not support video, remove video from call structure */ 09502 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09503 ast_rtp_destroy(p->vrtp); 09504 p->vrtp = NULL; 09505 } 09506 } 09507 if (user && debug) 09508 ast_verbose("Found user '%s'\n", user->name); 09509 } else { 09510 if (user) { 09511 if (!authpeer && debug) 09512 ast_verbose("Found user '%s', but fails host access\n", user->name); 09513 ASTOBJ_UNREF(user,sip_destroy_user); 09514 } 09515 user = NULL; 09516 } 09517 09518 if (!user) { 09519 /* If we didn't find a user match, check for peers */ 09520 if (sipmethod == SIP_SUBSCRIBE) 09521 /* For subscribes, match on peer name only */ 09522 peer = find_peer(of, NULL, 1); 09523 else 09524 /* Look for peer based on the IP address we received data from */ 09525 /* If peer is registered from this IP address or have this as a default 09526 IP address, this call is from the peer 09527 */ 09528 peer = find_peer(NULL, &p->recv, 1); 09529 09530 if (peer) { 09531 /* Set Frame packetization */ 09532 if (p->rtp) { 09533 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09534 p->autoframing = peer->autoframing; 09535 } 09536 if (debug) 09537 ast_verbose("Found peer '%s'\n", peer->name); 09538 09539 /* Take the peer */ 09540 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09541 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09542 09543 /* Copy SIP extensions profile to peer */ 09544 if (p->sipoptions) 09545 peer->sipoptions = p->sipoptions; 09546 09547 /* replace callerid if rpid found, and not restricted */ 09548 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09549 char *tmp = ast_strdupa(rpid_num); 09550 if (*calleridname) 09551 ast_string_field_set(p, cid_name, calleridname); 09552 if (ast_is_shrinkable_phonenumber(tmp)) 09553 ast_shrink_phone_number(tmp); 09554 ast_string_field_set(p, cid_num, tmp); 09555 } 09556 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09557 09558 ast_string_field_set(p, peersecret, peer->secret); 09559 ast_string_field_set(p, peermd5secret, peer->md5secret); 09560 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09561 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09562 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09563 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09564 p->callingpres = peer->callingpres; 09565 if (peer->maxms && peer->lastms) 09566 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09567 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09568 /* Pretend there is no required authentication */ 09569 ast_string_field_free(p, peersecret); 09570 ast_string_field_free(p, peermd5secret); 09571 } 09572 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09573 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09574 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09575 /* If we have a call limit, set flag */ 09576 if (peer->call_limit) 09577 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09578 ast_string_field_set(p, peername, peer->name); 09579 ast_string_field_set(p, authname, peer->name); 09580 09581 /* copy channel vars */ 09582 for (v = peer->chanvars ; v ; v = v->next) { 09583 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09584 tmpvar->next = p->chanvars; 09585 p->chanvars = tmpvar; 09586 } 09587 } 09588 if (authpeer) { 09589 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09590 } 09591 09592 if (!ast_strlen_zero(peer->username)) { 09593 ast_string_field_set(p, username, peer->username); 09594 /* Use the default username for authentication on outbound calls */ 09595 /* XXX this takes the name from the caller... can we override ? */ 09596 ast_string_field_set(p, authname, peer->username); 09597 } 09598 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09599 char *tmp = ast_strdupa(peer->cid_num); 09600 if (ast_is_shrinkable_phonenumber(tmp)) 09601 ast_shrink_phone_number(tmp); 09602 ast_string_field_set(p, cid_num, tmp); 09603 } 09604 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09605 ast_string_field_set(p, cid_name, peer->cid_name); 09606 ast_string_field_set(p, fullcontact, peer->fullcontact); 09607 if (!ast_strlen_zero(peer->context)) 09608 ast_string_field_set(p, context, peer->context); 09609 ast_string_field_set(p, peersecret, peer->secret); 09610 ast_string_field_set(p, peermd5secret, peer->md5secret); 09611 ast_string_field_set(p, language, peer->language); 09612 ast_string_field_set(p, accountcode, peer->accountcode); 09613 p->amaflags = peer->amaflags; 09614 p->callgroup = peer->callgroup; 09615 p->pickupgroup = peer->pickupgroup; 09616 p->capability = peer->capability; 09617 p->prefs = peer->prefs; 09618 p->jointcapability = peer->capability; 09619 if (p->peercapability) 09620 p->jointcapability &= p->peercapability; 09621 p->maxcallbitrate = peer->maxcallbitrate; 09622 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09623 ast_rtp_destroy(p->vrtp); 09624 p->vrtp = NULL; 09625 } 09626 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09627 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09628 p->noncodeccapability |= AST_RTP_DTMF; 09629 else 09630 p->noncodeccapability &= ~AST_RTP_DTMF; 09631 p->jointnoncodeccapability = p->noncodeccapability; 09632 if (p->t38.peercapability) 09633 p->t38.jointcapability &= p->t38.peercapability; 09634 } 09635 ASTOBJ_UNREF(peer, sip_destroy_peer); 09636 } else { 09637 if (debug) 09638 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09639 09640 /* do we allow guests? */ 09641 if (!global_allowguest) { 09642 if (global_alwaysauthreject) 09643 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09644 else 09645 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09646 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09647 char *tmp = ast_strdupa(rpid_num); 09648 if (*calleridname) 09649 ast_string_field_set(p, cid_name, calleridname); 09650 if (ast_is_shrinkable_phonenumber(tmp)) 09651 ast_shrink_phone_number(tmp); 09652 ast_string_field_set(p, cid_num, tmp); 09653 } 09654 } 09655 09656 } 09657 09658 if (user) 09659 ASTOBJ_UNREF(user, sip_destroy_user); 09660 return res; 09661 }
static void check_via | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 9215 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
09216 { 09217 char via[256]; 09218 char *c, *pt; 09219 struct hostent *hp; 09220 struct ast_hostent ahp; 09221 09222 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09223 09224 /* Work on the leftmost value of the topmost Via header */ 09225 c = strchr(via, ','); 09226 if (c) 09227 *c = '\0'; 09228 09229 /* Check for rport */ 09230 c = strstr(via, ";rport"); 09231 if (c && (c[6] != '=')) /* rport query, not answer */ 09232 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09233 09234 c = strchr(via, ';'); 09235 if (c) 09236 *c = '\0'; 09237 09238 c = strchr(via, ' '); 09239 if (c) { 09240 *c = '\0'; 09241 c = ast_skip_blanks(c+1); 09242 if (strcasecmp(via, "SIP/2.0/UDP")) { 09243 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09244 return; 09245 } 09246 pt = strchr(c, ':'); 09247 if (pt) 09248 *pt++ = '\0'; /* remember port pointer */ 09249 hp = ast_gethostbyname(c, &ahp); 09250 if (!hp) { 09251 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09252 return; 09253 } 09254 memset(&p->sa, 0, sizeof(p->sa)); 09255 p->sa.sin_family = AF_INET; 09256 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09257 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09258 09259 if (sip_debug_test_pvt(p)) { 09260 const struct sockaddr_in *dst = sip_real_dst(p); 09261 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09262 } 09263 } 09264 }
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 10110 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
10111 { 10112 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10113 10114 while ((oldcontext = strsep(&old, "&"))) { 10115 stalecontext = '\0'; 10116 ast_copy_string(newlist, new, sizeof(newlist)); 10117 stringp = newlist; 10118 while ((newcontext = strsep(&stringp, "&"))) { 10119 if (strcmp(newcontext, oldcontext) == 0) { 10120 /* This is not the context you're looking for */ 10121 stalecontext = '\0'; 10122 break; 10123 } else if (strcmp(newcontext, oldcontext)) { 10124 stalecontext = oldcontext; 10125 } 10126 10127 } 10128 if (stalecontext) 10129 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10130 } 10131 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16319 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16320 { 16321 struct sip_auth *a = authlist; 16322 struct sip_auth *b; 16323 16324 while (a) { 16325 b = a; 16326 a = a->next; 16327 free(b); 16328 } 16329 16330 return 1; 16331 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16248 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().
16249 { 16250 struct domain *d; 16251 16252 AST_LIST_LOCK(&domain_list); 16253 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16254 free(d); 16255 AST_LIST_UNLOCK(&domain_list); 16256 }
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 10918 of file chan_sip.c.
References complete_sip_peer().
10919 { 10920 if (pos == 3) 10921 return complete_sip_peer(word, state, 0); 10922 10923 return NULL; 10924 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10892 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10893 { 10894 char *result = NULL; 10895 int wordlen = strlen(word); 10896 int which = 0; 10897 10898 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10899 /* locking of the object is not required because only the name and flags are being compared */ 10900 if (!strncasecmp(word, iterator->name, wordlen) && 10901 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10902 ++which > state) 10903 result = ast_strdup(iterator->name); 10904 } while(0) ); 10905 return result; 10906 }
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 10986 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10987 { 10988 if (pos == 4) 10989 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10990 return NULL; 10991 }
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 10994 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10995 { 10996 if (pos == 4) 10997 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10998 10999 return NULL; 11000 }
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 10909 of file chan_sip.c.
References complete_sip_peer().
10910 { 10911 if (pos == 3) 10912 return complete_sip_peer(word, state, 0); 10913 10914 return NULL; 10915 }
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 10947 of file chan_sip.c.
References complete_sip_user().
10948 { 10949 if (pos == 3) 10950 return complete_sip_user(word, state, 0); 10951 10952 return NULL; 10953 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10927 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10928 { 10929 char *result = NULL; 10930 int wordlen = strlen(word); 10931 int which = 0; 10932 10933 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10934 /* locking of the object is not required because only the name and flags are being compared */ 10935 if (!strncasecmp(word, iterator->name, wordlen)) { 10936 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10937 continue; 10938 if (++which > state) { 10939 result = ast_strdup(iterator->name); 10940 } 10941 } 10942 } while(0) ); 10943 return result; 10944 }
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 10873 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, iflist, and sip_pvt::next.
10874 { 10875 int which=0; 10876 struct sip_pvt *cur; 10877 char *c = NULL; 10878 int wordlen = strlen(word); 10879 10880 ast_mutex_lock(&iflock); 10881 for (cur = iflist; cur; cur = cur->next) { 10882 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10883 c = ast_strdup(cur->callid); 10884 break; 10885 } 10886 } 10887 ast_mutex_unlock(&iflock); 10888 return c; 10889 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10956 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10957 { 10958 char *c = NULL; 10959 10960 if (pos == 2) { 10961 int which = 0; 10962 char *cat = NULL; 10963 int wordlen = strlen(word); 10964 10965 /* do completion for notify type */ 10966 10967 if (!notify_types) 10968 return NULL; 10969 10970 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10971 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10972 c = ast_strdup(cat); 10973 break; 10974 } 10975 } 10976 return c; 10977 } 10978 10979 if (pos > 2) 10980 return complete_sip_peer(word, state, 0); 10981 10982 return NULL; 10983 }
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 5598 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05599 { 05600 int start = 0; 05601 int copied = 0; 05602 for (;;) { 05603 const char *tmp = __get_header(orig, field, &start); 05604 05605 if (ast_strlen_zero(tmp)) 05606 break; 05607 /* Add what we're responding to */ 05608 add_header(req, field, tmp); 05609 copied++; 05610 } 05611 return copied ? 0 : -1; 05612 }
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 5587 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05588 { 05589 const char *tmp = get_header(orig, field); 05590 05591 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05592 return add_header(req, field, tmp); 05593 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05594 return -1; 05595 }
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 6635 of file chan_sip.c.
References sip_request::header, sip_request::line, offset, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06636 { 06637 long offset; 06638 int x; 06639 offset = ((void *)dst) - ((void *)src); 06640 /* First copy stuff */ 06641 memcpy(dst, src, sizeof(*dst)); 06642 /* Now fix pointer arithmetic */ 06643 for (x=0; x < src->headers; x++) 06644 dst->header[x] += offset; 06645 for (x=0; x < src->lines; x++) 06646 dst->line[x] += offset; 06647 dst->rlPart1 += offset; 06648 dst->rlPart2 += offset; 06649 }
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 5620 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().
05621 { 05622 int copied = 0; 05623 int start = 0; 05624 05625 for (;;) { 05626 char new[256]; 05627 const char *oh = __get_header(orig, field, &start); 05628 05629 if (ast_strlen_zero(oh)) 05630 break; 05631 05632 if (!copied) { /* Only check for empty rport in topmost via header */ 05633 char leftmost[256], *others, *rport; 05634 05635 /* Only work on leftmost value */ 05636 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05637 others = strchr(leftmost, ','); 05638 if (others) 05639 *others++ = '\0'; 05640 05641 /* Find ;rport; (empty request) */ 05642 rport = strstr(leftmost, ";rport"); 05643 if (rport && *(rport+6) == '=') 05644 rport = NULL; /* We already have a parameter to rport */ 05645 05646 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05647 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05648 /* We need to add received port - rport */ 05649 char *end; 05650 05651 rport = strstr(leftmost, ";rport"); 05652 05653 if (rport) { 05654 end = strchr(rport + 1, ';'); 05655 if (end) 05656 memmove(rport, end, strlen(end) + 1); 05657 else 05658 *rport = '\0'; 05659 } 05660 05661 /* Add rport to first VIA header if requested */ 05662 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05663 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05664 ntohs(p->recv.sin_port), 05665 others ? "," : "", others ? others : ""); 05666 } else { 05667 /* We should *always* add a received to the topmost via */ 05668 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05669 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05670 others ? "," : "", others ? others : ""); 05671 } 05672 oh = new; /* the header to copy */ 05673 } /* else add the following via headers untouched */ 05674 add_header(req, field, oh); 05675 copied++; 05676 } 05677 if (!copied) { 05678 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05679 return -1; 05680 } 05681 return 0; 05682 }
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 2862 of file chan_sip.c.
References ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02863 { 02864 struct hostent *hp; 02865 struct ast_hostent ahp; 02866 struct sip_peer *p; 02867 char *port; 02868 int portno; 02869 char host[MAXHOSTNAMELEN], *hostn; 02870 char peer[256]; 02871 02872 ast_copy_string(peer, opeer, sizeof(peer)); 02873 port = strchr(peer, ':'); 02874 if (port) 02875 *port++ = '\0'; 02876 dialog->sa.sin_family = AF_INET; 02877 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02878 p = find_peer(peer, NULL, 1); 02879 02880 if (p) { 02881 int res = create_addr_from_peer(dialog, p); 02882 ASTOBJ_UNREF(p, sip_destroy_peer); 02883 return res; 02884 } 02885 hostn = peer; 02886 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02887 if (srvlookup) { 02888 char service[MAXHOSTNAMELEN]; 02889 int tportno; 02890 int ret; 02891 02892 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02893 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02894 if (ret > 0) { 02895 hostn = host; 02896 portno = tportno; 02897 } 02898 } 02899 hp = ast_gethostbyname(hostn, &ahp); 02900 if (!hp) { 02901 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02902 return -1; 02903 } 02904 ast_string_field_set(dialog, tohost, peer); 02905 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02906 dialog->sa.sin_port = htons(portno); 02907 dialog->recv = dialog->sa; 02908 return 0; 02909 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2754 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, domain::context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02755 { 02756 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02757 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02758 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02759 dialog->recv = dialog->sa; 02760 } else 02761 return -1; 02762 02763 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02764 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02765 dialog->capability = peer->capability; 02766 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02767 ast_rtp_destroy(dialog->vrtp); 02768 dialog->vrtp = NULL; 02769 } 02770 dialog->prefs = peer->prefs; 02771 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02772 dialog->t38.capability = global_t38_capability; 02773 if (dialog->udptl) { 02774 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02775 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02776 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02777 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02778 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02779 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02780 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02781 if (option_debug > 1) 02782 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02783 } 02784 dialog->t38.jointcapability = dialog->t38.capability; 02785 } else if (dialog->udptl) { 02786 ast_udptl_destroy(dialog->udptl); 02787 dialog->udptl = NULL; 02788 } 02789 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02790 02791 if (dialog->rtp) { 02792 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02793 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02794 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02795 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02796 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02797 /* Set Frame packetization */ 02798 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02799 dialog->autoframing = peer->autoframing; 02800 } 02801 if (dialog->vrtp) { 02802 ast_rtp_setdtmf(dialog->vrtp, 0); 02803 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02804 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02805 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02806 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02807 } 02808 02809 ast_string_field_set(dialog, peername, peer->name); 02810 ast_string_field_set(dialog, authname, peer->username); 02811 ast_string_field_set(dialog, username, peer->username); 02812 ast_string_field_set(dialog, peersecret, peer->secret); 02813 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02814 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02815 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02816 ast_string_field_set(dialog, tohost, peer->tohost); 02817 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02818 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02819 char *tmpcall; 02820 char *c; 02821 tmpcall = ast_strdupa(dialog->callid); 02822 c = strchr(tmpcall, '@'); 02823 if (c) { 02824 *c = '\0'; 02825 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02826 } 02827 } 02828 if (ast_strlen_zero(dialog->tohost)) 02829 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02830 if (!ast_strlen_zero(peer->fromdomain)) 02831 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02832 if (!ast_strlen_zero(peer->fromuser)) 02833 ast_string_field_set(dialog, fromuser, peer->fromuser); 02834 if (!ast_strlen_zero(peer->language)) 02835 ast_string_field_set(dialog, language, peer->language); 02836 dialog->maxtime = peer->maxms; 02837 dialog->callgroup = peer->callgroup; 02838 dialog->pickupgroup = peer->pickupgroup; 02839 dialog->allowtransfer = peer->allowtransfer; 02840 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02841 /* Minimum is settable or default to 100 ms */ 02842 if (peer->maxms && peer->lastms) 02843 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02844 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02845 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02846 dialog->noncodeccapability |= AST_RTP_DTMF; 02847 else 02848 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02849 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02850 ast_string_field_set(dialog, context, peer->context); 02851 dialog->rtptimeout = peer->rtptimeout; 02852 if (peer->call_limit) 02853 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02854 dialog->maxcallbitrate = peer->maxcallbitrate; 02855 02856 return 0; 02857 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7814 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07815 { 07816 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07817 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07818 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07819 else 07820 ast_db_del("SIP/Registry", peer->name); 07821 } 07822 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6679 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06680 { 06681 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06682 06683 if (!*e) 06684 return -1; 06685 req->rlPart1 = e; /* method or protocol */ 06686 e = ast_skip_nonblanks(e); 06687 if (*e) 06688 *e++ = '\0'; 06689 /* Get URI or status code */ 06690 e = ast_skip_blanks(e); 06691 if ( !*e ) 06692 return -1; 06693 ast_trim_blanks(e); 06694 06695 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06696 if (strlen(e) < 3) /* status code is 3 digits */ 06697 return -1; 06698 req->rlPart2 = e; 06699 } else { /* We have a request */ 06700 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06701 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06702 e++; 06703 if (!*e) 06704 return -1; 06705 } 06706 req->rlPart2 = e; /* URI */ 06707 e = ast_skip_nonblanks(e); 06708 if (*e) 06709 *e++ = '\0'; 06710 e = ast_skip_blanks(e); 06711 if (strcasecmp(e, "SIP/2.0") ) { 06712 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06713 return -1; 06714 } 06715 } 06716 return 1; 06717 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15563 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_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, does_peer_need_mwi(), FALSE, iflist, LOG_DEBUG, LOG_NOTICE, sip_pvt::next, option_debug, option_verbose, peerl, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, and VERBOSE_PREFIX_1.
15564 { 15565 int res; 15566 struct sip_pvt *sip; 15567 struct sip_peer *peer = NULL; 15568 time_t t; 15569 int fastrestart = FALSE; 15570 int lastpeernum = -1; 15571 int curpeernum; 15572 int reloading; 15573 15574 /* Add an I/O event to our SIP UDP socket */ 15575 if (sipsock > -1) 15576 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15577 15578 /* From here on out, we die whenever asked */ 15579 for(;;) { 15580 /* Check for a reload request */ 15581 ast_mutex_lock(&sip_reload_lock); 15582 reloading = sip_reloading; 15583 sip_reloading = FALSE; 15584 ast_mutex_unlock(&sip_reload_lock); 15585 if (reloading) { 15586 if (option_verbose > 0) 15587 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15588 sip_do_reload(sip_reloadreason); 15589 15590 /* Change the I/O fd of our UDP socket */ 15591 if (sipsock > -1) { 15592 if (sipsock_read_id) 15593 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15594 else 15595 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15596 } 15597 } 15598 /* Check for interfaces needing to be killed */ 15599 ast_mutex_lock(&iflock); 15600 restartsearch: 15601 t = time(NULL); 15602 /* don't scan the interface list if it hasn't been a reasonable period 15603 of time since the last time we did it (when MWI is being sent, we can 15604 get back to this point every millisecond or less) 15605 */ 15606 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15607 /*! \note If we can't get a lock on an interface, skip it and come 15608 * back later. Note that there is the possibility of a deadlock with 15609 * sip_hangup otherwise, because sip_hangup is called with the channel 15610 * locked first, and the iface lock is attempted second. 15611 */ 15612 if (ast_mutex_trylock(&sip->lock)) 15613 continue; 15614 15615 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15616 if (sip->rtp && sip->owner && 15617 (sip->owner->_state == AST_STATE_UP) && 15618 !sip->redirip.sin_addr.s_addr && 15619 sip->t38.state != T38_ENABLED) { 15620 if (sip->lastrtptx && 15621 ast_rtp_get_rtpkeepalive(sip->rtp) && 15622 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15623 /* Need to send an empty RTP packet */ 15624 sip->lastrtptx = time(NULL); 15625 ast_rtp_sendcng(sip->rtp, 0); 15626 } 15627 if (sip->lastrtprx && 15628 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15629 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15630 /* Might be a timeout now -- see if we're on hold */ 15631 struct sockaddr_in sin; 15632 ast_rtp_get_peer(sip->rtp, &sin); 15633 if (sin.sin_addr.s_addr || 15634 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15635 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15636 /* Needs a hangup */ 15637 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15638 while (sip->owner && ast_channel_trylock(sip->owner)) { 15639 ast_mutex_unlock(&sip->lock); 15640 usleep(1); 15641 ast_mutex_lock(&sip->lock); 15642 } 15643 if (sip->owner) { 15644 ast_log(LOG_NOTICE, 15645 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15646 sip->owner->name, 15647 (long) (t - sip->lastrtprx)); 15648 /* Issue a softhangup */ 15649 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15650 ast_channel_unlock(sip->owner); 15651 /* forget the timeouts for this call, since a hangup 15652 has already been requested and we don't want to 15653 repeatedly request hangups 15654 */ 15655 ast_rtp_set_rtptimeout(sip->rtp, 0); 15656 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15657 if (sip->vrtp) { 15658 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15659 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15660 } 15661 } 15662 } 15663 } 15664 } 15665 } 15666 /* If we have sessions that needs to be destroyed, do it now */ 15667 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15668 !sip->owner) { 15669 ast_mutex_unlock(&sip->lock); 15670 __sip_destroy(sip, 1); 15671 goto restartsearch; 15672 } 15673 ast_mutex_unlock(&sip->lock); 15674 } 15675 ast_mutex_unlock(&iflock); 15676 15677 pthread_testcancel(); 15678 /* Wait for sched or io */ 15679 res = ast_sched_wait(sched); 15680 if ((res < 0) || (res > 1000)) 15681 res = 1000; 15682 /* If we might need to send more mailboxes, don't wait long at all.*/ 15683 if (fastrestart) 15684 res = 1; 15685 res = ast_io_wait(io, res); 15686 if (option_debug && res > 20) 15687 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15688 ast_mutex_lock(&monlock); 15689 if (res >= 0) { 15690 res = ast_sched_runq(sched); 15691 if (option_debug && res >= 20) 15692 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15693 } 15694 15695 /* Send MWI notifications to peers - static and cached realtime peers */ 15696 t = time(NULL); 15697 fastrestart = FALSE; 15698 curpeernum = 0; 15699 peer = NULL; 15700 /* Find next peer that needs mwi */ 15701 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15702 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15703 fastrestart = TRUE; 15704 lastpeernum = curpeernum; 15705 peer = ASTOBJ_REF(iterator); 15706 }; 15707 curpeernum++; 15708 } while (0) 15709 ); 15710 /* Send MWI to the peer */ 15711 if (peer) { 15712 ASTOBJ_WRLOCK(peer); 15713 sip_send_mwi_to_peer(peer); 15714 ASTOBJ_UNLOCK(peer); 15715 ASTOBJ_UNREF(peer,sip_destroy_peer); 15716 } else { 15717 /* Reset where we come from */ 15718 lastpeernum = -1; 15719 } 15720 ast_mutex_unlock(&monlock); 15721 } 15722 /* Never reached */ 15723 return NULL; 15724 15725 }
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 11459 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().
11460 { 11461 char digest[1024]; 11462 11463 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11464 return -2; 11465 11466 p->authtries++; 11467 if (option_debug > 1) 11468 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11469 memset(digest, 0, sizeof(digest)); 11470 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11471 /* No way to authenticate */ 11472 return -1; 11473 } 11474 /* Now we have a reply digest */ 11475 p->options->auth = digest; 11476 p->options->authheader = respheader; 11477 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11478 }
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 11438 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
11439 { 11440 char digest[1024]; 11441 p->authtries++; 11442 memset(digest,0,sizeof(digest)); 11443 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11444 /* There's nothing to use for authentication */ 11445 /* No digest challenge in request */ 11446 if (sip_debug_test_pvt(p) && p->registry) 11447 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11448 /* No old challenge */ 11449 return -1; 11450 } 11451 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11452 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11453 if (sip_debug_test_pvt(p) && p->registry) 11454 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11455 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11456 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2730 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, domain::mode, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02731 { 02732 const char *mode = natflags ? "On" : "Off"; 02733 02734 if (p->rtp) { 02735 if (option_debug) 02736 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02737 ast_rtp_setnat(p->rtp, natflags); 02738 } 02739 if (p->vrtp) { 02740 if (option_debug) 02741 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02742 ast_rtp_setnat(p->vrtp, natflags); 02743 } 02744 if (p->udptl) { 02745 if (option_debug) 02746 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02747 ast_udptl_setnat(p->udptl, natflags); 02748 } 02749 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15542 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.
Referenced by do_monitor().
15543 { 15544 time_t t = time(NULL); 15545 15546 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15547 !peer->mwipvt) { /* We don't have a subscription */ 15548 peer->lastmsgcheck = t; /* Reset timer */ 15549 return FALSE; 15550 } 15551 15552 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15553 return TRUE; 15554 15555 return FALSE; 15556 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10299 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10300 { 10301 switch (mode) { 10302 case SIP_DOMAIN_AUTO: 10303 return "[Automatic]"; 10304 case SIP_DOMAIN_CONFIG: 10305 return "[Configured]"; 10306 } 10307 10308 return ""; 10309 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 10079 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().
10080 { 10081 switch (mode) { 10082 case SIP_DTMF_RFC2833: 10083 return "rfc2833"; 10084 case SIP_DTMF_INFO: 10085 return "info"; 10086 case SIP_DTMF_INBAND: 10087 return "inband"; 10088 case SIP_DTMF_AUTO: 10089 return "auto"; 10090 } 10091 return "<error>"; 10092 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7825 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().
07826 { 07827 struct sip_peer *peer = (struct sip_peer *)data; 07828 07829 if (!peer) /* Hmmm. We have no peer. Weird. */ 07830 return 0; 07831 07832 memset(&peer->addr, 0, sizeof(peer->addr)); 07833 07834 destroy_association(peer); /* remove registration data from storage */ 07835 07836 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07837 register_peer_exten(peer, FALSE); /* Remove regexten */ 07838 peer->expire = -1; 07839 ast_device_state_changed("SIP/%s", peer->name); 07840 07841 /* Do we need to release this peer from memory? 07842 Only for realtime peers and autocreated peers 07843 */ 07844 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07845 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07846 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07847 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07848 } 07849 07850 return 0; 07851 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6769 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and strsep().
Referenced by handle_request(), and handle_request_invite().
06770 { 06771 char stripped[BUFSIZ]; 06772 char *c; 06773 06774 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06775 c = get_in_brackets(stripped); 06776 c = strsep(&c, ";"); /* trim ; and beyond */ 06777 if (!ast_strlen_zero(c)) 06778 ast_string_field_set(p, uri, c); 06779 }
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 4166 of file chan_sip.c.
References aliases.
04167 { 04168 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04169 static const struct cfalias { 04170 char * const fullname; 04171 char * const shortname; 04172 } aliases[] = { 04173 { "Content-Type", "c" }, 04174 { "Content-Encoding", "e" }, 04175 { "From", "f" }, 04176 { "Call-ID", "i" }, 04177 { "Contact", "m" }, 04178 { "Content-Length", "l" }, 04179 { "Subject", "s" }, 04180 { "To", "t" }, 04181 { "Supported", "k" }, 04182 { "Refer-To", "r" }, 04183 { "Referred-By", "b" }, 04184 { "Allow-Events", "u" }, 04185 { "Event", "o" }, 04186 { "Via", "v" }, 04187 { "Accept-Contact", "a" }, 04188 { "Reject-Contact", "j" }, 04189 { "Request-Disposition", "d" }, 04190 { "Session-Expires", "x" }, 04191 { "Identity", "y" }, 04192 { "Identity-Info", "n" }, 04193 }; 04194 int x; 04195 04196 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04197 if (!strcasecmp(aliases[x].fullname, name)) 04198 return aliases[x].shortname; 04199 04200 return _default; 04201 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static, read] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4518 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, FALSE, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_ACK, sip_alloc(), sip_methods, SIP_NOTIFY, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, and transmit_response_using_temp().
Referenced by sipsock_read().
04519 { 04520 struct sip_pvt *p = NULL; 04521 char *tag = ""; /* note, tag is never NULL */ 04522 char totag[128]; 04523 char fromtag[128]; 04524 const char *callid = get_header(req, "Call-ID"); 04525 const char *from = get_header(req, "From"); 04526 const char *to = get_header(req, "To"); 04527 const char *cseq = get_header(req, "Cseq"); 04528 04529 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04530 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04531 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04532 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04533 return NULL; /* Invalid packet */ 04534 04535 if (pedanticsipchecking) { 04536 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04537 we need more to identify a branch - so we have to check branch, from 04538 and to tags to identify a call leg. 04539 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04540 in sip.conf 04541 */ 04542 if (gettag(req, "To", totag, sizeof(totag))) 04543 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04544 gettag(req, "From", fromtag, sizeof(fromtag)); 04545 04546 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04547 04548 if (option_debug > 4 ) 04549 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); 04550 } 04551 04552 ast_mutex_lock(&iflock); 04553 for (p = iflist; p; p = p->next) { 04554 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04555 int found = FALSE; 04556 if (ast_strlen_zero(p->callid)) 04557 continue; 04558 if (req->method == SIP_REGISTER) 04559 found = (!strcmp(p->callid, callid)); 04560 else 04561 found = (!strcmp(p->callid, callid) && 04562 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04563 04564 if (option_debug > 4) 04565 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); 04566 04567 /* If we get a new request within an existing to-tag - check the to tag as well */ 04568 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04569 if (p->tag[0] == '\0' && totag[0]) { 04570 /* We have no to tag, but they have. Wrong dialog */ 04571 found = FALSE; 04572 } else if (totag[0]) { /* Both have tags, compare them */ 04573 if (strcmp(totag, p->tag)) { 04574 found = FALSE; /* This is not our packet */ 04575 } 04576 } 04577 if (!found && option_debug > 4) 04578 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); 04579 } 04580 04581 04582 if (found) { 04583 /* Found the call */ 04584 ast_mutex_lock(&p->lock); 04585 ast_mutex_unlock(&iflock); 04586 return p; 04587 } 04588 } 04589 ast_mutex_unlock(&iflock); 04590 04591 /* See if the method is capable of creating a dialog */ 04592 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04593 if (intended_method == SIP_REFER) { 04594 /* We do support REFER, but not outside of a dialog yet */ 04595 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04596 } else if (intended_method == SIP_NOTIFY) { 04597 /* We do not support out-of-dialog NOTIFY either, 04598 like voicemail notification, so cancel that early */ 04599 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04600 } else { 04601 /* Ok, time to create a new SIP dialog object, a pvt */ 04602 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04603 /* Ok, we've created a dialog, let's go and process it */ 04604 ast_mutex_lock(&p->lock); 04605 } else { 04606 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04607 getting a dialog from sip_alloc. 04608 04609 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04610 send an error message. 04611 04612 Sorry, we apologize for the inconvienience 04613 */ 04614 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04615 if (option_debug > 3) 04616 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04617 } 04618 } 04619 return p; 04620 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04621 /* A method we do not support, let's take it on the volley */ 04622 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04623 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04624 /* This is a request outside of a dialog that we don't know about 04625 ...never reply to an ACK! 04626 */ 04627 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04628 } 04629 /* We do not respond to responses for dialogs that we don't know about, we just drop 04630 the session quickly */ 04631 04632 return p; 04633 }
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 2294 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02295 { 02296 char last_char = '\0'; 02297 const char *s; 02298 for (s = start; *s && s != lim; last_char = *s++) { 02299 if (*s == '"' && last_char != '\\') 02300 break; 02301 } 02302 return s; 02303 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static, read] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2642 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02643 { 02644 struct sip_peer *p = NULL; 02645 02646 if (peer) 02647 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02648 else 02649 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02650 02651 if (!p && realtime) 02652 p = realtime_peer(peer, sin); 02653 02654 return p; 02655 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static, read] |
Find authentication for a specific realm.
Definition at line 16334 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16335 { 16336 struct sip_auth *a; 16337 16338 for (a = authlist; a; a = a->next) { 16339 if (!strcasecmp(a->realm, realm)) 16340 break; 16341 } 16342 16343 return a; 16344 }
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 4839 of file chan_sip.c.
References 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().
04840 { 04841 const char *content_type; 04842 const char *search; 04843 char *boundary; 04844 unsigned int x; 04845 int boundaryisquoted = FALSE; 04846 int found_application_sdp = FALSE; 04847 int found_end_of_headers = FALSE; 04848 04849 content_type = get_header(req, "Content-Type"); 04850 04851 /* if the body contains only SDP, this is easy */ 04852 if (!strcasecmp(content_type, "application/sdp")) { 04853 req->sdp_start = 0; 04854 req->sdp_end = req->lines; 04855 return req->lines ? 1 : 0; 04856 } 04857 04858 /* if it's not multipart/mixed, there cannot be an SDP */ 04859 if (strncasecmp(content_type, "multipart/mixed", 15)) 04860 return 0; 04861 04862 /* if there is no boundary marker, it's invalid */ 04863 if (!(search = strcasestr(content_type, ";boundary="))) 04864 return 0; 04865 04866 search += 10; 04867 if (ast_strlen_zero(search)) 04868 return 0; 04869 04870 /* If the boundary is quoted with ", remove quote */ 04871 if (*search == '\"') { 04872 search++; 04873 boundaryisquoted = TRUE; 04874 } 04875 04876 /* make a duplicate of the string, with two extra characters 04877 at the beginning */ 04878 boundary = ast_strdupa(search - 2); 04879 boundary[0] = boundary[1] = '-'; 04880 /* Remove final quote */ 04881 if (boundaryisquoted) 04882 boundary[strlen(boundary) - 1] = '\0'; 04883 04884 /* search for the boundary marker, the empty line delimiting headers from 04885 sdp part and the end boundry if it exists */ 04886 04887 for (x = 0; x < (req->lines ); x++) { 04888 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04889 if(found_application_sdp && found_end_of_headers){ 04890 req->sdp_end = x-1; 04891 return 1; 04892 } 04893 found_application_sdp = FALSE; 04894 } 04895 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04896 found_application_sdp = TRUE; 04897 04898 if(strlen(req->line[x]) == 0 ){ 04899 if(found_application_sdp && !found_end_of_headers){ 04900 req->sdp_start = x; 04901 found_end_of_headers = TRUE; 04902 } 04903 } 04904 } 04905 if(found_application_sdp && found_end_of_headers) { 04906 req->sdp_end = x; 04907 return TRUE; 04908 } 04909 return FALSE; 04910 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1676 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01677 { 01678 int i, res = 0; 01679 01680 if (ast_strlen_zero(msg)) 01681 return 0; 01682 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01683 if (method_match(i, msg)) 01684 res = sip_methods[i].id; 01685 } 01686 return res; 01687 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 10787 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10788 { 10789 int i; 10790 10791 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10792 if (subscription_types[i].type == subtype) { 10793 return &subscription_types[i]; 10794 } 10795 } 10796 return &subscription_types[0]; 10797 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2721 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02722 { 02723 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02724 if (!u && realtime) 02725 u = realtime_user(name); 02726 return u; 02727 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8156 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08157 { 08158 struct sip_route *next; 08159 08160 while (route) { 08161 next = route->next; 08162 free(route); 08163 route = next; 08164 } 08165 }
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 11785 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11786 { 11787 if (ast_strlen_zero(data)) { 11788 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11789 return -1; 11790 } 11791 if (check_sip_domain(data, NULL, 0)) 11792 ast_copy_string(buf, data, len); 11793 else 11794 buf[0] = '\0'; 11795 return 0; 11796 }
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 11721 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11722 { 11723 struct sip_pvt *p; 11724 const char *content = NULL; 11725 AST_DECLARE_APP_ARGS(args, 11726 AST_APP_ARG(header); 11727 AST_APP_ARG(number); 11728 ); 11729 int i, number, start = 0; 11730 11731 if (ast_strlen_zero(data)) { 11732 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11733 return -1; 11734 } 11735 11736 ast_channel_lock(chan); 11737 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11738 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11739 ast_channel_unlock(chan); 11740 return -1; 11741 } 11742 11743 AST_STANDARD_APP_ARGS(args, data); 11744 if (!args.number) { 11745 number = 1; 11746 } else { 11747 sscanf(args.number, "%d", &number); 11748 if (number < 1) 11749 number = 1; 11750 } 11751 11752 p = chan->tech_pvt; 11753 11754 /* If there is no private structure, this channel is no longer alive */ 11755 if (!p) { 11756 ast_channel_unlock(chan); 11757 return -1; 11758 } 11759 11760 for (i = 0; i < number; i++) 11761 content = __get_header(&p->initreq, args.header, &start); 11762 11763 if (ast_strlen_zero(content)) { 11764 ast_channel_unlock(chan); 11765 return -1; 11766 } 11767 11768 ast_copy_string(buf, content, len); 11769 ast_channel_unlock(chan); 11770 11771 return 0; 11772 }
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 11900 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.
11901 { 11902 struct sip_pvt *p; 11903 11904 *buf = 0; 11905 11906 if (!data) { 11907 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11908 return -1; 11909 } 11910 11911 ast_channel_lock(chan); 11912 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11913 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11914 ast_channel_unlock(chan); 11915 return -1; 11916 } 11917 11918 p = chan->tech_pvt; 11919 11920 /* If there is no private structure, this channel is no longer alive */ 11921 if (!p) { 11922 ast_channel_unlock(chan); 11923 return -1; 11924 } 11925 11926 if (!strcasecmp(data, "peerip")) { 11927 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11928 } else if (!strcasecmp(data, "recvip")) { 11929 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11930 } else if (!strcasecmp(data, "from")) { 11931 ast_copy_string(buf, p->from, len); 11932 } else if (!strcasecmp(data, "uri")) { 11933 ast_copy_string(buf, p->uri, len); 11934 } else if (!strcasecmp(data, "useragent")) { 11935 ast_copy_string(buf, p->useragent, len); 11936 } else if (!strcasecmp(data, "peername")) { 11937 ast_copy_string(buf, p->peername, len); 11938 } else if (!strcasecmp(data, "t38passthrough")) { 11939 if (p->t38.state == T38_DISABLED) 11940 ast_copy_string(buf, "0", sizeof("0")); 11941 else /* T38 is offered or enabled in this call */ 11942 ast_copy_string(buf, "1", sizeof("1")); 11943 } else { 11944 ast_channel_unlock(chan); 11945 return -1; 11946 } 11947 ast_channel_unlock(chan); 11948 11949 return 0; 11950 }
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 11810 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.
11811 { 11812 struct sip_peer *peer; 11813 char *colname; 11814 11815 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11816 *colname++ = '\0'; 11817 else if ((colname = strchr(data, '|'))) 11818 *colname++ = '\0'; 11819 else 11820 colname = "ip"; 11821 11822 if (!(peer = find_peer(data, NULL, 1))) 11823 return -1; 11824 11825 if (!strcasecmp(colname, "ip")) { 11826 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11827 } else if (!strcasecmp(colname, "status")) { 11828 peer_status(peer, buf, len); 11829 } else if (!strcasecmp(colname, "language")) { 11830 ast_copy_string(buf, peer->language, len); 11831 } else if (!strcasecmp(colname, "regexten")) { 11832 ast_copy_string(buf, peer->regexten, len); 11833 } else if (!strcasecmp(colname, "limit")) { 11834 snprintf(buf, len, "%d", peer->call_limit); 11835 } else if (!strcasecmp(colname, "curcalls")) { 11836 snprintf(buf, len, "%d", peer->inUse); 11837 } else if (!strcasecmp(colname, "accountcode")) { 11838 ast_copy_string(buf, peer->accountcode, len); 11839 } else if (!strcasecmp(colname, "useragent")) { 11840 ast_copy_string(buf, peer->useragent, len); 11841 } else if (!strcasecmp(colname, "mailbox")) { 11842 ast_copy_string(buf, peer->mailbox, len); 11843 } else if (!strcasecmp(colname, "context")) { 11844 ast_copy_string(buf, peer->context, len); 11845 } else if (!strcasecmp(colname, "expire")) { 11846 snprintf(buf, len, "%d", peer->expire); 11847 } else if (!strcasecmp(colname, "dynamic")) { 11848 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11849 } else if (!strcasecmp(colname, "callerid_name")) { 11850 ast_copy_string(buf, peer->cid_name, len); 11851 } else if (!strcasecmp(colname, "callerid_num")) { 11852 ast_copy_string(buf, peer->cid_num, len); 11853 } else if (!strcasecmp(colname, "codecs")) { 11854 ast_getformatname_multiple(buf, len -1, peer->capability); 11855 } else if (!strncasecmp(colname, "codec[", 6)) { 11856 char *codecnum; 11857 int index = 0, codec = 0; 11858 11859 codecnum = colname + 6; /* move past the '[' */ 11860 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11861 index = atoi(codecnum); 11862 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11863 ast_copy_string(buf, ast_getformatname(codec), len); 11864 } 11865 } 11866 11867 ASTOBJ_UNREF(peer, sip_destroy_peer); 11868 11869 return 0; 11870 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4351 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04352 { 04353 long val[4]; 04354 int x; 04355 04356 for (x=0; x<4; x++) 04357 val[x] = ast_random(); 04358 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04359 04360 return buf; 04361 }
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 9155 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), domain::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
09156 { 09157 char tmp[256] = "", *c, *a; 09158 struct sip_request *req = oreq ? oreq : &p->initreq; 09159 struct sip_refer *referdata = NULL; 09160 const char *transfer_context = NULL; 09161 09162 if (!p->refer && !sip_refer_allocate(p)) 09163 return -1; 09164 09165 referdata = p->refer; 09166 09167 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09168 c = get_in_brackets(tmp); 09169 09170 if (pedanticsipchecking) 09171 ast_uri_decode(c); 09172 09173 if (strncasecmp(c, "sip:", 4)) { 09174 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09175 return -1; 09176 } 09177 c += 4; 09178 if ((a = strchr(c, ';'))) /* Remove arguments */ 09179 *a = '\0'; 09180 09181 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09182 *a++ = '\0'; 09183 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09184 } 09185 09186 if (sip_debug_test_pvt(p)) 09187 ast_verbose("Looking for %s in %s\n", c, p->context); 09188 09189 if (p->owner) /* Mimic behaviour in res_features.c */ 09190 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09191 09192 /* By default, use the context in the channel sending the REFER */ 09193 if (ast_strlen_zero(transfer_context)) { 09194 transfer_context = S_OR(p->owner->macrocontext, 09195 S_OR(p->context, default_context)); 09196 } 09197 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09198 /* This is a blind transfer */ 09199 if (option_debug) 09200 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09201 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09202 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09203 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09204 referdata->refer_call = NULL; 09205 /* Set new context */ 09206 ast_string_field_set(p, context, transfer_context); 09207 return 0; 09208 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09209 return 1; 09210 } 09211 09212 return -1; 09213 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4150 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04151 { 04152 int x; 04153 int len = strlen(name); 04154 char *r; 04155 04156 for (x = 0; x < req->lines; x++) { 04157 r = get_body_by_line(req->line[x], name, len); 04158 if (r[0] != '\0') 04159 return r; 04160 } 04161 04162 return ""; 04163 }
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 4116 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04117 { 04118 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04119 return ast_skip_blanks(line + nameLen + 1); 04120 04121 return ""; 04122 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9267 of file chan_sip.c.
Referenced by check_user_full().
09268 { 09269 const char *end = strchr(input,'<'); /* first_bracket */ 09270 const char *tmp = strchr(input,'"'); /* first quote */ 09271 int bytes = 0; 09272 int maxbytes = outputsize - 1; 09273 09274 if (!end || end == input) /* we require a part in brackets */ 09275 return NULL; 09276 09277 end--; /* move just before "<" */ 09278 09279 if (tmp && tmp <= end) { 09280 /* The quote (tmp) precedes the bracket (end+1). 09281 * Find the matching quote and return the content. 09282 */ 09283 end = strchr(tmp+1, '"'); 09284 if (!end) 09285 return NULL; 09286 bytes = (int) (end - tmp); 09287 /* protect the output buffer */ 09288 if (bytes > maxbytes) 09289 bytes = maxbytes; 09290 ast_copy_string(output, tmp + 1, bytes); 09291 } else { 09292 /* No quoted string, or it is inside brackets. */ 09293 /* clear the empty characters in the begining*/ 09294 input = ast_skip_blanks(input); 09295 /* clear the empty characters in the end */ 09296 while(*end && *end < 33 && end > input) 09297 end--; 09298 if (end >= input) { 09299 bytes = (int) (end - input) + 2; 09300 /* protect the output buffer */ 09301 if (bytes > maxbytes) 09302 bytes = maxbytes; 09303 ast_copy_string(output, input, bytes); 09304 } else 09305 return NULL; 09306 } 09307 return output; 09308 }
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 8810 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), domain::context, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, strsep(), and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08811 { 08812 char tmp[256] = "", *uri, *a; 08813 char tmpf[256] = "", *from; 08814 struct sip_request *req; 08815 char *colon; 08816 08817 req = oreq; 08818 if (!req) 08819 req = &p->initreq; 08820 08821 /* Find the request URI */ 08822 if (req->rlPart2) 08823 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08824 08825 if (pedanticsipchecking) 08826 ast_uri_decode(tmp); 08827 08828 uri = get_in_brackets(tmp); 08829 08830 if (strncasecmp(uri, "sip:", 4)) { 08831 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08832 return -1; 08833 } 08834 uri += 4; 08835 08836 /* Now find the From: caller ID and name */ 08837 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08838 if (!ast_strlen_zero(tmpf)) { 08839 if (pedanticsipchecking) 08840 ast_uri_decode(tmpf); 08841 from = get_in_brackets(tmpf); 08842 } else { 08843 from = NULL; 08844 } 08845 08846 if (!ast_strlen_zero(from)) { 08847 if (strncasecmp(from, "sip:", 4)) { 08848 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08849 return -1; 08850 } 08851 from += 4; 08852 if ((a = strchr(from, '@'))) 08853 *a++ = '\0'; 08854 else 08855 a = from; /* just a domain */ 08856 from = strsep(&from, ";"); /* Remove userinfo options */ 08857 a = strsep(&a, ";"); /* Remove URI options */ 08858 ast_string_field_set(p, fromdomain, a); 08859 } 08860 08861 /* Skip any options and find the domain */ 08862 08863 /* Get the target domain */ 08864 if ((a = strchr(uri, '@'))) { 08865 *a++ = '\0'; 08866 } else { /* No username part */ 08867 a = uri; 08868 uri = "s"; /* Set extension to "s" */ 08869 } 08870 colon = strchr(a, ':'); /* Remove :port */ 08871 if (colon) 08872 *colon = '\0'; 08873 08874 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08875 a = strsep(&a, ";"); /* Remove URI options */ 08876 08877 ast_string_field_set(p, domain, a); 08878 08879 if (!AST_LIST_EMPTY(&domain_list)) { 08880 char domain_context[AST_MAX_EXTENSION]; 08881 08882 domain_context[0] = '\0'; 08883 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08884 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08885 if (option_debug) 08886 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08887 return -2; 08888 } 08889 } 08890 /* If we have a context defined, overwrite the original context */ 08891 if (!ast_strlen_zero(domain_context)) 08892 ast_string_field_set(p, context, domain_context); 08893 } 08894 08895 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 08896 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 08897 ast_string_field_set(p, context, p->subscribecontext); 08898 08899 if (sip_debug_test_pvt(p)) 08900 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08901 08902 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 08903 if (req->method == SIP_SUBSCRIBE) { 08904 char hint[AST_MAX_EXTENSION]; 08905 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 08906 } else { 08907 /* Check the dialplan for the username part of the request URI, 08908 the domain will be stored in the SIPDOMAIN variable 08909 Since extensions.conf can have unescaped characters, try matching a decoded 08910 uri in addition to the non-decoded uri 08911 Return 0 if we have a matching extension */ 08912 char *decoded_uri = ast_strdupa(uri); 08913 ast_uri_decode(decoded_uri); 08914 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)) || 08915 !strcmp(uri, ast_pickup_ext())) { 08916 if (!oreq) 08917 ast_string_field_set(p, exten, uri); 08918 return 0; 08919 } 08920 } 08921 08922 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08923 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08924 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 08925 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08926 return 1; 08927 } 08928 08929 return -1; 08930 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4239 of file chan_sip.c.
References __get_header().
04240 { 04241 int start = 0; 04242 return __get_header(req, name, &start); 04243 }
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 2316 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().
02317 { 02318 const char *parse = tmp; 02319 char *first_bracket; 02320 02321 /* 02322 * Skip any quoted text until we find the part in brackets. 02323 * On any error give up and return the full string. 02324 */ 02325 while ( (first_bracket = strchr(parse, '<')) ) { 02326 char *first_quote = strchr(parse, '"'); 02327 02328 if (!first_quote || first_quote > first_bracket) 02329 break; /* no need to look at quoted part */ 02330 /* the bracket is within quotes, so ignore it */ 02331 parse = find_closing_quote(first_quote + 1, NULL); 02332 if (!*parse) { /* not found, return full string ? */ 02333 /* XXX or be robust and return in-bracket part ? */ 02334 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02335 break; 02336 } 02337 parse++; 02338 } 02339 if (first_bracket) { 02340 char *second_bracket = strchr(first_bracket + 1, '>'); 02341 if (second_bracket) { 02342 *second_bracket = '\0'; 02343 tmp = first_bracket + 1; 02344 } else { 02345 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02346 } 02347 } 02348 return tmp; 02349 }
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 9672 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09673 { 09674 int x; 09675 int y; 09676 09677 buf[0] = '\0'; 09678 y = len - strlen(buf) - 5; 09679 if (y < 0) 09680 y = 0; 09681 for (x=0;x<req->lines;x++) { 09682 strncat(buf, req->line[x], y); /* safe */ 09683 y -= strlen(req->line[x]) + 1; 09684 if (y < 0) 09685 y = 0; 09686 if (y != 0) 09687 strcat(buf, "\n"); /* safe */ 09688 } 09689 return 0; 09690 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8781 of file chan_sip.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08782 { 08783 char tmp[256], *c, *a; 08784 struct sip_request *req; 08785 08786 req = oreq; 08787 if (!req) 08788 req = &p->initreq; 08789 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08790 if (ast_strlen_zero(tmp)) 08791 return 0; 08792 c = get_in_brackets(tmp); 08793 if (strncasecmp(c, "sip:", 4)) { 08794 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08795 return -1; 08796 } 08797 c += 4; 08798 a = c; 08799 strsep(&a, "@;"); /* trim anything after @ or ; */ 08800 if (sip_debug_test_pvt(p)) 08801 ast_verbose("RDNIS is %s\n", c); 08802 ast_string_field_set(p, rdnis, c); 08803 08804 return 0; 08805 }
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 8989 of file chan_sip.c.
References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
08990 { 08991 08992 const char *p_referred_by = NULL; 08993 char *h_refer_to = NULL; 08994 char *h_referred_by = NULL; 08995 char *refer_to; 08996 const char *p_refer_to; 08997 char *referred_by_uri = NULL; 08998 char *ptr; 08999 struct sip_request *req = NULL; 09000 const char *transfer_context = NULL; 09001 struct sip_refer *referdata; 09002 09003 09004 req = outgoing_req; 09005 referdata = transferer->refer; 09006 09007 if (!req) 09008 req = &transferer->initreq; 09009 09010 p_refer_to = get_header(req, "Refer-To"); 09011 if (ast_strlen_zero(p_refer_to)) { 09012 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09013 return -2; /* Syntax error */ 09014 } 09015 h_refer_to = ast_strdupa(p_refer_to); 09016 refer_to = get_in_brackets(h_refer_to); 09017 if (pedanticsipchecking) 09018 ast_uri_decode(refer_to); 09019 09020 if (strncasecmp(refer_to, "sip:", 4)) { 09021 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09022 return -3; 09023 } 09024 refer_to += 4; /* Skip sip: */ 09025 09026 /* Get referred by header if it exists */ 09027 p_referred_by = get_header(req, "Referred-By"); 09028 if (!ast_strlen_zero(p_referred_by)) { 09029 char *lessthan; 09030 h_referred_by = ast_strdupa(p_referred_by); 09031 if (pedanticsipchecking) 09032 ast_uri_decode(h_referred_by); 09033 09034 /* Store referrer's caller ID name */ 09035 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09036 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09037 *(lessthan - 1) = '\0'; /* Space */ 09038 } 09039 09040 referred_by_uri = get_in_brackets(h_referred_by); 09041 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09042 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09043 referred_by_uri = (char *) NULL; 09044 } else { 09045 referred_by_uri += 4; /* Skip sip: */ 09046 } 09047 } 09048 09049 /* Check for arguments in the refer_to header */ 09050 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09051 *ptr++ = '\0'; 09052 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09053 char *to = NULL, *from = NULL; 09054 09055 /* This is an attended transfer */ 09056 referdata->attendedtransfer = 1; 09057 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09058 ast_uri_decode(referdata->replaces_callid); 09059 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09060 *ptr++ = '\0'; 09061 } 09062 09063 if (ptr) { 09064 /* Find the different tags before we destroy the string */ 09065 to = strcasestr(ptr, "to-tag="); 09066 from = strcasestr(ptr, "from-tag="); 09067 } 09068 09069 /* Grab the to header */ 09070 if (to) { 09071 ptr = to + 7; 09072 if ((to = strchr(ptr, '&'))) 09073 *to = '\0'; 09074 if ((to = strchr(ptr, ';'))) 09075 *to = '\0'; 09076 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09077 } 09078 09079 if (from) { 09080 ptr = from + 9; 09081 if ((to = strchr(ptr, '&'))) 09082 *to = '\0'; 09083 if ((to = strchr(ptr, ';'))) 09084 *to = '\0'; 09085 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09086 } 09087 09088 if (option_debug > 1) { 09089 if (!pedanticsipchecking) 09090 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09091 else 09092 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>" ); 09093 } 09094 } 09095 } 09096 09097 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09098 char *urioption = NULL, *domain; 09099 *ptr++ = '\0'; 09100 09101 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09102 *urioption++ = '\0'; 09103 09104 domain = ptr; 09105 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09106 *ptr = '\0'; 09107 09108 /* Save the domain for the dial plan */ 09109 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09110 if (urioption) 09111 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09112 } 09113 09114 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09115 *ptr = '\0'; 09116 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09117 09118 if (referred_by_uri) { 09119 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09120 *ptr = '\0'; 09121 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09122 } else { 09123 referdata->referred_by[0] = '\0'; 09124 } 09125 09126 /* Determine transfer context */ 09127 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09128 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09129 09130 /* By default, use the context in the channel sending the REFER */ 09131 if (ast_strlen_zero(transfer_context)) { 09132 transfer_context = S_OR(transferer->owner->macrocontext, 09133 S_OR(transferer->context, default_context)); 09134 } 09135 09136 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09137 09138 /* Either an existing extension or the parking extension */ 09139 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09140 if (sip_debug_test_pvt(transferer)) { 09141 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09142 } 09143 /* We are ready to transfer to the extension */ 09144 return 0; 09145 } 09146 if (sip_debug_test_pvt(transferer)) 09147 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09148 09149 /* Failure, we can't find this extension */ 09150 return -1; 09151 }
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 9314 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09315 { 09316 char *start; 09317 char *end; 09318 09319 start = strchr(input,':'); 09320 if (!start) { 09321 output[0] = '\0'; 09322 return 0; 09323 } 09324 start++; 09325 09326 /* we found "number" */ 09327 ast_copy_string(output,start,maxlen); 09328 output[maxlen-1] = '\0'; 09329 09330 end = strchr(output,'@'); 09331 if (end) 09332 *end = '\0'; 09333 else 09334 output[0] = '\0'; 09335 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09336 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09337 09338 return 0; 09339 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4142 of file chan_sip.c.
References get_sdp_iterate().
04143 { 04144 int dummy = 0; 04145 04146 return get_sdp_iterate(&dummy, req, name); 04147 }
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 4128 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04129 { 04130 int len = strlen(name); 04131 04132 while (*start < req->sdp_end) { 04133 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04134 if (r[0] != '\0') 04135 return r; 04136 } 04137 04138 return ""; 04139 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static, read] |
Lock interface lock and find matching pvt lock
Definition at line 8937 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().
08938 { 08939 struct sip_pvt *sip_pvt_ptr; 08940 08941 ast_mutex_lock(&iflock); 08942 08943 if (option_debug > 3 && totag) 08944 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08945 08946 /* Search interfaces and find the match */ 08947 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08948 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08949 int match = 1; 08950 char *ourtag = sip_pvt_ptr->tag; 08951 08952 /* Go ahead and lock it (and its owner) before returning */ 08953 ast_mutex_lock(&sip_pvt_ptr->lock); 08954 08955 /* Check if tags match. If not, this is not the call we want 08956 (With a forking SIP proxy, several call legs share the 08957 call id, but have different tags) 08958 */ 08959 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 08960 match = 0; 08961 08962 if (!match) { 08963 ast_mutex_unlock(&sip_pvt_ptr->lock); 08964 continue; 08965 } 08966 08967 if (option_debug > 3 && totag) 08968 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08969 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08970 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08971 08972 /* deadlock avoidance... */ 08973 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08974 ast_mutex_unlock(&sip_pvt_ptr->lock); 08975 usleep(1); 08976 ast_mutex_lock(&sip_pvt_ptr->lock); 08977 } 08978 break; 08979 } 08980 } 08981 ast_mutex_unlock(&iflock); 08982 if (option_debug > 3 && !sip_pvt_ptr) 08983 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08984 return sip_pvt_ptr; 08985 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13336 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
13337 { 13338 const char *thetag; 13339 13340 if (!tagbuf) 13341 return NULL; 13342 tagbuf[0] = '\0'; /* reset the buffer */ 13343 thetag = get_header(req, header); 13344 thetag = strcasestr(thetag, ";tag="); 13345 if (thetag) { 13346 thetag += 5; 13347 ast_copy_string(tagbuf, thetag, tagbufsize); 13348 return strsep(&tagbuf, ";"); 13349 } 13350 return NULL; 13351 }
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 16086 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
16087 { 16088 int res = 1; 16089 16090 if (!strcasecmp(v->name, "trustrpid")) { 16091 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16092 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16093 } else if (!strcasecmp(v->name, "sendrpid")) { 16094 ast_set_flag(&mask[0], SIP_SENDRPID); 16095 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16096 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16097 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16098 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16099 } else if (!strcasecmp(v->name, "useclientcode")) { 16100 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16101 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16102 } else if (!strcasecmp(v->name, "dtmfmode")) { 16103 ast_set_flag(&mask[0], SIP_DTMF); 16104 ast_clear_flag(&flags[0], SIP_DTMF); 16105 if (!strcasecmp(v->value, "inband")) 16106 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16107 else if (!strcasecmp(v->value, "rfc2833")) 16108 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16109 else if (!strcasecmp(v->value, "info")) 16110 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16111 else if (!strcasecmp(v->value, "auto")) 16112 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16113 else { 16114 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16115 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16116 } 16117 } else if (!strcasecmp(v->name, "nat")) { 16118 ast_set_flag(&mask[0], SIP_NAT); 16119 ast_clear_flag(&flags[0], SIP_NAT); 16120 if (!strcasecmp(v->value, "never")) 16121 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16122 else if (!strcasecmp(v->value, "route")) 16123 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16124 else if (ast_true(v->value)) 16125 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16126 else 16127 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16128 } else if (!strcasecmp(v->name, "canreinvite")) { 16129 ast_set_flag(&mask[0], SIP_REINVITE); 16130 ast_clear_flag(&flags[0], SIP_REINVITE); 16131 if(ast_true(v->value)) { 16132 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16133 } else if (!ast_false(v->value)) { 16134 char buf[64]; 16135 char *word, *next = buf; 16136 16137 ast_copy_string(buf, v->value, sizeof(buf)); 16138 while ((word = strsep(&next, ","))) { 16139 if(!strcasecmp(word, "update")) { 16140 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16141 } else if(!strcasecmp(word, "nonat")) { 16142 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16143 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16144 } else { 16145 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16146 } 16147 } 16148 } 16149 } else if (!strcasecmp(v->name, "insecure")) { 16150 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16151 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16152 set_insecure_flags(flags, v->value, v->lineno); 16153 } else if (!strcasecmp(v->name, "progressinband")) { 16154 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16155 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16156 if (ast_true(v->value)) 16157 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16158 else if (strcasecmp(v->value, "never")) 16159 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16160 } else if (!strcasecmp(v->name, "promiscredir")) { 16161 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16162 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16163 } else if (!strcasecmp(v->name, "videosupport")) { 16164 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16165 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16166 } else if (!strcasecmp(v->name, "allowoverlap")) { 16167 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16168 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16169 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16170 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16171 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16172 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16173 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16174 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16175 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16176 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16177 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16178 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16179 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16180 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16181 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16182 #endif 16183 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16184 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16185 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16186 } else if (!strcasecmp(v->name, "buggymwi")) { 16187 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16188 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16189 } else 16190 res = 0; 16191 16192 return res; 16193 }
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 13515 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13516 { 13517 struct ast_frame *f; 13518 int earlyreplace = 0; 13519 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13520 struct ast_channel *c = p->owner; /* Our incoming call */ 13521 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13522 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13523 13524 /* Check if we're in ring state */ 13525 if (replacecall->_state == AST_STATE_RING) 13526 earlyreplace = 1; 13527 13528 /* Check if we have a bridge */ 13529 if (!(targetcall = ast_bridged_channel(replacecall))) { 13530 /* We have no bridge */ 13531 if (!earlyreplace) { 13532 if (option_debug > 1) 13533 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13534 oneleggedreplace = 1; 13535 } 13536 } 13537 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13538 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13539 13540 if (option_debug > 3) { 13541 if (targetcall) 13542 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); 13543 else 13544 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13545 } 13546 13547 if (ignore) { 13548 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13549 /* We should answer something here. If we are here, the 13550 call we are replacing exists, so an accepted 13551 can't harm */ 13552 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13553 /* Do something more clever here */ 13554 ast_channel_unlock(c); 13555 ast_mutex_unlock(&p->refer->refer_call->lock); 13556 return 1; 13557 } 13558 if (!c) { 13559 /* What to do if no channel ??? */ 13560 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13561 transmit_response_reliable(p, "503 Service Unavailable", req); 13562 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13563 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13564 ast_mutex_unlock(&p->refer->refer_call->lock); 13565 return 1; 13566 } 13567 append_history(p, "Xfer", "INVITE/Replace received"); 13568 /* We have three channels to play with 13569 channel c: New incoming call 13570 targetcall: Call from PBX to target 13571 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13572 replacecall: The owner of the previous 13573 We need to masq C into refer_call to connect to 13574 targetcall; 13575 If we are talking to internal audio stream, target call is null. 13576 */ 13577 13578 /* Fake call progress */ 13579 transmit_response(p, "100 Trying", req); 13580 ast_setstate(c, AST_STATE_RING); 13581 13582 /* Masquerade the new call into the referred call to connect to target call 13583 Targetcall is not touched by the masq */ 13584 13585 /* Answer the incoming call and set channel to UP state */ 13586 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13587 13588 ast_setstate(c, AST_STATE_UP); 13589 13590 /* Stop music on hold and other generators */ 13591 ast_quiet_chan(replacecall); 13592 ast_quiet_chan(targetcall); 13593 if (option_debug > 3) 13594 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13595 /* Unlock clone, but not original (replacecall) */ 13596 if (!oneleggedreplace) 13597 ast_channel_unlock(c); 13598 13599 /* Unlock PVT */ 13600 ast_mutex_unlock(&p->refer->refer_call->lock); 13601 13602 /* Make sure that the masq does not free our PVT for the old call */ 13603 if (! earlyreplace && ! oneleggedreplace ) 13604 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13605 13606 /* Prepare the masquerade - if this does not happen, we will be gone */ 13607 if(ast_channel_masquerade(replacecall, c)) 13608 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13609 else if (option_debug > 3) 13610 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13611 13612 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13613 13614 /* C should now be in place of replacecall */ 13615 /* ast_read needs to lock channel */ 13616 ast_channel_unlock(c); 13617 13618 if (earlyreplace || oneleggedreplace ) { 13619 /* Force the masq to happen */ 13620 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13621 ast_frfree(f); 13622 f = NULL; 13623 if (option_debug > 3) 13624 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13625 } else { 13626 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13627 } 13628 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13629 if (!oneleggedreplace) 13630 ast_channel_unlock(replacecall); 13631 } else { /* Bridged call, UP channel */ 13632 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13633 /* Masq ok */ 13634 ast_frfree(f); 13635 f = NULL; 13636 if (option_debug > 2) 13637 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13638 } else { 13639 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13640 } 13641 ast_channel_unlock(replacecall); 13642 } 13643 ast_mutex_unlock(&p->refer->refer_call->lock); 13644 13645 ast_setstate(c, AST_STATE_DOWN); 13646 if (option_debug > 3) { 13647 struct ast_channel *test; 13648 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13649 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13650 if (replacecall) 13651 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13652 if (p->owner) { 13653 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13654 test = ast_bridged_channel(p->owner); 13655 if (test) 13656 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13657 else 13658 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13659 } else 13660 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13661 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13662 } 13663 13664 ast_channel_unlock(p->owner); /* Unlock new owner */ 13665 if (!oneleggedreplace) 13666 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13667 13668 /* The call should be down with no ast_channel, so hang it up */ 13669 c->tech_pvt = NULL; 13670 ast_hangup(c); 13671 return 0; 13672 }
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 15173 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, sip_pvt::lastnoninvite, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
15174 { 15175 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15176 relatively static */ 15177 const char *cmd; 15178 const char *cseq; 15179 const char *useragent; 15180 int seqno; 15181 int len; 15182 int ignore = FALSE; 15183 int respid; 15184 int res = 0; 15185 int debug = sip_debug_test_pvt(p); 15186 char *e; 15187 int error = 0; 15188 15189 /* Get Method and Cseq */ 15190 cseq = get_header(req, "Cseq"); 15191 cmd = req->header[0]; 15192 15193 /* Must have Cseq */ 15194 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15195 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15196 error = 1; 15197 } 15198 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15199 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15200 error = 1; 15201 } 15202 if (error) { 15203 if (!p->initreq.headers) /* New call */ 15204 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15205 return -1; 15206 } 15207 /* Get the command XXX */ 15208 15209 cmd = req->rlPart1; 15210 e = req->rlPart2; 15211 15212 /* Save useragent of the client */ 15213 useragent = get_header(req, "User-Agent"); 15214 if (!ast_strlen_zero(useragent)) 15215 ast_string_field_set(p, useragent, useragent); 15216 15217 /* Find out SIP method for incoming request */ 15218 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15219 /* Response to our request -- Do some sanity checks */ 15220 if (!p->initreq.headers) { 15221 if (option_debug) 15222 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15223 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15224 return 0; 15225 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15226 if (option_debug) 15227 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15228 return -1; 15229 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15230 /* ignore means "don't do anything with it" but still have to 15231 respond appropriately */ 15232 ignore = TRUE; 15233 ast_set_flag(req, SIP_PKT_IGNORE); 15234 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15235 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15236 } else if (e) { 15237 e = ast_skip_blanks(e); 15238 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15239 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15240 } else { 15241 if (respid <= 0) { 15242 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15243 return 0; 15244 } 15245 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15246 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15247 extract_uri(p, req); 15248 handle_response(p, respid, e + len, req, ignore, seqno); 15249 } 15250 } 15251 return 0; 15252 } 15253 15254 /* New SIP request coming in 15255 (could be new request in existing SIP dialog as well...) 15256 */ 15257 15258 p->method = req->method; /* Find out which SIP method they are using */ 15259 if (option_debug > 3) 15260 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15261 15262 if (p->icseq && (p->icseq > seqno)) { 15263 if (option_debug) 15264 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15265 if (req->method != SIP_ACK) 15266 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15267 return -1; 15268 } else if (p->icseq && 15269 p->icseq == seqno && 15270 req->method != SIP_ACK && 15271 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15272 /* ignore means "don't do anything with it" but still have to 15273 respond appropriately. We do this if we receive a repeat of 15274 the last sequence number */ 15275 ignore = 2; 15276 ast_set_flag(req, SIP_PKT_IGNORE); 15277 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15278 if (option_debug > 2) 15279 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15280 } 15281 15282 if (seqno >= p->icseq) 15283 /* Next should follow monotonically (but not necessarily 15284 incrementally -- thanks again to the genius authors of SIP -- 15285 increasing */ 15286 p->icseq = seqno; 15287 15288 /* Find their tag if we haven't got it */ 15289 if (ast_strlen_zero(p->theirtag)) { 15290 char tag[128]; 15291 15292 gettag(req, "From", tag, sizeof(tag)); 15293 ast_string_field_set(p, theirtag, tag); 15294 } 15295 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15296 15297 if (pedanticsipchecking) { 15298 /* If this is a request packet without a from tag, it's not 15299 correct according to RFC 3261 */ 15300 /* Check if this a new request in a new dialog with a totag already attached to it, 15301 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15302 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15303 /* If this is a first request and it got a to-tag, it is not for us */ 15304 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15305 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15306 /* Will cease to exist after ACK */ 15307 } else if (req->method != SIP_ACK) { 15308 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15309 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15310 } 15311 return res; 15312 } 15313 } 15314 15315 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15316 transmit_response(p, "400 Bad request", req); 15317 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15318 return -1; 15319 } 15320 15321 /* Handle various incoming SIP methods in requests */ 15322 switch (p->method) { 15323 case SIP_OPTIONS: 15324 res = handle_request_options(p, req); 15325 break; 15326 case SIP_INVITE: 15327 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15328 break; 15329 case SIP_REFER: 15330 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15331 break; 15332 case SIP_CANCEL: 15333 res = handle_request_cancel(p, req); 15334 break; 15335 case SIP_BYE: 15336 res = handle_request_bye(p, req); 15337 break; 15338 case SIP_MESSAGE: 15339 res = handle_request_message(p, req); 15340 break; 15341 case SIP_SUBSCRIBE: 15342 res = handle_request_subscribe(p, req, sin, seqno, e); 15343 break; 15344 case SIP_REGISTER: 15345 res = handle_request_register(p, req, sin, e); 15346 break; 15347 case SIP_INFO: 15348 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15349 ast_verbose("Receiving INFO!\n"); 15350 if (!ignore) 15351 handle_request_info(p, req); 15352 else /* if ignoring, transmit response */ 15353 transmit_response(p, "200 OK", req); 15354 break; 15355 case SIP_NOTIFY: 15356 res = handle_request_notify(p, req, sin, seqno, e); 15357 break; 15358 case SIP_ACK: 15359 /* Make sure we don't ignore this */ 15360 if (seqno == p->pendinginvite) { 15361 p->invitestate = INV_TERMINATED; 15362 p->pendinginvite = 0; 15363 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15364 if (find_sdp(req)) { 15365 if (process_sdp(p, req)) 15366 return -1; 15367 } 15368 check_pendings(p); 15369 } 15370 /* Got an ACK that we did not match. Ignore silently */ 15371 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15372 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15373 break; 15374 default: 15375 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15376 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15377 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15378 /* If this is some new method, and we don't have a call, destroy it now */ 15379 if (!p->initreq.headers) 15380 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15381 break; 15382 } 15383 return res; 15384 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14750 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
14751 { 14752 struct ast_channel *c=NULL; 14753 int res; 14754 struct ast_channel *bridged_to; 14755 14756 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14757 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14758 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14759 14760 p->invitestate = INV_TERMINATED; 14761 14762 copy_request(&p->initreq, req); 14763 check_via(p, req); 14764 sip_alreadygone(p); 14765 14766 /* Get RTCP quality before end of call */ 14767 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14768 char *audioqos, *videoqos; 14769 if (p->rtp) { 14770 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14771 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14772 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14773 if (p->owner) 14774 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14775 } 14776 if (p->vrtp) { 14777 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14778 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14779 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14780 if (p->owner) 14781 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14782 } 14783 } 14784 14785 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14786 14787 if (!ast_strlen_zero(get_header(req, "Also"))) { 14788 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14789 ast_inet_ntoa(p->recv.sin_addr)); 14790 if (ast_strlen_zero(p->context)) 14791 ast_string_field_set(p, context, default_context); 14792 res = get_also_info(p, req); 14793 if (!res) { 14794 c = p->owner; 14795 if (c) { 14796 bridged_to = ast_bridged_channel(c); 14797 if (bridged_to) { 14798 /* Don't actually hangup here... */ 14799 ast_queue_control(c, AST_CONTROL_UNHOLD); 14800 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14801 } else 14802 ast_queue_hangup(p->owner); 14803 } 14804 } else { 14805 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14806 if (p->owner) 14807 ast_queue_hangup(p->owner); 14808 } 14809 } else if (p->owner) { 14810 ast_queue_hangup(p->owner); 14811 if (option_debug > 2) 14812 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14813 } else { 14814 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14815 if (option_debug > 2) 14816 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14817 } 14818 transmit_response(p, "200 OK", req); 14819 14820 return 1; 14821 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14643 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::initreq, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
14644 { 14645 14646 check_via(p, req); 14647 sip_alreadygone(p); 14648 14649 /* At this point, we could have cancelled the invite at the same time 14650 as the other side sends a CANCEL. Our final reply with error code 14651 might not have been received by the other side before the CANCEL 14652 was sent, so let's just give up retransmissions and waiting for 14653 ACK on our error code. The call is hanging up any way. */ 14654 if (p->invitestate == INV_TERMINATED) 14655 __sip_pretend_ack(p); 14656 else 14657 p->invitestate = INV_CANCELLED; 14658 14659 if (p->owner && p->owner->_state == AST_STATE_UP) { 14660 /* This call is up, cancel is ignored, we need a bye */ 14661 transmit_response(p, "200 OK", req); 14662 if (option_debug) 14663 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14664 return 0; 14665 } 14666 14667 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14668 update_call_counter(p, DEC_CALL_LIMIT); 14669 14670 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14671 14672 if (p->owner) 14673 ast_queue_hangup(p->owner); 14674 else 14675 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14676 if (p->initreq.len > 0) { 14677 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14678 transmit_response(p, "200 OK", req); 14679 return 1; 14680 } else { 14681 transmit_response(p, "481 Call Leg Does Not Exist", req); 14682 return 0; 14683 } 14684 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11141 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().
Referenced by handle_request().
11142 { 11143 char buf[1024]; 11144 unsigned int event; 11145 const char *c = get_header(req, "Content-Type"); 11146 11147 /* Need to check the media/type */ 11148 if (!strcasecmp(c, "application/dtmf-relay") || 11149 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11150 unsigned int duration = 0; 11151 11152 /* Try getting the "signal=" part */ 11153 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11154 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11155 transmit_response(p, "200 OK", req); /* Should return error */ 11156 return; 11157 } else { 11158 ast_copy_string(buf, c, sizeof(buf)); 11159 } 11160 11161 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11162 duration = atoi(c); 11163 if (!duration) 11164 duration = 100; /* 100 ms */ 11165 11166 if (!p->owner) { /* not a PBX call */ 11167 transmit_response(p, "481 Call leg/transaction does not exist", req); 11168 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11169 return; 11170 } 11171 11172 if (ast_strlen_zero(buf)) { 11173 transmit_response(p, "200 OK", req); 11174 return; 11175 } 11176 11177 if (buf[0] == '*') 11178 event = 10; 11179 else if (buf[0] == '#') 11180 event = 11; 11181 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11182 event = 12 + buf[0] - 'A'; 11183 else 11184 event = atoi(buf); 11185 if (event == 16) { 11186 /* send a FLASH event */ 11187 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11188 ast_queue_frame(p->owner, &f); 11189 if (sipdebug) 11190 ast_verbose("* DTMF-relay event received: FLASH\n"); 11191 } else { 11192 /* send a DTMF event */ 11193 struct ast_frame f = { AST_FRAME_DTMF, }; 11194 if (event < 10) { 11195 f.subclass = '0' + event; 11196 } else if (event < 11) { 11197 f.subclass = '*'; 11198 } else if (event < 12) { 11199 f.subclass = '#'; 11200 } else if (event < 16) { 11201 f.subclass = 'A' + (event - 12); 11202 } 11203 f.len = duration; 11204 ast_queue_frame(p->owner, &f); 11205 if (sipdebug) 11206 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11207 } 11208 transmit_response(p, "200 OK", req); 11209 return; 11210 } else if (!strcasecmp(c, "application/media_control+xml")) { 11211 /* Eh, we'll just assume it's a fast picture update for now */ 11212 if (p->owner) 11213 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11214 transmit_response(p, "200 OK", req); 11215 return; 11216 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11217 /* Client code (from SNOM phone) */ 11218 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11219 if (p->owner && p->owner->cdr) 11220 ast_cdr_setuserfield(p->owner, c); 11221 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11222 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11223 transmit_response(p, "200 OK", req); 11224 } else { 11225 transmit_response(p, "403 Unauthorized", req); 11226 } 11227 return; 11228 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11229 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11230 transmit_response(p, "200 OK", req); 11231 return; 11232 } 11233 11234 /* Other type of INFO message, not really understood by Asterisk */ 11235 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11236 11237 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11238 transmit_response(p, "415 Unsupported media type", req); 11239 return; 11240 }
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 13681 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, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
13682 { 13683 int res = 1; 13684 int gotdest; 13685 const char *p_replaces; 13686 char *replace_id = NULL; 13687 const char *required; 13688 unsigned int required_profile = 0; 13689 struct ast_channel *c = NULL; /* New channel */ 13690 int reinvite = 0; 13691 13692 /* Find out what they support */ 13693 if (!p->sipoptions) { 13694 const char *supported = get_header(req, "Supported"); 13695 if (!ast_strlen_zero(supported)) 13696 parse_sip_options(p, supported); 13697 } 13698 13699 /* Find out what they require */ 13700 required = get_header(req, "Require"); 13701 if (!ast_strlen_zero(required)) { 13702 required_profile = parse_sip_options(NULL, required); 13703 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13704 /* At this point we only support REPLACES */ 13705 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13706 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13707 p->invitestate = INV_COMPLETED; 13708 if (!p->lastinvite) 13709 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13710 return -1; 13711 } 13712 } 13713 13714 /* Check if this is a loop */ 13715 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13716 /* This is a call to ourself. Send ourselves an error code and stop 13717 processing immediately, as SIP really has no good mechanism for 13718 being able to call yourself */ 13719 /* If pedantic is on, we need to check the tags. If they're different, this is 13720 in fact a forked call through a SIP proxy somewhere. */ 13721 transmit_response(p, "482 Loop Detected", req); 13722 p->invitestate = INV_COMPLETED; 13723 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13724 return 0; 13725 } 13726 13727 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13728 /* We already have a pending invite. Sorry. You are on hold. */ 13729 transmit_response(p, "491 Request Pending", req); 13730 if (option_debug) 13731 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13732 /* Don't destroy dialog here */ 13733 return 0; 13734 } 13735 13736 p_replaces = get_header(req, "Replaces"); 13737 if (!ast_strlen_zero(p_replaces)) { 13738 /* We have a replaces header */ 13739 char *ptr; 13740 char *fromtag = NULL; 13741 char *totag = NULL; 13742 char *start, *to; 13743 int error = 0; 13744 13745 if (p->owner) { 13746 if (option_debug > 2) 13747 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13748 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13749 /* Do not destroy existing call */ 13750 return -1; 13751 } 13752 13753 if (sipdebug && option_debug > 2) 13754 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13755 /* Create a buffer we can manipulate */ 13756 replace_id = ast_strdupa(p_replaces); 13757 ast_uri_decode(replace_id); 13758 13759 if (!p->refer && !sip_refer_allocate(p)) { 13760 transmit_response(p, "500 Server Internal Error", req); 13761 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13762 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13763 p->invitestate = INV_COMPLETED; 13764 return -1; 13765 } 13766 13767 /* Todo: (When we find phones that support this) 13768 if the replaces header contains ";early-only" 13769 we can only replace the call in early 13770 stage, not after it's up. 13771 13772 If it's not in early mode, 486 Busy. 13773 */ 13774 13775 /* Skip leading whitespace */ 13776 replace_id = ast_skip_blanks(replace_id); 13777 13778 start = replace_id; 13779 while ( (ptr = strsep(&start, ";")) ) { 13780 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13781 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13782 totag = to + 7; /* skip the keyword */ 13783 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13784 fromtag = to + 9; /* skip the keyword */ 13785 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13786 } 13787 } 13788 13789 if (sipdebug && option_debug > 3) 13790 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>"); 13791 13792 13793 /* Try to find call that we are replacing 13794 If we have a Replaces header, we need to cancel that call if we succeed with this call 13795 */ 13796 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13797 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13798 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13799 error = 1; 13800 } 13801 13802 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13803 13804 /* The matched call is the call from the transferer to Asterisk . 13805 We want to bridge the bridged part of the call to the 13806 incoming invite, thus taking over the refered call */ 13807 13808 if (p->refer->refer_call == p) { 13809 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13810 p->refer->refer_call = NULL; 13811 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13812 error = 1; 13813 } 13814 13815 if (!error && !p->refer->refer_call->owner) { 13816 /* Oops, someting wrong anyway, no owner, no call */ 13817 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13818 /* Check for better return code */ 13819 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13820 error = 1; 13821 } 13822 13823 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 ) { 13824 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13825 transmit_response(p, "603 Declined (Replaces)", req); 13826 error = 1; 13827 } 13828 13829 if (error) { /* Give up this dialog */ 13830 append_history(p, "Xfer", "INVITE/Replace Failed."); 13831 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13832 ast_mutex_unlock(&p->lock); 13833 if (p->refer->refer_call) { 13834 ast_mutex_unlock(&p->refer->refer_call->lock); 13835 ast_channel_unlock(p->refer->refer_call->owner); 13836 } 13837 p->invitestate = INV_COMPLETED; 13838 return -1; 13839 } 13840 } 13841 13842 13843 /* Check if this is an INVITE that sets up a new dialog or 13844 a re-invite in an existing dialog */ 13845 13846 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13847 int newcall = (p->initreq.headers ? TRUE : FALSE); 13848 13849 sip_cancel_destroy(p); 13850 /* This also counts as a pending invite */ 13851 p->pendinginvite = seqno; 13852 check_via(p, req); 13853 13854 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13855 if (!p->owner) { /* Not a re-invite */ 13856 if (debug) 13857 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13858 if (newcall) 13859 append_history(p, "Invite", "New call: %s", p->callid); 13860 parse_ok_contact(p, req); 13861 } else { /* Re-invite on existing call */ 13862 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13863 /* Handle SDP here if we already have an owner */ 13864 if (find_sdp(req)) { 13865 if (process_sdp(p, req)) { 13866 transmit_response(p, "488 Not acceptable here", req); 13867 if (!p->lastinvite) 13868 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13869 return -1; 13870 } 13871 } else { 13872 p->jointcapability = p->capability; 13873 if (option_debug > 2) 13874 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13875 /* Some devices signal they want to be put off hold by sending a re-invite 13876 *without* an SDP, which is supposed to mean "Go back to your state" 13877 and since they put os on remote hold, we go back to off hold */ 13878 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13879 change_hold_state(p, req, FALSE, 0); 13880 } 13881 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13882 append_history(p, "ReInv", "Re-invite received"); 13883 } 13884 } else if (debug) 13885 ast_verbose("Ignoring this INVITE request\n"); 13886 13887 13888 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13889 /* This is a new invite */ 13890 /* Handle authentication if this is our first invite */ 13891 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13892 if (res == AUTH_CHALLENGE_SENT) { 13893 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13894 return 0; 13895 } 13896 if (res < 0) { /* Something failed in authentication */ 13897 if (res == AUTH_FAKE_AUTH) { 13898 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13899 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 13900 } else { 13901 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13902 transmit_response_reliable(p, "403 Forbidden", req); 13903 } 13904 p->invitestate = INV_COMPLETED; 13905 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13906 ast_string_field_free(p, theirtag); 13907 return 0; 13908 } 13909 13910 /* We have a succesful authentication, process the SDP portion if there is one */ 13911 if (find_sdp(req)) { 13912 if (process_sdp(p, req)) { 13913 /* Unacceptable codecs */ 13914 transmit_response_reliable(p, "488 Not acceptable here", req); 13915 p->invitestate = INV_COMPLETED; 13916 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13917 if (option_debug) 13918 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13919 return -1; 13920 } 13921 } else { /* No SDP in invite, call control session */ 13922 p->jointcapability = p->capability; 13923 if (option_debug > 1) 13924 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13925 } 13926 13927 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13928 /* This seems redundant ... see !p-owner above */ 13929 if (p->owner) 13930 ast_queue_frame(p->owner, &ast_null_frame); 13931 13932 13933 /* Initialize the context if it hasn't been already */ 13934 if (ast_strlen_zero(p->context)) 13935 ast_string_field_set(p, context, default_context); 13936 13937 13938 /* Check number of concurrent calls -vs- incoming limit HERE */ 13939 if (option_debug) 13940 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13941 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13942 if (res < 0) { 13943 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13944 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13945 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13946 p->invitestate = INV_COMPLETED; 13947 } 13948 return 0; 13949 } 13950 gotdest = get_destination(p, NULL); /* Get destination right away */ 13951 get_rdnis(p, NULL); /* Get redirect information */ 13952 extract_uri(p, req); /* Get the Contact URI */ 13953 build_contact(p); /* Build our contact header */ 13954 13955 if (p->rtp) { 13956 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13957 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13958 } 13959 13960 if (!replace_id && gotdest) { /* No matching extension found */ 13961 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13962 transmit_response_reliable(p, "484 Address Incomplete", req); 13963 else { 13964 transmit_response_reliable(p, "404 Not Found", req); 13965 ast_log(LOG_NOTICE, "Call from '%s' to extension" 13966 " '%s' rejected because extension not found.\n", 13967 S_OR(p->username, p->peername), p->exten); 13968 } 13969 p->invitestate = INV_COMPLETED; 13970 update_call_counter(p, DEC_CALL_LIMIT); 13971 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13972 return 0; 13973 } else { 13974 /* If no extension was specified, use the s one */ 13975 /* Basically for calling to IP/Host name only */ 13976 if (ast_strlen_zero(p->exten)) 13977 ast_string_field_set(p, exten, "s"); 13978 /* Initialize our tag */ 13979 13980 make_our_tag(p->tag, sizeof(p->tag)); 13981 /* First invitation - create the channel */ 13982 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13983 *recount = 1; 13984 13985 /* Save Record-Route for any later requests we make on this dialogue */ 13986 build_route(p, req, 0); 13987 13988 if (c) { 13989 /* Pre-lock the call */ 13990 ast_channel_lock(c); 13991 } 13992 } 13993 } else { 13994 if (option_debug > 1 && sipdebug) { 13995 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13996 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13997 else 13998 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13999 } 14000 reinvite = 1; 14001 c = p->owner; 14002 } 14003 14004 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14005 p->lastinvite = seqno; 14006 14007 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14008 /* Go and take over the target call */ 14009 if (sipdebug && option_debug > 3) 14010 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14011 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14012 } 14013 14014 14015 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14016 switch(c->_state) { 14017 case AST_STATE_DOWN: 14018 if (option_debug > 1) 14019 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14020 transmit_response(p, "100 Trying", req); 14021 p->invitestate = INV_PROCEEDING; 14022 ast_setstate(c, AST_STATE_RING); 14023 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14024 enum ast_pbx_result res; 14025 14026 res = ast_pbx_start(c); 14027 14028 switch(res) { 14029 case AST_PBX_FAILED: 14030 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14031 p->invitestate = INV_COMPLETED; 14032 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14033 transmit_response(p, "503 Unavailable", req); 14034 else 14035 transmit_response_reliable(p, "503 Unavailable", req); 14036 break; 14037 case AST_PBX_CALL_LIMIT: 14038 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14039 p->invitestate = INV_COMPLETED; 14040 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14041 transmit_response(p, "480 Temporarily Unavailable", req); 14042 else 14043 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14044 break; 14045 case AST_PBX_SUCCESS: 14046 /* nothing to do */ 14047 break; 14048 } 14049 14050 if (res) { 14051 14052 /* Unlock locks so ast_hangup can do its magic */ 14053 ast_mutex_unlock(&c->lock); 14054 ast_mutex_unlock(&p->lock); 14055 ast_hangup(c); 14056 ast_mutex_lock(&p->lock); 14057 c = NULL; 14058 } 14059 } else { /* Pickup call in call group */ 14060 ast_channel_unlock(c); 14061 *nounlock = 1; 14062 if (ast_pickup_call(c)) { 14063 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14064 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14065 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14066 else 14067 transmit_response_reliable(p, "503 Unavailable", req); 14068 sip_alreadygone(p); 14069 /* Unlock locks so ast_hangup can do its magic */ 14070 ast_mutex_unlock(&p->lock); 14071 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14072 } else { 14073 ast_mutex_unlock(&p->lock); 14074 ast_setstate(c, AST_STATE_DOWN); 14075 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14076 } 14077 p->invitestate = INV_COMPLETED; 14078 ast_hangup(c); 14079 ast_mutex_lock(&p->lock); 14080 c = NULL; 14081 } 14082 break; 14083 case AST_STATE_RING: 14084 transmit_response(p, "100 Trying", req); 14085 p->invitestate = INV_PROCEEDING; 14086 break; 14087 case AST_STATE_RINGING: 14088 transmit_response(p, "180 Ringing", req); 14089 p->invitestate = INV_PROCEEDING; 14090 break; 14091 case AST_STATE_UP: 14092 if (option_debug > 1) 14093 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14094 14095 transmit_response(p, "100 Trying", req); 14096 14097 if (p->t38.state == T38_PEER_REINVITE) { 14098 struct ast_channel *bridgepeer = NULL; 14099 struct sip_pvt *bridgepvt = NULL; 14100 14101 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14102 /* 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*/ 14103 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14104 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14105 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14106 if (bridgepvt->t38.state == T38_DISABLED) { 14107 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14108 /* Send re-invite to the bridged channel */ 14109 sip_handle_t38_reinvite(bridgepeer, p, 1); 14110 } else { /* Something is wrong with peers udptl struct */ 14111 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14112 ast_mutex_lock(&bridgepvt->lock); 14113 bridgepvt->t38.state = T38_DISABLED; 14114 ast_mutex_unlock(&bridgepvt->lock); 14115 if (option_debug > 1) 14116 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14117 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14118 transmit_response(p, "488 Not acceptable here", req); 14119 else 14120 transmit_response_reliable(p, "488 Not acceptable here", req); 14121 14122 } 14123 } else { 14124 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14125 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14126 p->t38.state = T38_ENABLED; 14127 if (option_debug) 14128 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14129 } 14130 } else { 14131 /* Other side is not a SIP channel */ 14132 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14133 transmit_response(p, "488 Not acceptable here", req); 14134 else 14135 transmit_response_reliable(p, "488 Not acceptable here", req); 14136 p->t38.state = T38_DISABLED; 14137 if (option_debug > 1) 14138 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14139 14140 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14141 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14142 } 14143 } else { 14144 /* we are not bridged in a call */ 14145 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14146 p->t38.state = T38_ENABLED; 14147 if (option_debug) 14148 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14149 } 14150 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14151 int sendok = TRUE; 14152 14153 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14154 /* so handle it here (re-invite other party to RTP) */ 14155 struct ast_channel *bridgepeer = NULL; 14156 struct sip_pvt *bridgepvt = NULL; 14157 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14158 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14159 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14160 /* Does the bridged peer have T38 ? */ 14161 if (bridgepvt->t38.state == T38_ENABLED) { 14162 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14163 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14164 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14165 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14166 else 14167 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14168 sendok = FALSE; 14169 } 14170 /* No bridged peer with T38 enabled*/ 14171 } 14172 } 14173 /* Respond to normal re-invite */ 14174 if (sendok) 14175 /* If this is not a re-invite or something to ignore - it's critical */ 14176 transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ? XMIT_UNRELIABLE : XMIT_CRITICAL); 14177 } 14178 p->invitestate = INV_TERMINATED; 14179 break; 14180 default: 14181 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14182 transmit_response(p, "100 Trying", req); 14183 break; 14184 } 14185 } else { 14186 if (p && (p->autokillid == -1)) { 14187 const char *msg; 14188 14189 if (!p->jointcapability) 14190 msg = "488 Not Acceptable Here (codec error)"; 14191 else { 14192 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14193 msg = "503 Unavailable"; 14194 } 14195 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14196 transmit_response(p, msg, req); 14197 else 14198 transmit_response_reliable(p, msg, req); 14199 p->invitestate = INV_COMPLETED; 14200 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14201 } 14202 } 14203 return res; 14204 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14824 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().
14825 { 14826 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14827 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14828 ast_verbose("Receiving message!\n"); 14829 receive_message(p, req); 14830 } else 14831 transmit_response(p, "202 Accepted", req); 14832 return 1; 14833 }
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 13354 of file chan_sip.c.
References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13355 { 13356 /* This is mostly a skeleton for future improvements */ 13357 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13358 int res = 0; 13359 const char *event = get_header(req, "Event"); 13360 char *eventid = NULL; 13361 char *sep; 13362 13363 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13364 *sep++ = '\0'; 13365 eventid = sep; 13366 } 13367 13368 if (option_debug > 1 && sipdebug) 13369 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13370 13371 if (strcmp(event, "refer")) { 13372 /* We don't understand this event. */ 13373 /* Here's room to implement incoming voicemail notifications :-) */ 13374 transmit_response(p, "489 Bad event", req); 13375 res = -1; 13376 } else { 13377 /* Save nesting depth for now, since there might be other events we will 13378 support in the future */ 13379 13380 /* Handle REFER notifications */ 13381 13382 char buf[1024]; 13383 char *cmd, *code; 13384 int respcode; 13385 int success = TRUE; 13386 13387 /* EventID for each transfer... EventID is basically the REFER cseq 13388 13389 We are getting notifications on a call that we transfered 13390 We should hangup when we are getting a 200 OK in a sipfrag 13391 Check if we have an owner of this event */ 13392 13393 /* Check the content type */ 13394 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13395 /* We need a sipfrag */ 13396 transmit_response(p, "400 Bad request", req); 13397 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13398 return -1; 13399 } 13400 13401 /* Get the text of the attachment */ 13402 if (get_msg_text(buf, sizeof(buf), req)) { 13403 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13404 transmit_response(p, "400 Bad request", req); 13405 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13406 return -1; 13407 } 13408 13409 /* 13410 From the RFC... 13411 A minimal, but complete, implementation can respond with a single 13412 NOTIFY containing either the body: 13413 SIP/2.0 100 Trying 13414 13415 if the subscription is pending, the body: 13416 SIP/2.0 200 OK 13417 if the reference was successful, the body: 13418 SIP/2.0 503 Service Unavailable 13419 if the reference failed, or the body: 13420 SIP/2.0 603 Declined 13421 13422 if the REFER request was accepted before approval to follow the 13423 reference could be obtained and that approval was subsequently denied 13424 (see Section 2.4.7). 13425 13426 If there are several REFERs in the same dialog, we need to 13427 match the ID of the event header... 13428 */ 13429 if (option_debug > 2) 13430 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13431 cmd = ast_skip_blanks(buf); 13432 code = cmd; 13433 /* We are at SIP/2.0 */ 13434 while(*code && (*code > 32)) { /* Search white space */ 13435 code++; 13436 } 13437 *code++ = '\0'; 13438 code = ast_skip_blanks(code); 13439 sep = code; 13440 sep++; 13441 while(*sep && (*sep > 32)) { /* Search white space */ 13442 sep++; 13443 } 13444 *sep++ = '\0'; /* Response string */ 13445 respcode = atoi(code); 13446 switch (respcode) { 13447 case 100: /* Trying: */ 13448 case 101: /* dialog establishment */ 13449 /* Don't do anything yet */ 13450 break; 13451 case 183: /* Ringing: */ 13452 /* Don't do anything yet */ 13453 break; 13454 case 200: /* OK: The new call is up, hangup this call */ 13455 /* Hangup the call that we are replacing */ 13456 break; 13457 case 301: /* Moved permenantly */ 13458 case 302: /* Moved temporarily */ 13459 /* Do we get the header in the packet in this case? */ 13460 success = FALSE; 13461 break; 13462 case 503: /* Service Unavailable: The new call failed */ 13463 /* Cancel transfer, continue the call */ 13464 success = FALSE; 13465 break; 13466 case 603: /* Declined: Not accepted */ 13467 /* Cancel transfer, continue the current call */ 13468 success = FALSE; 13469 break; 13470 } 13471 if (!success) { 13472 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13473 } 13474 13475 /* Confirm that we received this packet */ 13476 transmit_response(p, "200 OK", req); 13477 }; 13478 13479 if (!p->lastinvite) 13480 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13481 13482 return res; 13483 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13486 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().
13487 { 13488 int res; 13489 13490 res = get_destination(p, req); 13491 build_contact(p); 13492 13493 /* XXX Should we authenticate OPTIONS? XXX */ 13494 13495 if (ast_strlen_zero(p->context)) 13496 ast_string_field_set(p, context, default_context); 13497 13498 if (ast_shutting_down()) 13499 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13500 else if (res < 0) 13501 transmit_response_with_allow(p, "404 Not Found", req, 0); 13502 else 13503 transmit_response_with_allow(p, "200 OK", req, 0); 13504 13505 /* Destroy if this OPTIONS was the opening request, but not if 13506 it's in the middle of a normal call flow. */ 13507 if (!p->lastinvite) 13508 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13509 13510 return res; 13511 }
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 14372 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(), sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
14373 { 14374 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14375 /* Chan2: Call between asterisk and transferee */ 14376 14377 int res = 0; 14378 14379 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14380 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"); 14381 14382 if (!p->owner) { 14383 /* This is a REFER outside of an existing SIP dialog */ 14384 /* We can't handle that, so decline it */ 14385 if (option_debug > 2) 14386 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14387 transmit_response(p, "603 Declined (No dialog)", req); 14388 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14389 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14390 sip_alreadygone(p); 14391 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14392 } 14393 return 0; 14394 } 14395 14396 14397 /* Check if transfer is allowed from this device */ 14398 if (p->allowtransfer == TRANSFER_CLOSED ) { 14399 /* Transfer not allowed, decline */ 14400 transmit_response(p, "603 Declined (policy)", req); 14401 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14402 /* Do not destroy SIP session */ 14403 return 0; 14404 } 14405 14406 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14407 /* Already have a pending REFER */ 14408 transmit_response(p, "491 Request pending", req); 14409 append_history(p, "Xfer", "Refer failed. Request pending."); 14410 return 0; 14411 } 14412 14413 /* Allocate memory for call transfer data */ 14414 if (!p->refer && !sip_refer_allocate(p)) { 14415 transmit_response(p, "500 Internal Server Error", req); 14416 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14417 return -3; 14418 } 14419 14420 res = get_refer_info(p, req); /* Extract headers */ 14421 14422 p->refer->status = REFER_SENT; 14423 14424 if (res != 0) { 14425 switch (res) { 14426 case -2: /* Syntax error */ 14427 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14428 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14429 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14430 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14431 break; 14432 case -3: 14433 transmit_response(p, "603 Declined (Non sip: uri)", req); 14434 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14435 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14436 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14437 break; 14438 default: 14439 /* Refer-to extension not found, fake a failed transfer */ 14440 transmit_response(p, "202 Accepted", req); 14441 append_history(p, "Xfer", "Refer failed. Bad extension."); 14442 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14443 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14444 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14445 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14446 break; 14447 } 14448 return 0; 14449 } 14450 if (ast_strlen_zero(p->context)) 14451 ast_string_field_set(p, context, default_context); 14452 14453 /* If we do not support SIP domains, all transfers are local */ 14454 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14455 p->refer->localtransfer = 1; 14456 if (sipdebug && option_debug > 2) 14457 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14458 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14459 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14460 p->refer->localtransfer = 1; 14461 } else if (sipdebug && option_debug > 2) 14462 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14463 14464 /* Is this a repeat of a current request? Ignore it */ 14465 /* Don't know what else to do right now. */ 14466 if (ignore) 14467 return res; 14468 14469 /* If this is a blind transfer, we have the following 14470 channels to work with: 14471 - chan1, chan2: The current call between transferer and transferee (2 channels) 14472 - target_channel: A new call from the transferee to the target (1 channel) 14473 We need to stay tuned to what happens in order to be able 14474 to bring back the call to the transferer */ 14475 14476 /* If this is a attended transfer, we should have all call legs within reach: 14477 - chan1, chan2: The call between the transferer and transferee (2 channels) 14478 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14479 We want to bridge chan2 with targetcall_pvt! 14480 14481 The replaces call id in the refer message points 14482 to the call leg between Asterisk and the transferer. 14483 So we need to connect the target and the transferee channel 14484 and hangup the two other channels silently 14485 14486 If the target is non-local, the call ID could be on a remote 14487 machine and we need to send an INVITE with replaces to the 14488 target. We basically handle this as a blind transfer 14489 and let the sip_call function catch that we need replaces 14490 header in the INVITE. 14491 */ 14492 14493 14494 /* Get the transferer's channel */ 14495 current.chan1 = p->owner; 14496 14497 /* Find the other part of the bridge (2) - transferee */ 14498 current.chan2 = ast_bridged_channel(current.chan1); 14499 14500 if (sipdebug && option_debug > 2) 14501 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>"); 14502 14503 if (!current.chan2 && !p->refer->attendedtransfer) { 14504 /* No bridged channel, propably IVR or echo or similar... */ 14505 /* Guess we should masquerade or something here */ 14506 /* Until we figure it out, refuse transfer of such calls */ 14507 if (sipdebug && option_debug > 2) 14508 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14509 p->refer->status = REFER_FAILED; 14510 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14511 transmit_response(p, "603 Declined", req); 14512 return -1; 14513 } 14514 14515 if (current.chan2) { 14516 if (sipdebug && option_debug > 3) 14517 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14518 14519 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14520 } 14521 14522 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14523 14524 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14525 if (p->refer->attendedtransfer) { 14526 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14527 return res; /* We're done with the transfer */ 14528 /* Fall through for remote transfers that we did not find locally */ 14529 if (sipdebug && option_debug > 3) 14530 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14531 /* Fallthrough if we can't find the call leg internally */ 14532 } 14533 14534 14535 /* Parking a call */ 14536 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14537 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14538 *nounlock = 1; 14539 ast_channel_unlock(current.chan1); 14540 copy_request(¤t.req, req); 14541 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14542 p->refer->status = REFER_200OK; 14543 append_history(p, "Xfer", "REFER to call parking."); 14544 if (sipdebug && option_debug > 3) 14545 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14546 sip_park(current.chan2, current.chan1, req, seqno); 14547 return res; 14548 } 14549 14550 /* Blind transfers and remote attended xfers */ 14551 transmit_response(p, "202 Accepted", req); 14552 14553 if (current.chan1 && current.chan2) { 14554 if (option_debug > 2) 14555 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14556 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14557 } 14558 if (current.chan2) { 14559 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14560 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14561 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14562 /* One for the new channel */ 14563 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14564 /* Attended transfer to remote host, prepare headers for the INVITE */ 14565 if (p->refer->referred_by) 14566 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14567 } 14568 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14569 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14570 char tempheader[BUFSIZ]; 14571 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14572 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14573 p->refer->replaces_callid_totag, 14574 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14575 p->refer->replaces_callid_fromtag); 14576 if (current.chan2) 14577 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14578 } 14579 /* Must release lock now, because it will not longer 14580 be accessible after the transfer! */ 14581 *nounlock = 1; 14582 ast_channel_unlock(current.chan1); 14583 14584 /* Connect the call */ 14585 14586 /* FAKE ringing if not attended transfer */ 14587 if (!p->refer->attendedtransfer) 14588 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14589 14590 /* For blind transfer, this will lead to a new call */ 14591 /* For attended transfer to remote host, this will lead to 14592 a new SIP call with a replaces header, if the dial plan allows it 14593 */ 14594 if (!current.chan2) { 14595 /* We have no bridge, so we're talking with Asterisk somehow */ 14596 /* We need to masquerade this call */ 14597 /* What to do to fix this situation: 14598 * Set up the new call in a new channel 14599 * Let the new channel masq into this channel 14600 Please add that code here :-) 14601 */ 14602 p->refer->status = REFER_FAILED; 14603 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14604 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14605 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14606 return -1; 14607 } 14608 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14609 14610 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14611 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14612 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14613 14614 if (!res) { 14615 /* Success - we have a new channel */ 14616 if (option_debug > 2) 14617 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14618 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14619 if (p->refer->localtransfer) 14620 p->refer->status = REFER_200OK; 14621 if (p->owner) 14622 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14623 append_history(p, "Xfer", "Refer succeeded."); 14624 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14625 /* Do not hangup call, the other side do that when we say 200 OK */ 14626 /* We could possibly implement a timer here, auto congestion */ 14627 res = 0; 14628 } else { 14629 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14630 if (option_debug > 2) 14631 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14632 append_history(p, "Xfer", "Refer failed."); 14633 /* Failure of some kind */ 14634 p->refer->status = REFER_FAILED; 14635 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14636 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14637 res = -1; 14638 } 14639 return res; 14640 }
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 15120 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().
15121 { 15122 enum check_auth_result res; 15123 15124 /* Use this as the basis */ 15125 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15126 ast_verbose("Using latest REGISTER request as basis request\n"); 15127 copy_request(&p->initreq, req); 15128 check_via(p, req); 15129 if ((res = register_verify(p, sin, req, e)) < 0) { 15130 const char *reason; 15131 15132 switch (res) { 15133 case AUTH_SECRET_FAILED: 15134 reason = "Wrong password"; 15135 break; 15136 case AUTH_USERNAME_MISMATCH: 15137 reason = "Username/auth name mismatch"; 15138 break; 15139 case AUTH_NOT_FOUND: 15140 reason = "No matching peer found"; 15141 break; 15142 case AUTH_UNKNOWN_DOMAIN: 15143 reason = "Not a local domain"; 15144 break; 15145 case AUTH_PEER_NOT_DYNAMIC: 15146 reason = "Peer is not supposed to register"; 15147 break; 15148 case AUTH_ACL_FAILED: 15149 reason = "Device does not match ACL"; 15150 break; 15151 default: 15152 reason = "Unknown failure"; 15153 break; 15154 } 15155 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15156 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15157 reason); 15158 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15159 } else 15160 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15161 15162 if (res < 1) { 15163 /* Destroy the session, but keep us around for just a bit in case they don't 15164 get our 200 OK */ 15165 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15166 } 15167 return res; 15168 }
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 14836 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(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
14837 { 14838 int gotdest; 14839 int res = 0; 14840 int firststate = AST_EXTENSION_REMOVED; 14841 struct sip_peer *authpeer = NULL; 14842 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14843 const char *accept = get_header(req, "Accept"); 14844 int resubscribe = (p->subscribed != NONE); 14845 char *temp, *event; 14846 14847 if (p->initreq.headers) { 14848 /* We already have a dialog */ 14849 if (p->initreq.method != SIP_SUBSCRIBE) { 14850 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14851 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14852 transmit_response(p, "403 Forbidden (within dialog)", req); 14853 /* Do not destroy session, since we will break the call if we do */ 14854 if (option_debug) 14855 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); 14856 return 0; 14857 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14858 if (option_debug) { 14859 if (resubscribe) 14860 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14861 else 14862 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14863 } 14864 } 14865 } 14866 14867 /* Check if we have a global disallow setting on subscriptions. 14868 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14869 */ 14870 if (!global_allowsubscribe) { 14871 transmit_response(p, "403 Forbidden (policy)", req); 14872 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14873 return 0; 14874 } 14875 14876 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14877 /* Use this as the basis */ 14878 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14879 ast_verbose("Creating new subscription\n"); 14880 14881 copy_request(&p->initreq, req); 14882 check_via(p, req); 14883 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14884 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14885 14886 /* Find parameters to Event: header value and remove them for now */ 14887 if (ast_strlen_zero(eventheader)) { 14888 transmit_response(p, "489 Bad Event", req); 14889 if (option_debug > 1) 14890 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14891 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14892 return 0; 14893 } 14894 14895 if ( (strchr(eventheader, ';'))) { 14896 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14897 temp = strchr(event, ';'); 14898 *temp = '\0'; /* Remove any options for now */ 14899 /* We might need to use them later :-) */ 14900 } else 14901 event = (char *) eventheader; /* XXX is this legal ? */ 14902 14903 /* Handle authentication */ 14904 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14905 /* if an authentication response was sent, we are done here */ 14906 if (res == AUTH_CHALLENGE_SENT) { 14907 if (authpeer) 14908 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14909 return 0; 14910 } 14911 if (res < 0) { 14912 if (res == AUTH_FAKE_AUTH) { 14913 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14914 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 14915 } else { 14916 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14917 transmit_response_reliable(p, "403 Forbidden", req); 14918 } 14919 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14920 if (authpeer) 14921 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14922 return 0; 14923 } 14924 14925 /* Check if this user/peer is allowed to subscribe at all */ 14926 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14927 transmit_response(p, "403 Forbidden (policy)", req); 14928 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14929 if (authpeer) 14930 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14931 return 0; 14932 } 14933 14934 /* Get destination right away */ 14935 gotdest = get_destination(p, NULL); 14936 14937 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14938 parse_ok_contact(p, req); 14939 14940 build_contact(p); 14941 if (gotdest) { 14942 transmit_response(p, "404 Not Found", req); 14943 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14944 if (authpeer) 14945 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14946 return 0; 14947 } 14948 14949 /* Initialize tag for new subscriptions */ 14950 if (ast_strlen_zero(p->tag)) 14951 make_our_tag(p->tag, sizeof(p->tag)); 14952 14953 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14954 if (authpeer) /* No need for authpeer here */ 14955 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14956 14957 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14958 /* Polycom phones only handle xpidf+xml, even if they say they can 14959 handle pidf+xml as well 14960 */ 14961 if (strstr(p->useragent, "Polycom")) { 14962 p->subscribed = XPIDF_XML; 14963 } else if (strstr(accept, "application/pidf+xml")) { 14964 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14965 } else if (strstr(accept, "application/dialog-info+xml")) { 14966 p->subscribed = DIALOG_INFO_XML; 14967 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14968 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14969 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14970 } else if (strstr(accept, "application/xpidf+xml")) { 14971 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14972 } else if (ast_strlen_zero(accept)) { 14973 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14974 transmit_response(p, "489 Bad Event", req); 14975 14976 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14977 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14978 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14979 return 0; 14980 } 14981 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14982 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14983 } else { 14984 /* Can't find a format for events that we know about */ 14985 char mybuf[200]; 14986 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14987 transmit_response(p, mybuf, req); 14988 14989 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14990 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14991 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14992 return 0; 14993 } 14994 } else if (!strcmp(event, "message-summary")) { 14995 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14996 /* Format requested that we do not support */ 14997 transmit_response(p, "406 Not Acceptable", req); 14998 if (option_debug > 1) 14999 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15000 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15001 if (authpeer) /* No need for authpeer here */ 15002 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15003 return 0; 15004 } 15005 /* Looks like they actually want a mailbox status 15006 This version of Asterisk supports mailbox subscriptions 15007 The subscribed URI needs to exist in the dial plan 15008 In most devices, this is configurable to the voicemailmain extension you use 15009 */ 15010 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15011 transmit_response(p, "404 Not found (no mailbox)", req); 15012 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15013 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15014 if (authpeer) /* No need for authpeer here */ 15015 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15016 return 0; 15017 } 15018 15019 p->subscribed = MWI_NOTIFICATION; 15020 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15021 /* We only allow one subscription per peer */ 15022 sip_destroy(authpeer->mwipvt); 15023 authpeer->mwipvt = p; /* Link from peer to pvt */ 15024 p->relatedpeer = authpeer; /* Link from pvt to peer */ 15025 } else { /* At this point, Asterisk does not understand the specified event */ 15026 transmit_response(p, "489 Bad Event", req); 15027 if (option_debug > 1) 15028 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15029 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15030 if (authpeer) /* No need for authpeer here */ 15031 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15032 return 0; 15033 } 15034 15035 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15036 if (p->stateid > -1) 15037 ast_extension_state_del(p->stateid, cb_extensionstate); 15038 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15039 } 15040 15041 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15042 p->lastinvite = seqno; 15043 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15044 p->expiry = atoi(get_header(req, "Expires")); 15045 15046 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15047 if (p->expiry > max_expiry) 15048 p->expiry = max_expiry; 15049 if (p->expiry < min_expiry && p->expiry > 0) 15050 p->expiry = min_expiry; 15051 15052 if (sipdebug || option_debug > 1) { 15053 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15054 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15055 else 15056 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15057 } 15058 if (p->autokillid > -1) 15059 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 15060 if (p->expiry > 0) 15061 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15062 15063 if (p->subscribed == MWI_NOTIFICATION) { 15064 transmit_response(p, "200 OK", req); 15065 if (p->relatedpeer) { /* Send first notification */ 15066 ASTOBJ_WRLOCK(p->relatedpeer); 15067 sip_send_mwi_to_peer(p->relatedpeer); 15068 ASTOBJ_UNLOCK(p->relatedpeer); 15069 } 15070 } else { 15071 struct sip_pvt *p_old; 15072 15073 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15074 15075 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)); 15076 transmit_response(p, "404 Not found", req); 15077 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15078 return 0; 15079 } 15080 15081 transmit_response(p, "200 OK", req); 15082 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15083 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15084 /* hide the 'complete' exten/context in the refer_to field for later display */ 15085 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15086 15087 /* remove any old subscription from this peer for the same exten/context, 15088 as the peer has obviously forgotten about it and it's wasteful to wait 15089 for it to expire and send NOTIFY messages to the peer only to have them 15090 ignored (or generate errors) 15091 */ 15092 ast_mutex_lock(&iflock); 15093 for (p_old = iflist; p_old; p_old = p_old->next) { 15094 if (p_old == p) 15095 continue; 15096 if (p_old->initreq.method != SIP_SUBSCRIBE) 15097 continue; 15098 if (p_old->subscribed == NONE) 15099 continue; 15100 ast_mutex_lock(&p_old->lock); 15101 if (!strcmp(p_old->username, p->username)) { 15102 if (!strcmp(p_old->exten, p->exten) && 15103 !strcmp(p_old->context, p->context)) { 15104 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15105 ast_mutex_unlock(&p_old->lock); 15106 break; 15107 } 15108 } 15109 ast_mutex_unlock(&p_old->lock); 15110 } 15111 ast_mutex_unlock(&iflock); 15112 } 15113 if (!p->expiry) 15114 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15115 } 15116 return 1; 15117 }
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 12655 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::authtries, do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_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.
12656 { 12657 struct ast_channel *owner; 12658 int sipmethod; 12659 int res = 1; 12660 const char *c = get_header(req, "Cseq"); 12661 const char *msg = strchr(c, ' '); 12662 12663 if (!msg) 12664 msg = ""; 12665 else 12666 msg++; 12667 sipmethod = find_sip_method(msg); 12668 12669 owner = p->owner; 12670 if (owner) 12671 owner->hangupcause = hangup_sip2cause(resp); 12672 12673 /* Acknowledge whatever it is destined for */ 12674 if ((resp >= 100) && (resp <= 199)) 12675 __sip_semi_ack(p, seqno, 0, sipmethod); 12676 else 12677 __sip_ack(p, seqno, 0, sipmethod); 12678 12679 /* Get their tag if we haven't already */ 12680 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12681 char tag[128]; 12682 12683 gettag(req, "To", tag, sizeof(tag)); 12684 ast_string_field_set(p, theirtag, tag); 12685 } 12686 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12687 /* We don't really care what the response is, just that it replied back. 12688 Well, as long as it's not a 100 response... since we might 12689 need to hang around for something more "definitive" */ 12690 if (resp != 100) 12691 handle_response_peerpoke(p, resp, req); 12692 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12693 switch(resp) { 12694 case 100: /* 100 Trying */ 12695 case 101: /* 101 Dialog establishment */ 12696 if (sipmethod == SIP_INVITE) 12697 handle_response_invite(p, resp, rest, req, seqno); 12698 break; 12699 case 183: /* 183 Session Progress */ 12700 if (sipmethod == SIP_INVITE) 12701 handle_response_invite(p, resp, rest, req, seqno); 12702 break; 12703 case 180: /* 180 Ringing */ 12704 if (sipmethod == SIP_INVITE) 12705 handle_response_invite(p, resp, rest, req, seqno); 12706 break; 12707 case 182: /* 182 Queued */ 12708 if (sipmethod == SIP_INVITE) 12709 handle_response_invite(p, resp, rest, req, seqno); 12710 break; 12711 case 200: /* 200 OK */ 12712 p->authtries = 0; /* Reset authentication counter */ 12713 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12714 /* We successfully transmitted a message 12715 or a video update request in INFO */ 12716 /* Nothing happens here - the message is inside a dialog */ 12717 } else if (sipmethod == SIP_INVITE) { 12718 handle_response_invite(p, resp, rest, req, seqno); 12719 } else if (sipmethod == SIP_NOTIFY) { 12720 /* They got the notify, this is the end */ 12721 if (p->owner) { 12722 if (!p->refer) { 12723 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12724 ast_queue_hangup(p->owner); 12725 } else if (option_debug > 3) 12726 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12727 } else { 12728 if (p->subscribed == NONE) 12729 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 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)) 12930 sip_cancel_destroy(p); 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)) 13035 sip_cancel_destroy(p); 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 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 13049 sip_cancel_destroy(p); 13050 } 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 12068 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_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
12069 { 12070 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12071 int res = 0; 12072 int xmitres = 0; 12073 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12074 struct ast_channel *bridgepeer = NULL; 12075 12076 if (option_debug > 3) { 12077 if (reinvite) 12078 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12079 else 12080 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12081 } 12082 12083 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12084 if (option_debug) 12085 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12086 return; 12087 } 12088 12089 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12090 if (p->initid > -1) { 12091 /* Don't auto congest anymore since we've gotten something useful back */ 12092 ast_sched_del(sched, p->initid); 12093 p->initid = -1; 12094 } 12095 12096 /* RFC3261 says we must treat every 1xx response (but not 100) 12097 that we don't recognize as if it was 183. 12098 */ 12099 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12100 resp = 183; 12101 12102 /* Any response between 100 and 199 is PROCEEDING */ 12103 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12104 p->invitestate = INV_PROCEEDING; 12105 12106 /* Final response, not 200 ? */ 12107 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12108 p->invitestate = INV_COMPLETED; 12109 12110 12111 switch (resp) { 12112 case 100: /* Trying */ 12113 case 101: /* Dialog establishment */ 12114 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12115 sip_cancel_destroy(p); 12116 check_pendings(p); 12117 break; 12118 12119 case 180: /* 180 Ringing */ 12120 case 182: /* 182 Queued */ 12121 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12122 sip_cancel_destroy(p); 12123 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12124 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12125 if (p->owner->_state != AST_STATE_UP) { 12126 ast_setstate(p->owner, AST_STATE_RINGING); 12127 } 12128 } 12129 if (find_sdp(req)) { 12130 p->invitestate = INV_EARLY_MEDIA; 12131 res = process_sdp(p, req); 12132 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12133 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12134 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12135 } 12136 } 12137 check_pendings(p); 12138 break; 12139 12140 case 183: /* Session progress */ 12141 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12142 sip_cancel_destroy(p); 12143 /* Ignore 183 Session progress without SDP */ 12144 if (find_sdp(req)) { 12145 p->invitestate = INV_EARLY_MEDIA; 12146 res = process_sdp(p, req); 12147 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12148 /* Queue a progress frame */ 12149 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12150 } 12151 } 12152 check_pendings(p); 12153 break; 12154 12155 case 200: /* 200 OK on invite - someone's answering our call */ 12156 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12157 sip_cancel_destroy(p); 12158 p->authtries = 0; 12159 if (find_sdp(req)) { 12160 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12161 if (!reinvite) 12162 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12163 /* For re-invites, we try to recover */ 12164 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12165 } 12166 12167 /* Parse contact header for continued conversation */ 12168 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12169 /* This is important when we have a SIP proxy between us and the phone */ 12170 if (outgoing) { 12171 update_call_counter(p, DEC_CALL_RINGING); 12172 parse_ok_contact(p, req); 12173 if(set_address_from_contact(p)) { 12174 /* Bad contact - we don't know how to reach this device */ 12175 /* We need to ACK, but then send a bye */ 12176 /* OEJ: Possible issue that may need a check: 12177 If we have a proxy route between us and the device, 12178 should we care about resolving the contact 12179 or should we just send it? 12180 */ 12181 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12182 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12183 } 12184 12185 /* Save Record-Route for any later requests we make on this dialogue */ 12186 build_route(p, req, 1); 12187 } 12188 12189 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12190 struct sip_pvt *bridgepvt = NULL; 12191 12192 if (!bridgepeer->tech) { 12193 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12194 break; 12195 } 12196 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12197 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12198 if (bridgepvt->udptl) { 12199 if (p->t38.state == T38_PEER_REINVITE) { 12200 sip_handle_t38_reinvite(bridgepeer, p, 0); 12201 ast_rtp_set_rtptimers_onhold(p->rtp); 12202 if (p->vrtp) 12203 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12204 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12205 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12206 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12207 /* XXXX Should we really destroy this session here, without any response at all??? */ 12208 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12209 } 12210 } else { 12211 if (option_debug > 1) 12212 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12213 ast_mutex_lock(&bridgepvt->lock); 12214 bridgepvt->t38.state = T38_DISABLED; 12215 ast_mutex_unlock(&bridgepvt->lock); 12216 if (option_debug) 12217 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12218 p->t38.state = T38_DISABLED; 12219 if (option_debug > 1) 12220 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12221 } 12222 } else { 12223 /* Other side is not a SIP channel */ 12224 if (option_debug > 1) 12225 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12226 p->t38.state = T38_DISABLED; 12227 if (option_debug > 1) 12228 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12229 } 12230 } 12231 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12232 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12233 p->t38.state = T38_ENABLED; 12234 if (option_debug) 12235 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12236 } 12237 12238 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12239 if (!reinvite) { 12240 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12241 } else { /* RE-invite */ 12242 ast_queue_frame(p->owner, &ast_null_frame); 12243 } 12244 } else { 12245 /* It's possible we're getting an 200 OK after we've tried to disconnect 12246 by sending CANCEL */ 12247 /* First send ACK, then send bye */ 12248 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12249 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12250 } 12251 /* If I understand this right, the branch is different for a non-200 ACK only */ 12252 p->invitestate = INV_TERMINATED; 12253 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12254 check_pendings(p); 12255 break; 12256 case 407: /* Proxy authentication */ 12257 case 401: /* Www auth */ 12258 /* First we ACK */ 12259 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12260 if (p->options) 12261 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12262 12263 /* Then we AUTH */ 12264 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12265 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12266 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12267 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12268 if (p->authtries < MAX_AUTHTRIES) 12269 p->invitestate = INV_CALLING; 12270 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12271 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12272 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12273 sip_alreadygone(p); 12274 if (p->owner) 12275 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12276 } 12277 } 12278 break; 12279 12280 case 403: /* Forbidden */ 12281 /* First we ACK */ 12282 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12283 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12284 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12285 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12286 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12287 sip_alreadygone(p); 12288 break; 12289 12290 case 404: /* Not found */ 12291 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12292 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12293 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12294 sip_alreadygone(p); 12295 break; 12296 12297 case 408: /* Request timeout */ 12298 case 481: /* Call leg does not exist */ 12299 /* Could be REFER caused INVITE with replaces */ 12300 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12301 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12302 if (p->owner) 12303 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12304 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12305 break; 12306 case 487: /* Cancelled transaction */ 12307 /* We have sent CANCEL on an outbound INVITE 12308 This transaction is already scheduled to be killed by sip_hangup(). 12309 */ 12310 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12311 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12312 ast_queue_hangup(p->owner); 12313 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12314 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12315 update_call_counter(p, DEC_CALL_LIMIT); 12316 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12317 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12318 sip_alreadygone(p); 12319 } 12320 break; 12321 case 488: /* Not acceptable here */ 12322 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12323 if (reinvite && p->udptl) { 12324 /* If this is a T.38 call, we should go back to 12325 audio. If this is an audio call - something went 12326 terribly wrong since we don't renegotiate codecs, 12327 only IP/port . 12328 */ 12329 p->t38.state = T38_DISABLED; 12330 /* Try to reset RTP timers */ 12331 ast_rtp_set_rtptimers_onhold(p->rtp); 12332 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12333 12334 /*! \bug Is there any way we can go back to the audio call on both 12335 sides here? 12336 */ 12337 /* While figuring that out, hangup the call */ 12338 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12339 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12340 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12341 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12342 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12343 right now we can't fall back to audio so totally abort. 12344 */ 12345 p->t38.state = T38_DISABLED; 12346 /* Try to reset RTP timers */ 12347 ast_rtp_set_rtptimers_onhold(p->rtp); 12348 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12349 12350 /* The dialog is now terminated */ 12351 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12352 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12353 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12354 sip_alreadygone(p); 12355 } else { 12356 /* We can't set up this call, so give up */ 12357 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12358 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12359 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12360 } 12361 break; 12362 case 491: /* Pending */ 12363 /* we really should have to wait a while, then retransmit */ 12364 /* We should support the retry-after at some point */ 12365 /* At this point, we treat this as a congestion */ 12366 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12367 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12368 if (p->owner->_state != AST_STATE_UP) { 12369 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12370 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12371 } else { 12372 /* This is a re-invite that failed. */ 12373 /* Reset the flag after a while 12374 */ 12375 int wait = 3 + ast_random() % 5; 12376 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12377 if (option_debug > 2) 12378 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12379 } 12380 } 12381 break; 12382 12383 case 501: /* Not implemented */ 12384 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12385 if (p->owner) 12386 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12387 break; 12388 } 12389 if (xmitres == XMIT_ERROR) 12390 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12391 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12595 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, SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12596 { 12597 struct sip_peer *peer = p->relatedpeer; 12598 int statechanged, is_reachable, was_reachable; 12599 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12600 12601 /* 12602 * Compute the response time to a ping (goes in peer->lastms.) 12603 * -1 means did not respond, 0 means unknown, 12604 * 1..maxms is a valid response, >maxms means late response. 12605 */ 12606 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12607 pingtime = 1; 12608 12609 /* Now determine new state and whether it has changed. 12610 * Use some helper variables to simplify the writing 12611 * of the expressions. 12612 */ 12613 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12614 is_reachable = pingtime <= peer->maxms; 12615 statechanged = peer->lastms == 0 /* yes, unknown before */ 12616 || was_reachable != is_reachable; 12617 12618 peer->lastms = pingtime; 12619 peer->call = NULL; 12620 if (statechanged) { 12621 const char *s = is_reachable ? "Reachable" : "Lagged"; 12622 12623 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12624 peer->name, s, pingtime, peer->maxms); 12625 ast_device_state_changed("SIP/%s", peer->name); 12626 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12627 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12628 peer->name, s, pingtime); 12629 } 12630 12631 if (peer->pokeexpire > -1) 12632 ast_sched_del(sched, peer->pokeexpire); 12633 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12634 12635 /* Try again eventually */ 12636 peer->pokeexpire = ast_sched_add(sched, 12637 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12638 sip_poke_peer_s, peer); 12639 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12396 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
12397 { 12398 char *auth = "Proxy-Authenticate"; 12399 char *auth2 = "Proxy-Authorization"; 12400 12401 /* If no refer structure exists, then do nothing */ 12402 if (!p->refer) 12403 return; 12404 12405 switch (resp) { 12406 case 202: /* Transfer accepted */ 12407 /* We need to do something here */ 12408 /* The transferee is now sending INVITE to target */ 12409 p->refer->status = REFER_ACCEPTED; 12410 /* Now wait for next message */ 12411 if (option_debug > 2) 12412 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12413 /* We should hang along, waiting for NOTIFY's here */ 12414 break; 12415 12416 case 401: /* Not www-authorized on SIP method */ 12417 case 407: /* Proxy auth */ 12418 if (ast_strlen_zero(p->authname)) { 12419 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12420 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12421 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12422 } 12423 if (resp == 401) { 12424 auth = "WWW-Authenticate"; 12425 auth2 = "Authorization"; 12426 } 12427 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12428 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12429 p->refer->status = REFER_NOAUTH; 12430 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12431 } 12432 break; 12433 case 481: /* Call leg does not exist */ 12434 12435 /* A transfer with Replaces did not work */ 12436 /* OEJ: We should Set flag, cancel the REFER, go back 12437 to original call - but right now we can't */ 12438 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12439 if (p->owner) 12440 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12441 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12442 break; 12443 12444 case 500: /* Server error */ 12445 case 501: /* Method not implemented */ 12446 /* Return to the current call onhold */ 12447 /* Status flag needed to be reset */ 12448 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12449 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12450 p->refer->status = REFER_FAILED; 12451 break; 12452 case 603: /* Transfer declined */ 12453 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12454 p->refer->status = REFER_FAILED; 12455 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12456 break; 12457 } 12458 }
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 12461 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12462 { 12463 int expires, expires_ms; 12464 struct sip_registry *r; 12465 r=p->registry; 12466 12467 switch (resp) { 12468 case 401: /* Unauthorized */ 12469 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12470 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12471 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12472 } 12473 break; 12474 case 403: /* Forbidden */ 12475 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12476 if (global_regattempts_max) 12477 p->registry->regattempts = global_regattempts_max+1; 12478 ast_sched_del(sched, r->timeout); 12479 r->timeout = -1; 12480 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12481 break; 12482 case 404: /* Not found */ 12483 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12484 if (global_regattempts_max) 12485 p->registry->regattempts = global_regattempts_max+1; 12486 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12487 r->call = NULL; 12488 ast_sched_del(sched, r->timeout); 12489 r->timeout = -1; 12490 break; 12491 case 407: /* Proxy auth */ 12492 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12493 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12494 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12495 } 12496 break; 12497 case 408: /* Request timeout */ 12498 if (global_regattempts_max) 12499 p->registry->regattempts = global_regattempts_max+1; 12500 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12501 r->call = NULL; 12502 ast_sched_del(sched, r->timeout); 12503 r->timeout = -1; 12504 break; 12505 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12506 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12507 if (global_regattempts_max) 12508 p->registry->regattempts = global_regattempts_max+1; 12509 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12510 r->call = NULL; 12511 ast_sched_del(sched, r->timeout); 12512 r->timeout = -1; 12513 break; 12514 case 200: /* 200 OK */ 12515 if (!r) { 12516 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12517 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12518 return 0; 12519 } 12520 12521 r->regstate = REG_STATE_REGISTERED; 12522 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12523 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12524 r->regattempts = 0; 12525 if (option_debug) 12526 ast_log(LOG_DEBUG, "Registration successful\n"); 12527 if (r->timeout > -1) { 12528 if (option_debug) 12529 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12530 ast_sched_del(sched, r->timeout); 12531 } 12532 r->timeout=-1; 12533 r->call = NULL; 12534 p->registry = NULL; 12535 /* Let this one hang around until we have all the responses */ 12536 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12537 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12538 12539 /* set us up for re-registering */ 12540 /* figure out how long we got registered for */ 12541 if (r->expire > -1) 12542 ast_sched_del(sched, r->expire); 12543 /* according to section 6.13 of RFC, contact headers override 12544 expires headers, so check those first */ 12545 expires = 0; 12546 12547 /* XXX todo: try to save the extra call */ 12548 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12549 const char *contact = NULL; 12550 const char *tmptmp = NULL; 12551 int start = 0; 12552 for(;;) { 12553 contact = __get_header(req, "Contact", &start); 12554 /* this loop ensures we get a contact header about our register request */ 12555 if(!ast_strlen_zero(contact)) { 12556 if( (tmptmp=strstr(contact, p->our_contact))) { 12557 contact=tmptmp; 12558 break; 12559 } 12560 } else 12561 break; 12562 } 12563 tmptmp = strcasestr(contact, "expires="); 12564 if (tmptmp) { 12565 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12566 expires = 0; 12567 } 12568 12569 } 12570 if (!expires) 12571 expires=atoi(get_header(req, "expires")); 12572 if (!expires) 12573 expires=default_expiry; 12574 12575 expires_ms = expires * 1000; 12576 if (expires <= EXPIRY_GUARD_LIMIT) 12577 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12578 else 12579 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12580 if (sipdebug) 12581 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12582 12583 r->refresh= (int) expires_ms / 1000; 12584 12585 /* Schedule re-registration before we expire */ 12586 if (r->expire > -1) 12587 ast_sched_del(sched, r->expire); 12588 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12589 ASTOBJ_UNREF(r, sip_registry_destroy); 12590 } 12591 return 1; 12592 }
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 3403 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().
03404 { 03405 switch (cause) { 03406 case AST_CAUSE_UNALLOCATED: /* 1 */ 03407 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03408 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03409 return "404 Not Found"; 03410 case AST_CAUSE_CONGESTION: /* 34 */ 03411 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03412 return "503 Service Unavailable"; 03413 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03414 return "408 Request Timeout"; 03415 case AST_CAUSE_NO_ANSWER: /* 19 */ 03416 return "480 Temporarily unavailable"; 03417 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03418 return "403 Forbidden"; 03419 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03420 return "410 Gone"; 03421 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03422 return "480 Temporarily unavailable"; 03423 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03424 return "484 Address incomplete"; 03425 case AST_CAUSE_USER_BUSY: 03426 return "486 Busy here"; 03427 case AST_CAUSE_FAILURE: 03428 return "500 Server internal failure"; 03429 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03430 return "501 Not Implemented"; 03431 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03432 return "503 Service Unavailable"; 03433 /* Used in chan_iax2 */ 03434 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03435 return "502 Bad Gateway"; 03436 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03437 return "488 Not Acceptable Here"; 03438 03439 case AST_CAUSE_NOTDEFINED: 03440 default: 03441 if (option_debug) 03442 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03443 return NULL; 03444 } 03445 03446 /* Never reached */ 03447 return 0; 03448 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3291 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().
03292 { 03293 /* Possible values taken from causes.h */ 03294 03295 switch(cause) { 03296 case 401: /* Unauthorized */ 03297 return AST_CAUSE_CALL_REJECTED; 03298 case 403: /* Not found */ 03299 return AST_CAUSE_CALL_REJECTED; 03300 case 404: /* Not found */ 03301 return AST_CAUSE_UNALLOCATED; 03302 case 405: /* Method not allowed */ 03303 return AST_CAUSE_INTERWORKING; 03304 case 407: /* Proxy authentication required */ 03305 return AST_CAUSE_CALL_REJECTED; 03306 case 408: /* No reaction */ 03307 return AST_CAUSE_NO_USER_RESPONSE; 03308 case 409: /* Conflict */ 03309 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03310 case 410: /* Gone */ 03311 return AST_CAUSE_UNALLOCATED; 03312 case 411: /* Length required */ 03313 return AST_CAUSE_INTERWORKING; 03314 case 413: /* Request entity too large */ 03315 return AST_CAUSE_INTERWORKING; 03316 case 414: /* Request URI too large */ 03317 return AST_CAUSE_INTERWORKING; 03318 case 415: /* Unsupported media type */ 03319 return AST_CAUSE_INTERWORKING; 03320 case 420: /* Bad extension */ 03321 return AST_CAUSE_NO_ROUTE_DESTINATION; 03322 case 480: /* No answer */ 03323 return AST_CAUSE_NO_ANSWER; 03324 case 481: /* No answer */ 03325 return AST_CAUSE_INTERWORKING; 03326 case 482: /* Loop detected */ 03327 return AST_CAUSE_INTERWORKING; 03328 case 483: /* Too many hops */ 03329 return AST_CAUSE_NO_ANSWER; 03330 case 484: /* Address incomplete */ 03331 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03332 case 485: /* Ambigous */ 03333 return AST_CAUSE_UNALLOCATED; 03334 case 486: /* Busy everywhere */ 03335 return AST_CAUSE_BUSY; 03336 case 487: /* Request terminated */ 03337 return AST_CAUSE_INTERWORKING; 03338 case 488: /* No codecs approved */ 03339 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03340 case 491: /* Request pending */ 03341 return AST_CAUSE_INTERWORKING; 03342 case 493: /* Undecipherable */ 03343 return AST_CAUSE_INTERWORKING; 03344 case 500: /* Server internal failure */ 03345 return AST_CAUSE_FAILURE; 03346 case 501: /* Call rejected */ 03347 return AST_CAUSE_FACILITY_REJECTED; 03348 case 502: 03349 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03350 case 503: /* Service unavailable */ 03351 return AST_CAUSE_CONGESTION; 03352 case 504: /* Gateway timeout */ 03353 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03354 case 505: /* SIP version not supported */ 03355 return AST_CAUSE_INTERWORKING; 03356 case 600: /* Busy everywhere */ 03357 return AST_CAUSE_USER_BUSY; 03358 case 603: /* Decline */ 03359 return AST_CAUSE_CALL_REJECTED; 03360 case 604: /* Does not exist anywhere */ 03361 return AST_CAUSE_UNALLOCATED; 03362 case 606: /* Not acceptable */ 03363 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03364 default: 03365 return AST_CAUSE_NORMAL; 03366 } 03367 /* Never reached */ 03368 return 0; 03369 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5790 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, sip_methods, and cfsip_methods::text.
05791 { 05792 /* Initialize a request */ 05793 memset(req, 0, sizeof(*req)); 05794 req->method = sipmethod; 05795 req->header[0] = req->data; 05796 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05797 req->len = strlen(req->header[0]); 05798 req->headers++; 05799 return 0; 05800 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5777 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
05778 { 05779 /* Initialize a response */ 05780 memset(resp, 0, sizeof(*resp)); 05781 resp->method = SIP_RESPONSE; 05782 resp->header[0] = resp->data; 05783 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05784 resp->len = strlen(resp->header[0]); 05785 resp->headers++; 05786 return 0; 05787 }
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 1640 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().
01641 { 01642 if (p->initreq.headers && option_debug) { 01643 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01644 } 01645 /* Use this as the basis */ 01646 copy_request(&p->initreq, req); 01647 parse_request(&p->initreq); 01648 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01649 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01650 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6871 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, 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().
06872 { 06873 char invite_buf[256] = ""; 06874 char *invite = invite_buf; 06875 size_t invite_max = sizeof(invite_buf); 06876 char from[256]; 06877 char to[256]; 06878 char tmp[BUFSIZ/2]; 06879 char tmp2[BUFSIZ/2]; 06880 const char *l = NULL, *n = NULL; 06881 const char *urioptions = ""; 06882 06883 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06884 const char *s = p->username; /* being a string field, cannot be NULL */ 06885 06886 /* Test p->username against allowed characters in AST_DIGIT_ANY 06887 If it matches the allowed characters list, then sipuser = ";user=phone" 06888 If not, then sipuser = "" 06889 */ 06890 /* + is allowed in first position in a tel: uri */ 06891 if (*s == '+') 06892 s++; 06893 for (; *s; s++) { 06894 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06895 break; 06896 } 06897 /* If we have only digits, add ;user=phone to the uri */ 06898 if (*s) 06899 urioptions = ";user=phone"; 06900 } 06901 06902 06903 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06904 06905 if (p->owner) { 06906 l = p->owner->cid.cid_num; 06907 n = p->owner->cid.cid_name; 06908 } 06909 /* if we are not sending RPID and user wants his callerid restricted */ 06910 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06911 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06912 l = CALLERID_UNKNOWN; 06913 n = l; 06914 } 06915 if (ast_strlen_zero(l)) 06916 l = default_callerid; 06917 if (ast_strlen_zero(n)) 06918 n = l; 06919 /* Allow user to be overridden */ 06920 if (!ast_strlen_zero(p->fromuser)) 06921 l = p->fromuser; 06922 else /* Save for any further attempts */ 06923 ast_string_field_set(p, fromuser, l); 06924 06925 /* Allow user to be overridden */ 06926 if (!ast_strlen_zero(p->fromname)) 06927 n = p->fromname; 06928 else /* Save for any further attempts */ 06929 ast_string_field_set(p, fromname, n); 06930 06931 if (pedanticsipchecking) { 06932 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06933 n = tmp; 06934 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06935 l = tmp2; 06936 } 06937 06938 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06939 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); 06940 else 06941 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06942 06943 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06944 if (!ast_strlen_zero(p->fullcontact)) { 06945 /* If we have full contact, trust it */ 06946 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06947 } else { 06948 /* Otherwise, use the username while waiting for registration */ 06949 ast_build_string(&invite, &invite_max, "sip:"); 06950 if (!ast_strlen_zero(p->username)) { 06951 n = p->username; 06952 if (pedanticsipchecking) { 06953 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06954 n = tmp; 06955 } 06956 ast_build_string(&invite, &invite_max, "%s@", n); 06957 } 06958 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06959 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06960 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06961 ast_build_string(&invite, &invite_max, "%s", urioptions); 06962 } 06963 06964 /* If custom URI options have been provided, append them */ 06965 if (p->options && p->options->uri_options) 06966 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06967 06968 ast_string_field_set(p, uri, invite_buf); 06969 06970 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06971 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06972 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 06973 } else if (p->options && p->options->vxml_url) { 06974 /* If there is a VXML URL append it to the SIP URL */ 06975 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06976 } else 06977 snprintf(to, sizeof(to), "<%s>", p->uri); 06978 06979 init_req(req, sipmethod, p->uri); 06980 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06981 06982 add_header(req, "Via", p->via); 06983 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06984 * OTOH, then we won't have anything in p->route anyway */ 06985 /* Build Remote Party-ID and From */ 06986 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06987 build_rpid(p); 06988 add_header(req, "From", p->rpid_from); 06989 } else 06990 add_header(req, "From", from); 06991 add_header(req, "To", to); 06992 ast_string_field_set(p, exten, l); 06993 build_contact(p); 06994 add_header(req, "Contact", p->our_contact); 06995 add_header(req, "Call-ID", p->callid); 06996 add_header(req, "CSeq", tmp); 06997 if (!ast_strlen_zero(global_useragent)) 06998 add_header(req, "User-Agent", global_useragent); 06999 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07000 if (!ast_strlen_zero(p->rpid)) 07001 add_header(req, "Remote-Party-ID", p->rpid); 07002 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 10095 of file chan_sip.c.
Referenced by _sip_show_peer().
10096 { 10097 if (port && invite) 10098 return "port,invite"; 10099 else if (port) 10100 return "port"; 10101 else if (invite) 10102 return "invite"; 10103 else 10104 return "no"; 10105 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8168 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08169 { 08170 if (!route) 08171 ast_verbose("list_route: no route\n"); 08172 else { 08173 for (;route; route = route->next) 08174 ast_verbose("list_route: hop: <%s>\n", route->hop); 08175 } 08176 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17999 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, EVENT_FLAG_SYSTEM, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, and userl.
18000 { 18001 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18002 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18003 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18004 18005 if (!(sched = sched_context_create())) { 18006 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18007 return AST_MODULE_LOAD_FAILURE; 18008 } 18009 18010 if (!(io = io_context_create())) { 18011 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18012 sched_context_destroy(sched); 18013 return AST_MODULE_LOAD_FAILURE; 18014 } 18015 18016 sip_reloadreason = CHANNEL_MODULE_LOAD; 18017 18018 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18019 return AST_MODULE_LOAD_DECLINE; 18020 18021 /* Make sure we can register our sip channel type */ 18022 if (ast_channel_register(&sip_tech)) { 18023 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18024 io_context_destroy(io); 18025 sched_context_destroy(sched); 18026 return AST_MODULE_LOAD_FAILURE; 18027 } 18028 18029 /* Register all CLI functions for SIP */ 18030 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18031 18032 /* Tell the RTP subdriver that we're here */ 18033 ast_rtp_proto_register(&sip_rtp); 18034 18035 /* Tell the UDPTL subdriver that we're here */ 18036 ast_udptl_proto_register(&sip_udptl); 18037 18038 /* Register dialplan applications */ 18039 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18040 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18041 18042 /* Register dialplan functions */ 18043 ast_custom_function_register(&sip_header_function); 18044 ast_custom_function_register(&sippeer_function); 18045 ast_custom_function_register(&sipchaninfo_function); 18046 ast_custom_function_register(&checksipdomain_function); 18047 18048 /* Register manager commands */ 18049 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18050 "List SIP peers (text format)", mandescr_show_peers); 18051 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18052 "Show SIP peer (text format)", mandescr_show_peer); 18053 18054 sip_poke_all_peers(); 18055 sip_send_all_registers(); 18056 18057 /* And start the monitor for the first time */ 18058 restart_monitor(); 18059 18060 return AST_MODULE_LOAD_SUCCESS; 18061 }
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 14208 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().
14209 { 14210 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14211 /* Chan 2: Call from Asterisk to target */ 14212 int res = 0; 14213 struct sip_pvt *targetcall_pvt; 14214 14215 /* Check if the call ID of the replaces header does exist locally */ 14216 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14217 transferer->refer->replaces_callid_fromtag))) { 14218 if (transferer->refer->localtransfer) { 14219 /* We did not find the refered call. Sorry, can't accept then */ 14220 transmit_response(transferer, "202 Accepted", req); 14221 /* Let's fake a response from someone else in order 14222 to follow the standard */ 14223 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14224 append_history(transferer, "Xfer", "Refer failed"); 14225 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14226 transferer->refer->status = REFER_FAILED; 14227 return -1; 14228 } 14229 /* Fall through for remote transfers that we did not find locally */ 14230 if (option_debug > 2) 14231 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14232 return 0; 14233 } 14234 14235 /* Ok, we can accept this transfer */ 14236 transmit_response(transferer, "202 Accepted", req); 14237 append_history(transferer, "Xfer", "Refer accepted"); 14238 if (!targetcall_pvt->owner) { /* No active channel */ 14239 if (option_debug > 3) 14240 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14241 /* Cancel transfer */ 14242 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14243 append_history(transferer, "Xfer", "Refer failed"); 14244 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14245 transferer->refer->status = REFER_FAILED; 14246 ast_mutex_unlock(&targetcall_pvt->lock); 14247 ast_channel_unlock(current->chan1); 14248 return -1; 14249 } 14250 14251 /* We have a channel, find the bridge */ 14252 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14253 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14254 14255 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14256 /* Wrong state of new channel */ 14257 if (option_debug > 3) { 14258 if (target.chan2) 14259 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14260 else if (target.chan1->_state != AST_STATE_RING) 14261 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14262 else 14263 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14264 } 14265 } 14266 14267 /* Transfer */ 14268 if (option_debug > 3 && sipdebug) { 14269 if (current->chan2) /* We have two bridges */ 14270 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14271 else /* One bridge, propably transfer of IVR/voicemail etc */ 14272 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14273 } 14274 14275 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14276 14277 /* Perform the transfer */ 14278 res = attempt_transfer(current, &target); 14279 ast_mutex_unlock(&targetcall_pvt->lock); 14280 if (res) { 14281 /* Failed transfer */ 14282 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14283 append_history(transferer, "Xfer", "Refer failed"); 14284 transferer->refer->status = REFER_FAILED; 14285 if (targetcall_pvt->owner) 14286 ast_channel_unlock(targetcall_pvt->owner); 14287 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14288 if (res != -2) 14289 ast_hangup(transferer->owner); 14290 else 14291 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14292 } else { 14293 /* Transfer succeeded! */ 14294 14295 /* Tell transferer that we're done. */ 14296 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14297 append_history(transferer, "Xfer", "Refer succeeded"); 14298 transferer->refer->status = REFER_200OK; 14299 if (targetcall_pvt->owner) { 14300 if (option_debug) 14301 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14302 ast_channel_unlock(targetcall_pvt->owner); 14303 } 14304 } 14305 return 1; 14306 }
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 4714 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04715 { 04716 int h = 0, t = 0; 04717 int lws = 0; 04718 04719 for (; h < len;) { 04720 /* Eliminate all CRs */ 04721 if (msgbuf[h] == '\r') { 04722 h++; 04723 continue; 04724 } 04725 /* Check for end-of-line */ 04726 if (msgbuf[h] == '\n') { 04727 /* Check for end-of-message */ 04728 if (h + 1 == len) 04729 break; 04730 /* Check for a continuation line */ 04731 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04732 /* Merge continuation line */ 04733 h++; 04734 continue; 04735 } 04736 /* Propagate LF and start new line */ 04737 msgbuf[t++] = msgbuf[h++]; 04738 lws = 0; 04739 continue; 04740 } 04741 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04742 if (lws) { 04743 h++; 04744 continue; 04745 } 04746 msgbuf[t++] = msgbuf[h++]; 04747 lws = 1; 04748 continue; 04749 } 04750 msgbuf[t++] = msgbuf[h++]; 04751 if (lws) 04752 lws = 0; 04753 } 04754 msgbuf[t] = '\0'; 04755 return t; 04756 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4385 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().
04386 { 04387 snprintf(tagbuf, len, "as%08lx", ast_random()); 04388 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10340 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
10341 { 10342 const char *a[4]; 10343 const char *peer; 10344 int ret; 10345 10346 peer = astman_get_header(m,"Peer"); 10347 if (ast_strlen_zero(peer)) { 10348 astman_send_error(s, m, "Peer: <name> missing.\n"); 10349 return 0; 10350 } 10351 a[0] = "sip"; 10352 a[1] = "show"; 10353 a[2] = "peer"; 10354 a[3] = peer; 10355 10356 ret = _sip_show_peer(1, -1, s, m, 4, a); 10357 astman_append(s, "\r\n\r\n" ); 10358 return ret; 10359 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9891 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), and total.
Referenced by load_module().
09892 { 09893 const char *id = astman_get_header(m,"ActionID"); 09894 const char *a[] = {"sip", "show", "peers"}; 09895 char idtext[256] = ""; 09896 int total = 0; 09897 09898 if (!ast_strlen_zero(id)) 09899 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09900 09901 astman_send_ack(s, m, "Peer status list will follow"); 09902 /* List the peers in separate manager events */ 09903 _sip_show_peers(-1, &total, s, m, 3, a); 09904 /* Send final confirmation */ 09905 astman_append(s, 09906 "Event: PeerlistComplete\r\n" 09907 "ListItems: %d\r\n" 09908 "%s" 09909 "\r\n", total, idtext); 09910 return 0; 09911 }
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 1666 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01667 { 01668 int len = strlen(sip_methods[id].text); 01669 int l_name = name ? strlen(name) : 0; 01670 /* true if the string is long enough, and ends with whitespace, and matches */ 01671 return (l_name >= len && name[len] < 33 && 01672 !strncasecmp(sip_methods[id].text, name, len)); 01673 }
static char * nat2str | ( | int | nat | ) | [static] |
Convert NAT setting to text string.
Definition at line 9794 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().
09795 { 09796 switch(nat) { 09797 case SIP_NAT_NEVER: 09798 return "No"; 09799 case SIP_NAT_ROUTE: 09800 return "Route"; 09801 case SIP_NAT_ALWAYS: 09802 return "Always"; 09803 case SIP_NAT_RFC3581: 09804 return "RFC3581"; 09805 default: 09806 return "Unknown"; 09807 } 09808 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2221 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02222 { 02223 memset(dst, 0, sizeof(*dst)); 02224 memcpy(dst->data, src->data, sizeof(dst->data)); 02225 dst->len = src->len; 02226 parse_request(dst); 02227 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11969 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, and t.
Referenced by handle_response().
11970 { 11971 char tmp[BUFSIZ]; 11972 char *s, *e, *uri, *t; 11973 char *domain; 11974 11975 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11976 if ((t = strchr(tmp, ','))) 11977 *t = '\0'; 11978 s = get_in_brackets(tmp); 11979 uri = ast_strdupa(s); 11980 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11981 if (!strncasecmp(s, "sip:", 4)) 11982 s += 4; 11983 e = strchr(s, ';'); 11984 if (e) 11985 *e = '\0'; 11986 if (option_debug) 11987 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11988 if (p->owner) 11989 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11990 } else { 11991 e = strchr(tmp, '@'); 11992 if (e) { 11993 *e++ = '\0'; 11994 domain = e; 11995 } else { 11996 /* No username part */ 11997 domain = tmp; 11998 } 11999 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12000 if (e) 12001 *e = '\0'; 12002 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12003 if (e) 12004 *e = '\0'; 12005 12006 if (!strncasecmp(s, "sip:", 4)) 12007 s += 4; 12008 if (option_debug > 1) 12009 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12010 if (p->owner) { 12011 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12012 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12013 ast_string_field_set(p->owner, call_forward, s); 12014 } 12015 } 12016 }
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 7924 of file chan_sip.c.
References ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
07925 { 07926 char contact[BUFSIZ]; 07927 char *c; 07928 07929 /* Look for brackets */ 07930 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07931 c = get_in_brackets(contact); 07932 07933 /* Save full contact to call pvt for later bye or re-invite */ 07934 ast_string_field_set(pvt, fullcontact, c); 07935 07936 /* Save URI for later ACKs, BYE or RE-invites */ 07937 ast_string_field_set(pvt, okcontacturi, c); 07938 07939 /* We should return false for URI:s we can't handle, 07940 like sips:, tel:, mailto:,ldap: etc */ 07941 return TRUE; 07942 }
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 8008 of file chan_sip.c.
References sip_peer::addr, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, 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().
08009 { 08010 char contact[BUFSIZ]; 08011 char data[BUFSIZ]; 08012 const char *expires = get_header(req, "Expires"); 08013 int expiry = atoi(expires); 08014 char *curi, *n, *pt; 08015 int port; 08016 const char *useragent; 08017 struct hostent *hp; 08018 struct ast_hostent ahp; 08019 struct sockaddr_in oldsin; 08020 08021 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08022 08023 if (ast_strlen_zero(expires)) { /* No expires header */ 08024 expires = strcasestr(contact, ";expires="); 08025 if (expires) { 08026 /* XXX bug here, we overwrite the string */ 08027 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08028 if (sscanf(expires + 9, "%d", &expiry) != 1) 08029 expiry = default_expiry; 08030 } else { 08031 /* Nothing has been specified */ 08032 expiry = default_expiry; 08033 } 08034 } 08035 08036 /* Look for brackets */ 08037 curi = contact; 08038 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08039 strsep(&curi, ";"); /* This is Header options, not URI options */ 08040 curi = get_in_brackets(contact); 08041 08042 /* if they did not specify Contact: or Expires:, they are querying 08043 what we currently have stored as their contact address, so return 08044 it 08045 */ 08046 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08047 /* If we have an active registration, tell them when the registration is going to expire */ 08048 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08049 pvt->expiry = ast_sched_when(sched, peer->expire); 08050 return PARSE_REGISTER_QUERY; 08051 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08052 /* This means remove all registrations and return OK */ 08053 memset(&peer->addr, 0, sizeof(peer->addr)); 08054 if (peer->expire > -1) 08055 ast_sched_del(sched, peer->expire); 08056 peer->expire = -1; 08057 08058 destroy_association(peer); 08059 08060 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08061 peer->fullcontact[0] = '\0'; 08062 peer->useragent[0] = '\0'; 08063 peer->sipoptions = 0; 08064 peer->lastms = 0; 08065 08066 if (option_verbose > 2) 08067 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08068 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08069 return PARSE_REGISTER_UPDATE; 08070 } 08071 08072 /* Store whatever we got as a contact from the client */ 08073 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08074 08075 /* For the 200 OK, we should use the received contact */ 08076 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08077 08078 /* Make sure it's a SIP URL */ 08079 if (strncasecmp(curi, "sip:", 4)) { 08080 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08081 } else 08082 curi += 4; 08083 /* Ditch q */ 08084 curi = strsep(&curi, ";"); 08085 /* Grab host */ 08086 n = strchr(curi, '@'); 08087 if (!n) { 08088 n = curi; 08089 curi = NULL; 08090 } else 08091 *n++ = '\0'; 08092 pt = strchr(n, ':'); 08093 if (pt) { 08094 *pt++ = '\0'; 08095 port = atoi(pt); 08096 } else 08097 port = STANDARD_SIP_PORT; 08098 oldsin = peer->addr; 08099 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08100 /* XXX This could block for a long time XXX */ 08101 hp = ast_gethostbyname(n, &ahp); 08102 if (!hp) { 08103 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08104 return PARSE_REGISTER_FAILED; 08105 } 08106 peer->addr.sin_family = AF_INET; 08107 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08108 peer->addr.sin_port = htons(port); 08109 } else { 08110 /* Don't trust the contact field. Just use what they came to us 08111 with */ 08112 peer->addr = pvt->recv; 08113 } 08114 08115 /* Save SIP options profile */ 08116 peer->sipoptions = pvt->sipoptions; 08117 08118 if (curi && ast_strlen_zero(peer->username)) 08119 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08120 08121 if (peer->expire > -1) { 08122 ast_sched_del(sched, peer->expire); 08123 peer->expire = -1; 08124 } 08125 if (expiry > max_expiry) 08126 expiry = max_expiry; 08127 if (expiry < min_expiry) 08128 expiry = min_expiry; 08129 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 08130 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 08131 pvt->expiry = expiry; 08132 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); 08133 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08134 ast_db_put("SIP/Registry", peer->name, data); 08135 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08136 08137 /* Is this a new IP address for us? */ 08138 if (inaddrcmp(&peer->addr, &oldsin)) { 08139 sip_poke_peer(peer); 08140 if (option_verbose > 2) 08141 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); 08142 register_peer_exten(peer, 1); 08143 } 08144 08145 /* Save User agent */ 08146 useragent = get_header(req, "User-Agent"); 08147 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08148 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08149 if (option_verbose > 3) 08150 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08151 } 08152 return PARSE_REGISTER_UPDATE; 08153 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4761 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04762 { 04763 /* Divide fields by NULL's */ 04764 char *c; 04765 int f = 0; 04766 04767 c = req->data; 04768 04769 /* First header starts immediately */ 04770 req->header[f] = c; 04771 while(*c) { 04772 if (*c == '\n') { 04773 /* We've got a new header */ 04774 *c = 0; 04775 04776 if (sipdebug && option_debug > 3) 04777 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04778 if (ast_strlen_zero(req->header[f])) { 04779 /* Line by itself means we're now in content */ 04780 c++; 04781 break; 04782 } 04783 if (f >= SIP_MAX_HEADERS - 1) { 04784 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04785 } else 04786 f++; 04787 req->header[f] = c + 1; 04788 } else if (*c == '\r') { 04789 /* Ignore but eliminate \r's */ 04790 *c = 0; 04791 } 04792 c++; 04793 } 04794 /* Check for last header */ 04795 if (!ast_strlen_zero(req->header[f])) { 04796 if (sipdebug && option_debug > 3) 04797 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04798 f++; 04799 } 04800 req->headers = f; 04801 /* Now we process any mime content */ 04802 f = 0; 04803 req->line[f] = c; 04804 while(*c) { 04805 if (*c == '\n') { 04806 /* We've got a new line */ 04807 *c = 0; 04808 if (sipdebug && option_debug > 3) 04809 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04810 if (f >= SIP_MAX_LINES - 1) { 04811 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04812 } else 04813 f++; 04814 req->line[f] = c + 1; 04815 } else if (*c == '\r') { 04816 /* Ignore and eliminate \r's */ 04817 *c = 0; 04818 } 04819 c++; 04820 } 04821 /* Check for last line */ 04822 if (!ast_strlen_zero(req->line[f])) 04823 f++; 04824 req->lines = f; 04825 if (*c) 04826 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04827 /* Split up the first line parts */ 04828 determine_firstline_parts(req); 04829 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1690 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01691 { 01692 char *next, *sep; 01693 char *temp; 01694 unsigned int profile = 0; 01695 int i, found; 01696 01697 if (ast_strlen_zero(supported) ) 01698 return 0; 01699 temp = ast_strdupa(supported); 01700 01701 if (option_debug > 2 && sipdebug) 01702 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01703 01704 for (next = temp; next; next = sep) { 01705 found = FALSE; 01706 if ( (sep = strchr(next, ',')) != NULL) 01707 *sep++ = '\0'; 01708 next = ast_skip_blanks(next); 01709 if (option_debug > 2 && sipdebug) 01710 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01711 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01712 if (!strcasecmp(next, sip_options[i].text)) { 01713 profile |= sip_options[i].id; 01714 found = TRUE; 01715 if (option_debug > 2 && sipdebug) 01716 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01717 break; 01718 } 01719 } 01720 if (!found && option_debug > 2 && sipdebug) { 01721 if (!strncasecmp(next, "x-", 2)) 01722 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01723 else 01724 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01725 } 01726 } 01727 01728 if (pvt) 01729 pvt->sipoptions = profile; 01730 return profile; 01731 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9813 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09814 { 09815 int res = 0; 09816 if (peer->maxms) { 09817 if (peer->lastms < 0) { 09818 ast_copy_string(status, "UNREACHABLE", statuslen); 09819 } else if (peer->lastms > peer->maxms) { 09820 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09821 res = 1; 09822 } else if (peer->lastms) { 09823 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09824 res = 1; 09825 } else { 09826 ast_copy_string(status, "UNKNOWN", statuslen); 09827 } 09828 } else { 09829 ast_copy_string(status, "Unmonitored", statuslen); 09830 /* Checking if port is 0 */ 09831 res = -1; 09832 } 09833 return res; 09834 }
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 10281 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().
10282 { 10283 int x, codec; 10284 10285 for(x = 0; x < 32 ; x++) { 10286 codec = ast_codec_pref_index(pref, x); 10287 if (!codec) 10288 break; 10289 ast_cli(fd, "%s", ast_getformatname(codec)); 10290 ast_cli(fd, ":%d", pref->framing[x]); 10291 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10292 ast_cli(fd, ","); 10293 } 10294 if (!x) 10295 ast_cli(fd, "none"); 10296 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10072 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10073 { 10074 char buf[256]; 10075 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10076 }
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 4944 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, LOG_WARNING, 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, 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.
04945 { 04946 const char *m; /* SDP media offer */ 04947 const char *c; 04948 const char *a; 04949 char host[258]; 04950 int len = -1; 04951 int portno = -1; /*!< RTP Audio port number */ 04952 int vportno = -1; /*!< RTP Video port number */ 04953 int udptlportno = -1; 04954 int peert38capability = 0; 04955 char s[256]; 04956 int old = 0; 04957 04958 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04959 int peercapability = 0, peernoncodeccapability = 0; 04960 int vpeercapability = 0, vpeernoncodeccapability = 0; 04961 struct sockaddr_in sin; /*!< media socket address */ 04962 struct sockaddr_in vsin; /*!< Video socket address */ 04963 04964 const char *codecs; 04965 struct hostent *hp; /*!< RTP Audio host IP */ 04966 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04967 struct ast_hostent audiohp; 04968 struct ast_hostent videohp; 04969 int codec; 04970 int destiterator = 0; 04971 int iterator; 04972 int sendonly = -1; 04973 int numberofports; 04974 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04975 int newjointcapability; /* Negotiated capability */ 04976 int newpeercapability; 04977 int newnoncodeccapability; 04978 int numberofmediastreams = 0; 04979 int debug = sip_debug_test_pvt(p); 04980 04981 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 04982 int last_rtpmap_codec=0; 04983 04984 if (!p->rtp) { 04985 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04986 return -1; 04987 } 04988 04989 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04990 newaudiortp = alloca(ast_rtp_alloc_size()); 04991 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04992 ast_rtp_new_init(newaudiortp); 04993 ast_rtp_pt_clear(newaudiortp); 04994 04995 newvideortp = alloca(ast_rtp_alloc_size()); 04996 memset(newvideortp, 0, ast_rtp_alloc_size()); 04997 ast_rtp_new_init(newvideortp); 04998 ast_rtp_pt_clear(newvideortp); 04999 05000 /* Update our last rtprx when we receive an SDP, too */ 05001 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05002 05003 05004 /* Try to find first media stream */ 05005 m = get_sdp(req, "m"); 05006 destiterator = req->sdp_start; 05007 c = get_sdp_iterate(&destiterator, req, "c"); 05008 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05009 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05010 return -1; 05011 } 05012 05013 /* Check for IPv4 address (not IPv6 yet) */ 05014 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05015 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05016 return -1; 05017 } 05018 05019 /* XXX This could block for a long time, and block the main thread! XXX */ 05020 hp = ast_gethostbyname(host, &audiohp); 05021 if (!hp) { 05022 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05023 return -1; 05024 } 05025 vhp = hp; /* Copy to video address as default too */ 05026 05027 iterator = req->sdp_start; 05028 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05029 05030 05031 /* Find media streams in this SDP offer */ 05032 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05033 int x; 05034 int audio = FALSE; 05035 05036 numberofports = 1; 05037 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05038 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05039 audio = TRUE; 05040 numberofmediastreams++; 05041 /* Found audio stream in this media definition */ 05042 portno = x; 05043 /* Scan through the RTP payload types specified in a "m=" line: */ 05044 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05045 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05046 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05047 return -1; 05048 } 05049 if (debug) 05050 ast_verbose("Found RTP audio format %d\n", codec); 05051 ast_rtp_set_m_type(newaudiortp, codec); 05052 } 05053 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05054 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05055 /* If it is not audio - is it video ? */ 05056 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05057 numberofmediastreams++; 05058 vportno = x; 05059 /* Scan through the RTP payload types specified in a "m=" line: */ 05060 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05061 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05062 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05063 return -1; 05064 } 05065 if (debug) 05066 ast_verbose("Found RTP video format %d\n", codec); 05067 ast_rtp_set_m_type(newvideortp, codec); 05068 } 05069 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05070 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05071 if (debug) 05072 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05073 udptlportno = x; 05074 numberofmediastreams++; 05075 05076 if (p->owner && p->lastinvite) { 05077 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05078 if (option_debug > 1) 05079 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05080 } else { 05081 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05082 if (option_debug > 1) 05083 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05084 } 05085 } else 05086 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05087 if (numberofports > 1) 05088 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05089 05090 05091 /* Check for Media-description-level-address for audio */ 05092 c = get_sdp_iterate(&destiterator, req, "c"); 05093 if (!ast_strlen_zero(c)) { 05094 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05095 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05096 } else { 05097 /* XXX This could block for a long time, and block the main thread! XXX */ 05098 if (audio) { 05099 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05100 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05101 return -2; 05102 } 05103 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05104 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05105 return -2; 05106 } 05107 } 05108 05109 } 05110 } 05111 if (portno == -1 && vportno == -1 && udptlportno == -1) 05112 /* No acceptable offer found in SDP - we have no ports */ 05113 /* Do not change RTP or VRTP if this is a re-invite */ 05114 return -2; 05115 05116 if (numberofmediastreams > 2) 05117 /* We have too many fax, audio and/or video media streams, fail this offer */ 05118 return -3; 05119 05120 /* RTP addresses and ports for audio and video */ 05121 sin.sin_family = AF_INET; 05122 vsin.sin_family = AF_INET; 05123 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05124 if (vhp) 05125 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05126 05127 /* Setup UDPTL port number */ 05128 if (p->udptl) { 05129 if (udptlportno > 0) { 05130 sin.sin_port = htons(udptlportno); 05131 ast_udptl_set_peer(p->udptl, &sin); 05132 if (debug) 05133 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05134 } else { 05135 ast_udptl_stop(p->udptl); 05136 if (debug) 05137 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05138 } 05139 } 05140 05141 05142 if (p->rtp) { 05143 if (portno > 0) { 05144 sin.sin_port = htons(portno); 05145 ast_rtp_set_peer(p->rtp, &sin); 05146 if (debug) 05147 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05148 } else { 05149 if (udptlportno > 0) { 05150 if (debug) 05151 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05152 } else { 05153 ast_rtp_stop(p->rtp); 05154 if (debug) 05155 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05156 } 05157 } 05158 } 05159 /* Setup video port number */ 05160 if (vportno != -1) 05161 vsin.sin_port = htons(vportno); 05162 05163 /* Next, scan through each "a=rtpmap:" line, noting each 05164 * specified RTP payload type (with corresponding MIME subtype): 05165 */ 05166 /* XXX This needs to be done per media stream, since it's media stream specific */ 05167 iterator = req->sdp_start; 05168 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05169 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05170 if (option_debug > 1) { 05171 int breakout = FALSE; 05172 05173 /* If we're debugging, check for unsupported sdp options */ 05174 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05175 if (debug) 05176 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05177 breakout = TRUE; 05178 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05179 /* Format parameters: Not supported */ 05180 /* Note: This is used for codec parameters, like bitrate for 05181 G722 and video formats for H263 and H264 05182 See RFC2327 for an example */ 05183 if (debug) 05184 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05185 breakout = TRUE; 05186 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05187 /* Video stuff: Not supported */ 05188 if (debug) 05189 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05190 breakout = TRUE; 05191 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05192 /* Video stuff: Not supported */ 05193 if (debug) 05194 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05195 breakout = TRUE; 05196 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05197 /* SRTP stuff, not yet supported */ 05198 if (debug) 05199 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05200 breakout = TRUE; 05201 } 05202 if (breakout) /* We have a match, skip to next header */ 05203 continue; 05204 } 05205 if (!strcasecmp(a, "sendonly")) { 05206 if (sendonly == -1) 05207 sendonly = 1; 05208 continue; 05209 } else if (!strcasecmp(a, "inactive")) { 05210 if (sendonly == -1) 05211 sendonly = 2; 05212 continue; 05213 } else if (!strcasecmp(a, "sendrecv")) { 05214 if (sendonly == -1) 05215 sendonly = 0; 05216 continue; 05217 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05218 char *tmp = strrchr(a, ':'); 05219 long int framing = 0; 05220 if (tmp) { 05221 tmp++; 05222 framing = strtol(tmp, NULL, 10); 05223 if (framing == LONG_MIN || framing == LONG_MAX) { 05224 framing = 0; 05225 if (option_debug) 05226 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05227 } 05228 } 05229 if (framing && last_rtpmap_codec) { 05230 if (p->autoframing) { 05231 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05232 int codec_n; 05233 int format = 0; 05234 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05235 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05236 if (!format) /* non-codec or not found */ 05237 continue; 05238 if (option_debug) 05239 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05240 ast_codec_pref_setsize(pref, format, framing); 05241 } 05242 ast_rtp_codec_setpref(p->rtp, pref); 05243 } 05244 } 05245 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05246 last_rtpmap_codec = 0; 05247 continue; 05248 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05249 /* We have a rtpmap to handle */ 05250 int found = FALSE; 05251 /* We should propably check if this is an audio or video codec 05252 so we know where to look */ 05253 05254 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05255 /* Note: should really look at the 'freq' and '#chans' params too */ 05256 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05257 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05258 if (debug) 05259 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05260 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05261 last_rtpmap_codec++; 05262 found = TRUE; 05263 05264 } else if (p->vrtp) { 05265 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05266 if (debug) 05267 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05268 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05269 last_rtpmap_codec++; 05270 found = TRUE; 05271 } 05272 } 05273 } else { 05274 if (debug) 05275 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05276 } 05277 05278 if (!found) { 05279 /* Remove this codec since it's an unknown media type for us */ 05280 /* XXX This is buggy since the media line for audio and video can have the 05281 same numbers. We need to check as described above, but for testing this works... */ 05282 ast_rtp_unset_m_type(newaudiortp, codec); 05283 ast_rtp_unset_m_type(newvideortp, codec); 05284 if (debug) 05285 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05286 } 05287 } 05288 } 05289 05290 if (udptlportno != -1) { 05291 int found = 0, x; 05292 05293 old = 0; 05294 05295 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05296 iterator = req->sdp_start; 05297 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05298 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05299 found = 1; 05300 if (option_debug > 2) 05301 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05302 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05303 found = 1; 05304 if (option_debug > 2) 05305 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05306 switch (x) { 05307 case 14400: 05308 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05309 break; 05310 case 12000: 05311 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05312 break; 05313 case 9600: 05314 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05315 break; 05316 case 7200: 05317 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05318 break; 05319 case 4800: 05320 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05321 break; 05322 case 2400: 05323 peert38capability |= T38FAX_RATE_2400; 05324 break; 05325 } 05326 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05327 found = 1; 05328 if (option_debug > 2) 05329 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05330 if (x == 0) 05331 peert38capability |= T38FAX_VERSION_0; 05332 else if (x == 1) 05333 peert38capability |= T38FAX_VERSION_1; 05334 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05335 found = 1; 05336 if (option_debug > 2) 05337 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05338 ast_udptl_set_far_max_datagram(p->udptl, x); 05339 ast_udptl_set_local_max_datagram(p->udptl, x); 05340 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05341 found = 1; 05342 if (option_debug > 2) 05343 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05344 if (x == 1) 05345 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05346 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05347 found = 1; 05348 if (option_debug > 2) 05349 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05350 if (x == 1) 05351 peert38capability |= T38FAX_TRANSCODING_MMR; 05352 } 05353 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05354 found = 1; 05355 if (option_debug > 2) 05356 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05357 if (x == 1) 05358 peert38capability |= T38FAX_TRANSCODING_JBIG; 05359 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05360 found = 1; 05361 if (option_debug > 2) 05362 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05363 if (!strcasecmp(s, "localTCF")) 05364 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05365 else if (!strcasecmp(s, "transferredTCF")) 05366 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05367 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05368 found = 1; 05369 if (option_debug > 2) 05370 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05371 if (!strcasecmp(s, "t38UDPRedundancy")) { 05372 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05373 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05374 } else if (!strcasecmp(s, "t38UDPFEC")) { 05375 peert38capability |= T38FAX_UDP_EC_FEC; 05376 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05377 } else { 05378 peert38capability |= T38FAX_UDP_EC_NONE; 05379 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05380 } 05381 } 05382 } 05383 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05384 p->t38.peercapability = peert38capability; 05385 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05386 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05387 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05388 } 05389 if (debug) 05390 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05391 p->t38.capability, 05392 p->t38.peercapability, 05393 p->t38.jointcapability); 05394 } else { 05395 p->t38.state = T38_DISABLED; 05396 if (option_debug > 2) 05397 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05398 } 05399 05400 /* Now gather all of the codecs that we are asked for: */ 05401 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05402 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05403 05404 newjointcapability = p->capability & (peercapability | vpeercapability); 05405 newpeercapability = (peercapability | vpeercapability); 05406 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05407 05408 05409 if (debug) { 05410 /* shame on whoever coded this.... */ 05411 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05412 05413 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05414 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05415 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05416 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05417 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05418 05419 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05420 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05421 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05422 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05423 } 05424 if (!newjointcapability) { 05425 /* If T.38 was not negotiated either, totally bail out... */ 05426 if (!p->t38.jointcapability) { 05427 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05428 /* Do NOT Change current setting */ 05429 return -1; 05430 } else { 05431 if (option_debug > 2) 05432 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05433 return 0; 05434 } 05435 } 05436 05437 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05438 they are acceptable */ 05439 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05440 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05441 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05442 05443 ast_rtp_pt_copy(p->rtp, newaudiortp); 05444 if (p->vrtp) 05445 ast_rtp_pt_copy(p->vrtp, newvideortp); 05446 05447 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05448 ast_clear_flag(&p->flags[0], SIP_DTMF); 05449 if (newnoncodeccapability & AST_RTP_DTMF) { 05450 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05451 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05452 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05453 ast_rtp_setdtmf(p->rtp, 1); 05454 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05455 } else { 05456 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05457 } 05458 } 05459 05460 /* Setup audio port number */ 05461 if (p->rtp && sin.sin_port) { 05462 ast_rtp_set_peer(p->rtp, &sin); 05463 if (debug) 05464 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05465 } 05466 05467 /* Setup video port number */ 05468 if (p->vrtp && vsin.sin_port) { 05469 ast_rtp_set_peer(p->vrtp, &vsin); 05470 if (debug) 05471 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05472 } 05473 05474 /* Ok, we're going with this offer */ 05475 if (option_debug > 1) { 05476 char buf[BUFSIZ]; 05477 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05478 } 05479 05480 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05481 return 0; 05482 05483 if (option_debug > 3) 05484 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05485 05486 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05487 if (debug) { 05488 char s1[BUFSIZ], s2[BUFSIZ]; 05489 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05490 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05491 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05492 } 05493 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05494 ast_set_read_format(p->owner, p->owner->readformat); 05495 ast_set_write_format(p->owner, p->owner->writeformat); 05496 } 05497 05498 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05499 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05500 /* Activate a re-invite */ 05501 ast_queue_frame(p->owner, &ast_null_frame); 05502 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05503 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05504 S_OR(p->mohsuggest, NULL), 05505 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05506 if (sendonly) 05507 ast_rtp_stop(p->rtp); 05508 /* RTCP needs to go ahead, even if we're on hold!!! */ 05509 /* Activate a re-invite */ 05510 ast_queue_frame(p->owner, &ast_null_frame); 05511 } 05512 05513 /* Manager Hold and Unhold events must be generated, if necessary */ 05514 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05515 change_hold_state(p, req, FALSE, sendonly); 05516 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05517 change_hold_state(p, req, TRUE, sendonly); 05518 return 0; 05519 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2490 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_dnsmgr_lookup(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.
02491 { 02492 struct sip_peer *peer=NULL; 02493 struct ast_variable *var = NULL; 02494 struct ast_config *peerlist = NULL; 02495 struct ast_variable *tmp; 02496 struct ast_flags flags = {0}; 02497 const char *iabuf = NULL; 02498 char portstring[6]; /*up to five digits plus null terminator*/ 02499 const char *insecure; 02500 char *cat = NULL; 02501 unsigned short portnum; 02502 02503 /* First check on peer name */ 02504 if (newpeername) { 02505 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02506 if (!var && sin) 02507 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02508 if (!var) { 02509 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02510 /*!\note 02511 * If this one loaded something, then we need to ensure that the host 02512 * field matched. The only reason why we can't have this as a criteria 02513 * is because we only have the IP address and the host field might be 02514 * set as a name (and the reverse PTR might not match). 02515 */ 02516 if (var) { 02517 for (tmp = var; tmp; tmp = tmp->next) { 02518 if (!strcasecmp(var->name, "host")) { 02519 struct in_addr sin2 = { 0, }; 02520 struct ast_dnsmgr_entry *dnsmgr = NULL; 02521 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02522 /* No match */ 02523 ast_variables_destroy(var); 02524 var = NULL; 02525 } 02526 break; 02527 } 02528 } 02529 } 02530 } 02531 } 02532 02533 if (!var && sin) { /* Then check on IP address */ 02534 iabuf = ast_inet_ntoa(sin->sin_addr); 02535 portnum = ntohs(sin->sin_port); 02536 sprintf(portstring, "%d", portnum); 02537 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02538 if (!var) 02539 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02540 if (!var) { 02541 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02542 if(peerlist){ 02543 while((cat = ast_category_browse(peerlist, cat))) 02544 { 02545 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02546 set_insecure_flags(&flags, insecure, -1); 02547 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02548 var = ast_category_root(peerlist, cat); 02549 break; 02550 } 02551 } 02552 } 02553 if(!var) { 02554 ast_config_destroy(peerlist); 02555 peerlist = NULL; /*for safety's sake*/ 02556 cat = NULL; 02557 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02558 if(peerlist) { 02559 while((cat = ast_category_browse(peerlist, cat))) 02560 { 02561 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02562 set_insecure_flags(&flags, insecure, -1); 02563 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02564 var = ast_category_root(peerlist, cat); 02565 break; 02566 } 02567 } 02568 } 02569 } 02570 } 02571 } 02572 02573 if (!var) { 02574 if(peerlist) 02575 ast_config_destroy(peerlist); 02576 return NULL; 02577 } 02578 02579 for (tmp = var; tmp; tmp = tmp->next) { 02580 /* If this is type=user, then skip this object. */ 02581 if (!strcasecmp(tmp->name, "type") && 02582 !strcasecmp(tmp->value, "user")) { 02583 ast_variables_destroy(var); 02584 return NULL; 02585 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02586 newpeername = tmp->value; 02587 } 02588 } 02589 02590 if (!newpeername) { /* Did not find peer in realtime */ 02591 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02592 if(peerlist) 02593 ast_config_destroy(peerlist); 02594 else 02595 ast_variables_destroy(var); 02596 return NULL; 02597 } 02598 02599 /* Peer found in realtime, now build it in memory */ 02600 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02601 if (!peer) { 02602 if(peerlist) 02603 ast_config_destroy(peerlist); 02604 else 02605 ast_variables_destroy(var); 02606 return NULL; 02607 } 02608 02609 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02610 /* Cache peer */ 02611 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02612 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02613 if (peer->expire > -1) { 02614 ast_sched_del(sched, peer->expire); 02615 } 02616 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02617 } 02618 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02619 } else { 02620 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02621 } 02622 if(peerlist) 02623 ast_config_destroy(peerlist); 02624 else 02625 ast_variables_destroy(var); 02626 return peer; 02627 }
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 2375 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02376 { 02377 char port[10]; 02378 char ipaddr[INET_ADDRSTRLEN]; 02379 char regseconds[20]; 02380 02381 char *sysname = ast_config_AST_SYSTEM_NAME; 02382 char *syslabel = NULL; 02383 02384 time_t nowtime = time(NULL) + expirey; 02385 const char *fc = fullcontact ? "fullcontact" : NULL; 02386 02387 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02388 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02389 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02390 02391 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02392 sysname = NULL; 02393 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02394 syslabel = "regserver"; 02395 02396 if (fc) 02397 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02398 "port", port, "regseconds", regseconds, 02399 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02400 else 02401 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02402 "port", port, "regseconds", regseconds, 02403 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02404 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static, read] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2677 of file chan_sip.c.
References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, userl, ast_variable::value, and var.
02678 { 02679 struct ast_variable *var; 02680 struct ast_variable *tmp; 02681 struct sip_user *user = NULL; 02682 02683 var = ast_load_realtime("sipusers", "name", username, NULL); 02684 02685 if (!var) 02686 return NULL; 02687 02688 for (tmp = var; tmp; tmp = tmp->next) { 02689 if (!strcasecmp(tmp->name, "type") && 02690 !strcasecmp(tmp->value, "peer")) { 02691 ast_variables_destroy(var); 02692 return NULL; 02693 } 02694 } 02695 02696 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02697 02698 if (!user) { /* No user found */ 02699 ast_variables_destroy(var); 02700 return NULL; 02701 } 02702 02703 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02704 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02705 suserobjs++; 02706 ASTOBJ_CONTAINER_LINK(&userl,user); 02707 } else { 02708 /* Move counter from s to r... */ 02709 suserobjs--; 02710 ruserobjs++; 02711 ast_set_flag(&user->flags[0], SIP_REALTIME); 02712 } 02713 ast_variables_destroy(var); 02714 return user; 02715 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9696 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
09697 { 09698 char buf[1024]; 09699 struct ast_frame f; 09700 const char *content_type = get_header(req, "Content-Type"); 09701 09702 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09703 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09704 if (!p->owner) 09705 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09706 return; 09707 } 09708 09709 if (get_msg_text(buf, sizeof(buf), req)) { 09710 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09711 transmit_response(p, "202 Accepted", req); 09712 if (!p->owner) 09713 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09714 return; 09715 } 09716 09717 if (p->owner) { 09718 if (sip_debug_test_pvt(p)) 09719 ast_verbose("Message received: '%s'\n", buf); 09720 memset(&f, 0, sizeof(f)); 09721 f.frametype = AST_FRAME_TEXT; 09722 f.subclass = 0; 09723 f.offset = 0; 09724 f.data = buf; 09725 f.datalen = strlen(buf); 09726 ast_queue_frame(p->owner, &f); 09727 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09728 } else { /* Message outside of a call, we do not support that */ 09729 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); 09730 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09731 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09732 } 09733 return; 09734 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1625 of file chan_sip.c.
References referstatusstrings, and c_referstatusstring::text.
Referenced by __sip_show_channels().
01626 { 01627 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01628 int x; 01629 01630 for (x = 0; x < i; x++) { 01631 if (referstatusstrings[x].status == rstatus) 01632 return (char *) referstatusstrings[x].text; 01633 } 01634 return ""; 01635 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7864 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(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07865 { 07866 char data[256]; 07867 struct in_addr in; 07868 int expiry; 07869 int port; 07870 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07871 07872 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07873 return; 07874 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07875 return; 07876 07877 scan = data; 07878 addr = strsep(&scan, ":"); 07879 port_str = strsep(&scan, ":"); 07880 expiry_str = strsep(&scan, ":"); 07881 username = strsep(&scan, ":"); 07882 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07883 07884 if (!inet_aton(addr, &in)) 07885 return; 07886 07887 if (port_str) 07888 port = atoi(port_str); 07889 else 07890 return; 07891 07892 if (expiry_str) 07893 expiry = atoi(expiry_str); 07894 else 07895 return; 07896 07897 if (username) 07898 ast_copy_string(peer->username, username, sizeof(peer->username)); 07899 if (contact) 07900 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07901 07902 if (option_debug > 1) 07903 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07904 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07905 07906 memset(&peer->addr, 0, sizeof(peer->addr)); 07907 peer->addr.sin_family = AF_INET; 07908 peer->addr.sin_addr = in; 07909 peer->addr.sin_port = htons(port); 07910 if (sipsock < 0) { 07911 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07912 if (peer->pokeexpire > -1) 07913 ast_sched_del(sched, peer->pokeexpire); 07914 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07915 } else 07916 sip_poke_peer(peer); 07917 if (peer->expire > -1) 07918 ast_sched_del(sched, peer->expire); 07919 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07920 register_peer_exten(peer, TRUE); 07921 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2407 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().
02408 { 02409 char multi[256]; 02410 char *stringp, *ext, *context; 02411 02412 /* XXX note that global_regcontext is both a global 'enable' flag and 02413 * the name of the global regexten context, if not specified 02414 * individually. 02415 */ 02416 if (ast_strlen_zero(global_regcontext)) 02417 return; 02418 02419 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02420 stringp = multi; 02421 while ((ext = strsep(&stringp, "&"))) { 02422 if ((context = strchr(ext, '@'))) { 02423 *context++ = '\0'; /* split ext@context */ 02424 if (!ast_context_find(context)) { 02425 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02426 continue; 02427 } 02428 } else { 02429 context = global_regcontext; 02430 } 02431 if (onoff) 02432 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02433 ast_strdup(peer->name), ast_free, "SIP"); 02434 else 02435 ast_context_remove_extension(context, ext, 1, NULL); 02436 } 02437 }
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 8608 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08610 { 08611 enum check_auth_result res = AUTH_NOT_FOUND; 08612 struct sip_peer *peer; 08613 char tmp[256]; 08614 char *name, *c; 08615 char *t; 08616 char *domain; 08617 08618 /* Terminate URI */ 08619 t = uri; 08620 while(*t && (*t > 32) && (*t != ';')) 08621 t++; 08622 *t = '\0'; 08623 08624 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08625 if (pedanticsipchecking) 08626 ast_uri_decode(tmp); 08627 08628 c = get_in_brackets(tmp); 08629 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08630 08631 if (!strncasecmp(c, "sip:", 4)) { 08632 name = c + 4; 08633 } else { 08634 name = c; 08635 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08636 } 08637 08638 /* Strip off the domain name */ 08639 if ((c = strchr(name, '@'))) { 08640 *c++ = '\0'; 08641 domain = c; 08642 if ((c = strchr(domain, ':'))) /* Remove :port */ 08643 *c = '\0'; 08644 if (!AST_LIST_EMPTY(&domain_list)) { 08645 if (!check_sip_domain(domain, NULL, 0)) { 08646 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08647 return AUTH_UNKNOWN_DOMAIN; 08648 } 08649 } 08650 } 08651 08652 ast_string_field_set(p, exten, name); 08653 build_contact(p); 08654 peer = find_peer(name, NULL, 1); 08655 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08656 /* Peer fails ACL check */ 08657 if (peer) { 08658 ASTOBJ_UNREF(peer, sip_destroy_peer); 08659 peer = NULL; 08660 res = AUTH_ACL_FAILED; 08661 } else 08662 res = AUTH_NOT_FOUND; 08663 } 08664 if (peer) { 08665 /* Set Frame packetization */ 08666 if (p->rtp) { 08667 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08668 p->autoframing = peer->autoframing; 08669 } 08670 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08671 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08672 res = AUTH_PEER_NOT_DYNAMIC; 08673 } else { 08674 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08675 transmit_response(p, "100 Trying", req); 08676 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08677 sip_cancel_destroy(p); 08678 08679 /* We have a succesful registration attemp with proper authentication, 08680 now, update the peer */ 08681 switch (parse_register_contact(p, peer, req)) { 08682 case PARSE_REGISTER_FAILED: 08683 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08684 transmit_response_with_date(p, "400 Bad Request", req); 08685 peer->lastmsgssent = -1; 08686 res = 0; 08687 break; 08688 case PARSE_REGISTER_QUERY: 08689 transmit_response_with_date(p, "200 OK", req); 08690 peer->lastmsgssent = -1; 08691 res = 0; 08692 break; 08693 case PARSE_REGISTER_UPDATE: 08694 update_peer(peer, p->expiry); 08695 /* Say OK and ask subsystem to retransmit msg counter */ 08696 transmit_response_with_date(p, "200 OK", req); 08697 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08698 peer->lastmsgssent = -1; 08699 res = 0; 08700 break; 08701 } 08702 } 08703 } 08704 } 08705 if (!peer && autocreatepeer) { 08706 /* Create peer if we have autocreate mode enabled */ 08707 peer = temp_peer(name); 08708 if (peer) { 08709 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08710 sip_cancel_destroy(p); 08711 switch (parse_register_contact(p, peer, req)) { 08712 case PARSE_REGISTER_FAILED: 08713 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08714 transmit_response_with_date(p, "400 Bad Request", req); 08715 peer->lastmsgssent = -1; 08716 res = 0; 08717 break; 08718 case PARSE_REGISTER_QUERY: 08719 transmit_response_with_date(p, "200 OK", req); 08720 peer->lastmsgssent = -1; 08721 res = 0; 08722 break; 08723 case PARSE_REGISTER_UPDATE: 08724 /* Say OK and ask subsystem to retransmit msg counter */ 08725 transmit_response_with_date(p, "200 OK", req); 08726 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08727 peer->lastmsgssent = -1; 08728 res = 0; 08729 break; 08730 } 08731 } 08732 } 08733 if (!peer && global_alwaysauthreject) { 08734 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 08735 * trying to avoid leaking information, we MUST also transmit the same 08736 * response when we DON'T find a peer. */ 08737 transmit_response(p, "100 Trying", req); 08738 /* Insert a fake delay between the 100 and the subsequent failure. */ 08739 sched_yield(); 08740 } 08741 if (!res) { 08742 ast_device_state_changed("SIP/%s", peer->name); 08743 } 08744 if (res < 0) { 08745 switch (res) { 08746 case AUTH_SECRET_FAILED: 08747 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08748 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08749 break; 08750 case AUTH_USERNAME_MISMATCH: 08751 /* Username and digest username does not match. 08752 Asterisk uses the From: username for authentication. We need the 08753 users to use the same authentication user name until we support 08754 proper authentication by digest auth name */ 08755 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08756 break; 08757 case AUTH_NOT_FOUND: 08758 case AUTH_PEER_NOT_DYNAMIC: 08759 case AUTH_ACL_FAILED: 08760 if (global_alwaysauthreject) { 08761 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 08762 } else { 08763 /* URI not found */ 08764 if (res == AUTH_PEER_NOT_DYNAMIC) 08765 transmit_response(p, "403 Forbidden", &p->initreq); 08766 else 08767 transmit_response(p, "404 Not found", &p->initreq); 08768 } 08769 break; 08770 default: 08771 break; 08772 } 08773 } 08774 if (peer) 08775 ASTOBJ_UNREF(peer, sip_destroy_peer); 08776 08777 return res; 08778 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 7362 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.
07363 { 07364 switch(regstate) { 07365 case REG_STATE_FAILED: 07366 return "Failed"; 07367 case REG_STATE_UNREGISTERED: 07368 return "Unregistered"; 07369 case REG_STATE_REGSENT: 07370 return "Request Sent"; 07371 case REG_STATE_AUTHSENT: 07372 return "Auth. Sent"; 07373 case REG_STATE_REGISTERED: 07374 return "Registered"; 07375 case REG_STATE_REJECTED: 07376 return "Rejected"; 07377 case REG_STATE_TIMEOUT: 07378 return "Timeout"; 07379 case REG_STATE_NOAUTH: 07380 return "No Authentication"; 07381 default: 07382 return "Unknown"; 07383 } 07384 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17885 of file chan_sip.c.
References sip_reload().
17886 { 17887 return sip_reload(0, 0, NULL); 17888 }
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 16782 of file chan_sip.c.
References __ourip, add_realm_authentication(), add_sip_domain(), ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_flags, ast_device_state_changed(), ast_enable_packet_fragmentation(), ast_find_ourip(), AST_FLAGS_ALL, ast_free_ha(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_tos2str(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, authl, bindaddr, build_peer(), build_user(), channelreloadreason2txt(), cleanup_stale_contexts(), clear_realm_authentication(), clear_sip_domains(), context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_DEFAULT_EXPIRY, DEFAULT_EXPIRY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, errno, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, gen, global_jbconf, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_variable::name, ast_variable::next, notify_types, option_debug, option_verbose, ourport, outboundproxyip, peerl, regl, secret, SIP_CAN_REINVITE, sip_destroy(), sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, sip_register(), sip_registry_destroy(), SIP_USEREQPHONE, sipsock, STANDARD_SIP_PORT, strsep(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, userl, username, ast_variable::value, and VERBOSE_PREFIX_2.
16783 { 16784 struct ast_config *cfg, *ucfg; 16785 struct ast_variable *v; 16786 struct sip_peer *peer; 16787 struct sip_user *user; 16788 struct ast_hostent ahp; 16789 char *cat, *stringp, *context, *oldregcontext; 16790 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16791 struct hostent *hp; 16792 int format; 16793 struct ast_flags dummy[2]; 16794 int auto_sip_domains = FALSE; 16795 struct sockaddr_in old_bindaddr = bindaddr; 16796 int registry_count = 0, peer_count = 0, user_count = 0; 16797 unsigned int temp_tos = 0; 16798 struct ast_flags debugflag = {0}; 16799 16800 cfg = ast_config_load(config); 16801 16802 /* We *must* have a config file otherwise stop immediately */ 16803 if (!cfg) { 16804 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16805 return -1; 16806 } 16807 16808 if (option_debug > 3) 16809 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 16810 16811 clear_realm_authentication(authl); 16812 clear_sip_domains(); 16813 authl = NULL; 16814 16815 /* First, destroy all outstanding registry calls */ 16816 /* This is needed, since otherwise active registry entries will not be destroyed */ 16817 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16818 ASTOBJ_RDLOCK(iterator); 16819 if (iterator->call) { 16820 if (option_debug > 2) 16821 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 16822 /* This will also remove references to the registry */ 16823 sip_destroy(iterator->call); 16824 } 16825 ASTOBJ_UNLOCK(iterator); 16826 16827 } while(0)); 16828 16829 /* Then, actually destroy users and registry */ 16830 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 16831 if (option_debug > 3) 16832 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 16833 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 16834 if (option_debug > 3) 16835 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 16836 ASTOBJ_CONTAINER_MARKALL(&peerl); 16837 16838 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16839 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16840 oldregcontext = oldcontexts; 16841 16842 /* Clear all flags before setting default values */ 16843 /* Preserve debugging settings for console */ 16844 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16845 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16846 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16847 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16848 16849 /* Reset IP addresses */ 16850 memset(&bindaddr, 0, sizeof(bindaddr)); 16851 ast_free_ha(localaddr); 16852 memset(&localaddr, 0, sizeof(localaddr)); 16853 memset(&externip, 0, sizeof(externip)); 16854 memset(&default_prefs, 0 , sizeof(default_prefs)); 16855 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16856 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16857 ourport = STANDARD_SIP_PORT; 16858 srvlookup = DEFAULT_SRVLOOKUP; 16859 global_tos_sip = DEFAULT_TOS_SIP; 16860 global_tos_audio = DEFAULT_TOS_AUDIO; 16861 global_tos_video = DEFAULT_TOS_VIDEO; 16862 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16863 externexpire = 0; /* Expiration for DNS re-issuing */ 16864 externrefresh = 10; 16865 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16866 16867 /* Reset channel settings to default before re-configuring */ 16868 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16869 global_regcontext[0] = '\0'; 16870 expiry = DEFAULT_EXPIRY; 16871 global_notifyringing = DEFAULT_NOTIFYRINGING; 16872 global_limitonpeers = FALSE; 16873 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16874 global_notifyhold = FALSE; 16875 global_alwaysauthreject = 0; 16876 global_allowsubscribe = FALSE; 16877 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16878 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16879 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16880 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16881 else 16882 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16883 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16884 compactheaders = DEFAULT_COMPACTHEADERS; 16885 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16886 global_regattempts_max = 0; 16887 pedanticsipchecking = DEFAULT_PEDANTIC; 16888 global_mwitime = DEFAULT_MWITIME; 16889 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16890 global_autoframing = 0; 16891 global_allowguest = DEFAULT_ALLOWGUEST; 16892 global_rtptimeout = 0; 16893 global_rtpholdtimeout = 0; 16894 global_rtpkeepalive = 0; 16895 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16896 global_rtautoclear = 120; 16897 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16898 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16899 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16900 16901 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16902 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16903 default_subscribecontext[0] = '\0'; 16904 default_language[0] = '\0'; 16905 default_fromdomain[0] = '\0'; 16906 default_qualify = DEFAULT_QUALIFY; 16907 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16908 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16909 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16910 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16911 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16912 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16913 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16914 16915 /* Debugging settings, always default to off */ 16916 dumphistory = FALSE; 16917 recordhistory = FALSE; 16918 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16919 16920 /* Misc settings for the channel */ 16921 global_relaxdtmf = FALSE; 16922 global_callevents = FALSE; 16923 global_t1min = DEFAULT_T1MIN; 16924 16925 global_matchexterniplocally = FALSE; 16926 16927 /* Copy the default jb config over global_jbconf */ 16928 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16929 16930 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16931 16932 /* Read the [general] config section of sip.conf (or from realtime config) */ 16933 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16934 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16935 continue; 16936 /* handle jb conf */ 16937 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16938 continue; 16939 16940 /* Create the interface list */ 16941 if (!strcasecmp(v->name, "context")) { 16942 ast_copy_string(default_context, v->value, sizeof(default_context)); 16943 } else if (!strcasecmp(v->name, "subscribecontext")) { 16944 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 16945 } else if (!strcasecmp(v->name, "allowguest")) { 16946 global_allowguest = ast_true(v->value) ? 1 : 0; 16947 } else if (!strcasecmp(v->name, "realm")) { 16948 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16949 } else if (!strcasecmp(v->name, "useragent")) { 16950 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16951 if (option_debug) 16952 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16953 } else if (!strcasecmp(v->name, "allowtransfer")) { 16954 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16955 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16956 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16957 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16958 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16959 } else if (!strcasecmp(v->name, "rtupdate")) { 16960 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16961 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16962 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16963 } else if (!strcasecmp(v->name, "t1min")) { 16964 global_t1min = atoi(v->value); 16965 } else if (!strcasecmp(v->name, "rtautoclear")) { 16966 int i = atoi(v->value); 16967 if (i > 0) 16968 global_rtautoclear = i; 16969 else 16970 i = 0; 16971 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16972 } else if (!strcasecmp(v->name, "usereqphone")) { 16973 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16974 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16975 global_relaxdtmf = ast_true(v->value); 16976 } else if (!strcasecmp(v->name, "checkmwi")) { 16977 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16978 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16979 global_mwitime = DEFAULT_MWITIME; 16980 } 16981 } else if (!strcasecmp(v->name, "vmexten")) { 16982 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16983 } else if (!strcasecmp(v->name, "rtptimeout")) { 16984 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16985 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16986 global_rtptimeout = 0; 16987 } 16988 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16989 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16990 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16991 global_rtpholdtimeout = 0; 16992 } 16993 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16994 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16995 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16996 global_rtpkeepalive = 0; 16997 } 16998 } else if (!strcasecmp(v->name, "compactheaders")) { 16999 compactheaders = ast_true(v->value); 17000 } else if (!strcasecmp(v->name, "notifymimetype")) { 17001 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17002 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17003 global_limitonpeers = ast_true(v->value); 17004 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17005 global_directrtpsetup = ast_true(v->value); 17006 } else if (!strcasecmp(v->name, "notifyringing")) { 17007 global_notifyringing = ast_true(v->value); 17008 } else if (!strcasecmp(v->name, "notifyhold")) { 17009 global_notifyhold = ast_true(v->value); 17010 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17011 global_alwaysauthreject = ast_true(v->value); 17012 } else if (!strcasecmp(v->name, "mohinterpret") 17013 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17014 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17015 } else if (!strcasecmp(v->name, "mohsuggest")) { 17016 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17017 } else if (!strcasecmp(v->name, "language")) { 17018 ast_copy_string(default_language, v->value, sizeof(default_language)); 17019 } else if (!strcasecmp(v->name, "regcontext")) { 17020 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17021 stringp = newcontexts; 17022 /* Let's remove any contexts that are no longer defined in regcontext */ 17023 cleanup_stale_contexts(stringp, oldregcontext); 17024 /* Create contexts if they don't exist already */ 17025 while ((context = strsep(&stringp, "&"))) { 17026 if (!ast_context_find(context)) 17027 ast_context_create(NULL, context,"SIP"); 17028 } 17029 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17030 } else if (!strcasecmp(v->name, "callerid")) { 17031 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17032 } else if (!strcasecmp(v->name, "fromdomain")) { 17033 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17034 } else if (!strcasecmp(v->name, "outboundproxy")) { 17035 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17036 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17037 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17038 /* Port needs to be after IP */ 17039 sscanf(v->value, "%d", &format); 17040 outboundproxyip.sin_port = htons(format); 17041 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17042 autocreatepeer = ast_true(v->value); 17043 } else if (!strcasecmp(v->name, "srvlookup")) { 17044 srvlookup = ast_true(v->value); 17045 } else if (!strcasecmp(v->name, "pedantic")) { 17046 pedanticsipchecking = ast_true(v->value); 17047 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17048 max_expiry = atoi(v->value); 17049 if (max_expiry < 1) 17050 max_expiry = DEFAULT_MAX_EXPIRY; 17051 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17052 min_expiry = atoi(v->value); 17053 if (min_expiry < 1) 17054 min_expiry = DEFAULT_MIN_EXPIRY; 17055 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17056 default_expiry = atoi(v->value); 17057 if (default_expiry < 1) 17058 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17059 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17060 if (ast_true(v->value)) 17061 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17062 } else if (!strcasecmp(v->name, "dumphistory")) { 17063 dumphistory = ast_true(v->value); 17064 } else if (!strcasecmp(v->name, "recordhistory")) { 17065 recordhistory = ast_true(v->value); 17066 } else if (!strcasecmp(v->name, "registertimeout")) { 17067 global_reg_timeout = atoi(v->value); 17068 if (global_reg_timeout < 1) 17069 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17070 } else if (!strcasecmp(v->name, "registerattempts")) { 17071 global_regattempts_max = atoi(v->value); 17072 } else if (!strcasecmp(v->name, "bindaddr")) { 17073 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17074 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17075 } else { 17076 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17077 } 17078 } else if (!strcasecmp(v->name, "localnet")) { 17079 struct ast_ha *na; 17080 if (!(na = ast_append_ha("d", v->value, localaddr))) 17081 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17082 else 17083 localaddr = na; 17084 } else if (!strcasecmp(v->name, "localmask")) { 17085 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17086 } else if (!strcasecmp(v->name, "externip")) { 17087 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17088 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17089 else 17090 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17091 externexpire = 0; 17092 } else if (!strcasecmp(v->name, "externhost")) { 17093 ast_copy_string(externhost, v->value, sizeof(externhost)); 17094 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17095 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17096 else 17097 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17098 externexpire = time(NULL); 17099 } else if (!strcasecmp(v->name, "externrefresh")) { 17100 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17101 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17102 externrefresh = 10; 17103 } 17104 } else if (!strcasecmp(v->name, "allow")) { 17105 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17106 } else if (!strcasecmp(v->name, "disallow")) { 17107 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17108 } else if (!strcasecmp(v->name, "autoframing")) { 17109 global_autoframing = ast_true(v->value); 17110 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17111 allow_external_domains = ast_true(v->value); 17112 } else if (!strcasecmp(v->name, "autodomain")) { 17113 auto_sip_domains = ast_true(v->value); 17114 } else if (!strcasecmp(v->name, "domain")) { 17115 char *domain = ast_strdupa(v->value); 17116 char *context = strchr(domain, ','); 17117 17118 if (context) 17119 *context++ = '\0'; 17120 17121 if (option_debug && ast_strlen_zero(context)) 17122 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17123 if (ast_strlen_zero(domain)) 17124 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17125 else 17126 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17127 } else if (!strcasecmp(v->name, "register")) { 17128 if (sip_register(v->value, v->lineno) == 0) 17129 registry_count++; 17130 } else if (!strcasecmp(v->name, "tos")) { 17131 if (!ast_str2tos(v->value, &temp_tos)) { 17132 global_tos_sip = temp_tos; 17133 global_tos_audio = temp_tos; 17134 global_tos_video = temp_tos; 17135 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17136 } else 17137 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17138 } else if (!strcasecmp(v->name, "tos_sip")) { 17139 if (ast_str2tos(v->value, &global_tos_sip)) 17140 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17141 } else if (!strcasecmp(v->name, "tos_audio")) { 17142 if (ast_str2tos(v->value, &global_tos_audio)) 17143 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17144 } else if (!strcasecmp(v->name, "tos_video")) { 17145 if (ast_str2tos(v->value, &global_tos_video)) 17146 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17147 } else if (!strcasecmp(v->name, "bindport")) { 17148 if (sscanf(v->value, "%d", &ourport) == 1) { 17149 bindaddr.sin_port = htons(ourport); 17150 } else { 17151 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17152 } 17153 } else if (!strcasecmp(v->name, "qualify")) { 17154 if (!strcasecmp(v->value, "no")) { 17155 default_qualify = 0; 17156 } else if (!strcasecmp(v->value, "yes")) { 17157 default_qualify = DEFAULT_MAXMS; 17158 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17159 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17160 default_qualify = 0; 17161 } 17162 } else if (!strcasecmp(v->name, "callevents")) { 17163 global_callevents = ast_true(v->value); 17164 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17165 default_maxcallbitrate = atoi(v->value); 17166 if (default_maxcallbitrate < 0) 17167 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17168 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17169 global_matchexterniplocally = ast_true(v->value); 17170 } 17171 } 17172 17173 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17174 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17175 allow_external_domains = 1; 17176 } 17177 17178 /* Build list of authentication to various SIP realms, i.e. service providers */ 17179 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17180 /* Format for authentication is auth = username:password@realm */ 17181 if (!strcasecmp(v->name, "auth")) 17182 authl = add_realm_authentication(authl, v->value, v->lineno); 17183 } 17184 17185 ucfg = ast_config_load("users.conf"); 17186 if (ucfg) { 17187 struct ast_variable *gen; 17188 int genhassip, genregistersip; 17189 const char *hassip, *registersip; 17190 17191 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17192 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17193 gen = ast_variable_browse(ucfg, "general"); 17194 cat = ast_category_browse(ucfg, NULL); 17195 while (cat) { 17196 if (strcasecmp(cat, "general")) { 17197 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17198 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17199 if (ast_true(hassip) || (!hassip && genhassip)) { 17200 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17201 if (peer) { 17202 ast_device_state_changed("SIP/%s", peer->name); 17203 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17204 ASTOBJ_UNREF(peer, sip_destroy_peer); 17205 peer_count++; 17206 } 17207 } 17208 if (ast_true(registersip) || (!registersip && genregistersip)) { 17209 char tmp[256]; 17210 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17211 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17212 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17213 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17214 if (!host) 17215 host = ast_variable_retrieve(ucfg, "general", "host"); 17216 if (!username) 17217 username = ast_variable_retrieve(ucfg, "general", "username"); 17218 if (!secret) 17219 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17220 if (!contact) 17221 contact = "s"; 17222 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17223 if (!ast_strlen_zero(secret)) 17224 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17225 else 17226 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17227 if (sip_register(tmp, 0) == 0) 17228 registry_count++; 17229 } 17230 } 17231 } 17232 cat = ast_category_browse(ucfg, cat); 17233 } 17234 ast_config_destroy(ucfg); 17235 } 17236 17237 17238 /* Load peers, users and friends */ 17239 cat = NULL; 17240 while ( (cat = ast_category_browse(cfg, cat)) ) { 17241 const char *utype; 17242 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17243 continue; 17244 utype = ast_variable_retrieve(cfg, cat, "type"); 17245 if (!utype) { 17246 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17247 continue; 17248 } else { 17249 int is_user = 0, is_peer = 0; 17250 if (!strcasecmp(utype, "user")) 17251 is_user = 1; 17252 else if (!strcasecmp(utype, "friend")) 17253 is_user = is_peer = 1; 17254 else if (!strcasecmp(utype, "peer")) 17255 is_peer = 1; 17256 else { 17257 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17258 continue; 17259 } 17260 if (is_user) { 17261 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 17262 if (user) { 17263 ASTOBJ_CONTAINER_LINK(&userl,user); 17264 ASTOBJ_UNREF(user, sip_destroy_user); 17265 user_count++; 17266 } 17267 } 17268 if (is_peer) { 17269 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17270 if (peer) { 17271 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17272 ASTOBJ_UNREF(peer, sip_destroy_peer); 17273 peer_count++; 17274 } 17275 } 17276 } 17277 } 17278 if (ast_find_ourip(&__ourip, bindaddr)) { 17279 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17280 ast_config_destroy(cfg); 17281 return 0; 17282 } 17283 if (!ntohs(bindaddr.sin_port)) 17284 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17285 bindaddr.sin_family = AF_INET; 17286 ast_mutex_lock(&netlock); 17287 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17288 close(sipsock); 17289 sipsock = -1; 17290 } 17291 if (sipsock < 0) { 17292 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17293 if (sipsock < 0) { 17294 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17295 ast_config_destroy(cfg); 17296 return -1; 17297 } else { 17298 /* Allow SIP clients on the same host to access us: */ 17299 const int reuseFlag = 1; 17300 17301 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17302 (const char*)&reuseFlag, 17303 sizeof reuseFlag); 17304 17305 ast_enable_packet_fragmentation(sipsock); 17306 17307 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17308 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17309 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17310 strerror(errno)); 17311 close(sipsock); 17312 sipsock = -1; 17313 } else { 17314 if (option_verbose > 1) { 17315 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17316 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17317 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17318 } 17319 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17320 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17321 } 17322 } 17323 } 17324 ast_mutex_unlock(&netlock); 17325 17326 /* Add default domains - host name, IP address and IP:port */ 17327 /* Only do this if user added any sip domain with "localdomains" */ 17328 /* In order to *not* break backwards compatibility */ 17329 /* Some phones address us at IP only, some with additional port number */ 17330 if (auto_sip_domains) { 17331 char temp[MAXHOSTNAMELEN]; 17332 17333 /* First our default IP address */ 17334 if (bindaddr.sin_addr.s_addr) 17335 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17336 else 17337 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17338 17339 /* Our extern IP address, if configured */ 17340 if (externip.sin_addr.s_addr) 17341 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17342 17343 /* Extern host name (NAT traversal support) */ 17344 if (!ast_strlen_zero(externhost)) 17345 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17346 17347 /* Our host name */ 17348 if (!gethostname(temp, sizeof(temp))) 17349 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17350 } 17351 17352 /* Release configuration from memory */ 17353 ast_config_destroy(cfg); 17354 17355 /* Load the list of manual NOTIFY types to support */ 17356 if (notify_types) 17357 ast_config_destroy(notify_types); 17358 notify_types = ast_config_load(notify_config); 17359 17360 /* Done, tell the manager */ 17361 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); 17362 17363 return 0; 17364 }
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 11484 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, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11485 { 11486 char tmp[512]; 11487 char *c; 11488 char oldnonce[256]; 11489 11490 /* table of recognised keywords, and places where they should be copied */ 11491 const struct x { 11492 const char *key; 11493 int field_index; 11494 } *i, keys[] = { 11495 { "realm=", ast_string_field_index(p, realm) }, 11496 { "nonce=", ast_string_field_index(p, nonce) }, 11497 { "opaque=", ast_string_field_index(p, opaque) }, 11498 { "qop=", ast_string_field_index(p, qop) }, 11499 { "domain=", ast_string_field_index(p, domain) }, 11500 { NULL, 0 }, 11501 }; 11502 11503 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11504 if (ast_strlen_zero(tmp)) 11505 return -1; 11506 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11507 ast_log(LOG_WARNING, "missing Digest.\n"); 11508 return -1; 11509 } 11510 c = tmp + strlen("Digest "); 11511 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11512 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11513 for (i = keys; i->key != NULL; i++) { 11514 char *src, *separator; 11515 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11516 continue; 11517 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11518 c += strlen(i->key); 11519 if (*c == '"') { 11520 src = ++c; 11521 separator = "\""; 11522 } else { 11523 src = c; 11524 separator = ","; 11525 } 11526 strsep(&c, separator); /* clear separator and move ptr */ 11527 ast_string_field_index_set(p, i->field_index, src); 11528 break; 11529 } 11530 if (i->key == NULL) /* not found, try ',' */ 11531 strsep(&c, ","); 11532 } 11533 /* Reset nonce count */ 11534 if (strcmp(p->nonce, oldnonce)) 11535 p->noncecount = 0; 11536 11537 /* Save auth data for following registrations */ 11538 if (p->registry) { 11539 struct sip_registry *r = p->registry; 11540 11541 if (strcmp(r->nonce, p->nonce)) { 11542 ast_string_field_set(r, realm, p->realm); 11543 ast_string_field_set(r, nonce, p->nonce); 11544 ast_string_field_set(r, domain, p->domain); 11545 ast_string_field_set(r, opaque, p->opaque); 11546 ast_string_field_set(r, qop, p->qop); 11547 r->noncecount = 0; 11548 } 11549 } 11550 return build_reply_digest(p, sipmethod, digest, digest_len); 11551 }
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 5852 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.
05853 { 05854 struct sip_request *orig = &p->initreq; 05855 char stripped[80]; 05856 char tmp[80]; 05857 char newto[256]; 05858 const char *c; 05859 const char *ot, *of; 05860 int is_strict = FALSE; /*!< Strict routing flag */ 05861 05862 memset(req, 0, sizeof(struct sip_request)); 05863 05864 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05865 05866 if (!seqno) { 05867 p->ocseq++; 05868 seqno = p->ocseq; 05869 } 05870 05871 if (newbranch) { 05872 p->branch ^= ast_random(); 05873 build_via(p); 05874 } 05875 05876 /* Check for strict or loose router */ 05877 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05878 is_strict = TRUE; 05879 if (sipdebug) 05880 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05881 } 05882 05883 if (sipmethod == SIP_CANCEL) 05884 c = p->initreq.rlPart2; /* Use original URI */ 05885 else if (sipmethod == SIP_ACK) { 05886 /* Use URI from Contact: in 200 OK (if INVITE) 05887 (we only have the contacturi on INVITEs) */ 05888 if (!ast_strlen_zero(p->okcontacturi)) 05889 c = is_strict ? p->route->hop : p->okcontacturi; 05890 else 05891 c = p->initreq.rlPart2; 05892 } else if (!ast_strlen_zero(p->okcontacturi)) 05893 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05894 else if (!ast_strlen_zero(p->uri)) 05895 c = p->uri; 05896 else { 05897 char *n; 05898 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05899 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05900 sizeof(stripped)); 05901 n = get_in_brackets(stripped); 05902 c = strsep(&n, ";"); /* trim ; and beyond */ 05903 } 05904 init_req(req, sipmethod, c); 05905 05906 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05907 05908 add_header(req, "Via", p->via); 05909 if (p->route) { 05910 set_destination(p, p->route->hop); 05911 add_route(req, is_strict ? p->route->next : p->route); 05912 } 05913 05914 ot = get_header(orig, "To"); 05915 of = get_header(orig, "From"); 05916 05917 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05918 as our original request, including tag (or presumably lack thereof) */ 05919 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05920 /* Add the proper tag if we don't have it already. If they have specified 05921 their tag, use it. Otherwise, use our own tag */ 05922 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05923 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05924 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05925 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05926 else 05927 snprintf(newto, sizeof(newto), "%s", ot); 05928 ot = newto; 05929 } 05930 05931 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05932 add_header(req, "From", of); 05933 add_header(req, "To", ot); 05934 } else { 05935 add_header(req, "From", ot); 05936 add_header(req, "To", of); 05937 } 05938 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05939 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05940 add_header(req, "Contact", p->our_contact); 05941 05942 copy_header(req, orig, "Call-ID"); 05943 add_header(req, "CSeq", tmp); 05944 05945 if (!ast_strlen_zero(global_useragent)) 05946 add_header(req, "User-Agent", global_useragent); 05947 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05948 05949 if (!ast_strlen_zero(p->rpid)) 05950 add_header(req, "Remote-Party-ID", p->rpid); 05951 05952 return 0; 05953 }
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 5804 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, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.
05805 { 05806 char newto[256]; 05807 const char *ot; 05808 05809 init_resp(resp, msg); 05810 copy_via_headers(p, resp, req, "Via"); 05811 if (msg[0] == '1' || msg[0] == '2') 05812 copy_all_header(resp, req, "Record-Route"); 05813 copy_header(resp, req, "From"); 05814 ot = get_header(req, "To"); 05815 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05816 /* Add the proper tag if we don't have it already. If they have specified 05817 their tag, use it. Otherwise, use our own tag */ 05818 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05819 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05820 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05821 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05822 else 05823 ast_copy_string(newto, ot, sizeof(newto)); 05824 ot = newto; 05825 } 05826 add_header(resp, "To", ot); 05827 copy_header(resp, req, "Call-ID"); 05828 copy_header(resp, req, "CSeq"); 05829 if (!ast_strlen_zero(global_useragent)) 05830 add_header(resp, "User-Agent", global_useragent); 05831 add_header(resp, "Allow", ALLOWED_METHODS); 05832 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05833 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05834 /* For registration responses, we also need expiry and 05835 contact info */ 05836 char tmp[256]; 05837 05838 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05839 add_header(resp, "Expires", tmp); 05840 if (p->expiry) { /* Only add contact if we have an expiry time */ 05841 char contact[BUFSIZ]; 05842 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05843 add_header(resp, "Contact", contact); /* Not when we unregister */ 05844 } 05845 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05846 add_header(resp, "Contact", p->our_contact); 05847 } 05848 return 0; 05849 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15728 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
15729 { 15730 /* If we're supposed to be stopped -- stay stopped */ 15731 if (monitor_thread == AST_PTHREADT_STOP) 15732 return 0; 15733 ast_mutex_lock(&monlock); 15734 if (monitor_thread == pthread_self()) { 15735 ast_mutex_unlock(&monlock); 15736 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15737 return -1; 15738 } 15739 if (monitor_thread != AST_PTHREADT_NULL) { 15740 /* Wake up the thread */ 15741 pthread_kill(monitor_thread, SIGURG); 15742 } else { 15743 /* Start a new monitor */ 15744 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15745 ast_mutex_unlock(&monlock); 15746 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15747 return -1; 15748 } 15749 } 15750 ast_mutex_unlock(&monlock); 15751 return 0; 15752 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1893 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.
01894 { 01895 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01896 int reschedule = DEFAULT_RETRANS; 01897 int xmitres = 0; 01898 01899 /* Lock channel PVT */ 01900 ast_mutex_lock(&pkt->owner->lock); 01901 01902 if (pkt->retrans < MAX_RETRANS) { 01903 pkt->retrans++; 01904 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01905 if (sipdebug && option_debug > 3) 01906 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); 01907 } else { 01908 int siptimer_a; 01909 01910 if (sipdebug && option_debug > 3) 01911 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01912 if (!pkt->timer_a) 01913 pkt->timer_a = 2 ; 01914 else 01915 pkt->timer_a = 2 * pkt->timer_a; 01916 01917 /* For non-invites, a maximum of 4 secs */ 01918 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01919 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01920 siptimer_a = 4000; 01921 01922 /* Reschedule re-transmit */ 01923 reschedule = siptimer_a; 01924 if (option_debug > 3) 01925 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); 01926 } 01927 01928 if (sip_debug_test_pvt(pkt->owner)) { 01929 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01930 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01931 pkt->retrans, sip_nat_mode(pkt->owner), 01932 ast_inet_ntoa(dst->sin_addr), 01933 ntohs(dst->sin_port), pkt->data); 01934 } 01935 01936 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01937 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01938 ast_mutex_unlock(&pkt->owner->lock); 01939 if (xmitres == XMIT_ERROR) 01940 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01941 else 01942 return reschedule; 01943 } 01944 /* Too many retries */ 01945 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01946 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01947 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"); 01948 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01949 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01950 } 01951 if (xmitres == XMIT_ERROR) { 01952 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01953 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01954 } else 01955 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01956 01957 pkt->retransid = -1; 01958 01959 if (ast_test_flag(pkt, FLAG_FATAL)) { 01960 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01961 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01962 usleep(1); 01963 ast_mutex_lock(&pkt->owner->lock); 01964 } 01965 01966 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01967 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01968 01969 if (pkt->owner->owner) { 01970 sip_alreadygone(pkt->owner); 01971 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01972 ast_queue_hangup(pkt->owner->owner); 01973 ast_channel_unlock(pkt->owner->owner); 01974 } else { 01975 /* If no channel owner, destroy now */ 01976 01977 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01978 if (pkt->method != SIP_OPTIONS) { 01979 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01980 sip_alreadygone(pkt->owner); 01981 if (option_debug) 01982 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01983 } 01984 } 01985 } 01986 01987 if (pkt->method == SIP_BYE) { 01988 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01989 if (pkt->owner->owner) 01990 ast_channel_unlock(pkt->owner->owner); 01991 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01992 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01993 } 01994 01995 /* In any case, go ahead and remove the packet */ 01996 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01997 if (cur == pkt) 01998 break; 01999 } 02000 if (cur) { 02001 if (prev) 02002 prev->next = cur->next; 02003 else 02004 pkt->owner->packets = cur->next; 02005 ast_mutex_unlock(&pkt->owner->lock); 02006 free(cur); 02007 pkt = NULL; 02008 } else 02009 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02010 if (pkt) 02011 ast_mutex_unlock(&pkt->owner->lock); 02012 return 0; 02013 }
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 2268 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.
02269 { 02270 int res; 02271 02272 add_blank(req); 02273 if (sip_debug_test_pvt(p)) { 02274 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02275 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); 02276 else 02277 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); 02278 } 02279 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02280 struct sip_request tmp; 02281 parse_copy(&tmp, req); 02282 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02283 } 02284 res = (reliable) ? 02285 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02286 __sip_xmit(p, req->data, req->len); 02287 return res; 02288 }
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 2240 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_request::rlPart2, sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02241 { 02242 int res; 02243 02244 add_blank(req); 02245 if (sip_debug_test_pvt(p)) { 02246 const struct sockaddr_in *dst = sip_real_dst(p); 02247 02248 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02249 reliable ? "Reliably " : "", sip_nat_mode(p), 02250 ast_inet_ntoa(dst->sin_addr), 02251 ntohs(dst->sin_port), req->data); 02252 } 02253 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02254 struct sip_request tmp; 02255 parse_copy(&tmp, req); 02256 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02257 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02258 } 02259 res = (reliable) ? 02260 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02261 __sip_xmit(p, req->data, req->len); 02262 if (res > 0) 02263 return 0; 02264 return res; 02265 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7945 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strdupa, ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
07946 { 07947 struct hostent *hp; 07948 struct ast_hostent ahp; 07949 int port; 07950 char *c, *host, *pt; 07951 char *contact; 07952 07953 07954 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07955 /* NAT: Don't trust the contact field. Just use what they came to us 07956 with. */ 07957 pvt->sa = pvt->recv; 07958 return 0; 07959 } 07960 07961 07962 /* Work on a copy */ 07963 contact = ast_strdupa(pvt->fullcontact); 07964 07965 /* Make sure it's a SIP URL */ 07966 if (strncasecmp(contact, "sip:", 4)) { 07967 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07968 } else 07969 contact += 4; 07970 07971 /* Ditch arguments */ 07972 /* XXX this code is replicated also shortly below */ 07973 07974 /* Grab host */ 07975 host = strchr(contact, '@'); 07976 if (!host) { /* No username part */ 07977 host = contact; 07978 c = NULL; 07979 } else { 07980 *host++ = '\0'; 07981 } 07982 pt = strchr(host, ':'); 07983 if (pt) { 07984 *pt++ = '\0'; 07985 port = atoi(pt); 07986 } else 07987 port = STANDARD_SIP_PORT; 07988 07989 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 07990 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 07991 07992 /* XXX This could block for a long time XXX */ 07993 /* We should only do this if it's a name, not an IP */ 07994 hp = ast_gethostbyname(host, &ahp); 07995 if (!hp) { 07996 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07997 return -1; 07998 } 07999 pvt->sa.sin_family = AF_INET; 08000 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08001 pvt->sa.sin_port = htons(port); 08002 08003 return 0; 08004 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5713 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05714 { 05715 char *h, *maddr, hostname[256]; 05716 int port, hn; 05717 struct hostent *hp; 05718 struct ast_hostent ahp; 05719 int debug=sip_debug_test_pvt(p); 05720 05721 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05722 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05723 05724 if (debug) 05725 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05726 05727 /* Find and parse hostname */ 05728 h = strchr(uri, '@'); 05729 if (h) 05730 ++h; 05731 else { 05732 h = uri; 05733 if (strncasecmp(h, "sip:", 4) == 0) 05734 h += 4; 05735 else if (strncasecmp(h, "sips:", 5) == 0) 05736 h += 5; 05737 } 05738 hn = strcspn(h, ":;>") + 1; 05739 if (hn > sizeof(hostname)) 05740 hn = sizeof(hostname); 05741 ast_copy_string(hostname, h, hn); 05742 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05743 h += hn - 1; 05744 05745 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05746 if (*h == ':') { 05747 /* Parse port */ 05748 ++h; 05749 port = strtol(h, &h, 10); 05750 } 05751 else 05752 port = STANDARD_SIP_PORT; 05753 05754 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05755 maddr = strstr(h, "maddr="); 05756 if (maddr) { 05757 maddr += 6; 05758 hn = strspn(maddr, "0123456789.") + 1; 05759 if (hn > sizeof(hostname)) 05760 hn = sizeof(hostname); 05761 ast_copy_string(hostname, maddr, hn); 05762 } 05763 05764 hp = ast_gethostbyname(hostname, &ahp); 05765 if (hp == NULL) { 05766 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05767 return; 05768 } 05769 p->sa.sin_family = AF_INET; 05770 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05771 p->sa.sin_port = htons(port); 05772 if (debug) 05773 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05774 }
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 16035 of file chan_sip.c.
References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options(), and realtime_peer().
16036 { 16037 static int dep_insecure_very = 0; 16038 static int dep_insecure_yes = 0; 16039 16040 if (ast_strlen_zero(value)) 16041 return; 16042 16043 if (!strcasecmp(value, "very")) { 16044 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16045 if(!dep_insecure_very) { 16046 if(lineno != -1) 16047 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16048 else 16049 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16050 dep_insecure_very = 1; 16051 } 16052 } 16053 else if (ast_true(value)) { 16054 ast_set_flag(flags, SIP_INSECURE_PORT); 16055 if(!dep_insecure_yes) { 16056 if(lineno != -1) 16057 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16058 else 16059 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16060 dep_insecure_yes = 1; 16061 } 16062 } 16063 else if (!ast_false(value)) { 16064 char buf[64]; 16065 char *word, *next; 16066 ast_copy_string(buf, value, sizeof(buf)); 16067 next = buf; 16068 while ((word = strsep(&next, ","))) { 16069 if (!strcasecmp(word, "port")) 16070 ast_set_flag(flags, SIP_INSECURE_PORT); 16071 else if (!strcasecmp(word, "invite")) 16072 ast_set_flag(flags, SIP_INSECURE_INVITE); 16073 else 16074 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16075 } 16076 } 16077 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16462 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
16463 { 16464 if (peer->expire == 0) { 16465 /* Don't reset expire or port time during reload 16466 if we have an active registration 16467 */ 16468 peer->expire = -1; 16469 peer->pokeexpire = -1; 16470 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16471 } 16472 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16473 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16474 strcpy(peer->context, default_context); 16475 strcpy(peer->subscribecontext, default_subscribecontext); 16476 strcpy(peer->language, default_language); 16477 strcpy(peer->mohinterpret, default_mohinterpret); 16478 strcpy(peer->mohsuggest, default_mohsuggest); 16479 peer->addr.sin_family = AF_INET; 16480 peer->defaddr.sin_family = AF_INET; 16481 peer->capability = global_capability; 16482 peer->maxcallbitrate = default_maxcallbitrate; 16483 peer->rtptimeout = global_rtptimeout; 16484 peer->rtpholdtimeout = global_rtpholdtimeout; 16485 peer->rtpkeepalive = global_rtpkeepalive; 16486 peer->allowtransfer = global_allowtransfer; 16487 peer->autoframing = global_autoframing; 16488 strcpy(peer->vmexten, default_vmexten); 16489 peer->secret[0] = '\0'; 16490 peer->md5secret[0] = '\0'; 16491 peer->cid_num[0] = '\0'; 16492 peer->cid_name[0] = '\0'; 16493 peer->fromdomain[0] = '\0'; 16494 peer->fromuser[0] = '\0'; 16495 peer->regexten[0] = '\0'; 16496 peer->mailbox[0] = '\0'; 16497 peer->callgroup = 0; 16498 peer->pickupgroup = 0; 16499 peer->maxms = default_qualify; 16500 peer->prefs = default_prefs; 16501 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17703 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
17704 { 17705 int no = 0; 17706 int ok = FALSE; 17707 char varbuf[30]; 17708 char *inbuf = (char *) data; 17709 17710 if (ast_strlen_zero(inbuf)) { 17711 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17712 return 0; 17713 } 17714 ast_channel_lock(chan); 17715 17716 /* Check for headers */ 17717 while (!ok && no <= 50) { 17718 no++; 17719 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17720 17721 /* Compare without the leading underscore */ 17722 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17723 ok = TRUE; 17724 } 17725 if (ok) { 17726 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17727 if (sipdebug) 17728 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17729 } else { 17730 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17731 } 17732 ast_channel_unlock(chan); 17733 return 0; 17734 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2630 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02631 { 02632 /* We know name is the first field, so we can cast */ 02633 struct sip_peer *p = (struct sip_peer *) name; 02634 return !(!inaddrcmp(&p->addr, sin) || 02635 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02636 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02637 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static, read] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4391 of file chan_sip.c.
References __ourip, sip_pvt::allowtransfer, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), sip_pvt::autokillid, bindaddr, sip_pvt::branch, build_callid_pvt(), build_via(), t38properties::capability, sip_pvt::capability, sip_pvt::chanvars, domain::context, default_prefs, do_setnat(), errno, sip_pvt::flags, free, global_t38_capability, iflist, INITIAL_CSEQ, sip_pvt::initid, t38properties::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ocseq, option_debug, sip_pvt::ourip, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::tag, text, sip_pvt::timer_t1, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and sip_pvt::waitid.
Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04393 { 04394 struct sip_pvt *p; 04395 04396 if (!(p = ast_calloc(1, sizeof(*p)))) 04397 return NULL; 04398 04399 if (ast_string_field_init(p, 512)) { 04400 free(p); 04401 return NULL; 04402 } 04403 04404 ast_mutex_init(&p->lock); 04405 04406 p->method = intended_method; 04407 p->initid = -1; 04408 p->waitid = -1; 04409 p->autokillid = -1; 04410 p->subscribed = NONE; 04411 p->stateid = -1; 04412 p->prefs = default_prefs; /* Set default codecs for this call */ 04413 04414 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04415 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04416 04417 if (sin) { 04418 p->sa = *sin; 04419 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04420 p->ourip = __ourip; 04421 } else 04422 p->ourip = __ourip; 04423 04424 /* Copy global flags to this PVT at setup. */ 04425 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04426 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04427 04428 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04429 04430 p->branch = ast_random(); 04431 make_our_tag(p->tag, sizeof(p->tag)); 04432 p->ocseq = INITIAL_CSEQ; 04433 04434 if (sip_methods[intended_method].need_rtp) { 04435 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04436 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04437 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04438 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04439 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04440 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04441 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04442 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04443 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04444 ast_mutex_destroy(&p->lock); 04445 if (p->chanvars) { 04446 ast_variables_destroy(p->chanvars); 04447 p->chanvars = NULL; 04448 } 04449 free(p); 04450 return NULL; 04451 } 04452 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04453 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04454 ast_rtp_settos(p->rtp, global_tos_audio); 04455 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04456 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04457 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04458 if (p->vrtp) { 04459 ast_rtp_settos(p->vrtp, global_tos_video); 04460 ast_rtp_setdtmf(p->vrtp, 0); 04461 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04462 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04463 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04464 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04465 } 04466 if (p->udptl) 04467 ast_udptl_settos(p->udptl, global_tos_audio); 04468 p->maxcallbitrate = default_maxcallbitrate; 04469 } 04470 04471 if (useglobal_nat && sin) { 04472 /* Setup NAT structure according to global settings if we have an address */ 04473 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04474 p->recv = *sin; 04475 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04476 } 04477 04478 if (p->method != SIP_REGISTER) 04479 ast_string_field_set(p, fromdomain, default_fromdomain); 04480 build_via(p); 04481 if (!callid) 04482 build_callid_pvt(p); 04483 else 04484 ast_string_field_set(p, callid, callid); 04485 /* Assign default music on hold class */ 04486 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04487 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04488 p->capability = global_capability; 04489 p->allowtransfer = global_allowtransfer; 04490 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04491 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04492 p->noncodeccapability |= AST_RTP_DTMF; 04493 if (p->udptl) { 04494 p->t38.capability = global_t38_capability; 04495 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04496 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04497 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04498 p->t38.capability |= T38FAX_UDP_EC_FEC; 04499 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04500 p->t38.capability |= T38FAX_UDP_EC_NONE; 04501 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04502 p->t38.jointcapability = p->t38.capability; 04503 } 04504 ast_string_field_set(p, context, default_context); 04505 04506 /* Add to active dialog list */ 04507 ast_mutex_lock(&iflock); 04508 p->next = iflist; 04509 iflist = p; 04510 ast_mutex_unlock(&iflock); 04511 if (option_debug) 04512 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"); 04513 return p; 04514 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1652 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().
01653 { 01654 if (option_debug > 2) 01655 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01656 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01657 }
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 3639 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, option_debug, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03640 { 03641 int res = 0; 03642 struct sip_pvt *p = ast->tech_pvt; 03643 03644 ast_mutex_lock(&p->lock); 03645 if (ast->_state != AST_STATE_UP) { 03646 try_suggested_sip_codec(p); 03647 03648 ast_setstate(ast, AST_STATE_UP); 03649 if (option_debug) 03650 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03651 if (p->t38.state == T38_PEER_DIRECT) { 03652 p->t38.state = T38_ENABLED; 03653 if (option_debug > 1) 03654 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03655 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03656 } else 03657 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03658 } 03659 ast_mutex_unlock(&p->lock); 03660 return res; 03661 }
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 2934 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, 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.
02935 { 02936 int res, xmitres = 0; 02937 struct sip_pvt *p; 02938 struct varshead *headp; 02939 struct ast_var_t *current; 02940 const char *referer = NULL; /* SIP refererer */ 02941 02942 p = ast->tech_pvt; 02943 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02944 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02945 return -1; 02946 } 02947 02948 /* Check whether there is vxml_url, distinctive ring variables */ 02949 headp=&ast->varshead; 02950 AST_LIST_TRAVERSE(headp,current,entries) { 02951 /* Check whether there is a VXML_URL variable */ 02952 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02953 p->options->vxml_url = ast_var_value(current); 02954 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02955 p->options->uri_options = ast_var_value(current); 02956 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02957 /* Check whether there is a ALERT_INFO variable */ 02958 p->options->distinctive_ring = ast_var_value(current); 02959 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02960 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02961 p->options->addsipheaders = 1; 02962 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02963 /* This is a transfered call */ 02964 p->options->transfer = 1; 02965 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02966 /* This is the referer */ 02967 referer = ast_var_value(current); 02968 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02969 /* We're replacing a call. */ 02970 p->options->replaces = ast_var_value(current); 02971 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02972 p->t38.state = T38_LOCAL_DIRECT; 02973 if (option_debug) 02974 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02975 } 02976 02977 } 02978 02979 res = 0; 02980 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02981 02982 if (p->options->transfer) { 02983 char buf[BUFSIZ/2]; 02984 02985 if (referer) { 02986 if (sipdebug && option_debug > 2) 02987 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02988 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02989 } else 02990 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02991 ast_string_field_set(p, cid_name, buf); 02992 } 02993 if (option_debug) 02994 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02995 02996 res = update_call_counter(p, INC_CALL_RINGING); 02997 if ( res != -1 ) { 02998 p->callingpres = ast->cid.cid_pres; 02999 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03000 p->jointnoncodeccapability = p->noncodeccapability; 03001 03002 /* If there are no audio formats left to offer, punt */ 03003 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03004 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03005 res = -1; 03006 } else { 03007 p->t38.jointcapability = p->t38.capability; 03008 if (option_debug > 1) 03009 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03010 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03011 if (xmitres == XMIT_ERROR) 03012 return -1; /* Transmission error */ 03013 03014 p->invitestate = INV_CALLING; 03015 03016 /* Initialize auto-congest time */ 03017 if (p->initid > -1) 03018 ast_sched_del(sched, p->initid); 03019 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03020 } 03021 } 03022 return res; 03023 }
static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2128 of file chan_sip.c.
References append_history, ast_sched_del(), and sip_pvt::autokillid.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02129 { 02130 if (p->autokillid > -1) { 02131 ast_sched_del(sched, p->autokillid); 02132 append_history(p, "CancelDestroy", ""); 02133 p->autokillid = -1; 02134 } 02135 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1734 of file chan_sip.c.
References debugaddr, and sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01735 { 01736 if (!sipdebug) 01737 return 0; 01738 if (debugaddr.sin_addr.s_addr) { 01739 if (((ntohs(debugaddr.sin_port) != 0) 01740 && (debugaddr.sin_port != addr->sin_port)) 01741 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01742 return 0; 01743 } 01744 return 1; 01745 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1760 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().
01761 { 01762 if (!sipdebug) 01763 return 0; 01764 return sip_debug_test_addr(sip_real_dst(p)); 01765 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3281 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().
03282 { 03283 ast_mutex_lock(&iflock); 03284 if (option_debug > 2) 03285 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03286 __sip_destroy(p, 1); 03287 ast_mutex_unlock(&iflock); 03288 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2440 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(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_prune_realtime(), unload_module(), and update_call_counter().
02441 { 02442 if (option_debug > 2) 02443 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02444 02445 /* Delete it, it needs to disappear */ 02446 if (peer->call) 02447 sip_destroy(peer->call); 02448 02449 if (peer->mwipvt) /* We have an active subscription, delete it */ 02450 sip_destroy(peer->mwipvt); 02451 02452 if (peer->chanvars) { 02453 ast_variables_destroy(peer->chanvars); 02454 peer->chanvars = NULL; 02455 } 02456 if (peer->expire > -1) 02457 ast_sched_del(sched, peer->expire); 02458 02459 if (peer->pokeexpire > -1) 02460 ast_sched_del(sched, peer->pokeexpire); 02461 register_peer_exten(peer, FALSE); 02462 ast_free_ha(peer->ha); 02463 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02464 apeerobjs--; 02465 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02466 rpeerobjs--; 02467 else 02468 speerobjs--; 02469 clear_realm_authentication(peer->auth); 02470 peer->auth = NULL; 02471 free(peer); 02472 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2658 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), reload_config(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter().
02659 { 02660 if (option_debug > 2) 02661 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02662 ast_free_ha(user->ha); 02663 if (user->chanvars) { 02664 ast_variables_destroy(user->chanvars); 02665 user->chanvars = NULL; 02666 } 02667 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02668 ruserobjs--; 02669 else 02670 suserobjs--; 02671 free(user); 02672 }
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 15877 of file chan_sip.c.
References sip_peer::addr, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
15878 { 15879 char *host; 15880 char *tmp; 15881 15882 struct hostent *hp; 15883 struct ast_hostent ahp; 15884 struct sip_peer *p; 15885 15886 int res = AST_DEVICE_INVALID; 15887 15888 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15889 host = ast_strdupa(data ? data : ""); 15890 if ((tmp = strchr(host, '@'))) 15891 host = tmp + 1; 15892 15893 if (option_debug > 2) 15894 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15895 15896 if ((p = find_peer(host, NULL, 1))) { 15897 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15898 /* we have an address for the peer */ 15899 15900 /* Check status in this order 15901 - Hold 15902 - Ringing 15903 - Busy (enforced only by call limit) 15904 - Inuse (we have a call) 15905 - Unreachable (qualify) 15906 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15907 for registered devices */ 15908 15909 if (p->onHold) 15910 /* First check for hold or ring states */ 15911 res = AST_DEVICE_ONHOLD; 15912 else if (p->inRinging) { 15913 if (p->inRinging == p->inUse) 15914 res = AST_DEVICE_RINGING; 15915 else 15916 res = AST_DEVICE_RINGINUSE; 15917 } else if (p->call_limit && (p->inUse == p->call_limit)) 15918 /* check call limit */ 15919 res = AST_DEVICE_BUSY; 15920 else if (p->call_limit && p->inUse) 15921 /* Not busy, but we do have a call */ 15922 res = AST_DEVICE_INUSE; 15923 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 15924 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15925 res = AST_DEVICE_UNAVAILABLE; 15926 else /* Default reply if we're registered and have no other data */ 15927 res = AST_DEVICE_NOT_INUSE; 15928 } else { 15929 /* there is no address, it's unavailable */ 15930 res = AST_DEVICE_UNAVAILABLE; 15931 } 15932 ASTOBJ_UNREF(p,sip_destroy_peer); 15933 } else { 15934 char *port = strchr(host, ':'); 15935 if (port) 15936 *port = '\0'; 15937 hp = ast_gethostbyname(host, &ahp); 15938 if (hp) 15939 res = AST_DEVICE_UNKNOWN; 15940 } 15941 15942 return res; 15943 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11297 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11298 { 11299 int oldsipdebug = sipdebug_console; 11300 if (argc != 3) { 11301 if (argc != 5) 11302 return RESULT_SHOWUSAGE; 11303 else if (strcmp(argv[3], "ip") == 0) 11304 return sip_do_debug_ip(fd, argc, argv); 11305 else if (strcmp(argv[3], "peer") == 0) 11306 return sip_do_debug_peer(fd, argc, argv); 11307 else 11308 return RESULT_SHOWUSAGE; 11309 } 11310 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11311 memset(&debugaddr, 0, sizeof(debugaddr)); 11312 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11313 return RESULT_SUCCESS; 11314 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11316 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11317 { 11318 int oldsipdebug = sipdebug_console; 11319 char *newargv[6] = { "sip", "set", "debug", NULL }; 11320 if (argc != 2) { 11321 if (argc != 4) 11322 return RESULT_SHOWUSAGE; 11323 else if (strcmp(argv[2], "ip") == 0) { 11324 newargv[3] = argv[2]; 11325 newargv[4] = argv[3]; 11326 return sip_do_debug_ip(fd, argc + 1, newargv); 11327 } else if (strcmp(argv[2], "peer") == 0) { 11328 newargv[3] = argv[2]; 11329 newargv[4] = argv[3]; 11330 return sip_do_debug_peer(fd, argc + 1, newargv); 11331 } else 11332 return RESULT_SHOWUSAGE; 11333 } 11334 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11335 memset(&debugaddr, 0, sizeof(debugaddr)); 11336 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11337 return RESULT_SUCCESS; 11338 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11243 of file chan_sip.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11244 { 11245 struct hostent *hp; 11246 struct ast_hostent ahp; 11247 int port = 0; 11248 char *p, *arg; 11249 11250 /* sip set debug ip <ip> */ 11251 if (argc != 5) 11252 return RESULT_SHOWUSAGE; 11253 p = arg = argv[4]; 11254 strsep(&p, ":"); 11255 if (p) 11256 port = atoi(p); 11257 hp = ast_gethostbyname(arg, &ahp); 11258 if (hp == NULL) 11259 return RESULT_SHOWUSAGE; 11260 11261 debugaddr.sin_family = AF_INET; 11262 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11263 debugaddr.sin_port = htons(port); 11264 if (port == 0) 11265 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11266 else 11267 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11268 11269 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11270 11271 return RESULT_SUCCESS; 11272 }
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 11275 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11276 { 11277 struct sip_peer *peer; 11278 if (argc != 5) 11279 return RESULT_SHOWUSAGE; 11280 peer = find_peer(argv[4], NULL, 1); 11281 if (peer) { 11282 if (peer->addr.sin_addr.s_addr) { 11283 debugaddr.sin_family = AF_INET; 11284 debugaddr.sin_addr = peer->addr.sin_addr; 11285 debugaddr.sin_port = peer->addr.sin_port; 11286 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11287 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11288 } else 11289 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11290 ASTOBJ_UNREF(peer,sip_destroy_peer); 11291 } else 11292 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11293 return RESULT_SUCCESS; 11294 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11416 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11417 { 11418 if (argc != 2) { 11419 return RESULT_SHOWUSAGE; 11420 } 11421 recordhistory = TRUE; 11422 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11423 return RESULT_SUCCESS; 11424 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17844 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, option_debug, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
17845 { 17846 reload_config(reason); 17847 17848 /* Prune peers who still are supposed to be deleted */ 17849 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17850 if (option_debug > 3) 17851 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17852 17853 /* Send qualify (OPTIONS) to all peers */ 17854 sip_poke_all_peers(); 17855 17856 /* Register with all services */ 17857 sip_send_all_registers(); 17858 17859 if (option_debug > 3) 17860 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17861 17862 return 0; 17863 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17648 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
17649 { 17650 struct sip_pvt *p; 17651 char *mode; 17652 if (data) 17653 mode = (char *)data; 17654 else { 17655 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17656 return 0; 17657 } 17658 ast_channel_lock(chan); 17659 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17660 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17661 ast_channel_unlock(chan); 17662 return 0; 17663 } 17664 p = chan->tech_pvt; 17665 if (!p) { 17666 ast_channel_unlock(chan); 17667 return 0; 17668 } 17669 ast_mutex_lock(&p->lock); 17670 if (!strcasecmp(mode,"info")) { 17671 ast_clear_flag(&p->flags[0], SIP_DTMF); 17672 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17673 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17674 } else if (!strcasecmp(mode,"rfc2833")) { 17675 ast_clear_flag(&p->flags[0], SIP_DTMF); 17676 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17677 p->jointnoncodeccapability |= AST_RTP_DTMF; 17678 } else if (!strcasecmp(mode,"inband")) { 17679 ast_clear_flag(&p->flags[0], SIP_DTMF); 17680 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17681 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17682 } else 17683 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17684 if (p->rtp) 17685 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17686 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17687 if (!p->vad) { 17688 p->vad = ast_dsp_new(); 17689 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17690 } 17691 } else { 17692 if (p->vad) { 17693 ast_dsp_free(p->vad); 17694 p->vad = NULL; 17695 } 17696 } 17697 ast_mutex_unlock(&p->lock); 17698 ast_channel_unlock(chan); 17699 return 0; 17700 }
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 11108 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().
11109 { 11110 int x = 0; 11111 struct sip_history *hist; 11112 static int errmsg = 0; 11113 11114 if (!dialog) 11115 return; 11116 11117 if (!option_debug && !sipdebug) { 11118 if (!errmsg) { 11119 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11120 errmsg = 1; 11121 } 11122 return; 11123 } 11124 11125 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11126 if (dialog->subscribed) 11127 ast_log(LOG_DEBUG, " * Subscription\n"); 11128 else 11129 ast_log(LOG_DEBUG, " * SIP Call\n"); 11130 if (dialog->history) 11131 AST_LIST_TRAVERSE(dialog->history, hist, list) 11132 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11133 if (!x) 11134 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11135 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11136 }
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 3741 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, and ast_channel::tech_pvt.
03742 { 03743 int ret = -1; 03744 struct sip_pvt *p; 03745 03746 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03747 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03748 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03749 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03750 03751 if (!newchan || !newchan->tech_pvt) { 03752 if (!newchan) 03753 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03754 else 03755 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03756 return -1; 03757 } 03758 p = newchan->tech_pvt; 03759 03760 if (!p) { 03761 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03762 return -1; 03763 } 03764 03765 ast_mutex_lock(&p->lock); 03766 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03767 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03768 if (p->owner != oldchan) 03769 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03770 else { 03771 p->owner = newchan; 03772 ret = 0; 03773 } 03774 if (option_debug > 2) 03775 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03776 03777 ast_mutex_unlock(&p->lock); 03778 return ret; 03779 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17793 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17794 { 17795 struct sip_pvt *p = chan->tech_pvt; 17796 return p->peercapability ? p->peercapability : p->capability; 17797 }
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 17501 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.
17502 { 17503 struct sip_pvt *p = NULL; 17504 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17505 17506 if (!(p = chan->tech_pvt)) 17507 return AST_RTP_GET_FAILED; 17508 17509 ast_mutex_lock(&p->lock); 17510 if (!(p->rtp)) { 17511 ast_mutex_unlock(&p->lock); 17512 return AST_RTP_GET_FAILED; 17513 } 17514 17515 *rtp = p->rtp; 17516 17517 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17518 res = AST_RTP_TRY_PARTIAL; 17519 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17520 res = AST_RTP_TRY_NATIVE; 17521 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17522 res = AST_RTP_GET_FAILED; 17523 17524 ast_mutex_unlock(&p->lock); 17525 17526 return res; 17527 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 17366 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.
17367 { 17368 struct sip_pvt *p; 17369 struct ast_udptl *udptl = NULL; 17370 17371 p = chan->tech_pvt; 17372 if (!p) 17373 return NULL; 17374 17375 ast_mutex_lock(&p->lock); 17376 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17377 udptl = p->udptl; 17378 ast_mutex_unlock(&p->lock); 17379 return udptl; 17380 }
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 17530 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
17531 { 17532 struct sip_pvt *p = NULL; 17533 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17534 17535 if (!(p = chan->tech_pvt)) 17536 return AST_RTP_GET_FAILED; 17537 17538 ast_mutex_lock(&p->lock); 17539 if (!(p->vrtp)) { 17540 ast_mutex_unlock(&p->lock); 17541 return AST_RTP_GET_FAILED; 17542 } 17543 17544 *rtp = p->vrtp; 17545 17546 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17547 res = AST_RTP_TRY_NATIVE; 17548 17549 ast_mutex_unlock(&p->lock); 17550 17551 return res; 17552 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
T38 negotiation helper function
Definition at line 17418 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
17419 { 17420 struct sip_pvt *p; 17421 int flag = 0; 17422 17423 p = chan->tech_pvt; 17424 if (!p || !pvt->udptl) 17425 return -1; 17426 17427 /* Setup everything on the other side like offered/responded from first side */ 17428 ast_mutex_lock(&p->lock); 17429 17430 /*! \todo check if this is not set earlier when setting up the PVT. If not 17431 maybe it should move there. */ 17432 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17433 17434 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17435 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17436 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17437 17438 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17439 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17440 not really T38 re-invites which are different. In this 17441 case it's used properly, to see if we can reinvite over 17442 NAT 17443 */ 17444 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17445 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17446 flag =1; 17447 } else { 17448 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17449 } 17450 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17451 if (!p->pendinginvite) { 17452 if (option_debug > 2) { 17453 if (flag) 17454 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)); 17455 else 17456 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)); 17457 } 17458 transmit_reinvite_with_t38_sdp(p); 17459 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17460 if (option_debug > 2) { 17461 if (flag) 17462 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)); 17463 else 17464 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)); 17465 } 17466 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17467 } 17468 } 17469 /* Reset lastrtprx timer */ 17470 p->lastrtprx = p->lastrtptx = time(NULL); 17471 ast_mutex_unlock(&p->lock); 17472 return 0; 17473 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17474 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17475 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17476 flag = 1; 17477 } else { 17478 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17479 } 17480 if (option_debug > 2) { 17481 if (flag) 17482 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)); 17483 else 17484 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)); 17485 } 17486 pvt->t38.state = T38_ENABLED; 17487 p->t38.state = T38_ENABLED; 17488 if (option_debug > 1) { 17489 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17490 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17491 } 17492 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17493 p->lastrtprx = p->lastrtptx = time(NULL); 17494 ast_mutex_unlock(&p->lock); 17495 return 0; 17496 } 17497 }
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 3453 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), ast_sched_del(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::ocseq, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, sip_pvt::rtp, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, sip_pvt::vrtp, sip_pvt::waitid, and XMIT_RELIABLE.
03454 { 03455 struct sip_pvt *p = ast->tech_pvt; 03456 int needcancel = FALSE; 03457 int needdestroy = 0; 03458 struct ast_channel *oldowner = ast; 03459 03460 if (!p) { 03461 if (option_debug) 03462 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03463 return 0; 03464 } 03465 03466 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03467 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03468 if (option_debug && sipdebug) 03469 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03470 update_call_counter(p, DEC_CALL_LIMIT); 03471 } 03472 if (option_debug >3) 03473 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03474 if (p->autokillid > -1) 03475 sip_cancel_destroy(p); 03476 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03477 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03478 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03479 p->owner->tech_pvt = NULL; 03480 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03481 return 0; 03482 } 03483 if (option_debug) { 03484 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03485 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03486 else { 03487 if (option_debug) 03488 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03489 } 03490 } 03491 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03492 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03493 03494 ast_mutex_lock(&p->lock); 03495 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03496 if (option_debug && sipdebug) 03497 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03498 update_call_counter(p, DEC_CALL_LIMIT); 03499 } 03500 03501 /* Determine how to disconnect */ 03502 if (p->owner != ast) { 03503 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03504 ast_mutex_unlock(&p->lock); 03505 return 0; 03506 } 03507 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03508 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03509 needcancel = TRUE; 03510 if (option_debug > 3) 03511 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03512 } 03513 03514 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03515 03516 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03517 03518 /* Disconnect */ 03519 if (p->vad) 03520 ast_dsp_free(p->vad); 03521 03522 p->owner = NULL; 03523 ast->tech_pvt = NULL; 03524 03525 ast_module_unref(ast_module_info->self); 03526 03527 /* Do not destroy this pvt until we have timeout or 03528 get an answer to the BYE or INVITE/CANCEL 03529 If we get no answer during retransmit period, drop the call anyway. 03530 (Sorry, mother-in-law, you can't deny a hangup by sending 03531 603 declined to BYE...) 03532 */ 03533 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03534 needdestroy = 1; /* Set destroy flag at end of this function */ 03535 else if (p->invitestate != INV_CALLING) 03536 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03537 03538 /* Start the process if it's not already started */ 03539 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03540 if (needcancel) { /* Outgoing call, not up */ 03541 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03542 /* stop retransmitting an INVITE that has not received a response */ 03543 __sip_pretend_ack(p); 03544 03545 /* if we can't send right now, mark it pending */ 03546 if (p->invitestate == INV_CALLING) { 03547 /* We can't send anything in CALLING state */ 03548 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03549 /* 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. */ 03550 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03551 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03552 } else { 03553 /* Send a new request: CANCEL */ 03554 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03555 /* Actually don't destroy us yet, wait for the 487 on our original 03556 INVITE, but do set an autodestruct just in case we never get it. */ 03557 needdestroy = 0; 03558 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03559 p->invitestate = INV_CANCELLED; 03560 } 03561 if ( p->initid != -1 ) { 03562 /* channel still up - reverse dec of inUse counter 03563 only if the channel is not auto-congested */ 03564 update_call_counter(p, INC_CALL_LIMIT); 03565 } 03566 } else { /* Incoming call, not up */ 03567 const char *res; 03568 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03569 transmit_response_reliable(p, res, &p->initreq); 03570 else 03571 transmit_response_reliable(p, "603 Declined", &p->initreq); 03572 p->invitestate = INV_TERMINATED; 03573 } 03574 } else { /* Call is in UP state, send BYE */ 03575 if (!p->pendinginvite) { 03576 char *audioqos = ""; 03577 char *videoqos = ""; 03578 if (p->rtp) 03579 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03580 if (p->vrtp) 03581 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03582 /* Send a hangup */ 03583 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03584 03585 /* Get RTCP quality before end of call */ 03586 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03587 if (p->rtp) 03588 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03589 if (p->vrtp) 03590 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03591 } 03592 if (p->rtp && oldowner) 03593 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03594 if (p->vrtp && oldowner) 03595 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03596 } else { 03597 /* Note we will need a BYE when this all settles out 03598 but we can't send one while we have "INVITE" outstanding. */ 03599 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03600 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03601 if (p->waitid) 03602 ast_sched_del(sched, p->waitid); 03603 p->waitid = -1; 03604 sip_cancel_destroy(p); 03605 } 03606 } 03607 } 03608 if (needdestroy) 03609 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03610 ast_mutex_unlock(&p->lock); 03611 return 0; 03612 }
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 3850 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_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_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.
03851 { 03852 struct sip_pvt *p = ast->tech_pvt; 03853 int res = 0; 03854 03855 ast_mutex_lock(&p->lock); 03856 switch(condition) { 03857 case AST_CONTROL_RINGING: 03858 if (ast->_state == AST_STATE_RING) { 03859 p->invitestate = INV_EARLY_MEDIA; 03860 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03861 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03862 /* Send 180 ringing if out-of-band seems reasonable */ 03863 transmit_response(p, "180 Ringing", &p->initreq); 03864 ast_set_flag(&p->flags[0], SIP_RINGING); 03865 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03866 break; 03867 } else { 03868 /* Well, if it's not reasonable, just send in-band */ 03869 } 03870 } 03871 res = -1; 03872 break; 03873 case AST_CONTROL_BUSY: 03874 if (ast->_state != AST_STATE_UP) { 03875 transmit_response(p, "486 Busy Here", &p->initreq); 03876 p->invitestate = INV_COMPLETED; 03877 sip_alreadygone(p); 03878 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03879 break; 03880 } 03881 res = -1; 03882 break; 03883 case AST_CONTROL_CONGESTION: 03884 if (ast->_state != AST_STATE_UP) { 03885 transmit_response(p, "503 Service Unavailable", &p->initreq); 03886 p->invitestate = INV_COMPLETED; 03887 sip_alreadygone(p); 03888 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03889 break; 03890 } 03891 res = -1; 03892 break; 03893 case AST_CONTROL_PROCEEDING: 03894 if ((ast->_state != AST_STATE_UP) && 03895 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03896 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03897 transmit_response(p, "100 Trying", &p->initreq); 03898 p->invitestate = INV_PROCEEDING; 03899 break; 03900 } 03901 res = -1; 03902 break; 03903 case AST_CONTROL_PROGRESS: 03904 if ((ast->_state != AST_STATE_UP) && 03905 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03906 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03907 p->invitestate = INV_EARLY_MEDIA; 03908 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03909 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03910 break; 03911 } 03912 res = -1; 03913 break; 03914 case AST_CONTROL_HOLD: 03915 ast_moh_start(ast, data, p->mohinterpret); 03916 break; 03917 case AST_CONTROL_UNHOLD: 03918 ast_moh_stop(ast); 03919 break; 03920 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03921 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03922 transmit_info_with_vidupdate(p); 03923 /* ast_rtcp_send_h261fur(p->vrtp); */ 03924 } else 03925 res = -1; 03926 break; 03927 case -1: 03928 res = -1; 03929 break; 03930 default: 03931 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03932 res = -1; 03933 break; 03934 } 03935 ast_mutex_unlock(&p->lock); 03936 return res; 03937 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1754 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().
01755 { 01756 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01757 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static, read] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 3945 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, 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().
03946 { 03947 struct ast_channel *tmp; 03948 struct ast_variable *v = NULL; 03949 int fmt; 03950 int what; 03951 int needvideo = 0, video = 0; 03952 char *decoded_exten; 03953 { 03954 const char *my_name; /* pick a good name */ 03955 03956 if (title) 03957 my_name = title; 03958 else if ( (my_name = strchr(i->fromdomain,':')) ) 03959 my_name++; /* skip ':' */ 03960 else 03961 my_name = i->fromdomain; 03962 03963 ast_mutex_unlock(&i->lock); 03964 /* Don't hold a sip pvt lock while we allocate a channel */ 03965 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); 03966 03967 } 03968 if (!tmp) { 03969 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03970 return NULL; 03971 } 03972 ast_mutex_lock(&i->lock); 03973 03974 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03975 tmp->tech = &sip_tech_info; 03976 else 03977 tmp->tech = &sip_tech; 03978 03979 /* Select our native format based on codec preference until we receive 03980 something from another device to the contrary. */ 03981 if (i->jointcapability) { /* The joint capabilities of us and peer */ 03982 what = i->jointcapability; 03983 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 03984 } else if (i->capability) { /* Our configured capability for this peer */ 03985 what = i->capability; 03986 video = i->capability & AST_FORMAT_VIDEO_MASK; 03987 } else { 03988 what = global_capability; /* Global codec support */ 03989 video = global_capability & AST_FORMAT_VIDEO_MASK; 03990 } 03991 03992 /* Set the native formats for audio and merge in video */ 03993 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 03994 if (option_debug > 2) { 03995 char buf[BUFSIZ]; 03996 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03997 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03998 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03999 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 04000 if (i->prefcodec) 04001 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 04002 } 04003 04004 /* XXX Why are we choosing a codec from the native formats?? */ 04005 fmt = ast_best_codec(tmp->nativeformats); 04006 04007 /* If we have a prefcodec setting, we have an inbound channel that set a 04008 preferred format for this call. Otherwise, we check the jointcapability 04009 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04010 */ 04011 if (i->vrtp) { 04012 if (i->prefcodec) 04013 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04014 else 04015 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04016 } 04017 04018 if (option_debug > 2) { 04019 if (needvideo) 04020 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04021 else 04022 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04023 } 04024 04025 04026 04027 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04028 i->vad = ast_dsp_new(); 04029 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04030 if (global_relaxdtmf) 04031 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04032 } 04033 if (i->rtp) { 04034 tmp->fds[0] = ast_rtp_fd(i->rtp); 04035 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04036 } 04037 if (needvideo && i->vrtp) { 04038 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04039 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04040 } 04041 if (i->udptl) { 04042 tmp->fds[5] = ast_udptl_fd(i->udptl); 04043 } 04044 if (state == AST_STATE_RING) 04045 tmp->rings = 1; 04046 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04047 tmp->writeformat = fmt; 04048 tmp->rawwriteformat = fmt; 04049 tmp->readformat = fmt; 04050 tmp->rawreadformat = fmt; 04051 tmp->tech_pvt = i; 04052 04053 tmp->callgroup = i->callgroup; 04054 tmp->pickupgroup = i->pickupgroup; 04055 tmp->cid.cid_pres = i->callingpres; 04056 if (!ast_strlen_zero(i->accountcode)) 04057 ast_string_field_set(tmp, accountcode, i->accountcode); 04058 if (i->amaflags) 04059 tmp->amaflags = i->amaflags; 04060 if (!ast_strlen_zero(i->language)) 04061 ast_string_field_set(tmp, language, i->language); 04062 i->owner = tmp; 04063 ast_module_ref(ast_module_info->self); 04064 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04065 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04066 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04067 * structure so that there aren't issues when forming URI's 04068 */ 04069 decoded_exten = ast_strdupa(i->exten); 04070 ast_uri_decode(decoded_exten); 04071 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04072 04073 /* Don't use ast_set_callerid() here because it will 04074 * generate an unnecessary NewCallerID event */ 04075 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04076 if (!ast_strlen_zero(i->rdnis)) 04077 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04078 04079 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04080 tmp->cid.cid_dnid = ast_strdup(i->exten); 04081 04082 tmp->priority = 1; 04083 if (!ast_strlen_zero(i->uri)) 04084 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04085 if (!ast_strlen_zero(i->domain)) 04086 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04087 if (!ast_strlen_zero(i->useragent)) 04088 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04089 if (!ast_strlen_zero(i->callid)) 04090 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04091 if (i->rtp) 04092 ast_jb_configure(tmp, &global_jbconf); 04093 04094 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04095 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04096 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04097 04098 /* Set channel variables for this call from configuration */ 04099 for (v = i->chanvars ; v ; v = v->next) 04100 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04101 04102 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04103 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04104 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04105 ast_hangup(tmp); 04106 tmp = NULL; 04107 } 04108 04109 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04110 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04111 04112 return tmp; 04113 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11397 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11398 { 11399 if (argc != 4) 11400 return RESULT_SHOWUSAGE; 11401 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11402 ast_cli(fd, "SIP Debugging Disabled\n"); 11403 return RESULT_SUCCESS; 11404 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11406 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11407 { 11408 if (argc != 3) 11409 return RESULT_SHOWUSAGE; 11410 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11411 ast_cli(fd, "SIP Debugging Disabled\n"); 11412 return RESULT_SUCCESS; 11413 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11427 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11428 { 11429 if (argc != 3) { 11430 return RESULT_SHOWUSAGE; 11431 } 11432 recordhistory = FALSE; 11433 ast_cli(fd, "SIP History Recording Disabled\n"); 11434 return RESULT_SUCCESS; 11435 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11341 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.
11342 { 11343 struct ast_variable *varlist; 11344 int i; 11345 11346 if (argc < 4) 11347 return RESULT_SHOWUSAGE; 11348 11349 if (!notify_types) { 11350 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11351 return RESULT_FAILURE; 11352 } 11353 11354 varlist = ast_variable_browse(notify_types, argv[2]); 11355 11356 if (!varlist) { 11357 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11358 return RESULT_FAILURE; 11359 } 11360 11361 for (i = 3; i < argc; i++) { 11362 struct sip_pvt *p; 11363 struct sip_request req; 11364 struct ast_variable *var; 11365 11366 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11367 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11368 return RESULT_FAILURE; 11369 } 11370 11371 if (create_addr(p, argv[i])) { 11372 /* Maybe they're not registered, etc. */ 11373 sip_destroy(p); 11374 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11375 continue; 11376 } 11377 11378 initreqprep(&req, p, SIP_NOTIFY); 11379 11380 for (var = varlist; var; var = var->next) 11381 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11382 11383 /* Recalculate our side, and recalculate Call ID */ 11384 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11385 p->ourip = __ourip; 11386 build_via(p); 11387 build_callid_pvt(p); 11388 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11389 transmit_sip_request(p, &req); 11390 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11391 } 11392 11393 return RESULT_SUCCESS; 11394 }
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, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
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, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
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 8454 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().
08455 { 08456 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08457 08458 if (!peer) 08459 return; 08460 08461 /* If they put someone on hold, increment the value... otherwise decrement it */ 08462 if (hold) 08463 peer->onHold++; 08464 else 08465 peer->onHold--; 08466 08467 /* Request device state update */ 08468 ast_device_state_changed("SIP/%s", peer->name); 08469 08470 return; 08471 }
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 17803 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
17804 { 17805 int ms = 0; 17806 17807 if (!speerobjs) /* No peers, just give up */ 17808 return; 17809 17810 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17811 ASTOBJ_WRLOCK(iterator); 17812 if (iterator->pokeexpire > -1) 17813 ast_sched_del(sched, iterator->pokeexpire); 17814 ms += 100; 17815 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17816 ASTOBJ_UNLOCK(iterator); 17817 } while (0) 17818 ); 17819 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15755 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, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15756 { 15757 struct sip_peer *peer = (struct sip_peer *)data; 15758 15759 peer->pokeexpire = -1; 15760 if (peer->lastms > -1) { 15761 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15762 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15763 } 15764 if (peer->call) 15765 sip_destroy(peer->call); 15766 peer->call = NULL; 15767 peer->lastms = -1; 15768 ast_device_state_changed("SIP/%s", peer->name); 15769 /* Try again quickly */ 15770 if (peer->pokeexpire > -1) 15771 ast_sched_del(sched, peer->pokeexpire); 15772 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15773 return 0; 15774 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15779 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, 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().
15780 { 15781 struct sip_pvt *p; 15782 int xmitres = 0; 15783 15784 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15785 /* IF we have no IP, or this isn't to be monitored, return 15786 imeediately after clearing things out */ 15787 if (peer->pokeexpire > -1) 15788 ast_sched_del(sched, peer->pokeexpire); 15789 peer->lastms = 0; 15790 peer->pokeexpire = -1; 15791 peer->call = NULL; 15792 return 0; 15793 } 15794 if (peer->call) { 15795 if (sipdebug) 15796 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15797 sip_destroy(peer->call); 15798 } 15799 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15800 return -1; 15801 15802 p->sa = peer->addr; 15803 p->recv = peer->addr; 15804 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15805 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15806 15807 /* Send OPTIONs to peer's fullcontact */ 15808 if (!ast_strlen_zero(peer->fullcontact)) 15809 ast_string_field_set(p, fullcontact, peer->fullcontact); 15810 15811 if (!ast_strlen_zero(peer->tohost)) 15812 ast_string_field_set(p, tohost, peer->tohost); 15813 else 15814 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15815 15816 /* Recalculate our side, and recalculate Call ID */ 15817 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15818 p->ourip = __ourip; 15819 build_via(p); 15820 build_callid_pvt(p); 15821 15822 if (peer->pokeexpire > -1) 15823 ast_sched_del(sched, peer->pokeexpire); 15824 p->relatedpeer = peer; 15825 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15826 #ifdef VOCAL_DATA_HACK 15827 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15828 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15829 #else 15830 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15831 #endif 15832 gettimeofday(&peer->ps, NULL); 15833 if (xmitres == XMIT_ERROR) 15834 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 15835 else { 15836 if (peer->pokeexpire > -1) 15837 ast_sched_del(sched, peer->pokeexpire); 15838 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, peer); 15839 } 15840 15841 return 0; 15842 }
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 7854 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().
07855 { 07856 struct sip_peer *peer = (struct sip_peer *)data; 07857 07858 peer->pokeexpire = -1; 07859 sip_poke_peer(peer); 07860 return 0; 07861 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10134 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.
10135 { 10136 struct sip_peer *peer; 10137 struct sip_user *user; 10138 int pruneuser = FALSE; 10139 int prunepeer = FALSE; 10140 int multi = FALSE; 10141 char *name = NULL; 10142 regex_t regexbuf; 10143 10144 switch (argc) { 10145 case 4: 10146 if (!strcasecmp(argv[3], "user")) 10147 return RESULT_SHOWUSAGE; 10148 if (!strcasecmp(argv[3], "peer")) 10149 return RESULT_SHOWUSAGE; 10150 if (!strcasecmp(argv[3], "like")) 10151 return RESULT_SHOWUSAGE; 10152 if (!strcasecmp(argv[3], "all")) { 10153 multi = TRUE; 10154 pruneuser = prunepeer = TRUE; 10155 } else { 10156 pruneuser = prunepeer = TRUE; 10157 name = argv[3]; 10158 } 10159 break; 10160 case 5: 10161 if (!strcasecmp(argv[4], "like")) 10162 return RESULT_SHOWUSAGE; 10163 if (!strcasecmp(argv[3], "all")) 10164 return RESULT_SHOWUSAGE; 10165 if (!strcasecmp(argv[3], "like")) { 10166 multi = TRUE; 10167 name = argv[4]; 10168 pruneuser = prunepeer = TRUE; 10169 } else if (!strcasecmp(argv[3], "user")) { 10170 pruneuser = TRUE; 10171 if (!strcasecmp(argv[4], "all")) 10172 multi = TRUE; 10173 else 10174 name = argv[4]; 10175 } else if (!strcasecmp(argv[3], "peer")) { 10176 prunepeer = TRUE; 10177 if (!strcasecmp(argv[4], "all")) 10178 multi = TRUE; 10179 else 10180 name = argv[4]; 10181 } else 10182 return RESULT_SHOWUSAGE; 10183 break; 10184 case 6: 10185 if (strcasecmp(argv[4], "like")) 10186 return RESULT_SHOWUSAGE; 10187 if (!strcasecmp(argv[3], "user")) { 10188 pruneuser = TRUE; 10189 name = argv[5]; 10190 } else if (!strcasecmp(argv[3], "peer")) { 10191 prunepeer = TRUE; 10192 name = argv[5]; 10193 } else 10194 return RESULT_SHOWUSAGE; 10195 break; 10196 default: 10197 return RESULT_SHOWUSAGE; 10198 } 10199 10200 if (multi && name) { 10201 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10202 return RESULT_SHOWUSAGE; 10203 } 10204 10205 if (multi) { 10206 if (prunepeer) { 10207 int pruned = 0; 10208 10209 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10210 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10211 ASTOBJ_RDLOCK(iterator); 10212 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10213 ASTOBJ_UNLOCK(iterator); 10214 continue; 10215 }; 10216 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10217 ASTOBJ_MARK(iterator); 10218 pruned++; 10219 } 10220 ASTOBJ_UNLOCK(iterator); 10221 } while (0) ); 10222 if (pruned) { 10223 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10224 ast_cli(fd, "%d peers pruned.\n", pruned); 10225 } else 10226 ast_cli(fd, "No peers found to prune.\n"); 10227 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10228 } 10229 if (pruneuser) { 10230 int pruned = 0; 10231 10232 ASTOBJ_CONTAINER_WRLOCK(&userl); 10233 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10234 ASTOBJ_RDLOCK(iterator); 10235 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10236 ASTOBJ_UNLOCK(iterator); 10237 continue; 10238 }; 10239 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10240 ASTOBJ_MARK(iterator); 10241 pruned++; 10242 } 10243 ASTOBJ_UNLOCK(iterator); 10244 } while (0) ); 10245 if (pruned) { 10246 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10247 ast_cli(fd, "%d users pruned.\n", pruned); 10248 } else 10249 ast_cli(fd, "No users found to prune.\n"); 10250 ASTOBJ_CONTAINER_UNLOCK(&userl); 10251 } 10252 } else { 10253 if (prunepeer) { 10254 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10255 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10256 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10257 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10258 } else 10259 ast_cli(fd, "Peer '%s' pruned.\n", name); 10260 ASTOBJ_UNREF(peer, sip_destroy_peer); 10261 } else 10262 ast_cli(fd, "Peer '%s' not found.\n", name); 10263 } 10264 if (pruneuser) { 10265 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10266 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10267 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10268 ASTOBJ_CONTAINER_LINK(&userl, user); 10269 } else 10270 ast_cli(fd, "User '%s' pruned.\n", name); 10271 ASTOBJ_UNREF(user, sip_destroy_user); 10272 } else 10273 ast_cli(fd, "User '%s' not found.\n", name); 10274 } 10275 } 10276 10277 return RESULT_SUCCESS; 10278 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4316 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().
04317 { 04318 struct ast_frame *fr; 04319 struct sip_pvt *p = ast->tech_pvt; 04320 int faxdetected = FALSE; 04321 04322 ast_mutex_lock(&p->lock); 04323 fr = sip_rtp_read(ast, p, &faxdetected); 04324 p->lastrtprx = time(NULL); 04325 04326 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04327 /* 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 */ 04328 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04329 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04330 if (!p->pendinginvite) { 04331 if (option_debug > 2) 04332 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04333 p->t38.state = T38_LOCAL_REINVITE; 04334 transmit_reinvite_with_t38_sdp(p); 04335 if (option_debug > 1) 04336 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04337 } 04338 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04339 if (option_debug > 2) 04340 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04341 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04342 } 04343 } 04344 04345 ast_mutex_unlock(&p->lock); 04346 return fr; 04347 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 1748 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().
01749 { 01750 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01751 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7663 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().
07664 { 07665 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07666 return p->refer ? 1 : 0; 07667 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7419 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, 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().
07420 { 07421 07422 /* if we are here, our registration timed out, so we'll just do it over */ 07423 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07424 struct sip_pvt *p; 07425 int res; 07426 07427 /* if we couldn't get a reference to the registry object, punt */ 07428 if (!r) 07429 return 0; 07430 07431 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07432 if (r->call) { 07433 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07434 in the single SIP manager thread. */ 07435 p = r->call; 07436 if (p->registry) 07437 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07438 r->call = NULL; 07439 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07440 /* Pretend to ACK anything just in case */ 07441 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07442 } 07443 /* If we have a limit, stop registration and give up */ 07444 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07445 /* Ok, enough is enough. Don't try any more */ 07446 /* We could add an external notification here... 07447 steal it from app_voicemail :-) */ 07448 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07449 r->regstate = REG_STATE_FAILED; 07450 } else { 07451 r->regstate = REG_STATE_UNREGISTERED; 07452 r->timeout = -1; 07453 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07454 } 07455 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)); 07456 ASTOBJ_UNREF(r, sip_registry_destroy); 07457 return 0; 07458 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4636 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::callid_valid, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, and username.
Referenced by reload_config().
04637 { 04638 struct sip_registry *reg; 04639 int portnum = 0; 04640 char username[256] = ""; 04641 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04642 char *porta=NULL; 04643 char *contact=NULL; 04644 04645 if (!value) 04646 return -1; 04647 ast_copy_string(username, value, sizeof(username)); 04648 /* First split around the last '@' then parse the two components. */ 04649 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04650 if (hostname) 04651 *hostname++ = '\0'; 04652 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04653 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04654 return -1; 04655 } 04656 /* split user[:secret[:authuser]] */ 04657 secret = strchr(username, ':'); 04658 if (secret) { 04659 *secret++ = '\0'; 04660 authuser = strchr(secret, ':'); 04661 if (authuser) 04662 *authuser++ = '\0'; 04663 } 04664 /* split host[:port][/contact] */ 04665 contact = strchr(hostname, '/'); 04666 if (contact) 04667 *contact++ = '\0'; 04668 if (ast_strlen_zero(contact)) 04669 contact = "s"; 04670 porta = strchr(hostname, ':'); 04671 if (porta) { 04672 *porta++ = '\0'; 04673 portnum = atoi(porta); 04674 if (portnum == 0) { 04675 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04676 return -1; 04677 } 04678 } 04679 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04680 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04681 return -1; 04682 } 04683 04684 if (ast_string_field_init(reg, 256)) { 04685 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04686 free(reg); 04687 return -1; 04688 } 04689 04690 regobjs++; 04691 ASTOBJ_INIT(reg); 04692 ast_string_field_set(reg, contact, contact); 04693 if (!ast_strlen_zero(username)) 04694 ast_string_field_set(reg, username, username); 04695 if (hostname) 04696 ast_string_field_set(reg, hostname, hostname); 04697 if (authuser) 04698 ast_string_field_set(reg, authuser, authuser); 04699 if (secret) 04700 ast_string_field_set(reg, secret, secret); 04701 reg->expire = -1; 04702 reg->timeout = -1; 04703 reg->refresh = default_expiry; 04704 reg->portno = portnum; 04705 reg->callid_valid = FALSE; 04706 reg->ocseq = INITIAL_CSEQ; 04707 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04708 ASTOBJ_UNREF(reg,sip_registry_destroy); 04709 return 0; 04710 }
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 3027 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03028 { 03029 /* Really delete */ 03030 if (option_debug > 2) 03031 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03032 03033 if (reg->call) { 03034 /* Clear registry before destroying to ensure 03035 we don't get reentered trying to grab the registry lock */ 03036 reg->call->registry = NULL; 03037 if (option_debug > 2) 03038 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03039 sip_destroy(reg->call); 03040 } 03041 if (reg->expire > -1) 03042 ast_sched_del(sched, reg->expire); 03043 if (reg->timeout > -1) 03044 ast_sched_del(sched, reg->timeout); 03045 ast_string_field_free_memory(reg); 03046 regobjs--; 03047 free(reg); 03048 03049 }
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 12057 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12058 { 12059 struct sip_pvt *p = (struct sip_pvt *) data; 12060 12061 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12062 p->waitid = -1; 12063 return 0; 12064 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17866 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().
17867 { 17868 ast_mutex_lock(&sip_reload_lock); 17869 if (sip_reloading) 17870 ast_verbose("Previous SIP reload not yet done\n"); 17871 else { 17872 sip_reloading = TRUE; 17873 if (fd) 17874 sip_reloadreason = CHANNEL_CLI_RELOAD; 17875 else 17876 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17877 } 17878 ast_mutex_unlock(&sip_reload_lock); 17879 restart_monitor(); 17880 17881 return 0; 17882 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 15947 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
15948 { 15949 int oldformat; 15950 struct sip_pvt *p; 15951 struct ast_channel *tmpc = NULL; 15952 char *ext, *host; 15953 char tmp[256]; 15954 char *dest = data; 15955 15956 oldformat = format; 15957 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15958 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)); 15959 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15960 return NULL; 15961 } 15962 if (option_debug) 15963 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15964 15965 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15966 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15967 *cause = AST_CAUSE_SWITCH_CONGESTION; 15968 return NULL; 15969 } 15970 15971 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15972 15973 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15974 sip_destroy(p); 15975 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15976 *cause = AST_CAUSE_SWITCH_CONGESTION; 15977 return NULL; 15978 } 15979 15980 ast_copy_string(tmp, dest, sizeof(tmp)); 15981 host = strchr(tmp, '@'); 15982 if (host) { 15983 *host++ = '\0'; 15984 ext = tmp; 15985 } else { 15986 ext = strchr(tmp, '/'); 15987 if (ext) 15988 *ext++ = '\0'; 15989 host = tmp; 15990 } 15991 15992 if (create_addr(p, host)) { 15993 *cause = AST_CAUSE_UNREGISTERED; 15994 if (option_debug > 2) 15995 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15996 sip_destroy(p); 15997 return NULL; 15998 } 15999 if (ast_strlen_zero(p->peername) && ext) 16000 ast_string_field_set(p, peername, ext); 16001 /* Recalculate our side, and recalculate Call ID */ 16002 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16003 p->ourip = __ourip; 16004 build_via(p); 16005 build_callid_pvt(p); 16006 16007 /* We have an extension to call, don't use the full contact here */ 16008 /* This to enable dialing registered peers with extension dialling, 16009 like SIP/peername/extension 16010 SIP/peername will still use the full contact */ 16011 if (ext) { 16012 ast_string_field_set(p, username, ext); 16013 ast_string_field_free(p, fullcontact); 16014 } 16015 #if 0 16016 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16017 #endif 16018 p->prefcodec = oldformat; /* Format for this call */ 16019 ast_mutex_lock(&p->lock); 16020 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16021 ast_mutex_unlock(&p->lock); 16022 if (!tmpc) 16023 sip_destroy(p); 16024 ast_update_use_count(); 16025 restart_monitor(); 16026 return tmpc; 16027 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7387 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().
07388 { 07389 /* if we are here, we know that we need to reregister. */ 07390 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07391 07392 /* if we couldn't get a reference to the registry object, punt */ 07393 if (!r) 07394 return 0; 07395 07396 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07397 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07398 /* Since registry's are only added/removed by the the monitor thread, this 07399 may be overkill to reference/dereference at all here */ 07400 if (sipdebug) 07401 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07402 07403 r->expire = -1; 07404 __sip_do_register(r); 07405 ASTOBJ_UNREF(r, sip_registry_destroy); 07406 return 0; 07407 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static, read] |
Read RTP from network.
Definition at line 4246 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04247 { 04248 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04249 struct ast_frame *f; 04250 04251 if (!p->rtp) { 04252 /* We have no RTP allocated for this channel */ 04253 return &ast_null_frame; 04254 } 04255 04256 switch(ast->fdno) { 04257 case 0: 04258 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04259 break; 04260 case 1: 04261 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04262 break; 04263 case 2: 04264 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04265 break; 04266 case 3: 04267 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04268 break; 04269 case 5: 04270 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04271 break; 04272 default: 04273 f = &ast_null_frame; 04274 } 04275 /* Don't forward RFC2833 if we're not supposed to */ 04276 if (f && (f->frametype == AST_FRAME_DTMF) && 04277 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04278 return &ast_null_frame; 04279 04280 /* We already hold the channel lock */ 04281 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04282 return f; 04283 04284 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04285 if (!(f->subclass & p->jointcapability)) { 04286 if (option_debug) { 04287 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04288 ast_getformatname(f->subclass), p->owner->name); 04289 } 04290 return &ast_null_frame; 04291 } 04292 if (option_debug) 04293 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04294 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04295 ast_set_read_format(p->owner, p->owner->readformat); 04296 ast_set_write_format(p->owner, p->owner->writeformat); 04297 } 04298 04299 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04300 f = ast_dsp_process(p->owner, p->vad, f); 04301 if (f && f->frametype == AST_FRAME_DTMF) { 04302 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04303 if (option_debug) 04304 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04305 *faxdetect = 1; 04306 } else if (option_debug) { 04307 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04308 } 04309 } 04310 } 04311 04312 return f; 04313 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2110 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, sip_pvt::flags, sip_pvt::method, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
02111 { 02112 if (ms < 0) { 02113 if (p->timer_t1 == 0) 02114 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02115 ms = p->timer_t1 * 64; 02116 } 02117 if (sip_debug_test_pvt(p)) 02118 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02119 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02120 append_history(p, "SchedDestroy", "%d ms", ms); 02121 02122 if (p->autokillid > -1) 02123 ast_sched_del(sched, p->autokillid); 02124 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02125 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17822 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
17823 { 17824 int ms; 17825 int regspacing; 17826 if (!regobjs) 17827 return; 17828 regspacing = default_expiry * 1000/regobjs; 17829 if (regspacing > 100) 17830 regspacing = 100; 17831 ms = regspacing; 17832 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17833 ASTOBJ_WRLOCK(iterator); 17834 if (iterator->expire > -1) 17835 ast_sched_del(sched, iterator->expire); 17836 ms += regspacing; 17837 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17838 ASTOBJ_UNLOCK(iterator); 17839 } while (0) 17840 ); 17841 }
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 15492 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by do_monitor(), and handle_request_subscribe().
15493 { 15494 /* Called with peerl lock, but releases it */ 15495 struct sip_pvt *p; 15496 int newmsgs, oldmsgs; 15497 15498 /* Do we have an IP address? If not, skip this peer */ 15499 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15500 return 0; 15501 15502 /* Check for messages */ 15503 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15504 15505 peer->lastmsgcheck = time(NULL); 15506 15507 /* Return now if it's the same thing we told them last time */ 15508 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15509 return 0; 15510 } 15511 15512 15513 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15514 15515 if (peer->mwipvt) { 15516 /* Base message on subscription */ 15517 p = peer->mwipvt; 15518 } else { 15519 /* Build temporary dialog for this message */ 15520 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15521 return -1; 15522 if (create_addr_from_peer(p, peer)) { 15523 /* Maybe they're not registered, etc. */ 15524 sip_destroy(p); 15525 return 0; 15526 } 15527 /* Recalculate our side, and recalculate Call ID */ 15528 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15529 p->ourip = __ourip; 15530 build_via(p); 15531 build_callid_pvt(p); 15532 /* Destroy this session after 32 secs */ 15533 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15534 } 15535 /* Send MWI */ 15536 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15537 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15538 return 0; 15539 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3781 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.
03782 { 03783 struct sip_pvt *p = ast->tech_pvt; 03784 int res = 0; 03785 03786 ast_mutex_lock(&p->lock); 03787 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03788 case SIP_DTMF_INBAND: 03789 res = -1; /* Tell Asterisk to generate inband indications */ 03790 break; 03791 case SIP_DTMF_RFC2833: 03792 if (p->rtp) 03793 ast_rtp_senddigit_begin(p->rtp, digit); 03794 break; 03795 default: 03796 break; 03797 } 03798 ast_mutex_unlock(&p->lock); 03799 03800 return res; 03801 }
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 3805 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
03806 { 03807 struct sip_pvt *p = ast->tech_pvt; 03808 int res = 0; 03809 03810 ast_mutex_lock(&p->lock); 03811 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03812 case SIP_DTMF_INFO: 03813 transmit_info_with_digit(p, digit, duration); 03814 break; 03815 case SIP_DTMF_RFC2833: 03816 if (p->rtp) 03817 ast_rtp_senddigit_end(p->rtp, digit); 03818 break; 03819 case SIP_DTMF_INBAND: 03820 res = -1; /* Tell Asterisk to stop inband indications */ 03821 break; 03822 } 03823 ast_mutex_unlock(&p->lock); 03824 03825 return res; 03826 }
static int sip_sendtext | ( | struct ast_channel * | ast, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
Definition at line 2353 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().
02354 { 02355 struct sip_pvt *p = ast->tech_pvt; 02356 int debug = sip_debug_test_pvt(p); 02357 02358 if (debug) 02359 ast_verbose("Sending text %s on %s\n", text, ast->name); 02360 if (!p) 02361 return -1; 02362 if (ast_strlen_zero(text)) 02363 return 0; 02364 if (debug) 02365 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02366 transmit_message_with_text(p, text); 02367 return 0; 02368 }
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 17555 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.
17556 { 17557 struct sip_pvt *p; 17558 int changed = 0; 17559 17560 p = chan->tech_pvt; 17561 if (!p) 17562 return -1; 17563 17564 /* Disable early RTP bridge */ 17565 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17566 return 0; 17567 17568 ast_mutex_lock(&p->lock); 17569 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17570 /* If we're destroyed, don't bother */ 17571 ast_mutex_unlock(&p->lock); 17572 return 0; 17573 } 17574 17575 /* if this peer cannot handle reinvites of the media stream to devices 17576 that are known to be behind a NAT, then stop the process now 17577 */ 17578 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17579 ast_mutex_unlock(&p->lock); 17580 return 0; 17581 } 17582 17583 if (rtp) { 17584 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17585 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17586 memset(&p->redirip, 0, sizeof(p->redirip)); 17587 changed = 1; 17588 } 17589 if (vrtp) { 17590 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17591 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17592 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17593 changed = 1; 17594 } 17595 if (codecs) { 17596 if ((p->redircodecs != codecs)) { 17597 p->redircodecs = codecs; 17598 changed = 1; 17599 } 17600 if ((p->capability & codecs) != p->capability) { 17601 p->jointcapability &= codecs; 17602 p->capability &= codecs; 17603 changed = 1; 17604 } 17605 } 17606 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17607 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17608 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17609 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17610 if (option_debug) 17611 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)); 17612 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17613 if (option_debug > 2) { 17614 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)); 17615 } 17616 transmit_reinvite_with_sdp(p); 17617 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17618 if (option_debug > 2) { 17619 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)); 17620 } 17621 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17622 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17623 } 17624 } 17625 /* Reset lastrtprx timer */ 17626 p->lastrtprx = p->lastrtptx = time(NULL); 17627 ast_mutex_unlock(&p->lock); 17628 return 0; 17629 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17382 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.
17383 { 17384 struct sip_pvt *p; 17385 17386 p = chan->tech_pvt; 17387 if (!p) 17388 return -1; 17389 ast_mutex_lock(&p->lock); 17390 if (udptl) 17391 ast_udptl_get_peer(udptl, &p->udptlredirip); 17392 else 17393 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17394 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17395 if (!p->pendinginvite) { 17396 if (option_debug > 2) { 17397 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); 17398 } 17399 transmit_reinvite_with_t38_sdp(p); 17400 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17401 if (option_debug > 2) { 17402 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); 17403 } 17404 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17405 } 17406 } 17407 /* Reset lastrtprx timer */ 17408 p->lastrtprx = p->lastrtptx = time(NULL); 17409 ast_mutex_unlock(&p->lock); 17410 return 0; 17411 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11003 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
11004 { 11005 struct sip_pvt *cur; 11006 size_t len; 11007 int found = 0; 11008 11009 if (argc != 4) 11010 return RESULT_SHOWUSAGE; 11011 len = strlen(argv[3]); 11012 ast_mutex_lock(&iflock); 11013 for (cur = iflist; cur; cur = cur->next) { 11014 if (!strncasecmp(cur->callid, argv[3], len)) { 11015 char formatbuf[BUFSIZ/2]; 11016 ast_cli(fd,"\n"); 11017 if (cur->subscribed != NONE) 11018 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11019 else 11020 ast_cli(fd, " * SIP Call\n"); 11021 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11022 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11023 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11024 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11025 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11026 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11027 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11028 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11029 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11030 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11031 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11032 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11033 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11034 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)" ); 11035 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11036 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11037 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11038 if (!ast_strlen_zero(cur->username)) 11039 ast_cli(fd, " Username: %s\n", cur->username); 11040 if (!ast_strlen_zero(cur->peername)) 11041 ast_cli(fd, " Peername: %s\n", cur->peername); 11042 if (!ast_strlen_zero(cur->uri)) 11043 ast_cli(fd, " Original uri: %s\n", cur->uri); 11044 if (!ast_strlen_zero(cur->cid_num)) 11045 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11046 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11047 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11048 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11049 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11050 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11051 ast_cli(fd, " SIP Options: "); 11052 if (cur->sipoptions) { 11053 int x; 11054 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11055 if (cur->sipoptions & sip_options[x].id) 11056 ast_cli(fd, "%s ", sip_options[x].text); 11057 } 11058 } else 11059 ast_cli(fd, "(none)\n"); 11060 ast_cli(fd, "\n\n"); 11061 found++; 11062 } 11063 } 11064 ast_mutex_unlock(&iflock); 11065 if (!found) 11066 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11067 return RESULT_SUCCESS; 11068 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10800 of file chan_sip.c.
References __sip_show_channels().
10801 { 10802 return __sip_show_channels(fd, argc, argv, 0); 10803 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10312 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.
10313 { 10314 struct domain *d; 10315 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10316 10317 if (AST_LIST_EMPTY(&domain_list)) { 10318 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10319 return RESULT_SUCCESS; 10320 } else { 10321 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10322 AST_LIST_LOCK(&domain_list); 10323 AST_LIST_TRAVERSE(&domain_list, d, list) 10324 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10325 domain_mode_to_text(d->mode)); 10326 AST_LIST_UNLOCK(&domain_list); 10327 ast_cli(fd, "\n"); 10328 return RESULT_SUCCESS; 10329 } 10330 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11071 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.
11072 { 11073 struct sip_pvt *cur; 11074 size_t len; 11075 int found = 0; 11076 11077 if (argc != 4) 11078 return RESULT_SHOWUSAGE; 11079 if (!recordhistory) 11080 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11081 len = strlen(argv[3]); 11082 ast_mutex_lock(&iflock); 11083 for (cur = iflist; cur; cur = cur->next) { 11084 if (!strncasecmp(cur->callid, argv[3], len)) { 11085 struct sip_history *hist; 11086 int x = 0; 11087 11088 ast_cli(fd,"\n"); 11089 if (cur->subscribed != NONE) 11090 ast_cli(fd, " * Subscription\n"); 11091 else 11092 ast_cli(fd, " * SIP Call\n"); 11093 if (cur->history) 11094 AST_LIST_TRAVERSE(cur->history, hist, list) 11095 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11096 if (x == 0) 11097 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11098 found++; 11099 } 11100 } 11101 ast_mutex_unlock(&iflock); 11102 if (!found) 11103 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11104 return RESULT_SUCCESS; 11105 }
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 9737 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.
09738 { 09739 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09740 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09741 char ilimits[40]; 09742 char iused[40]; 09743 int showall = FALSE; 09744 09745 if (argc < 3) 09746 return RESULT_SHOWUSAGE; 09747 09748 if (argc == 4 && !strcmp(argv[3],"all")) 09749 showall = TRUE; 09750 09751 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09752 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09753 ASTOBJ_RDLOCK(iterator); 09754 if (iterator->call_limit) 09755 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09756 else 09757 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09758 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09759 if (showall || iterator->call_limit) 09760 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09761 ASTOBJ_UNLOCK(iterator); 09762 } while (0) ); 09763 09764 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09765 09766 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09767 ASTOBJ_RDLOCK(iterator); 09768 if (iterator->call_limit) 09769 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09770 else 09771 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09772 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09773 if (showall || iterator->call_limit) 09774 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09775 ASTOBJ_UNLOCK(iterator); 09776 } while (0) ); 09777 09778 return RESULT_SUCCESS; 09779 #undef FORMAT 09780 #undef FORMAT2 09781 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10058 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10059 { 10060 char tmp[256]; 10061 if (argc != 3) 10062 return RESULT_SHOWUSAGE; 10063 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10064 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10065 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10066 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10067 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10068 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10069 return RESULT_SUCCESS; 10070 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10364 of file chan_sip.c.
References _sip_show_peer().
10365 { 10366 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10367 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9914 of file chan_sip.c.
References _sip_show_peers().
09915 { 09916 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09917 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10637 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.
10638 { 10639 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10640 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10641 char host[80]; 10642 char tmpdat[256]; 10643 struct tm tm; 10644 10645 10646 if (argc != 3) 10647 return RESULT_SHOWUSAGE; 10648 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10649 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10650 ASTOBJ_RDLOCK(iterator); 10651 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10652 if (iterator->regtime) { 10653 ast_localtime(&iterator->regtime, &tm, NULL); 10654 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10655 } else { 10656 tmpdat[0] = 0; 10657 } 10658 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10659 ASTOBJ_UNLOCK(iterator); 10660 } while(0)); 10661 return RESULT_SUCCESS; 10662 #undef FORMAT 10663 #undef FORMAT2 10664 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10667 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().
10668 { 10669 int realtimepeers; 10670 int realtimeusers; 10671 char codec_buf[BUFSIZ]; 10672 10673 realtimepeers = ast_check_realtime("sippeers"); 10674 realtimeusers = ast_check_realtime("sipusers"); 10675 10676 if (argc != 3) 10677 return RESULT_SHOWUSAGE; 10678 ast_cli(fd, "\n\nGlobal Settings:\n"); 10679 ast_cli(fd, "----------------\n"); 10680 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10681 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10682 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10683 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10684 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10685 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10686 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10687 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10688 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10689 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10690 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10691 ast_cli(fd, " Our auth realm %s\n", global_realm); 10692 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10693 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10694 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10695 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10696 ast_cli(fd, " User Agent: %s\n", global_useragent); 10697 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10698 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10699 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10700 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10701 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10702 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10703 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10704 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10705 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10706 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10707 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10708 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10709 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10710 #endif 10711 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10712 if (!realtimepeers && !realtimeusers) 10713 ast_cli(fd, " SIP realtime: Disabled\n" ); 10714 else 10715 ast_cli(fd, " SIP realtime: Enabled\n" ); 10716 10717 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10718 ast_cli(fd, "---------------------------\n"); 10719 ast_cli(fd, " Codecs: "); 10720 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10721 ast_cli(fd, "%s\n", codec_buf); 10722 ast_cli(fd, " Codec Order: "); 10723 print_codec_to_cli(fd, &default_prefs); 10724 ast_cli(fd, "\n"); 10725 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10726 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10727 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10728 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10729 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10730 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10731 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10732 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10733 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10734 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10735 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10736 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10737 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10738 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10739 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10740 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10741 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10742 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10743 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10744 ast_cli(fd, "\nDefault Settings:\n"); 10745 ast_cli(fd, "-----------------\n"); 10746 ast_cli(fd, " Context: %s\n", default_context); 10747 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10748 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10749 ast_cli(fd, " Qualify: %d\n", default_qualify); 10750 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10751 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" ); 10752 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10753 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10754 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10755 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10756 10757 10758 if (realtimepeers || realtimeusers) { 10759 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10760 ast_cli(fd, "----------------------\n"); 10761 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10762 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10763 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10764 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10765 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10766 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10767 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10768 } 10769 ast_cli(fd, "\n----\n"); 10770 return RESULT_SUCCESS; 10771 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10806 of file chan_sip.c.
References __sip_show_channels().
10807 { 10808 return __sip_show_channels(fd, argc, argv, 1); 10809 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10582 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.
10583 { 10584 char cbuf[256]; 10585 struct sip_user *user; 10586 struct ast_variable *v; 10587 int load_realtime; 10588 10589 if (argc < 4) 10590 return RESULT_SHOWUSAGE; 10591 10592 /* Load from realtime storage? */ 10593 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10594 10595 user = find_user(argv[3], load_realtime); 10596 if (user) { 10597 ast_cli(fd,"\n\n"); 10598 ast_cli(fd, " * Name : %s\n", user->name); 10599 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10600 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10601 ast_cli(fd, " Context : %s\n", user->context); 10602 ast_cli(fd, " Language : %s\n", user->language); 10603 if (!ast_strlen_zero(user->accountcode)) 10604 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10605 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10606 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10607 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10608 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10609 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10610 ast_cli(fd, " Callgroup : "); 10611 print_group(fd, user->callgroup, 0); 10612 ast_cli(fd, " Pickupgroup : "); 10613 print_group(fd, user->pickupgroup, 0); 10614 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10615 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10616 ast_cli(fd, " Codec Order : ("); 10617 print_codec_to_cli(fd, &user->prefs); 10618 ast_cli(fd, ")\n"); 10619 10620 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10621 if (user->chanvars) { 10622 ast_cli(fd, " Variables :\n"); 10623 for (v = user->chanvars ; v ; v = v->next) 10624 ast_cli(fd, " %s = %s\n", v->name, v->value); 10625 } 10626 ast_cli(fd,"\n"); 10627 ASTOBJ_UNREF(user,sip_destroy_user); 10628 } else { 10629 ast_cli(fd,"User %s not found.\n", argv[3]); 10630 ast_cli(fd,"\n"); 10631 } 10632 10633 return RESULT_SUCCESS; 10634 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9837 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, TRUE, and userl.
09838 { 09839 regex_t regexbuf; 09840 int havepattern = FALSE; 09841 09842 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09843 09844 switch (argc) { 09845 case 5: 09846 if (!strcasecmp(argv[3], "like")) { 09847 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09848 return RESULT_SHOWUSAGE; 09849 havepattern = TRUE; 09850 } else 09851 return RESULT_SHOWUSAGE; 09852 case 3: 09853 break; 09854 default: 09855 return RESULT_SHOWUSAGE; 09856 } 09857 09858 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09859 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09860 ASTOBJ_RDLOCK(iterator); 09861 09862 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09863 ASTOBJ_UNLOCK(iterator); 09864 continue; 09865 } 09866 09867 ast_cli(fd, FORMAT, iterator->name, 09868 iterator->secret, 09869 iterator->accountcode, 09870 iterator->context, 09871 iterator->ha ? "Yes" : "No", 09872 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09873 ASTOBJ_UNLOCK(iterator); 09874 } while (0) 09875 ); 09876 09877 if (havepattern) 09878 regfree(®exbuf); 09879 09880 return RESULT_SUCCESS; 09881 #undef FORMAT 09882 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17742 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().
17743 { 17744 char *cdest; 17745 char *extension, *host, *port; 17746 char tmp[80]; 17747 17748 cdest = ast_strdupa(dest); 17749 17750 extension = strsep(&cdest, "@"); 17751 host = strsep(&cdest, ":"); 17752 port = strsep(&cdest, ":"); 17753 if (ast_strlen_zero(extension)) { 17754 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17755 return 0; 17756 } 17757 17758 /* we'll issue the redirect message here */ 17759 if (!host) { 17760 char *localtmp; 17761 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17762 if (ast_strlen_zero(tmp)) { 17763 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17764 return 0; 17765 } 17766 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17767 char lhost[80], lport[80]; 17768 memset(lhost, 0, sizeof(lhost)); 17769 memset(lport, 0, sizeof(lport)); 17770 localtmp++; 17771 /* This is okey because lhost and lport are as big as tmp */ 17772 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17773 if (ast_strlen_zero(lhost)) { 17774 ast_log(LOG_ERROR, "Can't find the host address\n"); 17775 return 0; 17776 } 17777 host = ast_strdupa(lhost); 17778 if (!ast_strlen_zero(lport)) { 17779 port = ast_strdupa(lport); 17780 } 17781 } 17782 } 17783 17784 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17785 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17786 17787 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17788 sip_alreadygone(p); 17789 return 0; 17790 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3829 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().
03830 { 03831 struct sip_pvt *p = ast->tech_pvt; 03832 int res; 03833 03834 if (dest == NULL) /* functions below do not take a NULL */ 03835 dest = ""; 03836 ast_mutex_lock(&p->lock); 03837 if (ast->_state == AST_STATE_RING) 03838 res = sip_sipredirect(p, dest); 03839 else 03840 res = transmit_refer(p, dest); 03841 ast_mutex_unlock(&p->lock); 03842 return res; 03843 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3664 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03665 { 03666 struct sip_pvt *p = ast->tech_pvt; 03667 int res = 0; 03668 03669 switch (frame->frametype) { 03670 case AST_FRAME_VOICE: 03671 if (!(frame->subclass & ast->nativeformats)) { 03672 char s1[512], s2[512], s3[512]; 03673 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03674 frame->subclass, 03675 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03676 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03677 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03678 ast->readformat, 03679 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03680 ast->writeformat); 03681 return 0; 03682 } 03683 if (p) { 03684 ast_mutex_lock(&p->lock); 03685 if (p->rtp) { 03686 /* If channel is not up, activate early media session */ 03687 if ((ast->_state != AST_STATE_UP) && 03688 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03689 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03690 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03691 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03692 } 03693 p->lastrtptx = time(NULL); 03694 res = ast_rtp_write(p->rtp, frame); 03695 } 03696 ast_mutex_unlock(&p->lock); 03697 } 03698 break; 03699 case AST_FRAME_VIDEO: 03700 if (p) { 03701 ast_mutex_lock(&p->lock); 03702 if (p->vrtp) { 03703 /* Activate video early media */ 03704 if ((ast->_state != AST_STATE_UP) && 03705 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03706 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03707 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03708 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03709 } 03710 p->lastrtptx = time(NULL); 03711 res = ast_rtp_write(p->vrtp, frame); 03712 } 03713 ast_mutex_unlock(&p->lock); 03714 } 03715 break; 03716 case AST_FRAME_IMAGE: 03717 return 0; 03718 break; 03719 case AST_FRAME_MODEM: 03720 if (p) { 03721 ast_mutex_lock(&p->lock); 03722 /* UDPTL requires two-way communication, so early media is not needed here. 03723 we simply forget the frames if we get modem frames before the bridge is up. 03724 Fax will re-transmit. 03725 */ 03726 if (p->udptl && ast->_state == AST_STATE_UP) 03727 res = ast_udptl_write(p->udptl, frame); 03728 ast_mutex_unlock(&p->lock); 03729 } 03730 break; 03731 default: 03732 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03733 return 0; 03734 } 03735 03736 return res; 03737 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15391 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_request::data, errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_request::rlPart1, sip_request::rlPart2, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15392 { 15393 struct sip_request req; 15394 struct sockaddr_in sin = { 0, }; 15395 struct sip_pvt *p; 15396 int res; 15397 socklen_t len = sizeof(sin); 15398 int nounlock; 15399 int recount = 0; 15400 int lockretry; 15401 15402 memset(&req, 0, sizeof(req)); 15403 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15404 if (res < 0) { 15405 #if !defined(__FreeBSD__) 15406 if (errno == EAGAIN) 15407 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15408 else 15409 #endif 15410 if (errno != ECONNREFUSED) 15411 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15412 return 1; 15413 } 15414 if (option_debug && res == sizeof(req.data)) { 15415 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15416 req.data[sizeof(req.data) - 1] = '\0'; 15417 } else 15418 req.data[res] = '\0'; 15419 req.len = res; 15420 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15421 ast_set_flag(&req, SIP_PKT_DEBUG); 15422 if (pedanticsipchecking) 15423 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15424 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15425 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15426 15427 parse_request(&req); 15428 req.method = find_sip_method(req.rlPart1); 15429 15430 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15431 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15432 15433 if (req.headers < 2) /* Must have at least two headers */ 15434 return 1; 15435 15436 /* Process request, with netlock held, and with usual deadlock avoidance */ 15437 for (lockretry = 100; lockretry > 0; lockretry--) { 15438 ast_mutex_lock(&netlock); 15439 15440 /* Find the active SIP dialog or create a new one */ 15441 p = find_call(&req, &sin, req.method); /* returns p locked */ 15442 if (p == NULL) { 15443 if (option_debug) 15444 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15445 ast_mutex_unlock(&netlock); 15446 return 1; 15447 } 15448 /* Go ahead and lock the owner if it has one -- we may need it */ 15449 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15450 if (!p->owner || !ast_channel_trylock(p->owner)) 15451 break; /* locking succeeded */ 15452 if (option_debug) 15453 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15454 ast_mutex_unlock(&p->lock); 15455 ast_mutex_unlock(&netlock); 15456 /* Sleep for a very short amount of time */ 15457 usleep(1); 15458 } 15459 p->recv = sin; 15460 15461 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15462 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15463 15464 if (!lockretry) { 15465 if (p->owner) 15466 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15467 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15468 if (req.method != SIP_ACK) 15469 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15470 /* XXX We could add retry-after to make sure they come back */ 15471 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15472 return 1; 15473 } 15474 nounlock = 0; 15475 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15476 /* Request failed */ 15477 if (option_debug) 15478 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15479 } 15480 15481 if (p->owner && !nounlock) 15482 ast_channel_unlock(p->owner); 15483 ast_mutex_unlock(&p->lock); 15484 ast_mutex_unlock(&netlock); 15485 if (recount) 15486 ast_update_use_count(); 15487 15488 return 1; 15489 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12642 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().
12643 { 12644 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12645 if (p->rtp) 12646 ast_rtp_stop(p->rtp); 12647 if (p->vrtp) 12648 ast_rtp_stop(p->vrtp); 12649 if (p->udptl) 12650 ast_udptl_stop(p->udptl); 12651 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10774 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
10775 { 10776 int i; 10777 10778 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10779 if (subscription_types[i].type == subtype) { 10780 return subscription_types[i].text; 10781 } 10782 } 10783 return subscription_types[0].text; 10784 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6203 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().
06204 { 06205 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06206 06207 if (maxrate & T38FAX_RATE_14400) { 06208 if (option_debug > 1) 06209 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06210 return 14400; 06211 } else if (maxrate & T38FAX_RATE_12000) { 06212 if (option_debug > 1) 06213 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06214 return 12000; 06215 } else if (maxrate & T38FAX_RATE_9600) { 06216 if (option_debug > 1) 06217 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06218 return 9600; 06219 } else if (maxrate & T38FAX_RATE_7200) { 06220 if (option_debug > 1) 06221 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06222 return 7200; 06223 } else if (maxrate & T38FAX_RATE_4800) { 06224 if (option_debug > 1) 06225 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06226 return 4800; 06227 } else if (maxrate & T38FAX_RATE_2400) { 06228 if (option_debug > 1) 06229 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06230 return 2400; 06231 } else { 06232 if (option_debug > 1) 06233 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06234 return 0; 06235 } 06236 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16504 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
16505 { 16506 struct sip_peer *peer; 16507 16508 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16509 return NULL; 16510 16511 apeerobjs++; 16512 ASTOBJ_INIT(peer); 16513 set_peer_defaults(peer); 16514 16515 ast_copy_string(peer->name, name, sizeof(peer->name)); 16516 16517 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16518 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16519 peer->prefs = default_prefs; 16520 reg_source_db(peer); 16521 16522 return peer; 16523 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 5979 of file chan_sip.c.
References ast_string_field_free_memory, and free.
05980 { 05981 struct sip_pvt *p = data; 05982 05983 ast_string_field_free_memory(p); 05984 05985 free(data); 05986 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 9784 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().
09785 { 09786 if (mode == TRANSFER_OPENFORALL) 09787 return "open"; 09788 else if (mode == TRANSFER_CLOSED) 09789 return "closed"; 09790 return "strict"; 09791 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8511 of file chan_sip.c.
References ast_random(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_pvt::initreq, key(), keys, s, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, strsep(), transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08512 { 08513 /* We have to emulate EXACTLY what we'd get with a good peer 08514 * and a bad password, or else we leak information. */ 08515 const char *response = "407 Proxy Authentication Required"; 08516 const char *reqheader = "Proxy-Authorization"; 08517 const char *respheader = "Proxy-Authenticate"; 08518 const char *authtoken; 08519 struct ast_dynamic_str *buf; 08520 char *c; 08521 08522 /* table of recognised keywords, and their value in the digest */ 08523 enum keys { K_NONCE, K_LAST }; 08524 struct x { 08525 const char *key; 08526 const char *s; 08527 } *i, keys[] = { 08528 [K_NONCE] = { "nonce=", "" }, 08529 [K_LAST] = { NULL, NULL} 08530 }; 08531 08532 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08533 response = "401 Unauthorized"; 08534 reqheader = "Authorization"; 08535 respheader = "WWW-Authenticate"; 08536 } 08537 authtoken = get_header(req, reqheader); 08538 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08539 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08540 * information */ 08541 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 08542 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08543 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08544 return; 08545 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08546 /* We have no auth, so issue challenge and request authentication */ 08547 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08548 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 08549 /* Schedule auto destroy in 32 seconds */ 08550 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08551 return; 08552 } 08553 08554 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 08555 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08556 return; 08557 } 08558 08559 /* Make a copy of the response and parse it */ 08560 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 08561 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08562 return; 08563 } 08564 08565 c = buf->str; 08566 08567 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08568 for (i = keys; i->key != NULL; i++) { 08569 const char *separator = ","; /* default */ 08570 08571 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 08572 continue; 08573 } 08574 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08575 c += strlen(i->key); 08576 if (*c == '"') { /* in quotes. Skip first and look for last */ 08577 c++; 08578 separator = "\""; 08579 } 08580 i->s = c; 08581 strsep(&c, separator); 08582 break; 08583 } 08584 if (i->key == NULL) { /* not found, jump after space or comma */ 08585 strsep(&c, " ,"); 08586 } 08587 } 08588 08589 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08590 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 08591 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08592 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08593 } 08594 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08595 08596 /* Schedule auto destroy in 32 seconds */ 08597 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08598 } else { 08599 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08600 } 08601 }
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 7745 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07746 { 07747 struct sip_request req; 07748 07749 reqprep(&req, p, SIP_INFO, 0, 1); 07750 add_digit(&req, digit, duration); 07751 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07752 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7755 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07756 { 07757 struct sip_request req; 07758 07759 reqprep(&req, p, SIP_INFO, 0, 1); 07760 add_vidupdate(&req); 07761 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07762 }
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 7005 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07006 { 07007 struct sip_request req; 07008 07009 req.method = sipmethod; 07010 if (init) { /* Seems like init always is 2 */ 07011 /* Bump branch even on initial requests */ 07012 p->branch ^= ast_random(); 07013 build_via(p); 07014 if (init > 1) 07015 initreqprep(&req, p, sipmethod); 07016 else 07017 reqprep(&req, p, sipmethod, 0, 1); 07018 } else 07019 reqprep(&req, p, sipmethod, 0, 1); 07020 07021 if (p->options && p->options->auth) 07022 add_header(&req, p->options->authheader, p->options->auth); 07023 append_date(&req); 07024 if (sipmethod == SIP_REFER) { /* Call transfer */ 07025 if (p->refer) { 07026 char buf[BUFSIZ]; 07027 if (!ast_strlen_zero(p->refer->refer_to)) 07028 add_header(&req, "Refer-To", p->refer->refer_to); 07029 if (!ast_strlen_zero(p->refer->referred_by)) { 07030 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07031 add_header(&req, "Referred-By", buf); 07032 } 07033 } 07034 } 07035 /* This new INVITE is part of an attended transfer. Make sure that the 07036 other end knows and replace the current call with this new call */ 07037 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07038 add_header(&req, "Replaces", p->options->replaces); 07039 add_header(&req, "Require", "replaces"); 07040 } 07041 07042 add_header(&req, "Allow", ALLOWED_METHODS); 07043 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07044 if (p->options && p->options->addsipheaders && p->owner) { 07045 struct ast_channel *chan = p->owner; /* The owner channel */ 07046 struct varshead *headp; 07047 07048 ast_channel_lock(chan); 07049 07050 headp = &chan->varshead; 07051 07052 if (!headp) 07053 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07054 else { 07055 const struct ast_var_t *current; 07056 AST_LIST_TRAVERSE(headp, current, entries) { 07057 /* SIPADDHEADER: Add SIP header to outgoing call */ 07058 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07059 char *content, *end; 07060 const char *header = ast_var_value(current); 07061 char *headdup = ast_strdupa(header); 07062 07063 /* Strip of the starting " (if it's there) */ 07064 if (*headdup == '"') 07065 headdup++; 07066 if ((content = strchr(headdup, ':'))) { 07067 *content++ = '\0'; 07068 content = ast_skip_blanks(content); /* Skip white space */ 07069 /* Strip the ending " (if it's there) */ 07070 end = content + strlen(content) -1; 07071 if (*end == '"') 07072 *end = '\0'; 07073 07074 add_header(&req, headdup, content); 07075 if (sipdebug) 07076 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07077 } 07078 } 07079 } 07080 } 07081 07082 ast_channel_unlock(chan); 07083 } 07084 if (sdp) { 07085 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 07086 ast_udptl_offered_from_local(p->udptl, 1); 07087 if (option_debug) 07088 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07089 add_t38_sdp(&req, p); 07090 } else if (p->rtp) 07091 add_sdp(&req, p); 07092 } else { 07093 add_header_contentLength(&req, 0); 07094 } 07095 07096 if (!p->initreq.headers) 07097 initialize_initreq(p, &req); 07098 p->lastinvite = p->ocseq; 07099 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07100 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7653 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().
07654 { 07655 struct sip_request req; 07656 07657 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07658 add_text(&req, text); 07659 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07660 }
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 7290 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07291 { 07292 struct sip_request req; 07293 char tmp[500]; 07294 char *t = tmp; 07295 size_t maxbytes = sizeof(tmp); 07296 07297 initreqprep(&req, p, SIP_NOTIFY); 07298 add_header(&req, "Event", "message-summary"); 07299 add_header(&req, "Content-Type", default_notifymime); 07300 07301 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07302 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07303 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07304 /* Cisco has a bug in the SIP stack where it can't accept the 07305 (0/0) notification. This can temporarily be disabled in 07306 sip.conf with the "buggymwi" option */ 07307 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)")); 07308 07309 if (p->subscribed) { 07310 if (p->expiry) 07311 add_header(&req, "Subscription-State", "active"); 07312 else /* Expired */ 07313 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07314 } 07315 07316 if (t > tmp + sizeof(tmp)) 07317 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07318 07319 add_header_contentLength(&req, strlen(tmp)); 07320 add_line(&req, tmp); 07321 07322 if (!p->initreq.headers) 07323 initialize_initreq(p, &req); 07324 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07325 }
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 7336 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, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07337 { 07338 struct sip_request req; 07339 char tmp[BUFSIZ/2]; 07340 07341 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07342 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07343 add_header(&req, "Event", tmp); 07344 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07345 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07346 add_header(&req, "Allow", ALLOWED_METHODS); 07347 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07348 07349 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07350 add_header_contentLength(&req, strlen(tmp)); 07351 add_line(&req, tmp); 07352 07353 if (!p->initreq.headers) 07354 initialize_initreq(p, &req); 07355 07356 p->lastnoninvite = p->ocseq; 07357 07358 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07359 }
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 7674 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().
07675 { 07676 struct sip_request req = { 07677 .headers = 0, 07678 }; 07679 char from[256]; 07680 const char *of; 07681 char *c; 07682 char referto[256]; 07683 char *ttag, *ftag; 07684 char *theirtag = ast_strdupa(p->theirtag); 07685 07686 if (option_debug || sipdebug) 07687 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07688 07689 /* Are we transfering an inbound or outbound call ? */ 07690 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07691 of = get_header(&p->initreq, "To"); 07692 ttag = theirtag; 07693 ftag = p->tag; 07694 } else { 07695 of = get_header(&p->initreq, "From"); 07696 ftag = theirtag; 07697 ttag = p->tag; 07698 } 07699 07700 ast_copy_string(from, of, sizeof(from)); 07701 of = get_in_brackets(from); 07702 ast_string_field_set(p, from, of); 07703 if (strncasecmp(of, "sip:", 4)) 07704 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07705 else 07706 of += 4; 07707 /* Get just the username part */ 07708 if ((c = strchr(dest, '@'))) 07709 c = NULL; 07710 else if ((c = strchr(of, '@'))) 07711 *c++ = '\0'; 07712 if (c) 07713 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07714 else 07715 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07716 07717 /* save in case we get 407 challenge */ 07718 sip_refer_allocate(p); 07719 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07720 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07721 p->refer->status = REFER_SENT; /* Set refer status */ 07722 07723 reqprep(&req, p, SIP_REFER, 0, 1); 07724 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07725 07726 add_header(&req, "Refer-To", referto); 07727 add_header(&req, "Allow", ALLOWED_METHODS); 07728 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07729 if (!ast_strlen_zero(p->our_contact)) 07730 add_header(&req, "Referred-By", p->our_contact); 07731 07732 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07733 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07734 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07735 07736 /*! \todo In theory, we should hang around and wait for a reply, before 07737 returning to the dial plan here. Don't know really how that would 07738 affect the transfer() app or the pbx, but, well, to make this 07739 useful we should have a STATUS code on transfer(). 07740 */ 07741 }
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 7461 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_pvt::ourip, sip_registry::portno, sip_pvt::recv, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07462 { 07463 struct sip_request req; 07464 char from[256]; 07465 char to[256]; 07466 char tmp[80]; 07467 char addr[80]; 07468 struct sip_pvt *p; 07469 07470 /* exit if we are already in process with this registrar ?*/ 07471 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07472 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07473 return 0; 07474 } 07475 07476 if (r->call) { /* We have a registration */ 07477 if (!auth) { 07478 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07479 return 0; 07480 } else { 07481 p = r->call; 07482 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07483 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07484 } 07485 } else { 07486 /* Build callid for registration if we haven't registered before */ 07487 if (!r->callid_valid) { 07488 build_callid_registry(r, __ourip, default_fromdomain); 07489 r->callid_valid = TRUE; 07490 } 07491 /* Allocate SIP packet for registration */ 07492 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07493 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07494 return 0; 07495 } 07496 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07497 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07498 /* Find address to hostname */ 07499 if (create_addr(p, r->hostname)) { 07500 /* we have what we hope is a temporary network error, 07501 * probably DNS. We need to reschedule a registration try */ 07502 sip_destroy(p); 07503 if (r->timeout > -1) { 07504 ast_sched_del(sched, r->timeout); 07505 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07506 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07507 } else { 07508 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07509 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); 07510 } 07511 r->regattempts++; 07512 return 0; 07513 } 07514 /* Copy back Call-ID in case create_addr changed it */ 07515 ast_string_field_set(r, callid, p->callid); 07516 if (r->portno) { 07517 p->sa.sin_port = htons(r->portno); 07518 p->recv.sin_port = htons(r->portno); 07519 } else /* Set registry port to the port set from the peer definition/srv or default */ 07520 r->portno = ntohs(p->sa.sin_port); 07521 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07522 r->call=p; /* Save pointer to SIP packet */ 07523 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07524 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07525 ast_string_field_set(p, peersecret, r->secret); 07526 if (!ast_strlen_zero(r->md5secret)) 07527 ast_string_field_set(p, peermd5secret, r->md5secret); 07528 /* User name in this realm 07529 - if authuser is set, use that, otherwise use username */ 07530 if (!ast_strlen_zero(r->authuser)) { 07531 ast_string_field_set(p, peername, r->authuser); 07532 ast_string_field_set(p, authname, r->authuser); 07533 } else if (!ast_strlen_zero(r->username)) { 07534 ast_string_field_set(p, peername, r->username); 07535 ast_string_field_set(p, authname, r->username); 07536 ast_string_field_set(p, fromuser, r->username); 07537 } 07538 if (!ast_strlen_zero(r->username)) 07539 ast_string_field_set(p, username, r->username); 07540 /* Save extension in packet */ 07541 ast_string_field_set(p, exten, r->contact); 07542 07543 /* 07544 check which address we should use in our contact header 07545 based on whether the remote host is on the external or 07546 internal network so we can register through nat 07547 */ 07548 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07549 p->ourip = bindaddr.sin_addr; 07550 build_contact(p); 07551 } 07552 07553 /* set up a timeout */ 07554 if (auth == NULL) { 07555 if (r->timeout > -1) { 07556 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07557 ast_sched_del(sched, r->timeout); 07558 } 07559 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07560 if (option_debug) 07561 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07562 } 07563 07564 if (strchr(r->username, '@')) { 07565 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07566 if (!ast_strlen_zero(p->theirtag)) 07567 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07568 else 07569 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07570 } else { 07571 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07572 if (!ast_strlen_zero(p->theirtag)) 07573 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07574 else 07575 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07576 } 07577 07578 /* Fromdomain is what we are registering to, regardless of actual 07579 host name from SRV */ 07580 if (!ast_strlen_zero(p->fromdomain)) { 07581 if (r->portno && r->portno != STANDARD_SIP_PORT) 07582 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07583 else 07584 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07585 } else { 07586 if (r->portno && r->portno != STANDARD_SIP_PORT) 07587 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07588 else 07589 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07590 } 07591 ast_string_field_set(p, uri, addr); 07592 07593 p->branch ^= ast_random(); 07594 07595 init_req(&req, sipmethod, addr); 07596 07597 /* Add to CSEQ */ 07598 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07599 p->ocseq = r->ocseq; 07600 07601 build_via(p); 07602 add_header(&req, "Via", p->via); 07603 add_header(&req, "From", from); 07604 add_header(&req, "To", to); 07605 add_header(&req, "Call-ID", p->callid); 07606 add_header(&req, "CSeq", tmp); 07607 if (!ast_strlen_zero(global_useragent)) 07608 add_header(&req, "User-Agent", global_useragent); 07609 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07610 07611 07612 if (auth) /* Add auth header */ 07613 add_header(&req, authheader, auth); 07614 else if (!ast_strlen_zero(r->nonce)) { 07615 char digest[1024]; 07616 07617 /* We have auth data to reuse, build a digest header! */ 07618 if (sipdebug) 07619 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07620 ast_string_field_set(p, realm, r->realm); 07621 ast_string_field_set(p, nonce, r->nonce); 07622 ast_string_field_set(p, domain, r->domain); 07623 ast_string_field_set(p, opaque, r->opaque); 07624 ast_string_field_set(p, qop, r->qop); 07625 r->noncecount++; 07626 p->noncecount = r->noncecount; 07627 07628 memset(digest,0,sizeof(digest)); 07629 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07630 add_header(&req, "Authorization", digest); 07631 else 07632 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07633 07634 } 07635 07636 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07637 add_header(&req, "Expires", tmp); 07638 add_header(&req, "Contact", p->our_contact); 07639 add_header(&req, "Event", "registration"); 07640 add_header_contentLength(&req, 0); 07641 07642 initialize_initreq(p, &req); 07643 if (sip_debug_test_pvt(p)) 07644 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07645 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07646 r->regattempts++; /* Another attempt */ 07647 if (option_debug > 3) 07648 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07649 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07650 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6725 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
06726 { 06727 struct sip_request req; 06728 06729 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06730 06731 add_header(&req, "Allow", ALLOWED_METHODS); 06732 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06733 if (sipdebug) 06734 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06735 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06736 append_history(p, "ReInv", "Re-invite sent"); 06737 add_sdp(&req, p); 06738 /* Use this as the basis */ 06739 initialize_initreq(p, &req); 06740 p->lastinvite = p->ocseq; 06741 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06742 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06743 }
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 6749 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().
06750 { 06751 struct sip_request req; 06752 06753 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06754 06755 add_header(&req, "Allow", ALLOWED_METHODS); 06756 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06757 if (sipdebug) 06758 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06759 ast_udptl_offered_from_local(p->udptl, 1); 06760 add_t38_sdp(&req, p); 06761 /* Use this as the basis */ 06762 initialize_initreq(p, &req); 06763 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06764 p->lastinvite = p->ocseq; 06765 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06766 }
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 7767 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().
07768 { 07769 struct sip_request resp; 07770 07771 if (sipmethod == SIP_ACK) 07772 p->invitestate = INV_CONFIRMED; 07773 07774 reqprep(&resp, p, sipmethod, seqno, newbranch); 07775 add_header_contentLength(&resp, 0); 07776 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07777 }
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 7780 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
07781 { 07782 struct sip_request resp; 07783 07784 reqprep(&resp, p, sipmethod, seqno, newbranch); 07785 if (!ast_strlen_zero(p->realm)) { 07786 char digest[1024]; 07787 07788 memset(digest, 0, sizeof(digest)); 07789 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07790 if (p->options && p->options->auth_type == PROXY_AUTH) 07791 add_header(&resp, "Proxy-Authorization", digest); 07792 else if (p->options && p->options->auth_type == WWW_AUTH) 07793 add_header(&resp, "Authorization", digest); 07794 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07795 add_header(&resp, "Proxy-Authorization", digest); 07796 } else 07797 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07798 } 07799 /* If we are hanging up and know a cause for that, send it in clear text to make 07800 debugging easier. */ 07801 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07802 char buf[10]; 07803 07804 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07805 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07806 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07807 } 07808 07809 add_header_contentLength(&resp, 0); 07810 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07811 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6039 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06040 { 06041 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06042 }
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 6058 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().
06059 { 06060 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06061 }
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 5989 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, sip_pvt::branch, build_via(), do_setnat(), sip_pvt::flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, and XMIT_UNRELIABLE.
Referenced by find_call().
05990 { 05991 struct sip_pvt *p = NULL; 05992 05993 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05994 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05995 return -1; 05996 } 05997 05998 /* if the structure was just allocated, initialize it */ 05999 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06000 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06001 if (ast_string_field_init(p, 512)) 06002 return -1; 06003 } 06004 06005 /* Initialize the bare minimum */ 06006 p->method = intended_method; 06007 06008 if (sin) { 06009 p->sa = *sin; 06010 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06011 p->ourip = __ourip; 06012 } else 06013 p->ourip = __ourip; 06014 06015 p->branch = ast_random(); 06016 make_our_tag(p->tag, sizeof(p->tag)); 06017 p->ocseq = INITIAL_CSEQ; 06018 06019 if (useglobal_nat && sin) { 06020 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06021 p->recv = *sin; 06022 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06023 } 06024 06025 ast_string_field_set(p, fromdomain, default_fromdomain); 06026 build_via(p); 06027 ast_string_field_set(p, callid, callid); 06028 06029 /* Use this temporary pvt structure to send the message */ 06030 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06031 06032 /* Free the string fields, but not the pool space */ 06033 ast_string_field_reset_all(p); 06034 06035 return 0; 06036 }
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 6086 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06087 { 06088 struct sip_request resp; 06089 respprep(&resp, p, msg, req); 06090 add_header(&resp, "Accept", "application/sdp"); 06091 add_header_contentLength(&resp, 0); 06092 return send_response(p, &resp, reliable, 0); 06093 }
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 6096 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
06097 { 06098 struct sip_request resp; 06099 char tmp[512]; 06100 int seqno = 0; 06101 06102 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06103 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06104 return -1; 06105 } 06106 /* Stale means that they sent us correct authentication, but 06107 based it on an old challenge (nonce) */ 06108 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06109 respprep(&resp, p, msg, req); 06110 add_header(&resp, header, tmp); 06111 add_header_contentLength(&resp, 0); 06112 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06113 return send_response(p, &resp, reliable, seqno); 06114 }
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 6076 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06077 { 06078 struct sip_request resp; 06079 respprep(&resp, p, msg, req); 06080 append_date(&resp); 06081 add_header_contentLength(&resp, 0); 06082 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06083 }
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 6654 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06655 { 06656 struct sip_request resp; 06657 int seqno; 06658 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06659 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06660 return -1; 06661 } 06662 respprep(&resp, p, msg, req); 06663 if (p->rtp) { 06664 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06665 if (option_debug) 06666 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06667 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06668 } 06669 try_suggested_sip_codec(p); 06670 add_sdp(&resp, p); 06671 } else 06672 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06673 if (reliable && !p->pendinginvite) 06674 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06675 return send_response(p, &resp, reliable, seqno); 06676 }
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 6614 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06615 { 06616 struct sip_request resp; 06617 int seqno; 06618 06619 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06620 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06621 return -1; 06622 } 06623 respprep(&resp, p, msg, req); 06624 if (p->udptl) { 06625 ast_udptl_offered_from_local(p->udptl, 0); 06626 add_t38_sdp(&resp, p); 06627 } else 06628 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06629 if (retrans && !p->pendinginvite) 06630 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06631 return send_response(p, &resp, retrans, seqno); 06632 }
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 6045 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06046 { 06047 struct sip_request resp; 06048 respprep(&resp, p, msg, req); 06049 append_date(&resp); 06050 add_header(&resp, "Unsupported", unsupported); 06051 add_header_contentLength(&resp, 0); 06052 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06053 }
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 7328 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().
07329 { 07330 if (!p->initreq.headers) /* Initialize first request before sending */ 07331 initialize_initreq(p, req); 07332 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07333 }
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 7103 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, 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().
07104 { 07105 char tmp[4000], from[256], to[256]; 07106 char *t = tmp, *c, *mfrom, *mto; 07107 size_t maxbytes = sizeof(tmp); 07108 struct sip_request req; 07109 char hint[AST_MAX_EXTENSION]; 07110 char *statestring = "terminated"; 07111 const struct cfsubscription_types *subscriptiontype; 07112 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07113 char *pidfstate = "--"; 07114 char *pidfnote= "Ready"; 07115 07116 memset(from, 0, sizeof(from)); 07117 memset(to, 0, sizeof(to)); 07118 memset(tmp, 0, sizeof(tmp)); 07119 07120 switch (state) { 07121 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07122 statestring = (global_notifyringing) ? "early" : "confirmed"; 07123 local_state = NOTIFY_INUSE; 07124 pidfstate = "busy"; 07125 pidfnote = "Ringing"; 07126 break; 07127 case AST_EXTENSION_RINGING: 07128 statestring = "early"; 07129 local_state = NOTIFY_INUSE; 07130 pidfstate = "busy"; 07131 pidfnote = "Ringing"; 07132 break; 07133 case AST_EXTENSION_INUSE: 07134 statestring = "confirmed"; 07135 local_state = NOTIFY_INUSE; 07136 pidfstate = "busy"; 07137 pidfnote = "On the phone"; 07138 break; 07139 case AST_EXTENSION_BUSY: 07140 statestring = "confirmed"; 07141 local_state = NOTIFY_CLOSED; 07142 pidfstate = "busy"; 07143 pidfnote = "On the phone"; 07144 break; 07145 case AST_EXTENSION_UNAVAILABLE: 07146 statestring = "terminated"; 07147 local_state = NOTIFY_CLOSED; 07148 pidfstate = "away"; 07149 pidfnote = "Unavailable"; 07150 break; 07151 case AST_EXTENSION_ONHOLD: 07152 statestring = "confirmed"; 07153 local_state = NOTIFY_INUSE; 07154 pidfstate = "busy"; 07155 pidfnote = "On Hold"; 07156 break; 07157 case AST_EXTENSION_NOT_INUSE: 07158 default: 07159 /* Default setting */ 07160 break; 07161 } 07162 07163 subscriptiontype = find_subscription_type(p->subscribed); 07164 07165 /* Check which device/devices we are watching and if they are registered */ 07166 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07167 char *hint2 = hint, *individual_hint = NULL; 07168 int hint_count = 0, unavailable_count = 0; 07169 07170 while ((individual_hint = strsep(&hint2, "&"))) { 07171 hint_count++; 07172 07173 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07174 unavailable_count++; 07175 } 07176 07177 /* If none of the hinted devices are registered, we will 07178 * override notification and show no availability. 07179 */ 07180 if (hint_count > 0 && hint_count == unavailable_count) { 07181 local_state = NOTIFY_CLOSED; 07182 pidfstate = "away"; 07183 pidfnote = "Not online"; 07184 } 07185 } 07186 07187 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07188 c = get_in_brackets(from); 07189 if (strncasecmp(c, "sip:", 4)) { 07190 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07191 return -1; 07192 } 07193 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07194 07195 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07196 c = get_in_brackets(to); 07197 if (strncasecmp(c, "sip:", 4)) { 07198 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07199 return -1; 07200 } 07201 mto = strsep(&c, ";"); /* trim ; and beyond */ 07202 07203 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07204 07205 07206 add_header(&req, "Event", subscriptiontype->event); 07207 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07208 switch(state) { 07209 case AST_EXTENSION_DEACTIVATED: 07210 if (timeout) 07211 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07212 else { 07213 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07214 add_header(&req, "Retry-After", "60"); 07215 } 07216 break; 07217 case AST_EXTENSION_REMOVED: 07218 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07219 break; 07220 default: 07221 if (p->expiry) 07222 add_header(&req, "Subscription-State", "active"); 07223 else /* Expired */ 07224 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07225 } 07226 switch (p->subscribed) { 07227 case XPIDF_XML: 07228 case CPIM_PIDF_XML: 07229 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07230 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07231 ast_build_string(&t, &maxbytes, "<presence>\n"); 07232 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07233 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07234 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07235 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07236 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07237 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07238 break; 07239 case PIDF_XML: /* Eyebeam supports this format */ 07240 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07241 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); 07242 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07243 if (pidfstate[0] != '-') 07244 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07245 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07246 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07247 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07248 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07249 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07250 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07251 else 07252 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07253 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07254 break; 07255 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07256 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07257 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); 07258 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07259 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07260 else 07261 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07262 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07263 if (state == AST_EXTENSION_ONHOLD) { 07264 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07265 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07266 "</target>\n</local>\n", mto); 07267 } 07268 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07269 break; 07270 case NONE: 07271 default: 07272 break; 07273 } 07274 07275 if (t > tmp + sizeof(tmp)) 07276 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07277 07278 add_header_contentLength(&req, strlen(tmp)); 07279 add_line(&req, tmp); 07280 07281 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07282 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3615 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().
03616 { 03617 int fmt; 03618 const char *codec; 03619 03620 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03621 if (!codec) 03622 return; 03623 03624 fmt = ast_getformatbyname(codec); 03625 if (fmt) { 03626 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03627 if (p->jointcapability & fmt) { 03628 p->jointcapability &= fmt; 03629 p->capability &= fmt; 03630 } else 03631 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03632 } else 03633 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03634 return; 03635 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18064 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, clear_realm_authentication(), clear_sip_domains(), iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipsock, TRUE, and userl.
18065 { 18066 struct sip_pvt *p, *pl; 18067 18068 /* First, take us out of the channel type list */ 18069 ast_channel_unregister(&sip_tech); 18070 18071 /* Unregister dial plan functions */ 18072 ast_custom_function_unregister(&sipchaninfo_function); 18073 ast_custom_function_unregister(&sippeer_function); 18074 ast_custom_function_unregister(&sip_header_function); 18075 ast_custom_function_unregister(&checksipdomain_function); 18076 18077 /* Unregister dial plan applications */ 18078 ast_unregister_application(app_dtmfmode); 18079 ast_unregister_application(app_sipaddheader); 18080 18081 /* Unregister CLI commands */ 18082 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18083 18084 /* Disconnect from the RTP subsystem */ 18085 ast_rtp_proto_unregister(&sip_rtp); 18086 18087 /* Disconnect from UDPTL */ 18088 ast_udptl_proto_unregister(&sip_udptl); 18089 18090 /* Unregister AMI actions */ 18091 ast_manager_unregister("SIPpeers"); 18092 ast_manager_unregister("SIPshowpeer"); 18093 18094 ast_mutex_lock(&iflock); 18095 /* Hangup all interfaces if they have an owner */ 18096 for (p = iflist; p ; p = p->next) { 18097 if (p->owner) 18098 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18099 } 18100 ast_mutex_unlock(&iflock); 18101 18102 ast_mutex_lock(&monlock); 18103 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18104 pthread_cancel(monitor_thread); 18105 pthread_kill(monitor_thread, SIGURG); 18106 pthread_join(monitor_thread, NULL); 18107 } 18108 monitor_thread = AST_PTHREADT_STOP; 18109 ast_mutex_unlock(&monlock); 18110 18111 ast_mutex_lock(&iflock); 18112 /* Destroy all the interfaces and free their memory */ 18113 p = iflist; 18114 while (p) { 18115 pl = p; 18116 p = p->next; 18117 __sip_destroy(pl, TRUE); 18118 } 18119 iflist = NULL; 18120 ast_mutex_unlock(&iflock); 18121 18122 /* Free memory for local network address mask */ 18123 ast_free_ha(localaddr); 18124 18125 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18126 ASTOBJ_CONTAINER_DESTROY(&userl); 18127 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18128 ASTOBJ_CONTAINER_DESTROY(&peerl); 18129 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18130 ASTOBJ_CONTAINER_DESTROY(®l); 18131 18132 clear_realm_authentication(authl); 18133 clear_sip_domains(); 18134 close(sipsock); 18135 sched_context_destroy(sched); 18136 18137 return 0; 18138 }
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 3167 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_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03168 { 03169 char name[256]; 03170 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03171 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03172 struct sip_user *u = NULL; 03173 struct sip_peer *p = NULL; 03174 03175 if (option_debug > 2) 03176 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03177 03178 /* Test if we need to check call limits, in order to avoid 03179 realtime lookups if we do not need it */ 03180 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03181 return 0; 03182 03183 ast_copy_string(name, fup->username, sizeof(name)); 03184 03185 /* Check the list of users only for incoming calls */ 03186 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03187 inuse = &u->inUse; 03188 call_limit = &u->call_limit; 03189 inringing = NULL; 03190 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03191 inuse = &p->inUse; 03192 call_limit = &p->call_limit; 03193 inringing = &p->inRinging; 03194 ast_copy_string(name, fup->peername, sizeof(name)); 03195 } 03196 if (!p && !u) { 03197 if (option_debug > 1) 03198 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03199 return 0; 03200 } 03201 03202 switch(event) { 03203 /* incoming and outgoing affects the inUse counter */ 03204 case DEC_CALL_LIMIT: 03205 if ( *inuse > 0 ) { 03206 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03207 (*inuse)--; 03208 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03209 } 03210 } else { 03211 *inuse = 0; 03212 } 03213 if (inringing) { 03214 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03215 if (*inringing > 0) 03216 (*inringing)--; 03217 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03218 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03219 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03220 } 03221 } 03222 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03223 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03224 sip_peer_hold(fup, 0); 03225 } 03226 if (option_debug > 1 || sipdebug) { 03227 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03228 } 03229 break; 03230 03231 case INC_CALL_RINGING: 03232 case INC_CALL_LIMIT: 03233 if (*call_limit > 0 ) { 03234 if (*inuse >= *call_limit) { 03235 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); 03236 if (u) 03237 ASTOBJ_UNREF(u, sip_destroy_user); 03238 else 03239 ASTOBJ_UNREF(p, sip_destroy_peer); 03240 return -1; 03241 } 03242 } 03243 if (inringing && (event == INC_CALL_RINGING)) { 03244 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03245 (*inringing)++; 03246 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03247 } 03248 } 03249 /* Continue */ 03250 (*inuse)++; 03251 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03252 if (option_debug > 1 || sipdebug) { 03253 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03254 } 03255 break; 03256 03257 case DEC_CALL_RINGING: 03258 if (inringing) { 03259 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03260 if (*inringing > 0) 03261 (*inringing)--; 03262 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03263 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03264 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03265 } 03266 } 03267 break; 03268 03269 default: 03270 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03271 } 03272 if (p) { 03273 ast_device_state_changed("SIP/%s", p->name); 03274 ASTOBJ_UNREF(p, sip_destroy_peer); 03275 } else /* u must be set */ 03276 ASTOBJ_UNREF(u, sip_destroy_user); 03277 return 0; 03278 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2475 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02476 { 02477 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02478 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02479 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02480 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02481 } 02482 }
struct in_addr __ourip [static] |
Definition at line 1206 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 565 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 581 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17633 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17635 of file chan_sip.c.
Authentication list for realm authentication
Definition at line 1195 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 545 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1200 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
Definition at line 11798 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
Definition at line 17900 of file chan_sip.c.
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 17890 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 17895 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 559 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 231 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11682 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1209 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 525 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 522 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 192 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 222 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 524 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 533 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 530 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 531 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 534 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 528 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 529 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17632 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17638 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 561 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1203 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1202 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1201 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1204 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 552 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 553 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 569 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 542 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 568 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 566 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 537 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 584 of file chan_sip.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 229 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 538 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 571 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 555 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 541 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 540 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 562 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 550 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 551 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 563 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 546 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 539 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 549 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 547 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 567 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 556 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 558 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 564 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11699 of file chan_sip.c.
struct io_context* io [static] |
The IO context
Definition at line 605 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1205 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 10333 of file chan_sip.c.
Referenced by load_module().
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 9884 of file chan_sip.c.
Referenced by load_module().
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 191 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 190 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 599 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 11691 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 11695 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 232 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1211 of file chan_sip.c.
Referenced by complete_sipnotify(), reload_config(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 11631 of file chan_sip.c.
int ourport [static] |
Definition at line 1208 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 544 of file chan_sip.c.
struct ast_peer_list peerl [static] |
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 11673 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 560 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 582 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 580 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 578 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 604 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 11655 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 11651 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 11626 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 11659 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 11646 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 11712 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 11668 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 11663 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 11678 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 11716 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 11708 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 11641 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 11636 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 11774 of file chan_sip.c.
struct cfsip_methods sip_methods[] [static] |
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
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 11704 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 601 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 602 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 1609 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 1551 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 1577 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 1618 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1199 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 606 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 579 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 543 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 577 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17631 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17636 of file chan_sip.c.
struct ast_user_list userl [static] |