#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 | 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_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, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
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 1839 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 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(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 516 of file chan_sip.c.
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(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 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 1600 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 4202 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04203 { 04204 int pass; 04205 04206 /* 04207 * Technically you can place arbitrary whitespace both before and after the ':' in 04208 * a header, although RFC3261 clearly says you shouldn't before, and place just 04209 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04210 * a good idea to say you can do it, and if you can do it, why in the hell would. 04211 * you say you shouldn't. 04212 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04213 * and we always allow spaces after that for compatibility. 04214 */ 04215 for (pass = 0; name && pass < 2;pass++) { 04216 int x, len = strlen(name); 04217 for (x=*start; x<req->headers; x++) { 04218 if (!strncasecmp(req->header[x], name, len)) { 04219 char *r = req->header[x] + len; /* skip name */ 04220 if (pedanticsipchecking) 04221 r = ast_skip_blanks(r); 04222 04223 if (*r == ':') { 04224 *start = x+1; 04225 return ast_skip_blanks(r+1); 04226 } 04227 } 04228 } 04229 if (pass == 0) /* Try aliases */ 04230 name = find_alias(name, NULL); 04231 } 04232 04233 /* Don't return NULL, so get_header is always a valid pointer */ 04234 return ""; 04235 }
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 2137 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().
02138 { 02139 struct sip_pkt *cur, *prev = NULL; 02140 02141 /* Just in case... */ 02142 char *msg; 02143 int res = FALSE; 02144 02145 msg = sip_methods[sipmethod].text; 02146 02147 ast_mutex_lock(&p->lock); 02148 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02149 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02150 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02151 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02152 if (!resp && (seqno == p->pendinginvite)) { 02153 if (option_debug) 02154 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02155 p->pendinginvite = 0; 02156 } 02157 /* this is our baby */ 02158 res = TRUE; 02159 UNLINK(cur, p->packets, prev); 02160 if (cur->retransid > -1) { 02161 if (sipdebug && option_debug > 3) 02162 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02163 ast_sched_del(sched, cur->retransid); 02164 cur->retransid = -1; 02165 } 02166 free(cur); 02167 break; 02168 } 02169 } 02170 ast_mutex_unlock(&p->lock); 02171 if (option_debug) 02172 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02173 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2063 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().
02064 { 02065 struct sip_pvt *p = (struct sip_pvt *)data; 02066 02067 /* If this is a subscription, tell the phone that we got a timeout */ 02068 if (p->subscribed) { 02069 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02070 p->subscribed = NONE; 02071 append_history(p, "Subscribestatus", "timeout"); 02072 if (option_debug > 2) 02073 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02074 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02075 } 02076 02077 /* If there are packets still waiting for delivery, delay the destruction */ 02078 if (p->packets) { 02079 if (option_debug > 2) 02080 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02081 append_history(p, "ReliableXmit", "timeout"); 02082 return 10000; 02083 } 02084 02085 /* If we're destroying a subscription, dereference peer object too */ 02086 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02087 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02088 02089 /* Reset schedule ID */ 02090 p->autokillid = -1; 02091 02092 if (option_debug) 02093 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02094 append_history(p, "AutoDestroy", "%s", p->callid); 02095 if (p->owner) { 02096 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02097 ast_queue_hangup(p->owner); 02098 } else if (p->refer) { 02099 if (option_debug > 2) 02100 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02101 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02102 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02103 } else 02104 sip_destroy(p); 02105 return 0; 02106 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3051 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().
03052 { 03053 struct sip_pvt *cur, *prev = NULL; 03054 struct sip_pkt *cp; 03055 03056 if (sip_debug_test_pvt(p) || option_debug > 2) 03057 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03058 03059 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03060 update_call_counter(p, DEC_CALL_LIMIT); 03061 if (option_debug > 1) 03062 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03063 } 03064 03065 /* Remove link from peer to subscription of MWI */ 03066 if (p->relatedpeer && p->relatedpeer->mwipvt) 03067 p->relatedpeer->mwipvt = NULL; 03068 03069 if (dumphistory) 03070 sip_dump_history(p); 03071 03072 if (p->options) 03073 free(p->options); 03074 03075 if (p->stateid > -1) 03076 ast_extension_state_del(p->stateid, NULL); 03077 if (p->initid > -1) 03078 ast_sched_del(sched, p->initid); 03079 if (p->waitid > -1) 03080 ast_sched_del(sched, p->waitid); 03081 if (p->autokillid > -1) 03082 ast_sched_del(sched, p->autokillid); 03083 03084 if (p->rtp) 03085 ast_rtp_destroy(p->rtp); 03086 if (p->vrtp) 03087 ast_rtp_destroy(p->vrtp); 03088 if (p->udptl) 03089 ast_udptl_destroy(p->udptl); 03090 if (p->refer) 03091 free(p->refer); 03092 if (p->route) { 03093 free_old_route(p->route); 03094 p->route = NULL; 03095 } 03096 if (p->registry) { 03097 if (p->registry->call == p) 03098 p->registry->call = NULL; 03099 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03100 } 03101 03102 /* Unlink us from the owner if we have one */ 03103 if (p->owner) { 03104 if (lockowner) 03105 ast_channel_lock(p->owner); 03106 if (option_debug) 03107 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03108 p->owner->tech_pvt = NULL; 03109 if (lockowner) 03110 ast_channel_unlock(p->owner); 03111 } 03112 /* Clear history */ 03113 if (p->history) { 03114 struct sip_history *hist; 03115 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03116 free(hist); 03117 p->history_entries--; 03118 } 03119 free(p->history); 03120 p->history = NULL; 03121 } 03122 03123 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03124 if (cur == p) { 03125 UNLINK(cur, iflist, prev); 03126 break; 03127 } 03128 } 03129 if (!cur) { 03130 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03131 return; 03132 } 03133 03134 /* remove all current packets in this dialog */ 03135 while((cp = p->packets)) { 03136 p->packets = p->packets->next; 03137 if (cp->retransid > -1) 03138 ast_sched_del(sched, cp->retransid); 03139 free(cp); 03140 } 03141 if (p->chanvars) { 03142 ast_variables_destroy(p->chanvars); 03143 p->chanvars = NULL; 03144 } 03145 ast_mutex_destroy(&p->lock); 03146 03147 ast_string_field_free_memory(p); 03148 03149 free(p); 03150 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7409 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07410 { 07411 int res; 07412 07413 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07414 return res; 07415 }
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 2177 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().
02178 { 02179 struct sip_pkt *cur = NULL; 02180 02181 while (p->packets) { 02182 int method; 02183 if (cur == p->packets) { 02184 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02185 return; 02186 } 02187 cur = p->packets; 02188 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02189 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02190 } 02191 }
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 2017 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().
02018 { 02019 struct sip_pkt *pkt; 02020 int siptimer_a = DEFAULT_RETRANS; 02021 int xmitres = 0; 02022 02023 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02024 return AST_FAILURE; 02025 memcpy(pkt->data, data, len); 02026 pkt->method = sipmethod; 02027 pkt->packetlen = len; 02028 pkt->next = p->packets; 02029 pkt->owner = p; 02030 pkt->seqno = seqno; 02031 if (resp) 02032 ast_set_flag(pkt, FLAG_RESPONSE); 02033 pkt->data[len] = '\0'; 02034 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02035 if (fatal) 02036 ast_set_flag(pkt, FLAG_FATAL); 02037 if (pkt->timer_t1) 02038 siptimer_a = pkt->timer_t1 * 2; 02039 02040 /* Schedule retransmission */ 02041 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02042 if (option_debug > 3 && sipdebug) 02043 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02044 pkt->next = p->packets; 02045 p->packets = pkt; 02046 if (sipmethod == SIP_INVITE) { 02047 /* Note this is a pending invite */ 02048 p->pendinginvite = seqno; 02049 } 02050 02051 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02052 02053 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02054 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02055 ast_sched_del(sched, pkt->retransid); /* No more retransmission */ 02056 pkt->retransid = -1; 02057 return AST_FAILURE; 02058 } else 02059 return AST_SUCCESS; 02060 }
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 2194 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().
02195 { 02196 struct sip_pkt *cur; 02197 int res = -1; 02198 02199 for (cur = p->packets; cur; cur = cur->next) { 02200 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02201 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02202 /* this is our baby */ 02203 if (cur->retransid > -1) { 02204 if (option_debug > 3 && sipdebug) 02205 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02206 ast_sched_del(sched, cur->retransid); 02207 cur->retransid = -1; 02208 } 02209 res = 0; 02210 break; 02211 } 02212 } 02213 if (option_debug) 02214 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"); 02215 return res; 02216 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10712 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().
10713 { 10714 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10715 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10716 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10717 struct sip_pvt *cur; 10718 int numchans = 0; 10719 char *referstatus = NULL; 10720 10721 if (argc != 3) 10722 return RESULT_SHOWUSAGE; 10723 ast_mutex_lock(&iflock); 10724 cur = iflist; 10725 if (!subscriptions) 10726 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10727 else 10728 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10729 for (; cur; cur = cur->next) { 10730 referstatus = ""; 10731 if (cur->refer) { /* SIP transfer in progress */ 10732 referstatus = referstatus2str(cur->refer->status); 10733 } 10734 if (cur->subscribed == NONE && !subscriptions) { 10735 char formatbuf[BUFSIZ/2]; 10736 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10737 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10738 cur->callid, 10739 cur->ocseq, cur->icseq, 10740 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 10741 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10742 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10743 cur->lastmsg , 10744 referstatus 10745 ); 10746 numchans++; 10747 } 10748 if (cur->subscribed != NONE && subscriptions) { 10749 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10750 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10751 cur->callid, 10752 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10753 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10754 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10755 subscription_type2str(cur->subscribed), 10756 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10757 ); 10758 numchans++; 10759 } 10760 } 10761 ast_mutex_unlock(&iflock); 10762 if (!subscriptions) 10763 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10764 else 10765 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10766 return RESULT_SUCCESS; 10767 #undef FORMAT 10768 #undef FORMAT2 10769 #undef FORMAT3 10770 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1767 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().
01768 { 01769 int res; 01770 const struct sockaddr_in *dst = sip_real_dst(p); 01771 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01772 01773 if (res == -1) { 01774 switch (errno) { 01775 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01776 case EHOSTUNREACH: /* Host can't be reached */ 01777 case ENETDOWN: /* Inteface down */ 01778 case ENETUNREACH: /* Network failure */ 01779 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01780 } 01781 } 01782 if (res != len) 01783 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)); 01784 return res; 01785 }
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 5955 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().
05956 { 05957 struct sip_request resp; 05958 int seqno = 0; 05959 05960 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05961 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05962 return -1; 05963 } 05964 respprep(&resp, p, msg, req); 05965 add_header_contentLength(&resp, 0); 05966 /* If we are cancelling an incoming invite for some reason, add information 05967 about the reason why we are doing this in clear text */ 05968 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05969 char buf[10]; 05970 05971 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05972 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05973 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05974 } 05975 return send_response(p, &resp, reliable, seqno); 05976 }
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 10270 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().
10271 { 10272 char status[30] = ""; 10273 char cbuf[256]; 10274 struct sip_peer *peer; 10275 char codec_buf[512]; 10276 struct ast_codec_pref *pref; 10277 struct ast_variable *v; 10278 struct sip_auth *auth; 10279 int x = 0, codec = 0, load_realtime; 10280 int realtimepeers; 10281 10282 realtimepeers = ast_check_realtime("sippeers"); 10283 10284 if (argc < 4) 10285 return RESULT_SHOWUSAGE; 10286 10287 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10288 peer = find_peer(argv[3], NULL, load_realtime); 10289 if (s) { /* Manager */ 10290 if (peer) { 10291 const char *id = astman_get_header(m,"ActionID"); 10292 10293 astman_append(s, "Response: Success\r\n"); 10294 if (!ast_strlen_zero(id)) 10295 astman_append(s, "ActionID: %s\r\n",id); 10296 } else { 10297 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10298 astman_send_error(s, m, cbuf); 10299 return 0; 10300 } 10301 } 10302 if (peer && type==0 ) { /* Normal listing */ 10303 ast_cli(fd,"\n\n"); 10304 ast_cli(fd, " * Name : %s\n", peer->name); 10305 if (realtimepeers) { /* Realtime is enabled */ 10306 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10307 } 10308 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10309 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10310 for (auth = peer->auth; auth; auth = auth->next) { 10311 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10312 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10313 } 10314 ast_cli(fd, " Context : %s\n", peer->context); 10315 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10316 ast_cli(fd, " Language : %s\n", peer->language); 10317 if (!ast_strlen_zero(peer->accountcode)) 10318 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10319 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10320 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10321 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10322 if (!ast_strlen_zero(peer->fromuser)) 10323 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10324 if (!ast_strlen_zero(peer->fromdomain)) 10325 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10326 ast_cli(fd, " Callgroup : "); 10327 print_group(fd, peer->callgroup, 0); 10328 ast_cli(fd, " Pickupgroup : "); 10329 print_group(fd, peer->pickupgroup, 0); 10330 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10331 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10332 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10333 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10334 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10335 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10336 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10337 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10338 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))); 10339 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10340 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10341 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10342 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10343 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10344 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10345 #endif 10346 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10347 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10348 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10349 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10350 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10351 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10352 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10353 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10354 10355 /* - is enumerated */ 10356 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10357 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10358 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10359 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)); 10360 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10361 if (!ast_strlen_zero(global_regcontext)) 10362 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10363 ast_cli(fd, " Def. Username: %s\n", peer->username); 10364 ast_cli(fd, " SIP Options : "); 10365 if (peer->sipoptions) { 10366 int lastoption = -1; 10367 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10368 if (sip_options[x].id != lastoption) { 10369 if (peer->sipoptions & sip_options[x].id) 10370 ast_cli(fd, "%s ", sip_options[x].text); 10371 lastoption = x; 10372 } 10373 } 10374 } else 10375 ast_cli(fd, "(none)"); 10376 10377 ast_cli(fd, "\n"); 10378 ast_cli(fd, " Codecs : "); 10379 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10380 ast_cli(fd, "%s\n", codec_buf); 10381 ast_cli(fd, " Codec Order : ("); 10382 print_codec_to_cli(fd, &peer->prefs); 10383 ast_cli(fd, ")\n"); 10384 10385 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10386 ast_cli(fd, " Status : "); 10387 peer_status(peer, status, sizeof(status)); 10388 ast_cli(fd, "%s\n",status); 10389 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10390 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10391 if (peer->chanvars) { 10392 ast_cli(fd, " Variables :\n"); 10393 for (v = peer->chanvars ; v ; v = v->next) 10394 ast_cli(fd, " %s = %s\n", v->name, v->value); 10395 } 10396 ast_cli(fd,"\n"); 10397 ASTOBJ_UNREF(peer,sip_destroy_peer); 10398 } else if (peer && type == 1) { /* manager listing */ 10399 char buf[256]; 10400 astman_append(s, "Channeltype: SIP\r\n"); 10401 astman_append(s, "ObjectName: %s\r\n", peer->name); 10402 astman_append(s, "ChanObjectType: peer\r\n"); 10403 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10404 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10405 astman_append(s, "Context: %s\r\n", peer->context); 10406 astman_append(s, "Language: %s\r\n", peer->language); 10407 if (!ast_strlen_zero(peer->accountcode)) 10408 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10409 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10410 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10411 if (!ast_strlen_zero(peer->fromuser)) 10412 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10413 if (!ast_strlen_zero(peer->fromdomain)) 10414 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10415 astman_append(s, "Callgroup: "); 10416 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10417 astman_append(s, "Pickupgroup: "); 10418 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10419 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10420 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10421 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10422 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10423 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10424 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10425 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10426 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10427 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))); 10428 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10429 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10430 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10431 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10432 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10433 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10434 10435 /* - is enumerated */ 10436 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10437 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10438 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10439 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)); 10440 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)); 10441 astman_append(s, "Default-Username: %s\r\n", peer->username); 10442 if (!ast_strlen_zero(global_regcontext)) 10443 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10444 astman_append(s, "Codecs: "); 10445 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10446 astman_append(s, "%s\r\n", codec_buf); 10447 astman_append(s, "CodecOrder: "); 10448 pref = &peer->prefs; 10449 for(x = 0; x < 32 ; x++) { 10450 codec = ast_codec_pref_index(pref,x); 10451 if (!codec) 10452 break; 10453 astman_append(s, "%s", ast_getformatname(codec)); 10454 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10455 astman_append(s, ","); 10456 } 10457 10458 astman_append(s, "\r\n"); 10459 astman_append(s, "Status: "); 10460 peer_status(peer, status, sizeof(status)); 10461 astman_append(s, "%s\r\n", status); 10462 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10463 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10464 if (peer->chanvars) { 10465 for (v = peer->chanvars ; v ; v = v->next) { 10466 astman_append(s, "ChanVariable:\n"); 10467 astman_append(s, " %s,%s\r\n", v->name, v->value); 10468 } 10469 } 10470 10471 ASTOBJ_UNREF(peer,sip_destroy_peer); 10472 10473 } else { 10474 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10475 ast_cli(fd,"\n"); 10476 } 10477 10478 return RESULT_SUCCESS; 10479 }
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 9820 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().
09821 { 09822 regex_t regexbuf; 09823 int havepattern = FALSE; 09824 09825 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09826 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09827 09828 char name[256]; 09829 int total_peers = 0; 09830 int peers_mon_online = 0; 09831 int peers_mon_offline = 0; 09832 int peers_unmon_offline = 0; 09833 int peers_unmon_online = 0; 09834 const char *id; 09835 char idtext[256] = ""; 09836 int realtimepeers; 09837 09838 realtimepeers = ast_check_realtime("sippeers"); 09839 09840 if (s) { /* Manager - get ActionID */ 09841 id = astman_get_header(m,"ActionID"); 09842 if (!ast_strlen_zero(id)) 09843 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09844 } 09845 09846 switch (argc) { 09847 case 5: 09848 if (!strcasecmp(argv[3], "like")) { 09849 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09850 return RESULT_SHOWUSAGE; 09851 havepattern = TRUE; 09852 } else 09853 return RESULT_SHOWUSAGE; 09854 case 3: 09855 break; 09856 default: 09857 return RESULT_SHOWUSAGE; 09858 } 09859 09860 if (!s) /* Normal list */ 09861 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09862 09863 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09864 char status[20] = ""; 09865 char srch[2000]; 09866 char pstatus; 09867 09868 ASTOBJ_RDLOCK(iterator); 09869 09870 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09871 ASTOBJ_UNLOCK(iterator); 09872 continue; 09873 } 09874 09875 if (!ast_strlen_zero(iterator->username) && !s) 09876 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09877 else 09878 ast_copy_string(name, iterator->name, sizeof(name)); 09879 09880 pstatus = peer_status(iterator, status, sizeof(status)); 09881 if (pstatus == 1) 09882 peers_mon_online++; 09883 else if (pstatus == 0) 09884 peers_mon_offline++; 09885 else { 09886 if (iterator->addr.sin_port == 0) 09887 peers_unmon_offline++; 09888 else 09889 peers_unmon_online++; 09890 } 09891 09892 snprintf(srch, sizeof(srch), FORMAT, name, 09893 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09894 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09895 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09896 iterator->ha ? " A " : " ", /* permit/deny */ 09897 ntohs(iterator->addr.sin_port), status, 09898 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09899 09900 if (!s) {/* Normal CLI list */ 09901 ast_cli(fd, FORMAT, name, 09902 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09903 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09904 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09905 iterator->ha ? " A " : " ", /* permit/deny */ 09906 09907 ntohs(iterator->addr.sin_port), status, 09908 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09909 } else { /* Manager format */ 09910 /* The names here need to be the same as other channels */ 09911 astman_append(s, 09912 "Event: PeerEntry\r\n%s" 09913 "Channeltype: SIP\r\n" 09914 "ObjectName: %s\r\n" 09915 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 09916 "IPaddress: %s\r\n" 09917 "IPport: %d\r\n" 09918 "Dynamic: %s\r\n" 09919 "Natsupport: %s\r\n" 09920 "VideoSupport: %s\r\n" 09921 "ACL: %s\r\n" 09922 "Status: %s\r\n" 09923 "RealtimeDevice: %s\r\n\r\n", 09924 idtext, 09925 iterator->name, 09926 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 09927 ntohs(iterator->addr.sin_port), 09928 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 09929 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 09930 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 09931 iterator->ha ? "yes" : "no", /* permit/deny */ 09932 status, 09933 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 09934 } 09935 09936 ASTOBJ_UNLOCK(iterator); 09937 09938 total_peers++; 09939 } while(0) ); 09940 09941 if (!s) 09942 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 09943 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 09944 09945 if (havepattern) 09946 regfree(®exbuf); 09947 09948 if (total) 09949 *total = total_peers; 09950 09951 09952 return RESULT_SUCCESS; 09953 #undef FORMAT 09954 #undef FORMAT2 09955 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14586 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.
14587 { 14588 struct ast_rtp_quality qos; 14589 struct sip_pvt *p = chan->tech_pvt; 14590 char *all = "", *parse = ast_strdupa(preparse); 14591 AST_DECLARE_APP_ARGS(args, 14592 AST_APP_ARG(param); 14593 AST_APP_ARG(type); 14594 AST_APP_ARG(field); 14595 ); 14596 AST_STANDARD_APP_ARGS(args, parse); 14597 14598 /* Sanity check */ 14599 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14600 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14601 return 0; 14602 } 14603 14604 if (strcasecmp(args.param, "rtpqos")) 14605 return 0; 14606 14607 /* Default arguments of audio,all */ 14608 if (ast_strlen_zero(args.type)) 14609 args.type = "audio"; 14610 if (ast_strlen_zero(args.field)) 14611 args.field = "all"; 14612 14613 memset(buf, 0, buflen); 14614 memset(&qos, 0, sizeof(qos)); 14615 14616 if (strcasecmp(args.type, "AUDIO") == 0) { 14617 all = ast_rtp_get_quality(p->rtp, &qos); 14618 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14619 all = ast_rtp_get_quality(p->vrtp, &qos); 14620 } 14621 14622 if (strcasecmp(args.field, "local_ssrc") == 0) 14623 snprintf(buf, buflen, "%u", qos.local_ssrc); 14624 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14625 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14626 else if (strcasecmp(args.field, "local_jitter") == 0) 14627 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14628 else if (strcasecmp(args.field, "local_count") == 0) 14629 snprintf(buf, buflen, "%u", qos.local_count); 14630 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14631 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14632 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14633 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14634 else if (strcasecmp(args.field, "remote_jitter") == 0) 14635 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14636 else if (strcasecmp(args.field, "remote_count") == 0) 14637 snprintf(buf, buflen, "%u", qos.remote_count); 14638 else if (strcasecmp(args.field, "rtt") == 0) 14639 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14640 else if (strcasecmp(args.field, "all") == 0) 14641 ast_copy_string(buf, all, buflen); 14642 else { 14643 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14644 return -1; 14645 } 14646 return 0; 14647 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2229 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02230 { 02231 if (!req->lines) { 02232 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02233 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02234 req->len += strlen(req->data + req->len); 02235 } 02236 }
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 6159 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().
06162 { 06163 int rtp_code; 06164 struct ast_format_list fmt; 06165 06166 06167 if (debug) 06168 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06169 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06170 return; 06171 06172 if (p->rtp) { 06173 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06174 fmt = ast_codec_pref_getsize(pref, codec); 06175 } 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 */ 06176 return; 06177 ast_build_string(m_buf, m_size, " %d", rtp_code); 06178 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06179 ast_rtp_lookup_mime_subtype(1, codec, 06180 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06181 sample_rate); 06182 if (codec == AST_FORMAT_G729A) { 06183 /* Indicate that we don't support VAD (G.729 annex B) */ 06184 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06185 } else if (codec == AST_FORMAT_G723_1) { 06186 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06187 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06188 } else if (codec == AST_FORMAT_ILBC) { 06189 /* Add information about us using only 20/30 ms packetization */ 06190 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06191 } 06192 06193 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06194 *min_packet_size = fmt.cur_ms; 06195 06196 /* Our first codec packetization processed cannot be less than zero */ 06197 if ((*min_packet_size) == 0 && fmt.cur_ms) 06198 *min_packet_size = fmt.cur_ms; 06199 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6127 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06128 { 06129 char tmp[256]; 06130 06131 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06132 add_header(req, "Content-Type", "application/dtmf-relay"); 06133 add_header_contentLength(req, strlen(tmp)); 06134 add_line(req, tmp); 06135 return 0; 06136 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5522 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.
05523 { 05524 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05525 05526 if (req->headers == SIP_MAX_HEADERS) { 05527 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05528 return -1; 05529 } 05530 05531 if (req->lines) { 05532 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05533 return -1; 05534 } 05535 05536 if (maxlen <= 0) { 05537 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05538 return -1; 05539 } 05540 05541 req->header[req->headers] = req->data + req->len; 05542 05543 if (compactheaders) 05544 var = find_alias(var, var); 05545 05546 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05547 req->len += strlen(req->header[req->headers]); 05548 req->headers++; 05549 05550 return 0; 05551 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5554 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().
05555 { 05556 char clen[10]; 05557 05558 snprintf(clen, sizeof(clen), "%d", len); 05559 return add_header(req, "Content-Length", clen); 05560 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5563 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.
05564 { 05565 if (req->lines == SIP_MAX_LINES) { 05566 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05567 return -1; 05568 } 05569 if (!req->lines) { 05570 /* Add extra empty return */ 05571 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05572 req->len += strlen(req->data + req->len); 05573 } 05574 if (req->len >= sizeof(req->data) - 4) { 05575 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05576 return -1; 05577 } 05578 req->line[req->lines] = req->data + req->len; 05579 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05580 req->len += strlen(req->line[req->lines]); 05581 req->lines++; 05582 return 0; 05583 }
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 6335 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().
06338 { 06339 int rtp_code; 06340 06341 if (debug) 06342 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06343 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06344 return; 06345 06346 ast_build_string(m_buf, m_size, " %d", rtp_code); 06347 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06348 ast_rtp_lookup_mime_subtype(0, format, 0), 06349 sample_rate); 06350 if (format == AST_RTP_DTMF) 06351 /* Indicate we support DTMF and FLASH... */ 06352 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06353 }
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 16160 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().
16161 { 16162 char authcopy[256]; 16163 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16164 char *stringp; 16165 struct sip_auth *a, *b, *auth; 16166 16167 if (ast_strlen_zero(configuration)) 16168 return authlist; 16169 16170 if (option_debug) 16171 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16172 16173 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16174 stringp = authcopy; 16175 16176 username = stringp; 16177 realm = strrchr(stringp, '@'); 16178 if (realm) 16179 *realm++ = '\0'; 16180 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16181 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16182 return authlist; 16183 } 16184 stringp = username; 16185 username = strsep(&stringp, ":"); 16186 if (username) { 16187 secret = strsep(&stringp, ":"); 16188 if (!secret) { 16189 stringp = username; 16190 md5secret = strsep(&stringp,"#"); 16191 } 16192 } 16193 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16194 return authlist; 16195 16196 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16197 ast_copy_string(auth->username, username, sizeof(auth->username)); 16198 if (secret) 16199 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16200 if (md5secret) 16201 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16202 16203 /* find the end of the list */ 16204 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16205 ; 16206 if (b) 16207 b->next = auth; /* Add structure add end of list */ 16208 else 16209 authlist = auth; 16210 16211 if (option_verbose > 2) 16212 ast_verbose("Added authentication for realm %s\n", realm); 16213 16214 return authlist; 16215 16216 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5684 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05685 { 05686 char r[BUFSIZ*2], *p; 05687 int n, rem = sizeof(r); 05688 05689 if (!route) 05690 return; 05691 05692 p = r; 05693 for (;route ; route = route->next) { 05694 n = strlen(route->hop); 05695 if (rem < n+3) /* we need room for ",<route>" */ 05696 break; 05697 if (p != r) { /* add a separator after fist route */ 05698 *p++ = ','; 05699 --rem; 05700 } 05701 *p++ = '<'; 05702 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05703 p += n; 05704 *p++ = '>'; 05705 rem -= (n+2); 05706 } 05707 *p = '\0'; 05708 add_header(req, "Route", r); 05709 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6358 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.
06359 { 06360 int len = 0; 06361 int alreadysent = 0; 06362 06363 struct sockaddr_in sin; 06364 struct sockaddr_in vsin; 06365 struct sockaddr_in dest; 06366 struct sockaddr_in vdest = { 0, }; 06367 06368 /* SDP fields */ 06369 char *version = "v=0\r\n"; /* Protocol version */ 06370 char *subject = "s=session\r\n"; /* Subject of the session */ 06371 char owner[256]; /* Session owner/creator */ 06372 char connection[256]; /* Connection data */ 06373 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06374 char bandwidth[256] = ""; /* Max bitrate */ 06375 char *hold; 06376 char m_audio[256]; /* Media declaration line for audio */ 06377 char m_video[256]; /* Media declaration line for video */ 06378 char a_audio[1024]; /* Attributes for audio */ 06379 char a_video[1024]; /* Attributes for video */ 06380 char *m_audio_next = m_audio; 06381 char *m_video_next = m_video; 06382 size_t m_audio_left = sizeof(m_audio); 06383 size_t m_video_left = sizeof(m_video); 06384 char *a_audio_next = a_audio; 06385 char *a_video_next = a_video; 06386 size_t a_audio_left = sizeof(a_audio); 06387 size_t a_video_left = sizeof(a_video); 06388 06389 int x; 06390 int capability; 06391 int needvideo = FALSE; 06392 int debug = sip_debug_test_pvt(p); 06393 int min_audio_packet_size = 0; 06394 int min_video_packet_size = 0; 06395 06396 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06397 06398 if (!p->rtp) { 06399 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06400 return AST_FAILURE; 06401 } 06402 06403 /* Set RTP Session ID and version */ 06404 if (!p->sessionid) { 06405 p->sessionid = getpid(); 06406 p->sessionversion = p->sessionid; 06407 } else 06408 p->sessionversion++; 06409 06410 /* Get our addresses */ 06411 ast_rtp_get_us(p->rtp, &sin); 06412 if (p->vrtp) 06413 ast_rtp_get_us(p->vrtp, &vsin); 06414 06415 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06416 if (p->redirip.sin_addr.s_addr) { 06417 dest.sin_port = p->redirip.sin_port; 06418 dest.sin_addr = p->redirip.sin_addr; 06419 } else { 06420 dest.sin_addr = p->ourip; 06421 dest.sin_port = sin.sin_port; 06422 } 06423 06424 capability = p->jointcapability; 06425 06426 06427 if (option_debug > 1) { 06428 char codecbuf[BUFSIZ]; 06429 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"); 06430 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06431 } 06432 06433 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06434 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06435 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06436 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06437 } 06438 #endif 06439 06440 /* Check if we need video in this call */ 06441 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06442 if (p->vrtp) { 06443 needvideo = TRUE; 06444 if (option_debug > 1) 06445 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06446 } else if (option_debug > 1) 06447 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06448 } 06449 06450 06451 /* Ok, we need video. Let's add what we need for video and set codecs. 06452 Video is handled differently than audio since we can not transcode. */ 06453 if (needvideo) { 06454 /* Determine video destination */ 06455 if (p->vredirip.sin_addr.s_addr) { 06456 vdest.sin_addr = p->vredirip.sin_addr; 06457 vdest.sin_port = p->vredirip.sin_port; 06458 } else { 06459 vdest.sin_addr = p->ourip; 06460 vdest.sin_port = vsin.sin_port; 06461 } 06462 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06463 06464 /* Build max bitrate string */ 06465 if (p->maxcallbitrate) 06466 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06467 if (debug) 06468 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06469 } 06470 06471 if (debug) 06472 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06473 06474 /* Start building generic SDP headers */ 06475 06476 /* We break with the "recommendation" and send our IP, in order that our 06477 peer doesn't have to ast_gethostbyname() us */ 06478 06479 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06480 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06481 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06482 06483 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06484 hold = "a=recvonly\r\n"; 06485 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06486 hold = "a=inactive\r\n"; 06487 else 06488 hold = "a=sendrecv\r\n"; 06489 06490 /* Now, start adding audio codecs. These are added in this order: 06491 - First what was requested by the calling channel 06492 - Then preferences in order from sip.conf device config for this peer/user 06493 - Then other codecs in capabilities, including video 06494 */ 06495 06496 /* Prefer the audio codec we were requested to use, first, no matter what 06497 Note that p->prefcodec can include video codecs, so mask them out 06498 */ 06499 if (capability & p->prefcodec) { 06500 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06501 06502 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06503 &m_audio_next, &m_audio_left, 06504 &a_audio_next, &a_audio_left, 06505 debug, &min_audio_packet_size); 06506 alreadysent |= codec; 06507 } 06508 06509 /* Start by sending our preferred audio codecs */ 06510 for (x = 0; x < 32; x++) { 06511 int codec; 06512 06513 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06514 break; 06515 06516 if (!(capability & codec)) 06517 continue; 06518 06519 if (alreadysent & codec) 06520 continue; 06521 06522 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06523 &m_audio_next, &m_audio_left, 06524 &a_audio_next, &a_audio_left, 06525 debug, &min_audio_packet_size); 06526 alreadysent |= codec; 06527 } 06528 06529 /* Now send any other common audio and video codecs, and non-codec formats: */ 06530 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06531 if (!(capability & x)) /* Codec not requested */ 06532 continue; 06533 06534 if (alreadysent & x) /* Already added to SDP */ 06535 continue; 06536 06537 if (x <= AST_FORMAT_MAX_AUDIO) 06538 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06539 &m_audio_next, &m_audio_left, 06540 &a_audio_next, &a_audio_left, 06541 debug, &min_audio_packet_size); 06542 else 06543 add_codec_to_sdp(p, x, 90000, 06544 &m_video_next, &m_video_left, 06545 &a_video_next, &a_video_left, 06546 debug, &min_video_packet_size); 06547 } 06548 06549 /* Now add DTMF RFC2833 telephony-event as a codec */ 06550 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06551 if (!(p->jointnoncodeccapability & x)) 06552 continue; 06553 06554 add_noncodec_to_sdp(p, x, 8000, 06555 &m_audio_next, &m_audio_left, 06556 &a_audio_next, &a_audio_left, 06557 debug); 06558 } 06559 06560 if (option_debug > 2) 06561 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06562 06563 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06564 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06565 06566 if (min_audio_packet_size) 06567 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06568 06569 if (min_video_packet_size) 06570 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06571 06572 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06573 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06574 06575 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06576 if (needvideo) 06577 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06578 06579 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06580 if (needvideo) /* only if video response is appropriate */ 06581 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06582 06583 add_header(resp, "Content-Type", "application/sdp"); 06584 add_header_contentLength(resp, len); 06585 add_line(resp, version); 06586 add_line(resp, owner); 06587 add_line(resp, subject); 06588 add_line(resp, connection); 06589 if (needvideo) /* only if video response is appropriate */ 06590 add_line(resp, bandwidth); 06591 add_line(resp, stime); 06592 add_line(resp, m_audio); 06593 add_line(resp, a_audio); 06594 add_line(resp, hold); 06595 if (needvideo) { /* only if video response is appropriate */ 06596 add_line(resp, m_video); 06597 add_line(resp, a_video); 06598 add_line(resp, hold); /* Repeat hold for the video stream */ 06599 } 06600 06601 /* Update lastrtprx when we send our SDP */ 06602 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06603 06604 if (option_debug > 2) { 06605 char buf[BUFSIZ]; 06606 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06607 } 06608 06609 return AST_SUCCESS; 06610 }
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 16096 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().
16097 { 16098 struct domain *d; 16099 16100 if (ast_strlen_zero(domain)) { 16101 ast_log(LOG_WARNING, "Zero length domain.\n"); 16102 return 1; 16103 } 16104 16105 if (!(d = ast_calloc(1, sizeof(*d)))) 16106 return 0; 16107 16108 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16109 16110 if (!ast_strlen_zero(context)) 16111 ast_copy_string(d->context, context, sizeof(d->context)); 16112 16113 d->mode = mode; 16114 16115 AST_LIST_LOCK(&domain_list); 16116 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16117 AST_LIST_UNLOCK(&domain_list); 16118 16119 if (sipdebug) 16120 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16121 16122 return 1; 16123 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6238 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().
06239 { 06240 int len = 0; 06241 int x = 0; 06242 struct sockaddr_in udptlsin; 06243 char v[256] = ""; 06244 char s[256] = ""; 06245 char o[256] = ""; 06246 char c[256] = ""; 06247 char t[256] = ""; 06248 char m_modem[256]; 06249 char a_modem[1024]; 06250 char *m_modem_next = m_modem; 06251 size_t m_modem_left = sizeof(m_modem); 06252 char *a_modem_next = a_modem; 06253 size_t a_modem_left = sizeof(a_modem); 06254 struct sockaddr_in udptldest = { 0, }; 06255 int debug; 06256 06257 debug = sip_debug_test_pvt(p); 06258 len = 0; 06259 if (!p->udptl) { 06260 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06261 return -1; 06262 } 06263 06264 if (!p->sessionid) { 06265 p->sessionid = getpid(); 06266 p->sessionversion = p->sessionid; 06267 } else 06268 p->sessionversion++; 06269 06270 /* Our T.38 end is */ 06271 ast_udptl_get_us(p->udptl, &udptlsin); 06272 06273 /* Determine T.38 UDPTL destination */ 06274 if (p->udptlredirip.sin_addr.s_addr) { 06275 udptldest.sin_port = p->udptlredirip.sin_port; 06276 udptldest.sin_addr = p->udptlredirip.sin_addr; 06277 } else { 06278 udptldest.sin_addr = p->ourip; 06279 udptldest.sin_port = udptlsin.sin_port; 06280 } 06281 06282 if (debug) 06283 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06284 06285 /* We break with the "recommendation" and send our IP, in order that our 06286 peer doesn't have to ast_gethostbyname() us */ 06287 06288 if (debug) { 06289 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06290 p->t38.capability, 06291 p->t38.peercapability, 06292 p->t38.jointcapability); 06293 } 06294 snprintf(v, sizeof(v), "v=0\r\n"); 06295 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06296 snprintf(s, sizeof(s), "s=session\r\n"); 06297 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06298 snprintf(t, sizeof(t), "t=0 0\r\n"); 06299 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06300 06301 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06302 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06303 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06304 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06305 if ((x = t38_get_rate(p->t38.jointcapability))) 06306 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06307 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06308 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06309 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06310 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06311 x = ast_udptl_get_local_max_datagram(p->udptl); 06312 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06313 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06314 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06315 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06316 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06317 add_header(resp, "Content-Type", "application/sdp"); 06318 add_header_contentLength(resp, len); 06319 add_line(resp, v); 06320 add_line(resp, o); 06321 add_line(resp, s); 06322 add_line(resp, c); 06323 add_line(resp, t); 06324 add_line(resp, m_modem); 06325 add_line(resp, a_modem); 06326 06327 /* Update lastrtprx when we send our SDP */ 06328 p->lastrtprx = p->lastrtptx = time(NULL); 06329 06330 return 0; 06331 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6116 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06117 { 06118 /* XXX Convert \n's to \r\n's XXX */ 06119 add_header(req, "Content-Type", "text/plain"); 06120 add_header_contentLength(req, strlen(text)); 06121 add_line(req, text); 06122 return 0; 06123 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6140 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06141 { 06142 const char *xml_is_a_huge_waste_of_space = 06143 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06144 " <media_control>\r\n" 06145 " <vc_primitive>\r\n" 06146 " <to_encoder>\r\n" 06147 " <picture_fast_update>\r\n" 06148 " </picture_fast_update>\r\n" 06149 " </to_encoder>\r\n" 06150 " </vc_primitive>\r\n" 06151 " </media_control>\r\n"; 06152 add_header(req, "Content-Type", "application/media_control+xml"); 06153 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06154 add_line(req, xml_is_a_huge_waste_of_space); 06155 return 0; 06156 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6063 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().
06064 { 06065 char tmpdat[256]; 06066 struct tm tm; 06067 time_t t = time(NULL); 06068 06069 gmtime_r(&t, &tm); 06070 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06071 add_header(req, "Date", tmpdat); 06072 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1872 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01873 { 01874 va_list ap; 01875 01876 if (!p) 01877 return; 01878 01879 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01880 && !recordhistory && !dumphistory) { 01881 return; 01882 } 01883 01884 va_start(ap, fmt); 01885 append_history_va(p, fmt, ap); 01886 va_end(ap); 01887 01888 return; 01889 }
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 1845 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().
01846 { 01847 char buf[80], *c = buf; /* max history length */ 01848 struct sip_history *hist; 01849 int l; 01850 01851 vsnprintf(buf, sizeof(buf), fmt, ap); 01852 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01853 l = strlen(buf) + 1; 01854 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01855 return; 01856 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01857 free(hist); 01858 return; 01859 } 01860 memcpy(hist->event, buf, l); 01861 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01862 struct sip_history *oldest; 01863 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01864 p->history_entries--; 01865 free(oldest); 01866 } 01867 AST_LIST_INSERT_TAIL(p->history, hist, list); 01868 p->history_entries++; 01869 }
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 13135 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().
13136 { 13137 if (chan && chan->_state == AST_STATE_UP) { 13138 if (chan->generatordata) 13139 ast_deactivate_generator(chan); 13140 } 13141 }
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 1805 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().
01806 { 01807 struct sockaddr_in theirs, ours; 01808 01809 /* Get our local information */ 01810 ast_ouraddrfor(them, us); 01811 theirs.sin_addr = *them; 01812 ours.sin_addr = *us; 01813 01814 if (localaddr && externip.sin_addr.s_addr && 01815 (ast_apply_ha(localaddr, &theirs)) && 01816 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01817 if (externexpire && time(NULL) >= externexpire) { 01818 struct ast_hostent ahp; 01819 struct hostent *hp; 01820 01821 externexpire = time(NULL) + externrefresh; 01822 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01823 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01824 } else 01825 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01826 } 01827 *us = externip.sin_addr; 01828 if (option_debug) { 01829 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01830 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01831 } 01832 } else if (bindaddr.sin_addr.s_addr) 01833 *us = bindaddr.sin_addr; 01834 return AST_SUCCESS; 01835 }
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 13145 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.
13146 { 13147 int res = 0; 13148 struct ast_channel *peera = NULL, 13149 *peerb = NULL, 13150 *peerc = NULL, 13151 *peerd = NULL; 13152 13153 13154 /* We will try to connect the transferee with the target and hangup 13155 all channels to the transferer */ 13156 if (option_debug > 3) { 13157 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13158 if (transferer->chan1) 13159 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13160 else 13161 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13162 if (target->chan1) 13163 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13164 else 13165 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13166 if (transferer->chan2) 13167 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13168 else 13169 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13170 if (target->chan2) 13171 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)"); 13172 else 13173 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13174 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13175 } 13176 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13177 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13178 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13179 peerc = transferer->chan2; /* Asterisk to Transferee */ 13180 peerd = target->chan2; /* Asterisk to Target */ 13181 if (option_debug > 2) 13182 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13183 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13184 peera = target->chan1; /* Transferer to PBX -> target channel */ 13185 peerb = transferer->chan1; /* Transferer to IVR*/ 13186 peerc = target->chan2; /* Asterisk to Target */ 13187 peerd = transferer->chan2; /* Nothing */ 13188 if (option_debug > 2) 13189 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13190 } 13191 13192 if (peera && peerb && peerc && (peerb != peerc)) { 13193 ast_quiet_chan(peera); /* Stop generators */ 13194 ast_quiet_chan(peerb); 13195 ast_quiet_chan(peerc); 13196 if (peerd) 13197 ast_quiet_chan(peerd); 13198 13199 /* Fix CDRs so they're attached to the remaining channel */ 13200 if (peera->cdr && peerb->cdr) 13201 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13202 else if (peera->cdr) 13203 peerb->cdr = peera->cdr; 13204 peera->cdr = NULL; 13205 13206 if (peerb->cdr && peerc->cdr) 13207 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13208 else if (peerc->cdr) 13209 peerb->cdr = peerc->cdr; 13210 peerc->cdr = NULL; 13211 13212 if (option_debug > 3) 13213 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13214 if (ast_channel_masquerade(peerb, peerc)) { 13215 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13216 res = -1; 13217 } else 13218 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13219 return res; 13220 } else { 13221 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13222 if (transferer->chan1) 13223 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13224 if (target->chan1) 13225 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13226 return -2; 13227 } 13228 return 0; 13229 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2911 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.
02912 { 02913 struct sip_pvt *p = (struct sip_pvt *)nothing; 02914 02915 ast_mutex_lock(&p->lock); 02916 p->initid = -1; 02917 if (p->owner) { 02918 /* XXX fails on possible deadlock */ 02919 if (!ast_channel_trylock(p->owner)) { 02920 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02921 append_history(p, "Cong", "Auto-congesting (timer)"); 02922 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02923 ast_channel_unlock(p->owner); 02924 } 02925 } 02926 ast_mutex_unlock(&p->lock); 02927 return 0; 02928 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4363 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().
04364 { 04365 char buf[33]; 04366 04367 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04368 04369 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04370 04371 }
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 4374 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04375 { 04376 char buf[33]; 04377 04378 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04379 04380 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04381 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6781 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().
06782 { 06783 /* Construct Contact: header */ 06784 if (ourport != STANDARD_SIP_PORT) 06785 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); 06786 else 06787 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06788 }
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 16426 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.
16427 { 16428 struct sip_peer *peer = NULL; 16429 struct ast_ha *oldha = NULL; 16430 int obproxyfound=0; 16431 int found=0; 16432 int firstpass=1; 16433 int format=0; /* Ama flags */ 16434 time_t regseconds = 0; 16435 char *varname = NULL, *varval = NULL; 16436 struct ast_variable *tmpvar = NULL; 16437 struct ast_flags peerflags[2] = {{(0)}}; 16438 struct ast_flags mask[2] = {{(0)}}; 16439 16440 16441 if (!realtime) 16442 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16443 /* We also use a case-sensitive comparison (unlike find_peer) so 16444 that case changes made to the peer name will be properly handled 16445 during reload 16446 */ 16447 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16448 16449 if (peer) { 16450 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16451 found = 1; 16452 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16453 firstpass = 0; 16454 } else { 16455 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16456 return NULL; 16457 16458 if (realtime) 16459 rpeerobjs++; 16460 else 16461 speerobjs++; 16462 ASTOBJ_INIT(peer); 16463 } 16464 /* Note that our peer HAS had its reference count incrased */ 16465 if (firstpass) { 16466 peer->lastmsgssent = -1; 16467 oldha = peer->ha; 16468 peer->ha = NULL; 16469 set_peer_defaults(peer); /* Set peer defaults */ 16470 } 16471 if (!found && name) 16472 ast_copy_string(peer->name, name, sizeof(peer->name)); 16473 16474 /* If we have channel variables, remove them (reload) */ 16475 if (peer->chanvars) { 16476 ast_variables_destroy(peer->chanvars); 16477 peer->chanvars = NULL; 16478 /* XXX should unregister ? */ 16479 } 16480 16481 /* If we have realm authentication information, remove them (reload) */ 16482 clear_realm_authentication(peer->auth); 16483 peer->auth = NULL; 16484 16485 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16486 if (handle_common_options(&peerflags[0], &mask[0], v)) 16487 continue; 16488 if (realtime && !strcasecmp(v->name, "regseconds")) { 16489 ast_get_time_t(v->value, ®seconds, 0, NULL); 16490 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16491 inet_aton(v->value, &(peer->addr.sin_addr)); 16492 } else if (realtime && !strcasecmp(v->name, "name")) 16493 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16494 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16495 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16496 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16497 } else if (!strcasecmp(v->name, "secret")) 16498 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16499 else if (!strcasecmp(v->name, "md5secret")) 16500 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16501 else if (!strcasecmp(v->name, "auth")) 16502 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16503 else if (!strcasecmp(v->name, "callerid")) { 16504 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16505 } else if (!strcasecmp(v->name, "fullname")) { 16506 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16507 } else if (!strcasecmp(v->name, "cid_number")) { 16508 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16509 } else if (!strcasecmp(v->name, "context")) { 16510 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16511 } else if (!strcasecmp(v->name, "subscribecontext")) { 16512 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16513 } else if (!strcasecmp(v->name, "fromdomain")) { 16514 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16515 } else if (!strcasecmp(v->name, "usereqphone")) { 16516 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16517 } else if (!strcasecmp(v->name, "fromuser")) { 16518 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16519 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16520 if (!strcasecmp(v->value, "dynamic")) { 16521 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16522 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16523 } else { 16524 /* They'll register with us */ 16525 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16526 /* Initialize stuff if this is a new peer, or if it used to be 16527 * non-dynamic before the reload. */ 16528 memset(&peer->addr.sin_addr, 0, 4); 16529 if (peer->addr.sin_port) { 16530 /* If we've already got a port, make it the default rather than absolute */ 16531 peer->defaddr.sin_port = peer->addr.sin_port; 16532 peer->addr.sin_port = 0; 16533 } 16534 } 16535 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16536 } 16537 } else { 16538 /* Non-dynamic. Make sure we become that way if we're not */ 16539 if (peer->expire > -1) 16540 ast_sched_del(sched, peer->expire); 16541 peer->expire = -1; 16542 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16543 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16544 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16545 ASTOBJ_UNREF(peer, sip_destroy_peer); 16546 return NULL; 16547 } 16548 } 16549 if (!strcasecmp(v->name, "outboundproxy")) 16550 obproxyfound=1; 16551 else { 16552 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16553 if (!peer->addr.sin_port) 16554 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16555 } 16556 } 16557 } else if (!strcasecmp(v->name, "defaultip")) { 16558 if (ast_get_ip(&peer->defaddr, v->value)) { 16559 ASTOBJ_UNREF(peer, sip_destroy_peer); 16560 return NULL; 16561 } 16562 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16563 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16564 } else if (!strcasecmp(v->name, "port")) { 16565 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16566 peer->defaddr.sin_port = htons(atoi(v->value)); 16567 else 16568 peer->addr.sin_port = htons(atoi(v->value)); 16569 } else if (!strcasecmp(v->name, "callingpres")) { 16570 peer->callingpres = ast_parse_caller_presentation(v->value); 16571 if (peer->callingpres == -1) 16572 peer->callingpres = atoi(v->value); 16573 } else if (!strcasecmp(v->name, "username")) { 16574 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16575 } else if (!strcasecmp(v->name, "language")) { 16576 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16577 } else if (!strcasecmp(v->name, "regexten")) { 16578 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16579 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16580 peer->call_limit = atoi(v->value); 16581 if (peer->call_limit < 0) 16582 peer->call_limit = 0; 16583 } else if (!strcasecmp(v->name, "amaflags")) { 16584 format = ast_cdr_amaflags2int(v->value); 16585 if (format < 0) { 16586 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16587 } else { 16588 peer->amaflags = format; 16589 } 16590 } else if (!strcasecmp(v->name, "accountcode")) { 16591 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16592 } else if (!strcasecmp(v->name, "mohinterpret") 16593 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16594 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16595 } else if (!strcasecmp(v->name, "mohsuggest")) { 16596 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16597 } else if (!strcasecmp(v->name, "mailbox")) { 16598 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16599 } else if (!strcasecmp(v->name, "subscribemwi")) { 16600 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16601 } else if (!strcasecmp(v->name, "vmexten")) { 16602 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16603 } else if (!strcasecmp(v->name, "callgroup")) { 16604 peer->callgroup = ast_get_group(v->value); 16605 } else if (!strcasecmp(v->name, "allowtransfer")) { 16606 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16607 } else if (!strcasecmp(v->name, "pickupgroup")) { 16608 peer->pickupgroup = ast_get_group(v->value); 16609 } else if (!strcasecmp(v->name, "allow")) { 16610 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16611 } else if (!strcasecmp(v->name, "disallow")) { 16612 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16613 } else if (!strcasecmp(v->name, "autoframing")) { 16614 peer->autoframing = ast_true(v->value); 16615 } else if (!strcasecmp(v->name, "rtptimeout")) { 16616 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16617 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16618 peer->rtptimeout = global_rtptimeout; 16619 } 16620 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16621 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16622 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16623 peer->rtpholdtimeout = global_rtpholdtimeout; 16624 } 16625 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16626 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16627 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16628 peer->rtpkeepalive = global_rtpkeepalive; 16629 } 16630 } else if (!strcasecmp(v->name, "setvar")) { 16631 /* Set peer channel variable */ 16632 varname = ast_strdupa(v->value); 16633 if ((varval = strchr(varname, '='))) { 16634 *varval++ = '\0'; 16635 if ((tmpvar = ast_variable_new(varname, varval))) { 16636 tmpvar->next = peer->chanvars; 16637 peer->chanvars = tmpvar; 16638 } 16639 } 16640 } else if (!strcasecmp(v->name, "qualify")) { 16641 if (!strcasecmp(v->value, "no")) { 16642 peer->maxms = 0; 16643 } else if (!strcasecmp(v->value, "yes")) { 16644 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 16645 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16646 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); 16647 peer->maxms = 0; 16648 } 16649 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16650 peer->maxcallbitrate = atoi(v->value); 16651 if (peer->maxcallbitrate < 0) 16652 peer->maxcallbitrate = default_maxcallbitrate; 16653 } 16654 } 16655 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16656 time_t nowtime = time(NULL); 16657 16658 if ((nowtime - regseconds) > 0) { 16659 destroy_association(peer); 16660 memset(&peer->addr, 0, sizeof(peer->addr)); 16661 if (option_debug) 16662 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16663 } 16664 } 16665 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16666 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16667 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16668 global_allowsubscribe = TRUE; /* No global ban any more */ 16669 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16670 reg_source_db(peer); 16671 ASTOBJ_UNMARK(peer); 16672 ast_free_ha(oldha); 16673 return peer; 16674 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11458 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().
11459 { 11460 char a1[256]; 11461 char a2[256]; 11462 char a1_hash[256]; 11463 char a2_hash[256]; 11464 char resp[256]; 11465 char resp_hash[256]; 11466 char uri[256]; 11467 char cnonce[80]; 11468 const char *username; 11469 const char *secret; 11470 const char *md5secret; 11471 struct sip_auth *auth = NULL; /* Realm authentication */ 11472 11473 if (!ast_strlen_zero(p->domain)) 11474 ast_copy_string(uri, p->domain, sizeof(uri)); 11475 else if (!ast_strlen_zero(p->uri)) 11476 ast_copy_string(uri, p->uri, sizeof(uri)); 11477 else 11478 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11479 11480 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11481 11482 /* Check if we have separate auth credentials */ 11483 if ((auth = find_realm_authentication(authl, p->realm))) { 11484 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11485 auth->username, p->peername, p->username); 11486 username = auth->username; 11487 secret = auth->secret; 11488 md5secret = auth->md5secret; 11489 if (sipdebug) 11490 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11491 } else { 11492 /* No authentication, use peer or register= config */ 11493 username = p->authname; 11494 secret = p->peersecret; 11495 md5secret = p->peermd5secret; 11496 } 11497 if (ast_strlen_zero(username)) /* We have no authentication */ 11498 return -1; 11499 11500 /* Calculate SIP digest response */ 11501 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11502 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11503 if (!ast_strlen_zero(md5secret)) 11504 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11505 else 11506 ast_md5_hash(a1_hash,a1); 11507 ast_md5_hash(a2_hash,a2); 11508 11509 p->noncecount++; 11510 if (!ast_strlen_zero(p->qop)) 11511 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11512 else 11513 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11514 ast_md5_hash(resp_hash, resp); 11515 /* XXX We hard code our qop to "auth" for now. XXX */ 11516 if (!ast_strlen_zero(p->qop)) 11517 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); 11518 else 11519 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); 11520 11521 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11522 11523 return 0; 11524 }
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 8178 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().
08179 { 08180 struct sip_route *thishop, *head, *tail; 08181 int start = 0; 08182 int len; 08183 const char *rr, *contact, *c; 08184 08185 /* Once a persistant route is set, don't fool with it */ 08186 if (p->route && p->route_persistant) { 08187 if (option_debug) 08188 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08189 return; 08190 } 08191 08192 if (p->route) { 08193 free_old_route(p->route); 08194 p->route = NULL; 08195 } 08196 08197 p->route_persistant = backwards; 08198 08199 /* Build a tailq, then assign it to p->route when done. 08200 * If backwards, we add entries from the head so they end up 08201 * in reverse order. However, we do need to maintain a correct 08202 * tail pointer because the contact is always at the end. 08203 */ 08204 head = NULL; 08205 tail = head; 08206 /* 1st we pass through all the hops in any Record-Route headers */ 08207 for (;;) { 08208 /* Each Record-Route header */ 08209 rr = __get_header(req, "Record-Route", &start); 08210 if (*rr == '\0') 08211 break; 08212 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08213 ++rr; 08214 len = strcspn(rr, ">") + 1; 08215 /* Make a struct route */ 08216 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08217 /* ast_calloc is not needed because all fields are initialized in this block */ 08218 ast_copy_string(thishop->hop, rr, len); 08219 if (option_debug > 1) 08220 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08221 /* Link in */ 08222 if (backwards) { 08223 /* Link in at head so they end up in reverse order */ 08224 thishop->next = head; 08225 head = thishop; 08226 /* If this was the first then it'll be the tail */ 08227 if (!tail) 08228 tail = thishop; 08229 } else { 08230 thishop->next = NULL; 08231 /* Link in at the end */ 08232 if (tail) 08233 tail->next = thishop; 08234 else 08235 head = thishop; 08236 tail = thishop; 08237 } 08238 } 08239 } 08240 } 08241 08242 /* Only append the contact if we are dealing with a strict router */ 08243 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08244 /* 2nd append the Contact: if there is one */ 08245 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08246 contact = get_header(req, "Contact"); 08247 if (!ast_strlen_zero(contact)) { 08248 if (option_debug > 1) 08249 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08250 /* Look for <: delimited address */ 08251 c = strchr(contact, '<'); 08252 if (c) { 08253 /* Take to > */ 08254 ++c; 08255 len = strcspn(c, ">") + 1; 08256 } else { 08257 /* No <> - just take the lot */ 08258 c = contact; 08259 len = strlen(contact) + 1; 08260 } 08261 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08262 /* ast_calloc is not needed because all fields are initialized in this block */ 08263 ast_copy_string(thishop->hop, c, len); 08264 thishop->next = NULL; 08265 /* Goes at the end */ 08266 if (tail) 08267 tail->next = thishop; 08268 else 08269 head = thishop; 08270 } 08271 } 08272 } 08273 08274 /* Store as new route */ 08275 p->route = head; 08276 08277 /* For debugging dump what we ended up with */ 08278 if (sip_debug_test_pvt(p)) 08279 list_route(p->route); 08280 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6791 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().
06792 { 06793 int send_pres_tags = TRUE; 06794 const char *privacy=NULL; 06795 const char *screen=NULL; 06796 char buf[256]; 06797 const char *clid = default_callerid; 06798 const char *clin = NULL; 06799 const char *fromdomain; 06800 06801 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06802 return; 06803 06804 if (p->owner && p->owner->cid.cid_num) 06805 clid = p->owner->cid.cid_num; 06806 if (p->owner && p->owner->cid.cid_name) 06807 clin = p->owner->cid.cid_name; 06808 if (ast_strlen_zero(clin)) 06809 clin = clid; 06810 06811 switch (p->callingpres) { 06812 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06813 privacy = "off"; 06814 screen = "no"; 06815 break; 06816 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06817 privacy = "off"; 06818 screen = "yes"; 06819 break; 06820 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06821 privacy = "off"; 06822 screen = "no"; 06823 break; 06824 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06825 privacy = "off"; 06826 screen = "yes"; 06827 break; 06828 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06829 privacy = "full"; 06830 screen = "no"; 06831 break; 06832 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06833 privacy = "full"; 06834 screen = "yes"; 06835 break; 06836 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06837 privacy = "full"; 06838 screen = "no"; 06839 break; 06840 case AST_PRES_PROHIB_NETWORK_NUMBER: 06841 privacy = "full"; 06842 screen = "yes"; 06843 break; 06844 case AST_PRES_NUMBER_NOT_AVAILABLE: 06845 send_pres_tags = FALSE; 06846 break; 06847 default: 06848 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06849 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06850 privacy = "full"; 06851 else 06852 privacy = "off"; 06853 screen = "no"; 06854 break; 06855 } 06856 06857 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06858 06859 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06860 if (send_pres_tags) 06861 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06862 ast_string_field_set(p, rpid, buf); 06863 06864 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06865 S_OR(p->fromuser, clid), 06866 fromdomain, p->tag); 06867 }
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 16247 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.
16248 { 16249 struct sip_user *user; 16250 int format; 16251 struct ast_ha *oldha = NULL; 16252 char *varname = NULL, *varval = NULL; 16253 struct ast_variable *tmpvar = NULL; 16254 struct ast_flags userflags[2] = {{(0)}}; 16255 struct ast_flags mask[2] = {{(0)}}; 16256 16257 16258 if (!(user = ast_calloc(1, sizeof(*user)))) 16259 return NULL; 16260 16261 suserobjs++; 16262 ASTOBJ_INIT(user); 16263 ast_copy_string(user->name, name, sizeof(user->name)); 16264 oldha = user->ha; 16265 user->ha = NULL; 16266 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16267 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16268 user->capability = global_capability; 16269 user->allowtransfer = global_allowtransfer; 16270 user->maxcallbitrate = default_maxcallbitrate; 16271 user->autoframing = global_autoframing; 16272 user->prefs = default_prefs; 16273 /* set default context */ 16274 strcpy(user->context, default_context); 16275 strcpy(user->language, default_language); 16276 strcpy(user->mohinterpret, default_mohinterpret); 16277 strcpy(user->mohsuggest, default_mohsuggest); 16278 for (; v; v = v->next) { 16279 if (handle_common_options(&userflags[0], &mask[0], v)) 16280 continue; 16281 16282 if (!strcasecmp(v->name, "context")) { 16283 ast_copy_string(user->context, v->value, sizeof(user->context)); 16284 } else if (!strcasecmp(v->name, "subscribecontext")) { 16285 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16286 } else if (!strcasecmp(v->name, "setvar")) { 16287 varname = ast_strdupa(v->value); 16288 if ((varval = strchr(varname,'='))) { 16289 *varval++ = '\0'; 16290 if ((tmpvar = ast_variable_new(varname, varval))) { 16291 tmpvar->next = user->chanvars; 16292 user->chanvars = tmpvar; 16293 } 16294 } 16295 } else if (!strcasecmp(v->name, "permit") || 16296 !strcasecmp(v->name, "deny")) { 16297 user->ha = ast_append_ha(v->name, v->value, user->ha); 16298 } else if (!strcasecmp(v->name, "allowtransfer")) { 16299 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16300 } else if (!strcasecmp(v->name, "secret")) { 16301 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16302 } else if (!strcasecmp(v->name, "md5secret")) { 16303 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16304 } else if (!strcasecmp(v->name, "callerid")) { 16305 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16306 } else if (!strcasecmp(v->name, "fullname")) { 16307 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16308 } else if (!strcasecmp(v->name, "cid_number")) { 16309 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16310 } else if (!strcasecmp(v->name, "callgroup")) { 16311 user->callgroup = ast_get_group(v->value); 16312 } else if (!strcasecmp(v->name, "pickupgroup")) { 16313 user->pickupgroup = ast_get_group(v->value); 16314 } else if (!strcasecmp(v->name, "language")) { 16315 ast_copy_string(user->language, v->value, sizeof(user->language)); 16316 } else if (!strcasecmp(v->name, "mohinterpret") 16317 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16318 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16319 } else if (!strcasecmp(v->name, "mohsuggest")) { 16320 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16321 } else if (!strcasecmp(v->name, "accountcode")) { 16322 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16323 } else if (!strcasecmp(v->name, "call-limit")) { 16324 user->call_limit = atoi(v->value); 16325 if (user->call_limit < 0) 16326 user->call_limit = 0; 16327 } else if (!strcasecmp(v->name, "amaflags")) { 16328 format = ast_cdr_amaflags2int(v->value); 16329 if (format < 0) { 16330 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16331 } else { 16332 user->amaflags = format; 16333 } 16334 } else if (!strcasecmp(v->name, "allow")) { 16335 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16336 } else if (!strcasecmp(v->name, "disallow")) { 16337 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16338 } else if (!strcasecmp(v->name, "autoframing")) { 16339 user->autoframing = ast_true(v->value); 16340 } else if (!strcasecmp(v->name, "callingpres")) { 16341 user->callingpres = ast_parse_caller_presentation(v->value); 16342 if (user->callingpres == -1) 16343 user->callingpres = atoi(v->value); 16344 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16345 user->maxcallbitrate = atoi(v->value); 16346 if (user->maxcallbitrate < 0) 16347 user->maxcallbitrate = default_maxcallbitrate; 16348 } 16349 /* We can't just report unknown options here because this may be a 16350 * type=friend entry. All user options are valid for a peer, but not 16351 * the other way around. */ 16352 } 16353 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16354 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16355 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16356 global_allowsubscribe = TRUE; /* No global ban any more */ 16357 ast_free_ha(oldha); 16358 return user; 16359 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1789 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().
01790 { 01791 /* Work around buggy UNIDEN UIP200 firmware */ 01792 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01793 01794 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01795 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01796 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01797 }
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 8470 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().
08471 { 08472 struct sip_pvt *p = data; 08473 08474 ast_mutex_lock(&p->lock); 08475 08476 switch(state) { 08477 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08478 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08479 if (p->autokillid > -1) 08480 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08481 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08482 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); 08483 p->stateid = -1; 08484 p->subscribed = NONE; 08485 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08486 break; 08487 default: /* Tell user */ 08488 p->laststate = state; 08489 break; 08490 } 08491 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08492 transmit_state_notify(p, state, 1, FALSE); 08493 08494 if (option_verbose > 1) 08495 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08496 08497 ast_mutex_unlock(&p->lock); 08498 08499 return 0; 08500 }
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 4912 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().
04913 { 04914 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 04915 sip_peer_hold(dialog, holdstate); 04916 if (global_callevents) 04917 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04918 "Channel: %s\r\n" 04919 "Uniqueid: %s\r\n", 04920 dialog->owner->name, 04921 dialog->owner->uniqueid); 04922 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04923 if (!holdstate) { /* Put off remote hold */ 04924 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04925 return; 04926 } 04927 /* No address for RTP, we're on hold */ 04928 04929 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 04930 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 04931 else if (sendonly == 2) /* Inactive stream */ 04932 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 04933 else 04934 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 04935 return; 04936 }
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).
Definition at line 8288 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, 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().
08291 { 08292 const char *response = "407 Proxy Authentication Required"; 08293 const char *reqheader = "Proxy-Authorization"; 08294 const char *respheader = "Proxy-Authenticate"; 08295 const char *authtoken; 08296 char a1_hash[256]; 08297 char resp_hash[256]=""; 08298 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08299 char *c; 08300 int wrongnonce = FALSE; 08301 int good_response; 08302 const char *usednonce = p->randdata; 08303 08304 /* table of recognised keywords, and their value in the digest */ 08305 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08306 struct x { 08307 const char *key; 08308 const char *s; 08309 } *i, keys[] = { 08310 [K_RESP] = { "response=", "" }, 08311 [K_URI] = { "uri=", "" }, 08312 [K_USER] = { "username=", "" }, 08313 [K_NONCE] = { "nonce=", "" }, 08314 [K_LAST] = { NULL, NULL} 08315 }; 08316 08317 /* Always OK if no secret */ 08318 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08319 return AUTH_SUCCESSFUL; 08320 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08321 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08322 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08323 different circumstances! What a surprise. */ 08324 response = "401 Unauthorized"; 08325 reqheader = "Authorization"; 08326 respheader = "WWW-Authenticate"; 08327 } 08328 authtoken = get_header(req, reqheader); 08329 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08330 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08331 information */ 08332 if (!reliable) { 08333 /* Resend message if this was NOT a reliable delivery. Otherwise the 08334 retransmission should get it */ 08335 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08336 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08337 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08338 } 08339 return AUTH_CHALLENGE_SENT; 08340 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08341 /* We have no auth, so issue challenge and request authentication */ 08342 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08343 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08344 /* Schedule auto destroy in 32 seconds */ 08345 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08346 return AUTH_CHALLENGE_SENT; 08347 } 08348 08349 /* --- We have auth, so check it */ 08350 08351 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08352 an example in the spec of just what it is you're doing a hash on. */ 08353 08354 08355 /* Make a copy of the response and parse it */ 08356 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08357 c = tmp; 08358 08359 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08360 for (i = keys; i->key != NULL; i++) { 08361 const char *separator = ","; /* default */ 08362 08363 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08364 continue; 08365 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08366 c += strlen(i->key); 08367 if (*c == '"') { /* in quotes. Skip first and look for last */ 08368 c++; 08369 separator = "\""; 08370 } 08371 i->s = c; 08372 strsep(&c, separator); 08373 break; 08374 } 08375 if (i->key == NULL) /* not found, jump after space or comma */ 08376 strsep(&c, " ,"); 08377 } 08378 08379 /* Verify that digest username matches the username we auth as */ 08380 if (strcmp(username, keys[K_USER].s)) { 08381 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08382 username, keys[K_USER].s); 08383 /* Oops, we're trying something here */ 08384 return AUTH_USERNAME_MISMATCH; 08385 } 08386 08387 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08388 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08389 wrongnonce = TRUE; 08390 usednonce = keys[K_NONCE].s; 08391 } 08392 08393 if (!ast_strlen_zero(md5secret)) 08394 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08395 else { 08396 char a1[256]; 08397 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08398 ast_md5_hash(a1_hash, a1); 08399 } 08400 08401 /* compute the expected response to compare with what we received */ 08402 { 08403 char a2[256]; 08404 char a2_hash[256]; 08405 char resp[256]; 08406 08407 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08408 S_OR(keys[K_URI].s, uri)); 08409 ast_md5_hash(a2_hash, a2); 08410 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08411 ast_md5_hash(resp_hash, resp); 08412 } 08413 08414 good_response = keys[K_RESP].s && 08415 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08416 if (wrongnonce) { 08417 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08418 if (good_response) { 08419 if (sipdebug) 08420 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08421 /* We got working auth token, based on stale nonce . */ 08422 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08423 } else { 08424 /* Everything was wrong, so give the device one more try with a new challenge */ 08425 if (sipdebug) 08426 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08427 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08428 } 08429 08430 /* Schedule auto destroy in 32 seconds */ 08431 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08432 return AUTH_CHALLENGE_SENT; 08433 } 08434 if (good_response) { 08435 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08436 return AUTH_SUCCESSFUL; 08437 } 08438 08439 /* Ok, we have a bad username/secret pair */ 08440 /* Tell the UAS not to re-send this authentication data, because 08441 it will continue to fail 08442 */ 08443 08444 return AUTH_SECRET_FAILED; 08445 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 11919 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().
11920 { 11921 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 11922 /* if we can't BYE, then this is really a pending CANCEL */ 11923 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 11924 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 11925 /* Actually don't destroy us yet, wait for the 487 on our original 11926 INVITE, but do set an autodestruct just in case we never get it. */ 11927 else { 11928 /* We have a pending outbound invite, don't send someting 11929 new in-transaction */ 11930 if (p->pendinginvite) 11931 return; 11932 11933 /* Perhaps there is an SD change INVITE outstanding */ 11934 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 11935 } 11936 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 11937 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11938 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 11939 /* if we can't REINVITE, hold it for later */ 11940 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 11941 if (option_debug) 11942 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 11943 } else { 11944 if (option_debug) 11945 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 11946 /* Didn't get to reinvite yet, so do it now */ 11947 transmit_reinvite_with_sdp(p); 11948 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 11949 } 11950 } 11951 }
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 16126 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().
16127 { 16128 struct domain *d; 16129 int result = 0; 16130 16131 AST_LIST_LOCK(&domain_list); 16132 AST_LIST_TRAVERSE(&domain_list, d, list) { 16133 if (strcasecmp(d->domain, domain)) 16134 continue; 16135 16136 if (len && !ast_strlen_zero(d->context)) 16137 ast_copy_string(context, d->context, len); 16138 16139 result = 1; 16140 break; 16141 } 16142 AST_LIST_UNLOCK(&domain_list); 16143 16144 return result; 16145 }
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 9566 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09567 { 09568 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09569 }
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 9247 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().
09250 { 09251 struct sip_user *user = NULL; 09252 struct sip_peer *peer; 09253 char from[256], *c; 09254 char *of; 09255 char rpid_num[50]; 09256 const char *rpid; 09257 enum check_auth_result res = AUTH_SUCCESSFUL; 09258 char *t; 09259 char calleridname[50]; 09260 int debug=sip_debug_test_addr(sin); 09261 struct ast_variable *tmpvar = NULL, *v = NULL; 09262 char *uri2 = ast_strdupa(uri); 09263 09264 /* Terminate URI */ 09265 t = uri2; 09266 while (*t && *t > 32 && *t != ';') 09267 t++; 09268 *t = '\0'; 09269 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09270 if (pedanticsipchecking) 09271 ast_uri_decode(from); 09272 /* XXX here tries to map the username for invite things */ 09273 memset(calleridname, 0, sizeof(calleridname)); 09274 get_calleridname(from, calleridname, sizeof(calleridname)); 09275 if (calleridname[0]) 09276 ast_string_field_set(p, cid_name, calleridname); 09277 09278 rpid = get_header(req, "Remote-Party-ID"); 09279 memset(rpid_num, 0, sizeof(rpid_num)); 09280 if (!ast_strlen_zero(rpid)) 09281 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09282 09283 of = get_in_brackets(from); 09284 if (ast_strlen_zero(p->exten)) { 09285 t = uri2; 09286 if (!strncasecmp(t, "sip:", 4)) 09287 t+= 4; 09288 ast_string_field_set(p, exten, t); 09289 t = strchr(p->exten, '@'); 09290 if (t) 09291 *t = '\0'; 09292 if (ast_strlen_zero(p->our_contact)) 09293 build_contact(p); 09294 } 09295 /* save the URI part of the From header */ 09296 ast_string_field_set(p, from, of); 09297 if (strncasecmp(of, "sip:", 4)) { 09298 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09299 } else 09300 of += 4; 09301 /* Get just the username part */ 09302 if ((c = strchr(of, '@'))) { 09303 char *tmp; 09304 *c = '\0'; 09305 if ((c = strchr(of, ':'))) 09306 *c = '\0'; 09307 tmp = ast_strdupa(of); 09308 /* We need to be able to handle auth-headers looking like 09309 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09310 */ 09311 tmp = strsep(&tmp, ";"); 09312 if (ast_is_shrinkable_phonenumber(tmp)) 09313 ast_shrink_phone_number(tmp); 09314 ast_string_field_set(p, cid_num, tmp); 09315 } 09316 09317 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09318 user = find_user(of, 1); 09319 09320 /* Find user based on user name in the from header */ 09321 if (user && ast_apply_ha(user->ha, sin)) { 09322 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09323 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09324 /* copy channel vars */ 09325 for (v = user->chanvars ; v ; v = v->next) { 09326 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09327 tmpvar->next = p->chanvars; 09328 p->chanvars = tmpvar; 09329 } 09330 } 09331 p->prefs = user->prefs; 09332 /* Set Frame packetization */ 09333 if (p->rtp) { 09334 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09335 p->autoframing = user->autoframing; 09336 } 09337 /* replace callerid if rpid found, and not restricted */ 09338 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09339 char *tmp; 09340 if (*calleridname) 09341 ast_string_field_set(p, cid_name, calleridname); 09342 tmp = ast_strdupa(rpid_num); 09343 if (ast_is_shrinkable_phonenumber(tmp)) 09344 ast_shrink_phone_number(tmp); 09345 ast_string_field_set(p, cid_num, tmp); 09346 } 09347 09348 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09349 09350 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09351 sip_cancel_destroy(p); 09352 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09353 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09354 /* Copy SIP extensions profile from INVITE */ 09355 if (p->sipoptions) 09356 user->sipoptions = p->sipoptions; 09357 09358 /* If we have a call limit, set flag */ 09359 if (user->call_limit) 09360 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09361 if (!ast_strlen_zero(user->context)) 09362 ast_string_field_set(p, context, user->context); 09363 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09364 char *tmp = ast_strdupa(user->cid_num); 09365 if (ast_is_shrinkable_phonenumber(tmp)) 09366 ast_shrink_phone_number(tmp); 09367 ast_string_field_set(p, cid_num, tmp); 09368 } 09369 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09370 ast_string_field_set(p, cid_name, user->cid_name); 09371 ast_string_field_set(p, username, user->name); 09372 ast_string_field_set(p, peername, user->name); 09373 ast_string_field_set(p, peersecret, user->secret); 09374 ast_string_field_set(p, peermd5secret, user->md5secret); 09375 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09376 ast_string_field_set(p, accountcode, user->accountcode); 09377 ast_string_field_set(p, language, user->language); 09378 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09379 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09380 p->allowtransfer = user->allowtransfer; 09381 p->amaflags = user->amaflags; 09382 p->callgroup = user->callgroup; 09383 p->pickupgroup = user->pickupgroup; 09384 if (user->callingpres) /* User callingpres setting will override RPID header */ 09385 p->callingpres = user->callingpres; 09386 09387 /* Set default codec settings for this call */ 09388 p->capability = user->capability; /* User codec choice */ 09389 p->jointcapability = user->capability; /* Our codecs */ 09390 if (p->peercapability) /* AND with peer's codecs */ 09391 p->jointcapability &= p->peercapability; 09392 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09393 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09394 p->noncodeccapability |= AST_RTP_DTMF; 09395 else 09396 p->noncodeccapability &= ~AST_RTP_DTMF; 09397 p->jointnoncodeccapability = p->noncodeccapability; 09398 if (p->t38.peercapability) 09399 p->t38.jointcapability &= p->t38.peercapability; 09400 p->maxcallbitrate = user->maxcallbitrate; 09401 /* If we do not support video, remove video from call structure */ 09402 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09403 ast_rtp_destroy(p->vrtp); 09404 p->vrtp = NULL; 09405 } 09406 } 09407 if (user && debug) 09408 ast_verbose("Found user '%s'\n", user->name); 09409 } else { 09410 if (user) { 09411 if (!authpeer && debug) 09412 ast_verbose("Found user '%s', but fails host access\n", user->name); 09413 ASTOBJ_UNREF(user,sip_destroy_user); 09414 } 09415 user = NULL; 09416 } 09417 09418 if (!user) { 09419 /* If we didn't find a user match, check for peers */ 09420 if (sipmethod == SIP_SUBSCRIBE) 09421 /* For subscribes, match on peer name only */ 09422 peer = find_peer(of, NULL, 1); 09423 else 09424 /* Look for peer based on the IP address we received data from */ 09425 /* If peer is registered from this IP address or have this as a default 09426 IP address, this call is from the peer 09427 */ 09428 peer = find_peer(NULL, &p->recv, 1); 09429 09430 if (peer) { 09431 /* Set Frame packetization */ 09432 if (p->rtp) { 09433 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09434 p->autoframing = peer->autoframing; 09435 } 09436 if (debug) 09437 ast_verbose("Found peer '%s'\n", peer->name); 09438 09439 /* Take the peer */ 09440 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09441 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09442 09443 /* Copy SIP extensions profile to peer */ 09444 if (p->sipoptions) 09445 peer->sipoptions = p->sipoptions; 09446 09447 /* replace callerid if rpid found, and not restricted */ 09448 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09449 char *tmp = ast_strdupa(rpid_num); 09450 if (*calleridname) 09451 ast_string_field_set(p, cid_name, calleridname); 09452 if (ast_is_shrinkable_phonenumber(tmp)) 09453 ast_shrink_phone_number(tmp); 09454 ast_string_field_set(p, cid_num, tmp); 09455 } 09456 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09457 09458 ast_string_field_set(p, peersecret, peer->secret); 09459 ast_string_field_set(p, peermd5secret, peer->md5secret); 09460 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09461 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09462 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09463 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09464 p->callingpres = peer->callingpres; 09465 if (peer->maxms && peer->lastms) 09466 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09467 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09468 /* Pretend there is no required authentication */ 09469 ast_string_field_free(p, peersecret); 09470 ast_string_field_free(p, peermd5secret); 09471 } 09472 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09473 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09474 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09475 /* If we have a call limit, set flag */ 09476 if (peer->call_limit) 09477 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09478 ast_string_field_set(p, peername, peer->name); 09479 ast_string_field_set(p, authname, peer->name); 09480 09481 /* copy channel vars */ 09482 for (v = peer->chanvars ; v ; v = v->next) { 09483 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09484 tmpvar->next = p->chanvars; 09485 p->chanvars = tmpvar; 09486 } 09487 } 09488 if (authpeer) { 09489 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09490 } 09491 09492 if (!ast_strlen_zero(peer->username)) { 09493 ast_string_field_set(p, username, peer->username); 09494 /* Use the default username for authentication on outbound calls */ 09495 /* XXX this takes the name from the caller... can we override ? */ 09496 ast_string_field_set(p, authname, peer->username); 09497 } 09498 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09499 char *tmp = ast_strdupa(peer->cid_num); 09500 if (ast_is_shrinkable_phonenumber(tmp)) 09501 ast_shrink_phone_number(tmp); 09502 ast_string_field_set(p, cid_num, tmp); 09503 } 09504 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09505 ast_string_field_set(p, cid_name, peer->cid_name); 09506 ast_string_field_set(p, fullcontact, peer->fullcontact); 09507 if (!ast_strlen_zero(peer->context)) 09508 ast_string_field_set(p, context, peer->context); 09509 ast_string_field_set(p, peersecret, peer->secret); 09510 ast_string_field_set(p, peermd5secret, peer->md5secret); 09511 ast_string_field_set(p, language, peer->language); 09512 ast_string_field_set(p, accountcode, peer->accountcode); 09513 p->amaflags = peer->amaflags; 09514 p->callgroup = peer->callgroup; 09515 p->pickupgroup = peer->pickupgroup; 09516 p->capability = peer->capability; 09517 p->prefs = peer->prefs; 09518 p->jointcapability = peer->capability; 09519 if (p->peercapability) 09520 p->jointcapability &= p->peercapability; 09521 p->maxcallbitrate = peer->maxcallbitrate; 09522 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09523 ast_rtp_destroy(p->vrtp); 09524 p->vrtp = NULL; 09525 } 09526 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09527 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09528 p->noncodeccapability |= AST_RTP_DTMF; 09529 else 09530 p->noncodeccapability &= ~AST_RTP_DTMF; 09531 p->jointnoncodeccapability = p->noncodeccapability; 09532 if (p->t38.peercapability) 09533 p->t38.jointcapability &= p->t38.peercapability; 09534 } 09535 ASTOBJ_UNREF(peer, sip_destroy_peer); 09536 } else { 09537 if (debug) 09538 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09539 09540 /* do we allow guests? */ 09541 if (!global_allowguest) { 09542 if (global_alwaysauthreject) 09543 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09544 else 09545 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09546 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09547 char *tmp = ast_strdupa(rpid_num); 09548 if (*calleridname) 09549 ast_string_field_set(p, cid_name, calleridname); 09550 if (ast_is_shrinkable_phonenumber(tmp)) 09551 ast_shrink_phone_number(tmp); 09552 ast_string_field_set(p, cid_num, tmp); 09553 } 09554 } 09555 09556 } 09557 09558 if (user) 09559 ASTOBJ_UNREF(user, sip_destroy_user); 09560 return res; 09561 }
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 9115 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().
09116 { 09117 char via[256]; 09118 char *c, *pt; 09119 struct hostent *hp; 09120 struct ast_hostent ahp; 09121 09122 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09123 09124 /* Work on the leftmost value of the topmost Via header */ 09125 c = strchr(via, ','); 09126 if (c) 09127 *c = '\0'; 09128 09129 /* Check for rport */ 09130 c = strstr(via, ";rport"); 09131 if (c && (c[6] != '=')) /* rport query, not answer */ 09132 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09133 09134 c = strchr(via, ';'); 09135 if (c) 09136 *c = '\0'; 09137 09138 c = strchr(via, ' '); 09139 if (c) { 09140 *c = '\0'; 09141 c = ast_skip_blanks(c+1); 09142 if (strcasecmp(via, "SIP/2.0/UDP")) { 09143 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09144 return; 09145 } 09146 pt = strchr(c, ':'); 09147 if (pt) 09148 *pt++ = '\0'; /* remember port pointer */ 09149 hp = ast_gethostbyname(c, &ahp); 09150 if (!hp) { 09151 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09152 return; 09153 } 09154 memset(&p->sa, 0, sizeof(p->sa)); 09155 p->sa.sin_family = AF_INET; 09156 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09157 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09158 09159 if (sip_debug_test_pvt(p)) { 09160 const struct sockaddr_in *dst = sip_real_dst(p); 09161 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09162 } 09163 } 09164 }
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 10010 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
10011 { 10012 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10013 10014 while ((oldcontext = strsep(&old, "&"))) { 10015 stalecontext = '\0'; 10016 ast_copy_string(newlist, new, sizeof(newlist)); 10017 stringp = newlist; 10018 while ((newcontext = strsep(&stringp, "&"))) { 10019 if (strcmp(newcontext, oldcontext) == 0) { 10020 /* This is not the context you're looking for */ 10021 stalecontext = '\0'; 10022 break; 10023 } else if (strcmp(newcontext, oldcontext)) { 10024 stalecontext = oldcontext; 10025 } 10026 10027 } 10028 if (stalecontext) 10029 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10030 } 10031 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16219 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16220 { 16221 struct sip_auth *a = authlist; 16222 struct sip_auth *b; 16223 16224 while (a) { 16225 b = a; 16226 a = a->next; 16227 free(b); 16228 } 16229 16230 return 1; 16231 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16148 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().
16149 { 16150 struct domain *d; 16151 16152 AST_LIST_LOCK(&domain_list); 16153 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16154 free(d); 16155 AST_LIST_UNLOCK(&domain_list); 16156 }
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 10818 of file chan_sip.c.
References complete_sip_peer().
10819 { 10820 if (pos == 3) 10821 return complete_sip_peer(word, state, 0); 10822 10823 return NULL; 10824 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10792 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().
10793 { 10794 char *result = NULL; 10795 int wordlen = strlen(word); 10796 int which = 0; 10797 10798 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10799 /* locking of the object is not required because only the name and flags are being compared */ 10800 if (!strncasecmp(word, iterator->name, wordlen) && 10801 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10802 ++which > state) 10803 result = ast_strdup(iterator->name); 10804 } while(0) ); 10805 return result; 10806 }
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 10886 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10887 { 10888 if (pos == 4) 10889 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10890 return NULL; 10891 }
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 10894 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10895 { 10896 if (pos == 4) 10897 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10898 10899 return NULL; 10900 }
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 10809 of file chan_sip.c.
References complete_sip_peer().
10810 { 10811 if (pos == 3) 10812 return complete_sip_peer(word, state, 0); 10813 10814 return NULL; 10815 }
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 10847 of file chan_sip.c.
References complete_sip_user().
10848 { 10849 if (pos == 3) 10850 return complete_sip_user(word, state, 0); 10851 10852 return NULL; 10853 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10827 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().
10828 { 10829 char *result = NULL; 10830 int wordlen = strlen(word); 10831 int which = 0; 10832 10833 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10834 /* locking of the object is not required because only the name and flags are being compared */ 10835 if (!strncasecmp(word, iterator->name, wordlen)) { 10836 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10837 continue; 10838 if (++which > state) { 10839 result = ast_strdup(iterator->name); 10840 } 10841 } 10842 } while(0) ); 10843 return result; 10844 }
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 10773 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, iflist, and sip_pvt::next.
10774 { 10775 int which=0; 10776 struct sip_pvt *cur; 10777 char *c = NULL; 10778 int wordlen = strlen(word); 10779 10780 ast_mutex_lock(&iflock); 10781 for (cur = iflist; cur; cur = cur->next) { 10782 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10783 c = ast_strdup(cur->callid); 10784 break; 10785 } 10786 } 10787 ast_mutex_unlock(&iflock); 10788 return c; 10789 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10856 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10857 { 10858 char *c = NULL; 10859 10860 if (pos == 2) { 10861 int which = 0; 10862 char *cat = NULL; 10863 int wordlen = strlen(word); 10864 10865 /* do completion for notify type */ 10866 10867 if (!notify_types) 10868 return NULL; 10869 10870 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10871 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10872 c = ast_strdup(cat); 10873 break; 10874 } 10875 } 10876 return c; 10877 } 10878 10879 if (pos > 2) 10880 return complete_sip_peer(word, state, 0); 10881 10882 return NULL; 10883 }
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 5597 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05598 { 05599 int start = 0; 05600 int copied = 0; 05601 for (;;) { 05602 const char *tmp = __get_header(orig, field, &start); 05603 05604 if (ast_strlen_zero(tmp)) 05605 break; 05606 /* Add what we're responding to */ 05607 add_header(req, field, tmp); 05608 copied++; 05609 } 05610 return copied ? 0 : -1; 05611 }
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 5586 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05587 { 05588 const char *tmp = get_header(orig, field); 05589 05590 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05591 return add_header(req, field, tmp); 05592 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05593 return -1; 05594 }
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 6634 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().
06635 { 06636 long offset; 06637 int x; 06638 offset = ((void *)dst) - ((void *)src); 06639 /* First copy stuff */ 06640 memcpy(dst, src, sizeof(*dst)); 06641 /* Now fix pointer arithmetic */ 06642 for (x=0; x < src->headers; x++) 06643 dst->header[x] += offset; 06644 for (x=0; x < src->lines; x++) 06645 dst->line[x] += offset; 06646 dst->rlPart1 += offset; 06647 dst->rlPart2 += offset; 06648 }
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 5619 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().
05620 { 05621 int copied = 0; 05622 int start = 0; 05623 05624 for (;;) { 05625 char new[256]; 05626 const char *oh = __get_header(orig, field, &start); 05627 05628 if (ast_strlen_zero(oh)) 05629 break; 05630 05631 if (!copied) { /* Only check for empty rport in topmost via header */ 05632 char leftmost[256], *others, *rport; 05633 05634 /* Only work on leftmost value */ 05635 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05636 others = strchr(leftmost, ','); 05637 if (others) 05638 *others++ = '\0'; 05639 05640 /* Find ;rport; (empty request) */ 05641 rport = strstr(leftmost, ";rport"); 05642 if (rport && *(rport+6) == '=') 05643 rport = NULL; /* We already have a parameter to rport */ 05644 05645 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05646 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05647 /* We need to add received port - rport */ 05648 char *end; 05649 05650 rport = strstr(leftmost, ";rport"); 05651 05652 if (rport) { 05653 end = strchr(rport + 1, ';'); 05654 if (end) 05655 memmove(rport, end, strlen(end) + 1); 05656 else 05657 *rport = '\0'; 05658 } 05659 05660 /* Add rport to first VIA header if requested */ 05661 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05662 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05663 ntohs(p->recv.sin_port), 05664 others ? "," : "", others ? others : ""); 05665 } else { 05666 /* We should *always* add a received to the topmost via */ 05667 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05668 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05669 others ? "," : "", others ? others : ""); 05670 } 05671 oh = new; /* the header to copy */ 05672 } /* else add the following via headers untouched */ 05673 add_header(req, field, oh); 05674 copied++; 05675 } 05676 if (!copied) { 05677 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05678 return -1; 05679 } 05680 return 0; 05681 }
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 2861 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.
02862 { 02863 struct hostent *hp; 02864 struct ast_hostent ahp; 02865 struct sip_peer *p; 02866 char *port; 02867 int portno; 02868 char host[MAXHOSTNAMELEN], *hostn; 02869 char peer[256]; 02870 02871 ast_copy_string(peer, opeer, sizeof(peer)); 02872 port = strchr(peer, ':'); 02873 if (port) 02874 *port++ = '\0'; 02875 dialog->sa.sin_family = AF_INET; 02876 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02877 p = find_peer(peer, NULL, 1); 02878 02879 if (p) { 02880 int res = create_addr_from_peer(dialog, p); 02881 ASTOBJ_UNREF(p, sip_destroy_peer); 02882 return res; 02883 } 02884 hostn = peer; 02885 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02886 if (srvlookup) { 02887 char service[MAXHOSTNAMELEN]; 02888 int tportno; 02889 int ret; 02890 02891 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02892 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02893 if (ret > 0) { 02894 hostn = host; 02895 portno = tportno; 02896 } 02897 } 02898 hp = ast_gethostbyname(hostn, &ahp); 02899 if (!hp) { 02900 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02901 return -1; 02902 } 02903 ast_string_field_set(dialog, tohost, peer); 02904 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02905 dialog->sa.sin_port = htons(portno); 02906 dialog->recv = dialog->sa; 02907 return 0; 02908 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2753 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().
02754 { 02755 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02756 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02757 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02758 dialog->recv = dialog->sa; 02759 } else 02760 return -1; 02761 02762 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02763 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02764 dialog->capability = peer->capability; 02765 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02766 ast_rtp_destroy(dialog->vrtp); 02767 dialog->vrtp = NULL; 02768 } 02769 dialog->prefs = peer->prefs; 02770 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02771 dialog->t38.capability = global_t38_capability; 02772 if (dialog->udptl) { 02773 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02774 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02775 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02776 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02777 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02778 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02779 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02780 if (option_debug > 1) 02781 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02782 } 02783 dialog->t38.jointcapability = dialog->t38.capability; 02784 } else if (dialog->udptl) { 02785 ast_udptl_destroy(dialog->udptl); 02786 dialog->udptl = NULL; 02787 } 02788 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02789 02790 if (dialog->rtp) { 02791 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02792 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02793 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02794 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02795 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02796 /* Set Frame packetization */ 02797 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02798 dialog->autoframing = peer->autoframing; 02799 } 02800 if (dialog->vrtp) { 02801 ast_rtp_setdtmf(dialog->vrtp, 0); 02802 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02803 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02804 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02805 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02806 } 02807 02808 ast_string_field_set(dialog, peername, peer->name); 02809 ast_string_field_set(dialog, authname, peer->username); 02810 ast_string_field_set(dialog, username, peer->username); 02811 ast_string_field_set(dialog, peersecret, peer->secret); 02812 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02813 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02814 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02815 ast_string_field_set(dialog, tohost, peer->tohost); 02816 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02817 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02818 char *tmpcall; 02819 char *c; 02820 tmpcall = ast_strdupa(dialog->callid); 02821 c = strchr(tmpcall, '@'); 02822 if (c) { 02823 *c = '\0'; 02824 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02825 } 02826 } 02827 if (ast_strlen_zero(dialog->tohost)) 02828 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02829 if (!ast_strlen_zero(peer->fromdomain)) 02830 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02831 if (!ast_strlen_zero(peer->fromuser)) 02832 ast_string_field_set(dialog, fromuser, peer->fromuser); 02833 if (!ast_strlen_zero(peer->language)) 02834 ast_string_field_set(dialog, language, peer->language); 02835 dialog->maxtime = peer->maxms; 02836 dialog->callgroup = peer->callgroup; 02837 dialog->pickupgroup = peer->pickupgroup; 02838 dialog->allowtransfer = peer->allowtransfer; 02839 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02840 /* Minimum is settable or default to 100 ms */ 02841 if (peer->maxms && peer->lastms) 02842 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02843 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02844 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02845 dialog->noncodeccapability |= AST_RTP_DTMF; 02846 else 02847 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02848 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02849 ast_string_field_set(dialog, context, peer->context); 02850 dialog->rtptimeout = peer->rtptimeout; 02851 if (peer->call_limit) 02852 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02853 dialog->maxcallbitrate = peer->maxcallbitrate; 02854 02855 return 0; 02856 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7813 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().
07814 { 07815 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07816 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07817 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07818 else 07819 ast_db_del("SIP/Registry", peer->name); 07820 } 07821 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6678 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06679 { 06680 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06681 06682 if (!*e) 06683 return -1; 06684 req->rlPart1 = e; /* method or protocol */ 06685 e = ast_skip_nonblanks(e); 06686 if (*e) 06687 *e++ = '\0'; 06688 /* Get URI or status code */ 06689 e = ast_skip_blanks(e); 06690 if ( !*e ) 06691 return -1; 06692 ast_trim_blanks(e); 06693 06694 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06695 if (strlen(e) < 3) /* status code is 3 digits */ 06696 return -1; 06697 req->rlPart2 = e; 06698 } else { /* We have a request */ 06699 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06700 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06701 e++; 06702 if (!*e) 06703 return -1; 06704 } 06705 req->rlPart2 = e; /* URI */ 06706 e = ast_skip_nonblanks(e); 06707 if (*e) 06708 *e++ = '\0'; 06709 e = ast_skip_blanks(e); 06710 if (strcasecmp(e, "SIP/2.0") ) { 06711 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06712 return -1; 06713 } 06714 } 06715 return 1; 06716 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15463 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.
15464 { 15465 int res; 15466 struct sip_pvt *sip; 15467 struct sip_peer *peer = NULL; 15468 time_t t; 15469 int fastrestart = FALSE; 15470 int lastpeernum = -1; 15471 int curpeernum; 15472 int reloading; 15473 15474 /* Add an I/O event to our SIP UDP socket */ 15475 if (sipsock > -1) 15476 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15477 15478 /* From here on out, we die whenever asked */ 15479 for(;;) { 15480 /* Check for a reload request */ 15481 ast_mutex_lock(&sip_reload_lock); 15482 reloading = sip_reloading; 15483 sip_reloading = FALSE; 15484 ast_mutex_unlock(&sip_reload_lock); 15485 if (reloading) { 15486 if (option_verbose > 0) 15487 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15488 sip_do_reload(sip_reloadreason); 15489 15490 /* Change the I/O fd of our UDP socket */ 15491 if (sipsock > -1) { 15492 if (sipsock_read_id) 15493 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15494 else 15495 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15496 } 15497 } 15498 /* Check for interfaces needing to be killed */ 15499 ast_mutex_lock(&iflock); 15500 restartsearch: 15501 t = time(NULL); 15502 /* don't scan the interface list if it hasn't been a reasonable period 15503 of time since the last time we did it (when MWI is being sent, we can 15504 get back to this point every millisecond or less) 15505 */ 15506 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15507 /*! \note If we can't get a lock on an interface, skip it and come 15508 * back later. Note that there is the possibility of a deadlock with 15509 * sip_hangup otherwise, because sip_hangup is called with the channel 15510 * locked first, and the iface lock is attempted second. 15511 */ 15512 if (ast_mutex_trylock(&sip->lock)) 15513 continue; 15514 15515 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15516 if (sip->rtp && sip->owner && 15517 (sip->owner->_state == AST_STATE_UP) && 15518 !sip->redirip.sin_addr.s_addr && 15519 sip->t38.state != T38_ENABLED) { 15520 if (sip->lastrtptx && 15521 ast_rtp_get_rtpkeepalive(sip->rtp) && 15522 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15523 /* Need to send an empty RTP packet */ 15524 sip->lastrtptx = time(NULL); 15525 ast_rtp_sendcng(sip->rtp, 0); 15526 } 15527 if (sip->lastrtprx && 15528 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15529 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15530 /* Might be a timeout now -- see if we're on hold */ 15531 struct sockaddr_in sin; 15532 ast_rtp_get_peer(sip->rtp, &sin); 15533 if (sin.sin_addr.s_addr || 15534 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15535 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15536 /* Needs a hangup */ 15537 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15538 while (sip->owner && ast_channel_trylock(sip->owner)) { 15539 ast_mutex_unlock(&sip->lock); 15540 usleep(1); 15541 ast_mutex_lock(&sip->lock); 15542 } 15543 if (sip->owner) { 15544 ast_log(LOG_NOTICE, 15545 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15546 sip->owner->name, 15547 (long) (t - sip->lastrtprx)); 15548 /* Issue a softhangup */ 15549 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15550 ast_channel_unlock(sip->owner); 15551 /* forget the timeouts for this call, since a hangup 15552 has already been requested and we don't want to 15553 repeatedly request hangups 15554 */ 15555 ast_rtp_set_rtptimeout(sip->rtp, 0); 15556 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15557 if (sip->vrtp) { 15558 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15559 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15560 } 15561 } 15562 } 15563 } 15564 } 15565 } 15566 /* If we have sessions that needs to be destroyed, do it now */ 15567 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15568 !sip->owner) { 15569 ast_mutex_unlock(&sip->lock); 15570 __sip_destroy(sip, 1); 15571 goto restartsearch; 15572 } 15573 ast_mutex_unlock(&sip->lock); 15574 } 15575 ast_mutex_unlock(&iflock); 15576 15577 pthread_testcancel(); 15578 /* Wait for sched or io */ 15579 res = ast_sched_wait(sched); 15580 if ((res < 0) || (res > 1000)) 15581 res = 1000; 15582 /* If we might need to send more mailboxes, don't wait long at all.*/ 15583 if (fastrestart) 15584 res = 1; 15585 res = ast_io_wait(io, res); 15586 if (option_debug && res > 20) 15587 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15588 ast_mutex_lock(&monlock); 15589 if (res >= 0) { 15590 res = ast_sched_runq(sched); 15591 if (option_debug && res >= 20) 15592 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15593 } 15594 15595 /* Send MWI notifications to peers - static and cached realtime peers */ 15596 t = time(NULL); 15597 fastrestart = FALSE; 15598 curpeernum = 0; 15599 peer = NULL; 15600 /* Find next peer that needs mwi */ 15601 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15602 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15603 fastrestart = TRUE; 15604 lastpeernum = curpeernum; 15605 peer = ASTOBJ_REF(iterator); 15606 }; 15607 curpeernum++; 15608 } while (0) 15609 ); 15610 /* Send MWI to the peer */ 15611 if (peer) { 15612 ASTOBJ_WRLOCK(peer); 15613 sip_send_mwi_to_peer(peer); 15614 ASTOBJ_UNLOCK(peer); 15615 ASTOBJ_UNREF(peer,sip_destroy_peer); 15616 } else { 15617 /* Reset where we come from */ 15618 lastpeernum = -1; 15619 } 15620 ast_mutex_unlock(&monlock); 15621 } 15622 /* Never reached */ 15623 return NULL; 15624 15625 }
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 11359 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().
11360 { 11361 char digest[1024]; 11362 11363 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11364 return -2; 11365 11366 p->authtries++; 11367 if (option_debug > 1) 11368 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11369 memset(digest, 0, sizeof(digest)); 11370 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11371 /* No way to authenticate */ 11372 return -1; 11373 } 11374 /* Now we have a reply digest */ 11375 p->options->auth = digest; 11376 p->options->authheader = respheader; 11377 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11378 }
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 11338 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().
11339 { 11340 char digest[1024]; 11341 p->authtries++; 11342 memset(digest,0,sizeof(digest)); 11343 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11344 /* There's nothing to use for authentication */ 11345 /* No digest challenge in request */ 11346 if (sip_debug_test_pvt(p) && p->registry) 11347 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11348 /* No old challenge */ 11349 return -1; 11350 } 11351 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11352 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11353 if (sip_debug_test_pvt(p) && p->registry) 11354 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11355 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11356 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2729 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().
02730 { 02731 const char *mode = natflags ? "On" : "Off"; 02732 02733 if (p->rtp) { 02734 if (option_debug) 02735 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02736 ast_rtp_setnat(p->rtp, natflags); 02737 } 02738 if (p->vrtp) { 02739 if (option_debug) 02740 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02741 ast_rtp_setnat(p->vrtp, natflags); 02742 } 02743 if (p->udptl) { 02744 if (option_debug) 02745 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02746 ast_udptl_setnat(p->udptl, natflags); 02747 } 02748 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15442 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().
15443 { 15444 time_t t = time(NULL); 15445 15446 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15447 !peer->mwipvt) { /* We don't have a subscription */ 15448 peer->lastmsgcheck = t; /* Reset timer */ 15449 return FALSE; 15450 } 15451 15452 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15453 return TRUE; 15454 15455 return FALSE; 15456 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10199 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10200 { 10201 switch (mode) { 10202 case SIP_DOMAIN_AUTO: 10203 return "[Automatic]"; 10204 case SIP_DOMAIN_CONFIG: 10205 return "[Configured]"; 10206 } 10207 10208 return ""; 10209 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 9979 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().
09980 { 09981 switch (mode) { 09982 case SIP_DTMF_RFC2833: 09983 return "rfc2833"; 09984 case SIP_DTMF_INFO: 09985 return "info"; 09986 case SIP_DTMF_INBAND: 09987 return "inband"; 09988 case SIP_DTMF_AUTO: 09989 return "auto"; 09990 } 09991 return "<error>"; 09992 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7824 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().
07825 { 07826 struct sip_peer *peer = (struct sip_peer *)data; 07827 07828 if (!peer) /* Hmmm. We have no peer. Weird. */ 07829 return 0; 07830 07831 memset(&peer->addr, 0, sizeof(peer->addr)); 07832 07833 destroy_association(peer); /* remove registration data from storage */ 07834 07835 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07836 register_peer_exten(peer, FALSE); /* Remove regexten */ 07837 peer->expire = -1; 07838 ast_device_state_changed("SIP/%s", peer->name); 07839 07840 /* Do we need to release this peer from memory? 07841 Only for realtime peers and autocreated peers 07842 */ 07843 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07844 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07845 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07846 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07847 } 07848 07849 return 0; 07850 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6768 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().
06769 { 06770 char stripped[BUFSIZ]; 06771 char *c; 06772 06773 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06774 c = get_in_brackets(stripped); 06775 c = strsep(&c, ";"); /* trim ; and beyond */ 06776 if (!ast_strlen_zero(c)) 06777 ast_string_field_set(p, uri, c); 06778 }
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 4165 of file chan_sip.c.
References aliases.
04166 { 04167 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04168 static const struct cfalias { 04169 char * const fullname; 04170 char * const shortname; 04171 } aliases[] = { 04172 { "Content-Type", "c" }, 04173 { "Content-Encoding", "e" }, 04174 { "From", "f" }, 04175 { "Call-ID", "i" }, 04176 { "Contact", "m" }, 04177 { "Content-Length", "l" }, 04178 { "Subject", "s" }, 04179 { "To", "t" }, 04180 { "Supported", "k" }, 04181 { "Refer-To", "r" }, 04182 { "Referred-By", "b" }, 04183 { "Allow-Events", "u" }, 04184 { "Event", "o" }, 04185 { "Via", "v" }, 04186 { "Accept-Contact", "a" }, 04187 { "Reject-Contact", "j" }, 04188 { "Request-Disposition", "d" }, 04189 { "Session-Expires", "x" }, 04190 { "Identity", "y" }, 04191 { "Identity-Info", "n" }, 04192 }; 04193 int x; 04194 04195 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04196 if (!strcasecmp(aliases[x].fullname, name)) 04197 return aliases[x].shortname; 04198 04199 return _default; 04200 }
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 4517 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().
04518 { 04519 struct sip_pvt *p = NULL; 04520 char *tag = ""; /* note, tag is never NULL */ 04521 char totag[128]; 04522 char fromtag[128]; 04523 const char *callid = get_header(req, "Call-ID"); 04524 const char *from = get_header(req, "From"); 04525 const char *to = get_header(req, "To"); 04526 const char *cseq = get_header(req, "Cseq"); 04527 04528 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04529 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04530 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04531 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04532 return NULL; /* Invalid packet */ 04533 04534 if (pedanticsipchecking) { 04535 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04536 we need more to identify a branch - so we have to check branch, from 04537 and to tags to identify a call leg. 04538 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04539 in sip.conf 04540 */ 04541 if (gettag(req, "To", totag, sizeof(totag))) 04542 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04543 gettag(req, "From", fromtag, sizeof(fromtag)); 04544 04545 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04546 04547 if (option_debug > 4 ) 04548 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); 04549 } 04550 04551 ast_mutex_lock(&iflock); 04552 for (p = iflist; p; p = p->next) { 04553 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04554 int found = FALSE; 04555 if (ast_strlen_zero(p->callid)) 04556 continue; 04557 if (req->method == SIP_REGISTER) 04558 found = (!strcmp(p->callid, callid)); 04559 else 04560 found = (!strcmp(p->callid, callid) && 04561 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04562 04563 if (option_debug > 4) 04564 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); 04565 04566 /* If we get a new request within an existing to-tag - check the to tag as well */ 04567 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04568 if (p->tag[0] == '\0' && totag[0]) { 04569 /* We have no to tag, but they have. Wrong dialog */ 04570 found = FALSE; 04571 } else if (totag[0]) { /* Both have tags, compare them */ 04572 if (strcmp(totag, p->tag)) { 04573 found = FALSE; /* This is not our packet */ 04574 } 04575 } 04576 if (!found && option_debug > 4) 04577 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); 04578 } 04579 04580 04581 if (found) { 04582 /* Found the call */ 04583 ast_mutex_lock(&p->lock); 04584 ast_mutex_unlock(&iflock); 04585 return p; 04586 } 04587 } 04588 ast_mutex_unlock(&iflock); 04589 04590 /* See if the method is capable of creating a dialog */ 04591 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04592 if (intended_method == SIP_REFER) { 04593 /* We do support REFER, but not outside of a dialog yet */ 04594 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04595 } else if (intended_method == SIP_NOTIFY) { 04596 /* We do not support out-of-dialog NOTIFY either, 04597 like voicemail notification, so cancel that early */ 04598 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04599 } else { 04600 /* Ok, time to create a new SIP dialog object, a pvt */ 04601 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04602 /* Ok, we've created a dialog, let's go and process it */ 04603 ast_mutex_lock(&p->lock); 04604 } else { 04605 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04606 getting a dialog from sip_alloc. 04607 04608 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04609 send an error message. 04610 04611 Sorry, we apologize for the inconvienience 04612 */ 04613 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04614 if (option_debug > 3) 04615 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04616 } 04617 } 04618 return p; 04619 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04620 /* A method we do not support, let's take it on the volley */ 04621 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04622 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04623 /* This is a request outside of a dialog that we don't know about 04624 ...never reply to an ACK! 04625 */ 04626 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04627 } 04628 /* We do not respond to responses for dialogs that we don't know about, we just drop 04629 the session quickly */ 04630 04631 return p; 04632 }
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 2293 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02294 { 02295 char last_char = '\0'; 02296 const char *s; 02297 for (s = start; *s && s != lim; last_char = *s++) { 02298 if (*s == '"' && last_char != '\\') 02299 break; 02300 } 02301 return s; 02302 }
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 2641 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02642 { 02643 struct sip_peer *p = NULL; 02644 02645 if (peer) 02646 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02647 else 02648 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02649 02650 if (!p && realtime) 02651 p = realtime_peer(peer, sin); 02652 02653 return p; 02654 }
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 16234 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16235 { 16236 struct sip_auth *a; 16237 16238 for (a = authlist; a; a = a->next) { 16239 if (!strcasecmp(a->realm, realm)) 16240 break; 16241 } 16242 16243 return a; 16244 }
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 4838 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().
04839 { 04840 const char *content_type; 04841 const char *search; 04842 char *boundary; 04843 unsigned int x; 04844 int boundaryisquoted = FALSE; 04845 int found_application_sdp = FALSE; 04846 int found_end_of_headers = FALSE; 04847 04848 content_type = get_header(req, "Content-Type"); 04849 04850 /* if the body contains only SDP, this is easy */ 04851 if (!strcasecmp(content_type, "application/sdp")) { 04852 req->sdp_start = 0; 04853 req->sdp_end = req->lines; 04854 return req->lines ? 1 : 0; 04855 } 04856 04857 /* if it's not multipart/mixed, there cannot be an SDP */ 04858 if (strncasecmp(content_type, "multipart/mixed", 15)) 04859 return 0; 04860 04861 /* if there is no boundary marker, it's invalid */ 04862 if (!(search = strcasestr(content_type, ";boundary="))) 04863 return 0; 04864 04865 search += 10; 04866 if (ast_strlen_zero(search)) 04867 return 0; 04868 04869 /* If the boundary is quoted with ", remove quote */ 04870 if (*search == '\"') { 04871 search++; 04872 boundaryisquoted = TRUE; 04873 } 04874 04875 /* make a duplicate of the string, with two extra characters 04876 at the beginning */ 04877 boundary = ast_strdupa(search - 2); 04878 boundary[0] = boundary[1] = '-'; 04879 /* Remove final quote */ 04880 if (boundaryisquoted) 04881 boundary[strlen(boundary) - 1] = '\0'; 04882 04883 /* search for the boundary marker, the empty line delimiting headers from 04884 sdp part and the end boundry if it exists */ 04885 04886 for (x = 0; x < (req->lines ); x++) { 04887 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 04888 if(found_application_sdp && found_end_of_headers){ 04889 req->sdp_end = x-1; 04890 return 1; 04891 } 04892 found_application_sdp = FALSE; 04893 } 04894 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 04895 found_application_sdp = TRUE; 04896 04897 if(strlen(req->line[x]) == 0 ){ 04898 if(found_application_sdp && !found_end_of_headers){ 04899 req->sdp_start = x; 04900 found_end_of_headers = TRUE; 04901 } 04902 } 04903 } 04904 if(found_application_sdp && found_end_of_headers) { 04905 req->sdp_end = x; 04906 return TRUE; 04907 } 04908 return FALSE; 04909 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1675 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01676 { 01677 int i, res = 0; 01678 01679 if (ast_strlen_zero(msg)) 01680 return 0; 01681 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01682 if (method_match(i, msg)) 01683 res = sip_methods[i].id; 01684 } 01685 return res; 01686 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 10687 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10688 { 10689 int i; 10690 10691 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10692 if (subscription_types[i].type == subtype) { 10693 return &subscription_types[i]; 10694 } 10695 } 10696 return &subscription_types[0]; 10697 }
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 2720 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02721 { 02722 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02723 if (!u && realtime) 02724 u = realtime_user(name); 02725 return u; 02726 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8155 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08156 { 08157 struct sip_route *next; 08158 08159 while (route) { 08160 next = route->next; 08161 free(route); 08162 route = next; 08163 } 08164 }
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 11685 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11686 { 11687 if (ast_strlen_zero(data)) { 11688 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11689 return -1; 11690 } 11691 if (check_sip_domain(data, NULL, 0)) 11692 ast_copy_string(buf, data, len); 11693 else 11694 buf[0] = '\0'; 11695 return 0; 11696 }
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 11621 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.
11622 { 11623 struct sip_pvt *p; 11624 const char *content = NULL; 11625 AST_DECLARE_APP_ARGS(args, 11626 AST_APP_ARG(header); 11627 AST_APP_ARG(number); 11628 ); 11629 int i, number, start = 0; 11630 11631 if (ast_strlen_zero(data)) { 11632 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11633 return -1; 11634 } 11635 11636 ast_channel_lock(chan); 11637 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11638 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11639 ast_channel_unlock(chan); 11640 return -1; 11641 } 11642 11643 AST_STANDARD_APP_ARGS(args, data); 11644 if (!args.number) { 11645 number = 1; 11646 } else { 11647 sscanf(args.number, "%d", &number); 11648 if (number < 1) 11649 number = 1; 11650 } 11651 11652 p = chan->tech_pvt; 11653 11654 /* If there is no private structure, this channel is no longer alive */ 11655 if (!p) { 11656 ast_channel_unlock(chan); 11657 return -1; 11658 } 11659 11660 for (i = 0; i < number; i++) 11661 content = __get_header(&p->initreq, args.header, &start); 11662 11663 if (ast_strlen_zero(content)) { 11664 ast_channel_unlock(chan); 11665 return -1; 11666 } 11667 11668 ast_copy_string(buf, content, len); 11669 ast_channel_unlock(chan); 11670 11671 return 0; 11672 }
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 11800 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.
11801 { 11802 struct sip_pvt *p; 11803 11804 *buf = 0; 11805 11806 if (!data) { 11807 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11808 return -1; 11809 } 11810 11811 ast_channel_lock(chan); 11812 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11813 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11814 ast_channel_unlock(chan); 11815 return -1; 11816 } 11817 11818 p = chan->tech_pvt; 11819 11820 /* If there is no private structure, this channel is no longer alive */ 11821 if (!p) { 11822 ast_channel_unlock(chan); 11823 return -1; 11824 } 11825 11826 if (!strcasecmp(data, "peerip")) { 11827 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11828 } else if (!strcasecmp(data, "recvip")) { 11829 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11830 } else if (!strcasecmp(data, "from")) { 11831 ast_copy_string(buf, p->from, len); 11832 } else if (!strcasecmp(data, "uri")) { 11833 ast_copy_string(buf, p->uri, len); 11834 } else if (!strcasecmp(data, "useragent")) { 11835 ast_copy_string(buf, p->useragent, len); 11836 } else if (!strcasecmp(data, "peername")) { 11837 ast_copy_string(buf, p->peername, len); 11838 } else if (!strcasecmp(data, "t38passthrough")) { 11839 if (p->t38.state == T38_DISABLED) 11840 ast_copy_string(buf, "0", sizeof("0")); 11841 else /* T38 is offered or enabled in this call */ 11842 ast_copy_string(buf, "1", sizeof("1")); 11843 } else { 11844 ast_channel_unlock(chan); 11845 return -1; 11846 } 11847 ast_channel_unlock(chan); 11848 11849 return 0; 11850 }
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 11710 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.
11711 { 11712 struct sip_peer *peer; 11713 char *colname; 11714 11715 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11716 *colname++ = '\0'; 11717 else if ((colname = strchr(data, '|'))) 11718 *colname++ = '\0'; 11719 else 11720 colname = "ip"; 11721 11722 if (!(peer = find_peer(data, NULL, 1))) 11723 return -1; 11724 11725 if (!strcasecmp(colname, "ip")) { 11726 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11727 } else if (!strcasecmp(colname, "status")) { 11728 peer_status(peer, buf, len); 11729 } else if (!strcasecmp(colname, "language")) { 11730 ast_copy_string(buf, peer->language, len); 11731 } else if (!strcasecmp(colname, "regexten")) { 11732 ast_copy_string(buf, peer->regexten, len); 11733 } else if (!strcasecmp(colname, "limit")) { 11734 snprintf(buf, len, "%d", peer->call_limit); 11735 } else if (!strcasecmp(colname, "curcalls")) { 11736 snprintf(buf, len, "%d", peer->inUse); 11737 } else if (!strcasecmp(colname, "accountcode")) { 11738 ast_copy_string(buf, peer->accountcode, len); 11739 } else if (!strcasecmp(colname, "useragent")) { 11740 ast_copy_string(buf, peer->useragent, len); 11741 } else if (!strcasecmp(colname, "mailbox")) { 11742 ast_copy_string(buf, peer->mailbox, len); 11743 } else if (!strcasecmp(colname, "context")) { 11744 ast_copy_string(buf, peer->context, len); 11745 } else if (!strcasecmp(colname, "expire")) { 11746 snprintf(buf, len, "%d", peer->expire); 11747 } else if (!strcasecmp(colname, "dynamic")) { 11748 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11749 } else if (!strcasecmp(colname, "callerid_name")) { 11750 ast_copy_string(buf, peer->cid_name, len); 11751 } else if (!strcasecmp(colname, "callerid_num")) { 11752 ast_copy_string(buf, peer->cid_num, len); 11753 } else if (!strcasecmp(colname, "codecs")) { 11754 ast_getformatname_multiple(buf, len -1, peer->capability); 11755 } else if (!strncasecmp(colname, "codec[", 6)) { 11756 char *codecnum; 11757 int index = 0, codec = 0; 11758 11759 codecnum = colname + 6; /* move past the '[' */ 11760 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11761 index = atoi(codecnum); 11762 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11763 ast_copy_string(buf, ast_getformatname(codec), len); 11764 } 11765 } 11766 11767 ASTOBJ_UNREF(peer, sip_destroy_peer); 11768 11769 return 0; 11770 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4350 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04351 { 04352 long val[4]; 04353 int x; 04354 04355 for (x=0; x<4; x++) 04356 val[x] = ast_random(); 04357 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04358 04359 return buf; 04360 }
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 9055 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().
09056 { 09057 char tmp[256] = "", *c, *a; 09058 struct sip_request *req = oreq ? oreq : &p->initreq; 09059 struct sip_refer *referdata = NULL; 09060 const char *transfer_context = NULL; 09061 09062 if (!p->refer && !sip_refer_allocate(p)) 09063 return -1; 09064 09065 referdata = p->refer; 09066 09067 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09068 c = get_in_brackets(tmp); 09069 09070 if (pedanticsipchecking) 09071 ast_uri_decode(c); 09072 09073 if (strncasecmp(c, "sip:", 4)) { 09074 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09075 return -1; 09076 } 09077 c += 4; 09078 if ((a = strchr(c, ';'))) /* Remove arguments */ 09079 *a = '\0'; 09080 09081 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09082 *a++ = '\0'; 09083 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09084 } 09085 09086 if (sip_debug_test_pvt(p)) 09087 ast_verbose("Looking for %s in %s\n", c, p->context); 09088 09089 if (p->owner) /* Mimic behaviour in res_features.c */ 09090 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09091 09092 /* By default, use the context in the channel sending the REFER */ 09093 if (ast_strlen_zero(transfer_context)) { 09094 transfer_context = S_OR(p->owner->macrocontext, 09095 S_OR(p->context, default_context)); 09096 } 09097 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09098 /* This is a blind transfer */ 09099 if (option_debug) 09100 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09101 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09102 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09103 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09104 referdata->refer_call = NULL; 09105 /* Set new context */ 09106 ast_string_field_set(p, context, transfer_context); 09107 return 0; 09108 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09109 return 1; 09110 } 09111 09112 return -1; 09113 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4149 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04150 { 04151 int x; 04152 int len = strlen(name); 04153 char *r; 04154 04155 for (x = 0; x < req->lines; x++) { 04156 r = get_body_by_line(req->line[x], name, len); 04157 if (r[0] != '\0') 04158 return r; 04159 } 04160 04161 return ""; 04162 }
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 4115 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04116 { 04117 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04118 return ast_skip_blanks(line + nameLen + 1); 04119 04120 return ""; 04121 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9167 of file chan_sip.c.
Referenced by check_user_full().
09168 { 09169 const char *end = strchr(input,'<'); /* first_bracket */ 09170 const char *tmp = strchr(input,'"'); /* first quote */ 09171 int bytes = 0; 09172 int maxbytes = outputsize - 1; 09173 09174 if (!end || end == input) /* we require a part in brackets */ 09175 return NULL; 09176 09177 end--; /* move just before "<" */ 09178 09179 if (tmp && tmp <= end) { 09180 /* The quote (tmp) precedes the bracket (end+1). 09181 * Find the matching quote and return the content. 09182 */ 09183 end = strchr(tmp+1, '"'); 09184 if (!end) 09185 return NULL; 09186 bytes = (int) (end - tmp); 09187 /* protect the output buffer */ 09188 if (bytes > maxbytes) 09189 bytes = maxbytes; 09190 ast_copy_string(output, tmp + 1, bytes); 09191 } else { 09192 /* No quoted string, or it is inside brackets. */ 09193 /* clear the empty characters in the begining*/ 09194 input = ast_skip_blanks(input); 09195 /* clear the empty characters in the end */ 09196 while(*end && *end < 33 && end > input) 09197 end--; 09198 if (end >= input) { 09199 bytes = (int) (end - input) + 2; 09200 /* protect the output buffer */ 09201 if (bytes > maxbytes) 09202 bytes = maxbytes; 09203 ast_copy_string(output, input, bytes); 09204 } else 09205 return NULL; 09206 } 09207 return output; 09208 }
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 8710 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().
08711 { 08712 char tmp[256] = "", *uri, *a; 08713 char tmpf[256] = "", *from; 08714 struct sip_request *req; 08715 char *colon; 08716 08717 req = oreq; 08718 if (!req) 08719 req = &p->initreq; 08720 08721 /* Find the request URI */ 08722 if (req->rlPart2) 08723 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08724 08725 if (pedanticsipchecking) 08726 ast_uri_decode(tmp); 08727 08728 uri = get_in_brackets(tmp); 08729 08730 if (strncasecmp(uri, "sip:", 4)) { 08731 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08732 return -1; 08733 } 08734 uri += 4; 08735 08736 /* Now find the From: caller ID and name */ 08737 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08738 if (!ast_strlen_zero(tmpf)) { 08739 if (pedanticsipchecking) 08740 ast_uri_decode(tmpf); 08741 from = get_in_brackets(tmpf); 08742 } else { 08743 from = NULL; 08744 } 08745 08746 if (!ast_strlen_zero(from)) { 08747 if (strncasecmp(from, "sip:", 4)) { 08748 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08749 return -1; 08750 } 08751 from += 4; 08752 if ((a = strchr(from, '@'))) 08753 *a++ = '\0'; 08754 else 08755 a = from; /* just a domain */ 08756 from = strsep(&from, ";"); /* Remove userinfo options */ 08757 a = strsep(&a, ";"); /* Remove URI options */ 08758 ast_string_field_set(p, fromdomain, a); 08759 } 08760 08761 /* Skip any options and find the domain */ 08762 08763 /* Get the target domain */ 08764 if ((a = strchr(uri, '@'))) { 08765 *a++ = '\0'; 08766 } else { /* No username part */ 08767 a = uri; 08768 uri = "s"; /* Set extension to "s" */ 08769 } 08770 colon = strchr(a, ':'); /* Remove :port */ 08771 if (colon) 08772 *colon = '\0'; 08773 08774 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08775 a = strsep(&a, ";"); /* Remove URI options */ 08776 08777 ast_string_field_set(p, domain, a); 08778 08779 if (!AST_LIST_EMPTY(&domain_list)) { 08780 char domain_context[AST_MAX_EXTENSION]; 08781 08782 domain_context[0] = '\0'; 08783 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08784 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08785 if (option_debug) 08786 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08787 return -2; 08788 } 08789 } 08790 /* If we have a context defined, overwrite the original context */ 08791 if (!ast_strlen_zero(domain_context)) 08792 ast_string_field_set(p, context, domain_context); 08793 } 08794 08795 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 08796 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 08797 ast_string_field_set(p, context, p->subscribecontext); 08798 08799 if (sip_debug_test_pvt(p)) 08800 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08801 08802 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 08803 if (req->method == SIP_SUBSCRIBE) { 08804 char hint[AST_MAX_EXTENSION]; 08805 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 08806 } else { 08807 /* Check the dialplan for the username part of the request URI, 08808 the domain will be stored in the SIPDOMAIN variable 08809 Since extensions.conf can have unescaped characters, try matching a decoded 08810 uri in addition to the non-decoded uri 08811 Return 0 if we have a matching extension */ 08812 char *decoded_uri = ast_strdupa(uri); 08813 ast_uri_decode(decoded_uri); 08814 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)) || 08815 !strcmp(uri, ast_pickup_ext())) { 08816 if (!oreq) 08817 ast_string_field_set(p, exten, uri); 08818 return 0; 08819 } 08820 } 08821 08822 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08823 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08824 ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))) || 08825 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08826 return 1; 08827 } 08828 08829 return -1; 08830 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4238 of file chan_sip.c.
References __get_header().
04239 { 04240 int start = 0; 04241 return __get_header(req, name, &start); 04242 }
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 2315 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().
02316 { 02317 const char *parse = tmp; 02318 char *first_bracket; 02319 02320 /* 02321 * Skip any quoted text until we find the part in brackets. 02322 * On any error give up and return the full string. 02323 */ 02324 while ( (first_bracket = strchr(parse, '<')) ) { 02325 char *first_quote = strchr(parse, '"'); 02326 02327 if (!first_quote || first_quote > first_bracket) 02328 break; /* no need to look at quoted part */ 02329 /* the bracket is within quotes, so ignore it */ 02330 parse = find_closing_quote(first_quote + 1, NULL); 02331 if (!*parse) { /* not found, return full string ? */ 02332 /* XXX or be robust and return in-bracket part ? */ 02333 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02334 break; 02335 } 02336 parse++; 02337 } 02338 if (first_bracket) { 02339 char *second_bracket = strchr(first_bracket + 1, '>'); 02340 if (second_bracket) { 02341 *second_bracket = '\0'; 02342 tmp = first_bracket + 1; 02343 } else { 02344 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02345 } 02346 } 02347 return tmp; 02348 }
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 9572 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09573 { 09574 int x; 09575 int y; 09576 09577 buf[0] = '\0'; 09578 y = len - strlen(buf) - 5; 09579 if (y < 0) 09580 y = 0; 09581 for (x=0;x<req->lines;x++) { 09582 strncat(buf, req->line[x], y); /* safe */ 09583 y -= strlen(req->line[x]) + 1; 09584 if (y < 0) 09585 y = 0; 09586 if (y != 0) 09587 strcat(buf, "\n"); /* safe */ 09588 } 09589 return 0; 09590 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8681 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().
08682 { 08683 char tmp[256], *c, *a; 08684 struct sip_request *req; 08685 08686 req = oreq; 08687 if (!req) 08688 req = &p->initreq; 08689 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08690 if (ast_strlen_zero(tmp)) 08691 return 0; 08692 c = get_in_brackets(tmp); 08693 if (strncasecmp(c, "sip:", 4)) { 08694 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08695 return -1; 08696 } 08697 c += 4; 08698 a = c; 08699 strsep(&a, "@;"); /* trim anything after @ or ; */ 08700 if (sip_debug_test_pvt(p)) 08701 ast_verbose("RDNIS is %s\n", c); 08702 ast_string_field_set(p, rdnis, c); 08703 08704 return 0; 08705 }
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 8889 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().
08890 { 08891 08892 const char *p_referred_by = NULL; 08893 char *h_refer_to = NULL; 08894 char *h_referred_by = NULL; 08895 char *refer_to; 08896 const char *p_refer_to; 08897 char *referred_by_uri = NULL; 08898 char *ptr; 08899 struct sip_request *req = NULL; 08900 const char *transfer_context = NULL; 08901 struct sip_refer *referdata; 08902 08903 08904 req = outgoing_req; 08905 referdata = transferer->refer; 08906 08907 if (!req) 08908 req = &transferer->initreq; 08909 08910 p_refer_to = get_header(req, "Refer-To"); 08911 if (ast_strlen_zero(p_refer_to)) { 08912 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 08913 return -2; /* Syntax error */ 08914 } 08915 h_refer_to = ast_strdupa(p_refer_to); 08916 refer_to = get_in_brackets(h_refer_to); 08917 if (pedanticsipchecking) 08918 ast_uri_decode(refer_to); 08919 08920 if (strncasecmp(refer_to, "sip:", 4)) { 08921 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 08922 return -3; 08923 } 08924 refer_to += 4; /* Skip sip: */ 08925 08926 /* Get referred by header if it exists */ 08927 p_referred_by = get_header(req, "Referred-By"); 08928 if (!ast_strlen_zero(p_referred_by)) { 08929 char *lessthan; 08930 h_referred_by = ast_strdupa(p_referred_by); 08931 if (pedanticsipchecking) 08932 ast_uri_decode(h_referred_by); 08933 08934 /* Store referrer's caller ID name */ 08935 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 08936 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 08937 *(lessthan - 1) = '\0'; /* Space */ 08938 } 08939 08940 referred_by_uri = get_in_brackets(h_referred_by); 08941 if(strncasecmp(referred_by_uri, "sip:", 4)) { 08942 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 08943 referred_by_uri = (char *) NULL; 08944 } else { 08945 referred_by_uri += 4; /* Skip sip: */ 08946 } 08947 } 08948 08949 /* Check for arguments in the refer_to header */ 08950 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 08951 *ptr++ = '\0'; 08952 if (!strncasecmp(ptr, "REPLACES=", 9)) { 08953 char *to = NULL, *from = NULL; 08954 08955 /* This is an attended transfer */ 08956 referdata->attendedtransfer = 1; 08957 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 08958 ast_uri_decode(referdata->replaces_callid); 08959 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 08960 *ptr++ = '\0'; 08961 } 08962 08963 if (ptr) { 08964 /* Find the different tags before we destroy the string */ 08965 to = strcasestr(ptr, "to-tag="); 08966 from = strcasestr(ptr, "from-tag="); 08967 } 08968 08969 /* Grab the to header */ 08970 if (to) { 08971 ptr = to + 7; 08972 if ((to = strchr(ptr, '&'))) 08973 *to = '\0'; 08974 if ((to = strchr(ptr, ';'))) 08975 *to = '\0'; 08976 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 08977 } 08978 08979 if (from) { 08980 ptr = from + 9; 08981 if ((to = strchr(ptr, '&'))) 08982 *to = '\0'; 08983 if ((to = strchr(ptr, ';'))) 08984 *to = '\0'; 08985 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 08986 } 08987 08988 if (option_debug > 1) { 08989 if (!pedanticsipchecking) 08990 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 08991 else 08992 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>" ); 08993 } 08994 } 08995 } 08996 08997 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 08998 char *urioption = NULL, *domain; 08999 *ptr++ = '\0'; 09000 09001 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09002 *urioption++ = '\0'; 09003 09004 domain = ptr; 09005 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09006 *ptr = '\0'; 09007 09008 /* Save the domain for the dial plan */ 09009 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09010 if (urioption) 09011 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09012 } 09013 09014 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09015 *ptr = '\0'; 09016 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09017 09018 if (referred_by_uri) { 09019 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09020 *ptr = '\0'; 09021 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09022 } else { 09023 referdata->referred_by[0] = '\0'; 09024 } 09025 09026 /* Determine transfer context */ 09027 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09028 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09029 09030 /* By default, use the context in the channel sending the REFER */ 09031 if (ast_strlen_zero(transfer_context)) { 09032 transfer_context = S_OR(transferer->owner->macrocontext, 09033 S_OR(transferer->context, default_context)); 09034 } 09035 09036 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09037 09038 /* Either an existing extension or the parking extension */ 09039 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09040 if (sip_debug_test_pvt(transferer)) { 09041 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09042 } 09043 /* We are ready to transfer to the extension */ 09044 return 0; 09045 } 09046 if (sip_debug_test_pvt(transferer)) 09047 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09048 09049 /* Failure, we can't find this extension */ 09050 return -1; 09051 }
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 9214 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09215 { 09216 char *start; 09217 char *end; 09218 09219 start = strchr(input,':'); 09220 if (!start) { 09221 output[0] = '\0'; 09222 return 0; 09223 } 09224 start++; 09225 09226 /* we found "number" */ 09227 ast_copy_string(output,start,maxlen); 09228 output[maxlen-1] = '\0'; 09229 09230 end = strchr(output,'@'); 09231 if (end) 09232 *end = '\0'; 09233 else 09234 output[0] = '\0'; 09235 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09236 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09237 09238 return 0; 09239 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4141 of file chan_sip.c.
References get_sdp_iterate().
04142 { 04143 int dummy = 0; 04144 04145 return get_sdp_iterate(&dummy, req, name); 04146 }
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 4127 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04128 { 04129 int len = strlen(name); 04130 04131 while (*start < req->sdp_end) { 04132 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04133 if (r[0] != '\0') 04134 return r; 04135 } 04136 04137 return ""; 04138 }
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 8837 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().
08838 { 08839 struct sip_pvt *sip_pvt_ptr; 08840 08841 ast_mutex_lock(&iflock); 08842 08843 if (option_debug > 3 && totag) 08844 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08845 08846 /* Search interfaces and find the match */ 08847 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08848 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08849 int match = 1; 08850 char *ourtag = sip_pvt_ptr->tag; 08851 08852 /* Go ahead and lock it (and its owner) before returning */ 08853 ast_mutex_lock(&sip_pvt_ptr->lock); 08854 08855 /* Check if tags match. If not, this is not the call we want 08856 (With a forking SIP proxy, several call legs share the 08857 call id, but have different tags) 08858 */ 08859 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 08860 match = 0; 08861 08862 if (!match) { 08863 ast_mutex_unlock(&sip_pvt_ptr->lock); 08864 continue; 08865 } 08866 08867 if (option_debug > 3 && totag) 08868 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08869 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08870 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08871 08872 /* deadlock avoidance... */ 08873 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08874 ast_mutex_unlock(&sip_pvt_ptr->lock); 08875 usleep(1); 08876 ast_mutex_lock(&sip_pvt_ptr->lock); 08877 } 08878 break; 08879 } 08880 } 08881 ast_mutex_unlock(&iflock); 08882 if (option_debug > 3 && !sip_pvt_ptr) 08883 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08884 return sip_pvt_ptr; 08885 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13236 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
13237 { 13238 const char *thetag; 13239 13240 if (!tagbuf) 13241 return NULL; 13242 tagbuf[0] = '\0'; /* reset the buffer */ 13243 thetag = get_header(req, header); 13244 thetag = strcasestr(thetag, ";tag="); 13245 if (thetag) { 13246 thetag += 5; 13247 ast_copy_string(tagbuf, thetag, tagbufsize); 13248 return strsep(&tagbuf, ";"); 13249 } 13250 return NULL; 13251 }
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 15986 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().
15987 { 15988 int res = 1; 15989 15990 if (!strcasecmp(v->name, "trustrpid")) { 15991 ast_set_flag(&mask[0], SIP_TRUSTRPID); 15992 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 15993 } else if (!strcasecmp(v->name, "sendrpid")) { 15994 ast_set_flag(&mask[0], SIP_SENDRPID); 15995 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 15996 } else if (!strcasecmp(v->name, "g726nonstandard")) { 15997 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 15998 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 15999 } else if (!strcasecmp(v->name, "useclientcode")) { 16000 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16001 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16002 } else if (!strcasecmp(v->name, "dtmfmode")) { 16003 ast_set_flag(&mask[0], SIP_DTMF); 16004 ast_clear_flag(&flags[0], SIP_DTMF); 16005 if (!strcasecmp(v->value, "inband")) 16006 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16007 else if (!strcasecmp(v->value, "rfc2833")) 16008 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16009 else if (!strcasecmp(v->value, "info")) 16010 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16011 else if (!strcasecmp(v->value, "auto")) 16012 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16013 else { 16014 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16015 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16016 } 16017 } else if (!strcasecmp(v->name, "nat")) { 16018 ast_set_flag(&mask[0], SIP_NAT); 16019 ast_clear_flag(&flags[0], SIP_NAT); 16020 if (!strcasecmp(v->value, "never")) 16021 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16022 else if (!strcasecmp(v->value, "route")) 16023 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16024 else if (ast_true(v->value)) 16025 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16026 else 16027 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16028 } else if (!strcasecmp(v->name, "canreinvite")) { 16029 ast_set_flag(&mask[0], SIP_REINVITE); 16030 ast_clear_flag(&flags[0], SIP_REINVITE); 16031 if(ast_true(v->value)) { 16032 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16033 } else if (!ast_false(v->value)) { 16034 char buf[64]; 16035 char *word, *next = buf; 16036 16037 ast_copy_string(buf, v->value, sizeof(buf)); 16038 while ((word = strsep(&next, ","))) { 16039 if(!strcasecmp(word, "update")) { 16040 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16041 } else if(!strcasecmp(word, "nonat")) { 16042 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16043 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16044 } else { 16045 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16046 } 16047 } 16048 } 16049 } else if (!strcasecmp(v->name, "insecure")) { 16050 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16051 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16052 set_insecure_flags(flags, v->value, v->lineno); 16053 } else if (!strcasecmp(v->name, "progressinband")) { 16054 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16055 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16056 if (ast_true(v->value)) 16057 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16058 else if (strcasecmp(v->value, "never")) 16059 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16060 } else if (!strcasecmp(v->name, "promiscredir")) { 16061 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16062 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16063 } else if (!strcasecmp(v->name, "videosupport")) { 16064 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16065 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16066 } else if (!strcasecmp(v->name, "allowoverlap")) { 16067 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16068 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16069 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16070 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16071 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16072 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16073 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16074 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16075 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16076 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16077 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16078 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16079 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16080 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16081 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16082 #endif 16083 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16084 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16085 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16086 } else if (!strcasecmp(v->name, "buggymwi")) { 16087 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16088 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16089 } else 16090 res = 0; 16091 16092 return res; 16093 }
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 13415 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().
13416 { 13417 struct ast_frame *f; 13418 int earlyreplace = 0; 13419 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13420 struct ast_channel *c = p->owner; /* Our incoming call */ 13421 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13422 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13423 13424 /* Check if we're in ring state */ 13425 if (replacecall->_state == AST_STATE_RING) 13426 earlyreplace = 1; 13427 13428 /* Check if we have a bridge */ 13429 if (!(targetcall = ast_bridged_channel(replacecall))) { 13430 /* We have no bridge */ 13431 if (!earlyreplace) { 13432 if (option_debug > 1) 13433 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13434 oneleggedreplace = 1; 13435 } 13436 } 13437 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13438 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13439 13440 if (option_debug > 3) { 13441 if (targetcall) 13442 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); 13443 else 13444 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13445 } 13446 13447 if (ignore) { 13448 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13449 /* We should answer something here. If we are here, the 13450 call we are replacing exists, so an accepted 13451 can't harm */ 13452 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13453 /* Do something more clever here */ 13454 ast_channel_unlock(c); 13455 ast_mutex_unlock(&p->refer->refer_call->lock); 13456 return 1; 13457 } 13458 if (!c) { 13459 /* What to do if no channel ??? */ 13460 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13461 transmit_response_reliable(p, "503 Service Unavailable", req); 13462 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13463 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13464 ast_mutex_unlock(&p->refer->refer_call->lock); 13465 return 1; 13466 } 13467 append_history(p, "Xfer", "INVITE/Replace received"); 13468 /* We have three channels to play with 13469 channel c: New incoming call 13470 targetcall: Call from PBX to target 13471 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13472 replacecall: The owner of the previous 13473 We need to masq C into refer_call to connect to 13474 targetcall; 13475 If we are talking to internal audio stream, target call is null. 13476 */ 13477 13478 /* Fake call progress */ 13479 transmit_response(p, "100 Trying", req); 13480 ast_setstate(c, AST_STATE_RING); 13481 13482 /* Masquerade the new call into the referred call to connect to target call 13483 Targetcall is not touched by the masq */ 13484 13485 /* Answer the incoming call and set channel to UP state */ 13486 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13487 13488 ast_setstate(c, AST_STATE_UP); 13489 13490 /* Stop music on hold and other generators */ 13491 ast_quiet_chan(replacecall); 13492 ast_quiet_chan(targetcall); 13493 if (option_debug > 3) 13494 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13495 /* Unlock clone, but not original (replacecall) */ 13496 if (!oneleggedreplace) 13497 ast_channel_unlock(c); 13498 13499 /* Unlock PVT */ 13500 ast_mutex_unlock(&p->refer->refer_call->lock); 13501 13502 /* Make sure that the masq does not free our PVT for the old call */ 13503 if (! earlyreplace && ! oneleggedreplace ) 13504 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13505 13506 /* Prepare the masquerade - if this does not happen, we will be gone */ 13507 if(ast_channel_masquerade(replacecall, c)) 13508 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13509 else if (option_debug > 3) 13510 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13511 13512 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13513 13514 /* C should now be in place of replacecall */ 13515 /* ast_read needs to lock channel */ 13516 ast_channel_unlock(c); 13517 13518 if (earlyreplace || oneleggedreplace ) { 13519 /* Force the masq to happen */ 13520 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13521 ast_frfree(f); 13522 f = NULL; 13523 if (option_debug > 3) 13524 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13525 } else { 13526 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13527 } 13528 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13529 if (!oneleggedreplace) 13530 ast_channel_unlock(replacecall); 13531 } else { /* Bridged call, UP channel */ 13532 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13533 /* Masq ok */ 13534 ast_frfree(f); 13535 f = NULL; 13536 if (option_debug > 2) 13537 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13538 } else { 13539 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13540 } 13541 ast_channel_unlock(replacecall); 13542 } 13543 ast_mutex_unlock(&p->refer->refer_call->lock); 13544 13545 ast_setstate(c, AST_STATE_DOWN); 13546 if (option_debug > 3) { 13547 struct ast_channel *test; 13548 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13549 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13550 if (replacecall) 13551 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13552 if (p->owner) { 13553 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13554 test = ast_bridged_channel(p->owner); 13555 if (test) 13556 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13557 else 13558 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13559 } else 13560 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13561 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13562 } 13563 13564 ast_channel_unlock(p->owner); /* Unlock new owner */ 13565 if (!oneleggedreplace) 13566 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13567 13568 /* The call should be down with no ast_channel, so hang it up */ 13569 c->tech_pvt = NULL; 13570 ast_hangup(c); 13571 return 0; 13572 }
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 15073 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.
15074 { 15075 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15076 relatively static */ 15077 const char *cmd; 15078 const char *cseq; 15079 const char *useragent; 15080 int seqno; 15081 int len; 15082 int ignore = FALSE; 15083 int respid; 15084 int res = 0; 15085 int debug = sip_debug_test_pvt(p); 15086 char *e; 15087 int error = 0; 15088 15089 /* Get Method and Cseq */ 15090 cseq = get_header(req, "Cseq"); 15091 cmd = req->header[0]; 15092 15093 /* Must have Cseq */ 15094 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15095 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15096 error = 1; 15097 } 15098 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15099 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15100 error = 1; 15101 } 15102 if (error) { 15103 if (!p->initreq.headers) /* New call */ 15104 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15105 return -1; 15106 } 15107 /* Get the command XXX */ 15108 15109 cmd = req->rlPart1; 15110 e = req->rlPart2; 15111 15112 /* Save useragent of the client */ 15113 useragent = get_header(req, "User-Agent"); 15114 if (!ast_strlen_zero(useragent)) 15115 ast_string_field_set(p, useragent, useragent); 15116 15117 /* Find out SIP method for incoming request */ 15118 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15119 /* Response to our request -- Do some sanity checks */ 15120 if (!p->initreq.headers) { 15121 if (option_debug) 15122 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15123 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15124 return 0; 15125 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15126 if (option_debug) 15127 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15128 return -1; 15129 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15130 /* ignore means "don't do anything with it" but still have to 15131 respond appropriately */ 15132 ignore = TRUE; 15133 ast_set_flag(req, SIP_PKT_IGNORE); 15134 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15135 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15136 } else if (e) { 15137 e = ast_skip_blanks(e); 15138 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15139 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15140 } else { 15141 if (respid <= 0) { 15142 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15143 return 0; 15144 } 15145 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15146 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15147 extract_uri(p, req); 15148 handle_response(p, respid, e + len, req, ignore, seqno); 15149 } 15150 } 15151 return 0; 15152 } 15153 15154 /* New SIP request coming in 15155 (could be new request in existing SIP dialog as well...) 15156 */ 15157 15158 p->method = req->method; /* Find out which SIP method they are using */ 15159 if (option_debug > 3) 15160 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15161 15162 if (p->icseq && (p->icseq > seqno)) { 15163 if (option_debug) 15164 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15165 if (req->method != SIP_ACK) 15166 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15167 return -1; 15168 } else if (p->icseq && 15169 p->icseq == seqno && 15170 req->method != SIP_ACK && 15171 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15172 /* ignore means "don't do anything with it" but still have to 15173 respond appropriately. We do this if we receive a repeat of 15174 the last sequence number */ 15175 ignore = 2; 15176 ast_set_flag(req, SIP_PKT_IGNORE); 15177 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15178 if (option_debug > 2) 15179 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15180 } 15181 15182 if (seqno >= p->icseq) 15183 /* Next should follow monotonically (but not necessarily 15184 incrementally -- thanks again to the genius authors of SIP -- 15185 increasing */ 15186 p->icseq = seqno; 15187 15188 /* Find their tag if we haven't got it */ 15189 if (ast_strlen_zero(p->theirtag)) { 15190 char tag[128]; 15191 15192 gettag(req, "From", tag, sizeof(tag)); 15193 ast_string_field_set(p, theirtag, tag); 15194 } 15195 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15196 15197 if (pedanticsipchecking) { 15198 /* If this is a request packet without a from tag, it's not 15199 correct according to RFC 3261 */ 15200 /* Check if this a new request in a new dialog with a totag already attached to it, 15201 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15202 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15203 /* If this is a first request and it got a to-tag, it is not for us */ 15204 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15205 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15206 /* Will cease to exist after ACK */ 15207 } else if (req->method != SIP_ACK) { 15208 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15209 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15210 } 15211 return res; 15212 } 15213 } 15214 15215 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15216 transmit_response(p, "400 Bad request", req); 15217 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15218 return -1; 15219 } 15220 15221 /* Handle various incoming SIP methods in requests */ 15222 switch (p->method) { 15223 case SIP_OPTIONS: 15224 res = handle_request_options(p, req); 15225 break; 15226 case SIP_INVITE: 15227 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15228 break; 15229 case SIP_REFER: 15230 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15231 break; 15232 case SIP_CANCEL: 15233 res = handle_request_cancel(p, req); 15234 break; 15235 case SIP_BYE: 15236 res = handle_request_bye(p, req); 15237 break; 15238 case SIP_MESSAGE: 15239 res = handle_request_message(p, req); 15240 break; 15241 case SIP_SUBSCRIBE: 15242 res = handle_request_subscribe(p, req, sin, seqno, e); 15243 break; 15244 case SIP_REGISTER: 15245 res = handle_request_register(p, req, sin, e); 15246 break; 15247 case SIP_INFO: 15248 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15249 ast_verbose("Receiving INFO!\n"); 15250 if (!ignore) 15251 handle_request_info(p, req); 15252 else /* if ignoring, transmit response */ 15253 transmit_response(p, "200 OK", req); 15254 break; 15255 case SIP_NOTIFY: 15256 res = handle_request_notify(p, req, sin, seqno, e); 15257 break; 15258 case SIP_ACK: 15259 /* Make sure we don't ignore this */ 15260 if (seqno == p->pendinginvite) { 15261 p->invitestate = INV_TERMINATED; 15262 p->pendinginvite = 0; 15263 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15264 if (find_sdp(req)) { 15265 if (process_sdp(p, req)) 15266 return -1; 15267 } 15268 check_pendings(p); 15269 } 15270 /* Got an ACK that we did not match. Ignore silently */ 15271 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15272 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15273 break; 15274 default: 15275 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15276 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15277 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15278 /* If this is some new method, and we don't have a call, destroy it now */ 15279 if (!p->initreq.headers) 15280 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15281 break; 15282 } 15283 return res; 15284 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14650 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().
14651 { 14652 struct ast_channel *c=NULL; 14653 int res; 14654 struct ast_channel *bridged_to; 14655 14656 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14657 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14658 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14659 14660 p->invitestate = INV_TERMINATED; 14661 14662 copy_request(&p->initreq, req); 14663 check_via(p, req); 14664 sip_alreadygone(p); 14665 14666 /* Get RTCP quality before end of call */ 14667 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14668 char *audioqos, *videoqos; 14669 if (p->rtp) { 14670 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14671 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14672 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14673 if (p->owner) 14674 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14675 } 14676 if (p->vrtp) { 14677 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14678 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14679 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14680 if (p->owner) 14681 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14682 } 14683 } 14684 14685 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14686 14687 if (!ast_strlen_zero(get_header(req, "Also"))) { 14688 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14689 ast_inet_ntoa(p->recv.sin_addr)); 14690 if (ast_strlen_zero(p->context)) 14691 ast_string_field_set(p, context, default_context); 14692 res = get_also_info(p, req); 14693 if (!res) { 14694 c = p->owner; 14695 if (c) { 14696 bridged_to = ast_bridged_channel(c); 14697 if (bridged_to) { 14698 /* Don't actually hangup here... */ 14699 ast_queue_control(c, AST_CONTROL_UNHOLD); 14700 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14701 } else 14702 ast_queue_hangup(p->owner); 14703 } 14704 } else { 14705 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14706 if (p->owner) 14707 ast_queue_hangup(p->owner); 14708 } 14709 } else if (p->owner) { 14710 ast_queue_hangup(p->owner); 14711 if (option_debug > 2) 14712 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14713 } else { 14714 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14715 if (option_debug > 2) 14716 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14717 } 14718 transmit_response(p, "200 OK", req); 14719 14720 return 1; 14721 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14543 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().
14544 { 14545 14546 check_via(p, req); 14547 sip_alreadygone(p); 14548 14549 /* At this point, we could have cancelled the invite at the same time 14550 as the other side sends a CANCEL. Our final reply with error code 14551 might not have been received by the other side before the CANCEL 14552 was sent, so let's just give up retransmissions and waiting for 14553 ACK on our error code. The call is hanging up any way. */ 14554 if (p->invitestate == INV_TERMINATED) 14555 __sip_pretend_ack(p); 14556 else 14557 p->invitestate = INV_CANCELLED; 14558 14559 if (p->owner && p->owner->_state == AST_STATE_UP) { 14560 /* This call is up, cancel is ignored, we need a bye */ 14561 transmit_response(p, "200 OK", req); 14562 if (option_debug) 14563 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14564 return 0; 14565 } 14566 14567 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14568 update_call_counter(p, DEC_CALL_LIMIT); 14569 14570 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14571 14572 if (p->owner) 14573 ast_queue_hangup(p->owner); 14574 else 14575 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14576 if (p->initreq.len > 0) { 14577 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14578 transmit_response(p, "200 OK", req); 14579 return 1; 14580 } else { 14581 transmit_response(p, "481 Call Leg Does Not Exist", req); 14582 return 0; 14583 } 14584 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11041 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().
11042 { 11043 char buf[1024]; 11044 unsigned int event; 11045 const char *c = get_header(req, "Content-Type"); 11046 11047 /* Need to check the media/type */ 11048 if (!strcasecmp(c, "application/dtmf-relay") || 11049 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11050 unsigned int duration = 0; 11051 11052 /* Try getting the "signal=" part */ 11053 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11054 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11055 transmit_response(p, "200 OK", req); /* Should return error */ 11056 return; 11057 } else { 11058 ast_copy_string(buf, c, sizeof(buf)); 11059 } 11060 11061 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11062 duration = atoi(c); 11063 if (!duration) 11064 duration = 100; /* 100 ms */ 11065 11066 if (!p->owner) { /* not a PBX call */ 11067 transmit_response(p, "481 Call leg/transaction does not exist", req); 11068 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11069 return; 11070 } 11071 11072 if (ast_strlen_zero(buf)) { 11073 transmit_response(p, "200 OK", req); 11074 return; 11075 } 11076 11077 if (buf[0] == '*') 11078 event = 10; 11079 else if (buf[0] == '#') 11080 event = 11; 11081 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11082 event = 12 + buf[0] - 'A'; 11083 else 11084 event = atoi(buf); 11085 if (event == 16) { 11086 /* send a FLASH event */ 11087 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11088 ast_queue_frame(p->owner, &f); 11089 if (sipdebug) 11090 ast_verbose("* DTMF-relay event received: FLASH\n"); 11091 } else { 11092 /* send a DTMF event */ 11093 struct ast_frame f = { AST_FRAME_DTMF, }; 11094 if (event < 10) { 11095 f.subclass = '0' + event; 11096 } else if (event < 11) { 11097 f.subclass = '*'; 11098 } else if (event < 12) { 11099 f.subclass = '#'; 11100 } else if (event < 16) { 11101 f.subclass = 'A' + (event - 12); 11102 } 11103 f.len = duration; 11104 ast_queue_frame(p->owner, &f); 11105 if (sipdebug) 11106 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11107 } 11108 transmit_response(p, "200 OK", req); 11109 return; 11110 } else if (!strcasecmp(c, "application/media_control+xml")) { 11111 /* Eh, we'll just assume it's a fast picture update for now */ 11112 if (p->owner) 11113 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11114 transmit_response(p, "200 OK", req); 11115 return; 11116 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11117 /* Client code (from SNOM phone) */ 11118 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11119 if (p->owner && p->owner->cdr) 11120 ast_cdr_setuserfield(p->owner, c); 11121 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11122 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11123 transmit_response(p, "200 OK", req); 11124 } else { 11125 transmit_response(p, "403 Unauthorized", req); 11126 } 11127 return; 11128 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11129 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11130 transmit_response(p, "200 OK", req); 11131 return; 11132 } 11133 11134 /* Other type of INFO message, not really understood by Asterisk */ 11135 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11136 11137 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11138 transmit_response(p, "415 Unsupported media type", req); 11139 return; 11140 }
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 13581 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().
13582 { 13583 int res = 1; 13584 int gotdest; 13585 const char *p_replaces; 13586 char *replace_id = NULL; 13587 const char *required; 13588 unsigned int required_profile = 0; 13589 struct ast_channel *c = NULL; /* New channel */ 13590 int reinvite = 0; 13591 13592 /* Find out what they support */ 13593 if (!p->sipoptions) { 13594 const char *supported = get_header(req, "Supported"); 13595 if (!ast_strlen_zero(supported)) 13596 parse_sip_options(p, supported); 13597 } 13598 13599 /* Find out what they require */ 13600 required = get_header(req, "Require"); 13601 if (!ast_strlen_zero(required)) { 13602 required_profile = parse_sip_options(NULL, required); 13603 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13604 /* At this point we only support REPLACES */ 13605 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13606 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13607 p->invitestate = INV_COMPLETED; 13608 if (!p->lastinvite) 13609 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13610 return -1; 13611 } 13612 } 13613 13614 /* Check if this is a loop */ 13615 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13616 /* This is a call to ourself. Send ourselves an error code and stop 13617 processing immediately, as SIP really has no good mechanism for 13618 being able to call yourself */ 13619 /* If pedantic is on, we need to check the tags. If they're different, this is 13620 in fact a forked call through a SIP proxy somewhere. */ 13621 transmit_response(p, "482 Loop Detected", req); 13622 p->invitestate = INV_COMPLETED; 13623 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13624 return 0; 13625 } 13626 13627 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13628 /* We already have a pending invite. Sorry. You are on hold. */ 13629 transmit_response(p, "491 Request Pending", req); 13630 if (option_debug) 13631 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13632 /* Don't destroy dialog here */ 13633 return 0; 13634 } 13635 13636 p_replaces = get_header(req, "Replaces"); 13637 if (!ast_strlen_zero(p_replaces)) { 13638 /* We have a replaces header */ 13639 char *ptr; 13640 char *fromtag = NULL; 13641 char *totag = NULL; 13642 char *start, *to; 13643 int error = 0; 13644 13645 if (p->owner) { 13646 if (option_debug > 2) 13647 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13648 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13649 /* Do not destroy existing call */ 13650 return -1; 13651 } 13652 13653 if (sipdebug && option_debug > 2) 13654 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13655 /* Create a buffer we can manipulate */ 13656 replace_id = ast_strdupa(p_replaces); 13657 ast_uri_decode(replace_id); 13658 13659 if (!p->refer && !sip_refer_allocate(p)) { 13660 transmit_response(p, "500 Server Internal Error", req); 13661 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13662 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13663 p->invitestate = INV_COMPLETED; 13664 return -1; 13665 } 13666 13667 /* Todo: (When we find phones that support this) 13668 if the replaces header contains ";early-only" 13669 we can only replace the call in early 13670 stage, not after it's up. 13671 13672 If it's not in early mode, 486 Busy. 13673 */ 13674 13675 /* Skip leading whitespace */ 13676 replace_id = ast_skip_blanks(replace_id); 13677 13678 start = replace_id; 13679 while ( (ptr = strsep(&start, ";")) ) { 13680 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13681 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13682 totag = to + 7; /* skip the keyword */ 13683 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13684 fromtag = to + 9; /* skip the keyword */ 13685 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13686 } 13687 } 13688 13689 if (sipdebug && option_debug > 3) 13690 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>"); 13691 13692 13693 /* Try to find call that we are replacing 13694 If we have a Replaces header, we need to cancel that call if we succeed with this call 13695 */ 13696 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13697 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13698 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13699 error = 1; 13700 } 13701 13702 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13703 13704 /* The matched call is the call from the transferer to Asterisk . 13705 We want to bridge the bridged part of the call to the 13706 incoming invite, thus taking over the refered call */ 13707 13708 if (p->refer->refer_call == p) { 13709 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13710 p->refer->refer_call = NULL; 13711 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13712 error = 1; 13713 } 13714 13715 if (!error && !p->refer->refer_call->owner) { 13716 /* Oops, someting wrong anyway, no owner, no call */ 13717 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13718 /* Check for better return code */ 13719 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13720 error = 1; 13721 } 13722 13723 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 ) { 13724 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13725 transmit_response(p, "603 Declined (Replaces)", req); 13726 error = 1; 13727 } 13728 13729 if (error) { /* Give up this dialog */ 13730 append_history(p, "Xfer", "INVITE/Replace Failed."); 13731 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13732 ast_mutex_unlock(&p->lock); 13733 if (p->refer->refer_call) { 13734 ast_mutex_unlock(&p->refer->refer_call->lock); 13735 ast_channel_unlock(p->refer->refer_call->owner); 13736 } 13737 p->invitestate = INV_COMPLETED; 13738 return -1; 13739 } 13740 } 13741 13742 13743 /* Check if this is an INVITE that sets up a new dialog or 13744 a re-invite in an existing dialog */ 13745 13746 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13747 int newcall = (p->initreq.headers ? TRUE : FALSE); 13748 13749 sip_cancel_destroy(p); 13750 /* This also counts as a pending invite */ 13751 p->pendinginvite = seqno; 13752 check_via(p, req); 13753 13754 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13755 if (!p->owner) { /* Not a re-invite */ 13756 if (debug) 13757 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13758 if (newcall) 13759 append_history(p, "Invite", "New call: %s", p->callid); 13760 parse_ok_contact(p, req); 13761 } else { /* Re-invite on existing call */ 13762 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13763 /* Handle SDP here if we already have an owner */ 13764 if (find_sdp(req)) { 13765 if (process_sdp(p, req)) { 13766 transmit_response(p, "488 Not acceptable here", req); 13767 if (!p->lastinvite) 13768 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13769 return -1; 13770 } 13771 } else { 13772 p->jointcapability = p->capability; 13773 if (option_debug > 2) 13774 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13775 /* Some devices signal they want to be put off hold by sending a re-invite 13776 *without* an SDP, which is supposed to mean "Go back to your state" 13777 and since they put os on remote hold, we go back to off hold */ 13778 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13779 change_hold_state(p, req, FALSE, 0); 13780 } 13781 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13782 append_history(p, "ReInv", "Re-invite received"); 13783 } 13784 } else if (debug) 13785 ast_verbose("Ignoring this INVITE request\n"); 13786 13787 13788 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13789 /* This is a new invite */ 13790 /* Handle authentication if this is our first invite */ 13791 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13792 if (res == AUTH_CHALLENGE_SENT) { 13793 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13794 return 0; 13795 } 13796 if (res < 0) { /* Something failed in authentication */ 13797 if (res == AUTH_FAKE_AUTH) { 13798 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13799 transmit_fake_auth_response(p, req, 1); 13800 } else { 13801 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13802 transmit_response_reliable(p, "403 Forbidden", req); 13803 } 13804 p->invitestate = INV_COMPLETED; 13805 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13806 ast_string_field_free(p, theirtag); 13807 return 0; 13808 } 13809 13810 /* We have a succesful authentication, process the SDP portion if there is one */ 13811 if (find_sdp(req)) { 13812 if (process_sdp(p, req)) { 13813 /* Unacceptable codecs */ 13814 transmit_response_reliable(p, "488 Not acceptable here", req); 13815 p->invitestate = INV_COMPLETED; 13816 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13817 if (option_debug) 13818 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13819 return -1; 13820 } 13821 } else { /* No SDP in invite, call control session */ 13822 p->jointcapability = p->capability; 13823 if (option_debug > 1) 13824 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13825 } 13826 13827 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13828 /* This seems redundant ... see !p-owner above */ 13829 if (p->owner) 13830 ast_queue_frame(p->owner, &ast_null_frame); 13831 13832 13833 /* Initialize the context if it hasn't been already */ 13834 if (ast_strlen_zero(p->context)) 13835 ast_string_field_set(p, context, default_context); 13836 13837 13838 /* Check number of concurrent calls -vs- incoming limit HERE */ 13839 if (option_debug) 13840 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13841 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13842 if (res < 0) { 13843 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13844 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13845 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13846 p->invitestate = INV_COMPLETED; 13847 } 13848 return 0; 13849 } 13850 gotdest = get_destination(p, NULL); /* Get destination right away */ 13851 get_rdnis(p, NULL); /* Get redirect information */ 13852 extract_uri(p, req); /* Get the Contact URI */ 13853 build_contact(p); /* Build our contact header */ 13854 13855 if (p->rtp) { 13856 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13857 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13858 } 13859 13860 if (!replace_id && gotdest) { /* No matching extension found */ 13861 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13862 transmit_response_reliable(p, "484 Address Incomplete", req); 13863 else { 13864 transmit_response_reliable(p, "404 Not Found", req); 13865 ast_log(LOG_NOTICE, "Call from '%s' to extension" 13866 " '%s' rejected because extension not found.\n", 13867 S_OR(p->username, p->peername), p->exten); 13868 } 13869 p->invitestate = INV_COMPLETED; 13870 update_call_counter(p, DEC_CALL_LIMIT); 13871 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13872 return 0; 13873 } else { 13874 /* If no extension was specified, use the s one */ 13875 /* Basically for calling to IP/Host name only */ 13876 if (ast_strlen_zero(p->exten)) 13877 ast_string_field_set(p, exten, "s"); 13878 /* Initialize our tag */ 13879 13880 make_our_tag(p->tag, sizeof(p->tag)); 13881 /* First invitation - create the channel */ 13882 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13883 *recount = 1; 13884 13885 /* Save Record-Route for any later requests we make on this dialogue */ 13886 build_route(p, req, 0); 13887 13888 if (c) { 13889 /* Pre-lock the call */ 13890 ast_channel_lock(c); 13891 } 13892 } 13893 } else { 13894 if (option_debug > 1 && sipdebug) { 13895 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13896 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13897 else 13898 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13899 } 13900 reinvite = 1; 13901 c = p->owner; 13902 } 13903 13904 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 13905 p->lastinvite = seqno; 13906 13907 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 13908 /* Go and take over the target call */ 13909 if (sipdebug && option_debug > 3) 13910 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 13911 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 13912 } 13913 13914 13915 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 13916 switch(c->_state) { 13917 case AST_STATE_DOWN: 13918 if (option_debug > 1) 13919 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 13920 transmit_response(p, "100 Trying", req); 13921 p->invitestate = INV_PROCEEDING; 13922 ast_setstate(c, AST_STATE_RING); 13923 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 13924 enum ast_pbx_result res; 13925 13926 res = ast_pbx_start(c); 13927 13928 switch(res) { 13929 case AST_PBX_FAILED: 13930 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 13931 p->invitestate = INV_COMPLETED; 13932 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13933 transmit_response(p, "503 Unavailable", req); 13934 else 13935 transmit_response_reliable(p, "503 Unavailable", req); 13936 break; 13937 case AST_PBX_CALL_LIMIT: 13938 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 13939 p->invitestate = INV_COMPLETED; 13940 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13941 transmit_response(p, "480 Temporarily Unavailable", req); 13942 else 13943 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 13944 break; 13945 case AST_PBX_SUCCESS: 13946 /* nothing to do */ 13947 break; 13948 } 13949 13950 if (res) { 13951 13952 /* Unlock locks so ast_hangup can do its magic */ 13953 ast_mutex_unlock(&c->lock); 13954 ast_mutex_unlock(&p->lock); 13955 ast_hangup(c); 13956 ast_mutex_lock(&p->lock); 13957 c = NULL; 13958 } 13959 } else { /* Pickup call in call group */ 13960 ast_channel_unlock(c); 13961 *nounlock = 1; 13962 if (ast_pickup_call(c)) { 13963 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 13964 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13965 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 13966 else 13967 transmit_response_reliable(p, "503 Unavailable", req); 13968 sip_alreadygone(p); 13969 /* Unlock locks so ast_hangup can do its magic */ 13970 ast_mutex_unlock(&p->lock); 13971 c->hangupcause = AST_CAUSE_CALL_REJECTED; 13972 } else { 13973 ast_mutex_unlock(&p->lock); 13974 ast_setstate(c, AST_STATE_DOWN); 13975 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13976 } 13977 p->invitestate = INV_COMPLETED; 13978 ast_hangup(c); 13979 ast_mutex_lock(&p->lock); 13980 c = NULL; 13981 } 13982 break; 13983 case AST_STATE_RING: 13984 transmit_response(p, "100 Trying", req); 13985 p->invitestate = INV_PROCEEDING; 13986 break; 13987 case AST_STATE_RINGING: 13988 transmit_response(p, "180 Ringing", req); 13989 p->invitestate = INV_PROCEEDING; 13990 break; 13991 case AST_STATE_UP: 13992 if (option_debug > 1) 13993 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 13994 13995 transmit_response(p, "100 Trying", req); 13996 13997 if (p->t38.state == T38_PEER_REINVITE) { 13998 struct ast_channel *bridgepeer = NULL; 13999 struct sip_pvt *bridgepvt = NULL; 14000 14001 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14002 /* 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*/ 14003 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14004 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14005 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14006 if (bridgepvt->t38.state == T38_DISABLED) { 14007 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14008 /* Send re-invite to the bridged channel */ 14009 sip_handle_t38_reinvite(bridgepeer, p, 1); 14010 } else { /* Something is wrong with peers udptl struct */ 14011 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14012 ast_mutex_lock(&bridgepvt->lock); 14013 bridgepvt->t38.state = T38_DISABLED; 14014 ast_mutex_unlock(&bridgepvt->lock); 14015 if (option_debug > 1) 14016 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14017 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14018 transmit_response(p, "488 Not acceptable here", req); 14019 else 14020 transmit_response_reliable(p, "488 Not acceptable here", req); 14021 14022 } 14023 } else { 14024 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14025 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14026 p->t38.state = T38_ENABLED; 14027 if (option_debug) 14028 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14029 } 14030 } else { 14031 /* Other side is not a SIP channel */ 14032 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14033 transmit_response(p, "488 Not acceptable here", req); 14034 else 14035 transmit_response_reliable(p, "488 Not acceptable here", req); 14036 p->t38.state = T38_DISABLED; 14037 if (option_debug > 1) 14038 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14039 14040 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14041 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14042 } 14043 } else { 14044 /* we are not bridged in a call */ 14045 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14046 p->t38.state = T38_ENABLED; 14047 if (option_debug) 14048 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14049 } 14050 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14051 int sendok = TRUE; 14052 14053 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14054 /* so handle it here (re-invite other party to RTP) */ 14055 struct ast_channel *bridgepeer = NULL; 14056 struct sip_pvt *bridgepvt = NULL; 14057 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14058 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14059 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14060 /* Does the bridged peer have T38 ? */ 14061 if (bridgepvt->t38.state == T38_ENABLED) { 14062 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14063 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14064 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14065 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14066 else 14067 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14068 sendok = FALSE; 14069 } 14070 /* No bridged peer with T38 enabled*/ 14071 } 14072 } 14073 /* Respond to normal re-invite */ 14074 if (sendok) 14075 /* If this is not a re-invite or something to ignore - it's critical */ 14076 transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ? XMIT_UNRELIABLE : XMIT_CRITICAL); 14077 } 14078 p->invitestate = INV_TERMINATED; 14079 break; 14080 default: 14081 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14082 transmit_response(p, "100 Trying", req); 14083 break; 14084 } 14085 } else { 14086 if (p && (p->autokillid == -1)) { 14087 const char *msg; 14088 14089 if (!p->jointcapability) 14090 msg = "488 Not Acceptable Here (codec error)"; 14091 else { 14092 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14093 msg = "503 Unavailable"; 14094 } 14095 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14096 transmit_response(p, msg, req); 14097 else 14098 transmit_response_reliable(p, msg, req); 14099 p->invitestate = INV_COMPLETED; 14100 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14101 } 14102 } 14103 return res; 14104 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14724 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().
14725 { 14726 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14727 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14728 ast_verbose("Receiving message!\n"); 14729 receive_message(p, req); 14730 } else 14731 transmit_response(p, "202 Accepted", req); 14732 return 1; 14733 }
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 13254 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().
13255 { 13256 /* This is mostly a skeleton for future improvements */ 13257 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13258 int res = 0; 13259 const char *event = get_header(req, "Event"); 13260 char *eventid = NULL; 13261 char *sep; 13262 13263 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13264 *sep++ = '\0'; 13265 eventid = sep; 13266 } 13267 13268 if (option_debug > 1 && sipdebug) 13269 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13270 13271 if (strcmp(event, "refer")) { 13272 /* We don't understand this event. */ 13273 /* Here's room to implement incoming voicemail notifications :-) */ 13274 transmit_response(p, "489 Bad event", req); 13275 res = -1; 13276 } else { 13277 /* Save nesting depth for now, since there might be other events we will 13278 support in the future */ 13279 13280 /* Handle REFER notifications */ 13281 13282 char buf[1024]; 13283 char *cmd, *code; 13284 int respcode; 13285 int success = TRUE; 13286 13287 /* EventID for each transfer... EventID is basically the REFER cseq 13288 13289 We are getting notifications on a call that we transfered 13290 We should hangup when we are getting a 200 OK in a sipfrag 13291 Check if we have an owner of this event */ 13292 13293 /* Check the content type */ 13294 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13295 /* We need a sipfrag */ 13296 transmit_response(p, "400 Bad request", req); 13297 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13298 return -1; 13299 } 13300 13301 /* Get the text of the attachment */ 13302 if (get_msg_text(buf, sizeof(buf), req)) { 13303 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13304 transmit_response(p, "400 Bad request", req); 13305 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13306 return -1; 13307 } 13308 13309 /* 13310 From the RFC... 13311 A minimal, but complete, implementation can respond with a single 13312 NOTIFY containing either the body: 13313 SIP/2.0 100 Trying 13314 13315 if the subscription is pending, the body: 13316 SIP/2.0 200 OK 13317 if the reference was successful, the body: 13318 SIP/2.0 503 Service Unavailable 13319 if the reference failed, or the body: 13320 SIP/2.0 603 Declined 13321 13322 if the REFER request was accepted before approval to follow the 13323 reference could be obtained and that approval was subsequently denied 13324 (see Section 2.4.7). 13325 13326 If there are several REFERs in the same dialog, we need to 13327 match the ID of the event header... 13328 */ 13329 if (option_debug > 2) 13330 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13331 cmd = ast_skip_blanks(buf); 13332 code = cmd; 13333 /* We are at SIP/2.0 */ 13334 while(*code && (*code > 32)) { /* Search white space */ 13335 code++; 13336 } 13337 *code++ = '\0'; 13338 code = ast_skip_blanks(code); 13339 sep = code; 13340 sep++; 13341 while(*sep && (*sep > 32)) { /* Search white space */ 13342 sep++; 13343 } 13344 *sep++ = '\0'; /* Response string */ 13345 respcode = atoi(code); 13346 switch (respcode) { 13347 case 100: /* Trying: */ 13348 case 101: /* dialog establishment */ 13349 /* Don't do anything yet */ 13350 break; 13351 case 183: /* Ringing: */ 13352 /* Don't do anything yet */ 13353 break; 13354 case 200: /* OK: The new call is up, hangup this call */ 13355 /* Hangup the call that we are replacing */ 13356 break; 13357 case 301: /* Moved permenantly */ 13358 case 302: /* Moved temporarily */ 13359 /* Do we get the header in the packet in this case? */ 13360 success = FALSE; 13361 break; 13362 case 503: /* Service Unavailable: The new call failed */ 13363 /* Cancel transfer, continue the call */ 13364 success = FALSE; 13365 break; 13366 case 603: /* Declined: Not accepted */ 13367 /* Cancel transfer, continue the current call */ 13368 success = FALSE; 13369 break; 13370 } 13371 if (!success) { 13372 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13373 } 13374 13375 /* Confirm that we received this packet */ 13376 transmit_response(p, "200 OK", req); 13377 }; 13378 13379 if (!p->lastinvite) 13380 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13381 13382 return res; 13383 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13386 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().
13387 { 13388 int res; 13389 13390 res = get_destination(p, req); 13391 build_contact(p); 13392 13393 /* XXX Should we authenticate OPTIONS? XXX */ 13394 13395 if (ast_strlen_zero(p->context)) 13396 ast_string_field_set(p, context, default_context); 13397 13398 if (ast_shutting_down()) 13399 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13400 else if (res < 0) 13401 transmit_response_with_allow(p, "404 Not Found", req, 0); 13402 else 13403 transmit_response_with_allow(p, "200 OK", req, 0); 13404 13405 /* Destroy if this OPTIONS was the opening request, but not if 13406 it's in the middle of a normal call flow. */ 13407 if (!p->lastinvite) 13408 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13409 13410 return res; 13411 }
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 14272 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().
14273 { 14274 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14275 /* Chan2: Call between asterisk and transferee */ 14276 14277 int res = 0; 14278 14279 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14280 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"); 14281 14282 if (!p->owner) { 14283 /* This is a REFER outside of an existing SIP dialog */ 14284 /* We can't handle that, so decline it */ 14285 if (option_debug > 2) 14286 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14287 transmit_response(p, "603 Declined (No dialog)", req); 14288 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14289 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14290 sip_alreadygone(p); 14291 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14292 } 14293 return 0; 14294 } 14295 14296 14297 /* Check if transfer is allowed from this device */ 14298 if (p->allowtransfer == TRANSFER_CLOSED ) { 14299 /* Transfer not allowed, decline */ 14300 transmit_response(p, "603 Declined (policy)", req); 14301 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14302 /* Do not destroy SIP session */ 14303 return 0; 14304 } 14305 14306 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14307 /* Already have a pending REFER */ 14308 transmit_response(p, "491 Request pending", req); 14309 append_history(p, "Xfer", "Refer failed. Request pending."); 14310 return 0; 14311 } 14312 14313 /* Allocate memory for call transfer data */ 14314 if (!p->refer && !sip_refer_allocate(p)) { 14315 transmit_response(p, "500 Internal Server Error", req); 14316 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14317 return -3; 14318 } 14319 14320 res = get_refer_info(p, req); /* Extract headers */ 14321 14322 p->refer->status = REFER_SENT; 14323 14324 if (res != 0) { 14325 switch (res) { 14326 case -2: /* Syntax error */ 14327 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14328 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14329 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14330 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14331 break; 14332 case -3: 14333 transmit_response(p, "603 Declined (Non sip: uri)", req); 14334 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14335 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14336 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14337 break; 14338 default: 14339 /* Refer-to extension not found, fake a failed transfer */ 14340 transmit_response(p, "202 Accepted", req); 14341 append_history(p, "Xfer", "Refer failed. Bad extension."); 14342 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14343 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14344 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14345 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14346 break; 14347 } 14348 return 0; 14349 } 14350 if (ast_strlen_zero(p->context)) 14351 ast_string_field_set(p, context, default_context); 14352 14353 /* If we do not support SIP domains, all transfers are local */ 14354 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14355 p->refer->localtransfer = 1; 14356 if (sipdebug && option_debug > 2) 14357 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14358 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14359 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14360 p->refer->localtransfer = 1; 14361 } else if (sipdebug && option_debug > 2) 14362 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14363 14364 /* Is this a repeat of a current request? Ignore it */ 14365 /* Don't know what else to do right now. */ 14366 if (ignore) 14367 return res; 14368 14369 /* If this is a blind transfer, we have the following 14370 channels to work with: 14371 - chan1, chan2: The current call between transferer and transferee (2 channels) 14372 - target_channel: A new call from the transferee to the target (1 channel) 14373 We need to stay tuned to what happens in order to be able 14374 to bring back the call to the transferer */ 14375 14376 /* If this is a attended transfer, we should have all call legs within reach: 14377 - chan1, chan2: The call between the transferer and transferee (2 channels) 14378 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14379 We want to bridge chan2 with targetcall_pvt! 14380 14381 The replaces call id in the refer message points 14382 to the call leg between Asterisk and the transferer. 14383 So we need to connect the target and the transferee channel 14384 and hangup the two other channels silently 14385 14386 If the target is non-local, the call ID could be on a remote 14387 machine and we need to send an INVITE with replaces to the 14388 target. We basically handle this as a blind transfer 14389 and let the sip_call function catch that we need replaces 14390 header in the INVITE. 14391 */ 14392 14393 14394 /* Get the transferer's channel */ 14395 current.chan1 = p->owner; 14396 14397 /* Find the other part of the bridge (2) - transferee */ 14398 current.chan2 = ast_bridged_channel(current.chan1); 14399 14400 if (sipdebug && option_debug > 2) 14401 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>"); 14402 14403 if (!current.chan2 && !p->refer->attendedtransfer) { 14404 /* No bridged channel, propably IVR or echo or similar... */ 14405 /* Guess we should masquerade or something here */ 14406 /* Until we figure it out, refuse transfer of such calls */ 14407 if (sipdebug && option_debug > 2) 14408 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14409 p->refer->status = REFER_FAILED; 14410 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14411 transmit_response(p, "603 Declined", req); 14412 return -1; 14413 } 14414 14415 if (current.chan2) { 14416 if (sipdebug && option_debug > 3) 14417 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14418 14419 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14420 } 14421 14422 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14423 14424 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14425 if (p->refer->attendedtransfer) { 14426 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14427 return res; /* We're done with the transfer */ 14428 /* Fall through for remote transfers that we did not find locally */ 14429 if (sipdebug && option_debug > 3) 14430 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14431 /* Fallthrough if we can't find the call leg internally */ 14432 } 14433 14434 14435 /* Parking a call */ 14436 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14437 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14438 *nounlock = 1; 14439 ast_channel_unlock(current.chan1); 14440 copy_request(¤t.req, req); 14441 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14442 p->refer->status = REFER_200OK; 14443 append_history(p, "Xfer", "REFER to call parking."); 14444 if (sipdebug && option_debug > 3) 14445 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14446 sip_park(current.chan2, current.chan1, req, seqno); 14447 return res; 14448 } 14449 14450 /* Blind transfers and remote attended xfers */ 14451 transmit_response(p, "202 Accepted", req); 14452 14453 if (current.chan1 && current.chan2) { 14454 if (option_debug > 2) 14455 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14456 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14457 } 14458 if (current.chan2) { 14459 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14460 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14461 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14462 /* One for the new channel */ 14463 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14464 /* Attended transfer to remote host, prepare headers for the INVITE */ 14465 if (p->refer->referred_by) 14466 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14467 } 14468 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14469 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14470 char tempheader[BUFSIZ]; 14471 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14472 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14473 p->refer->replaces_callid_totag, 14474 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14475 p->refer->replaces_callid_fromtag); 14476 if (current.chan2) 14477 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14478 } 14479 /* Must release lock now, because it will not longer 14480 be accessible after the transfer! */ 14481 *nounlock = 1; 14482 ast_channel_unlock(current.chan1); 14483 14484 /* Connect the call */ 14485 14486 /* FAKE ringing if not attended transfer */ 14487 if (!p->refer->attendedtransfer) 14488 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14489 14490 /* For blind transfer, this will lead to a new call */ 14491 /* For attended transfer to remote host, this will lead to 14492 a new SIP call with a replaces header, if the dial plan allows it 14493 */ 14494 if (!current.chan2) { 14495 /* We have no bridge, so we're talking with Asterisk somehow */ 14496 /* We need to masquerade this call */ 14497 /* What to do to fix this situation: 14498 * Set up the new call in a new channel 14499 * Let the new channel masq into this channel 14500 Please add that code here :-) 14501 */ 14502 p->refer->status = REFER_FAILED; 14503 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14504 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14505 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14506 return -1; 14507 } 14508 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14509 14510 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14511 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14512 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14513 14514 if (!res) { 14515 /* Success - we have a new channel */ 14516 if (option_debug > 2) 14517 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14518 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14519 if (p->refer->localtransfer) 14520 p->refer->status = REFER_200OK; 14521 if (p->owner) 14522 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14523 append_history(p, "Xfer", "Refer succeeded."); 14524 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14525 /* Do not hangup call, the other side do that when we say 200 OK */ 14526 /* We could possibly implement a timer here, auto congestion */ 14527 res = 0; 14528 } else { 14529 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14530 if (option_debug > 2) 14531 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14532 append_history(p, "Xfer", "Refer failed."); 14533 /* Failure of some kind */ 14534 p->refer->status = REFER_FAILED; 14535 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14536 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14537 res = -1; 14538 } 14539 return res; 14540 }
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 15020 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().
15021 { 15022 enum check_auth_result res; 15023 15024 /* Use this as the basis */ 15025 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15026 ast_verbose("Using latest REGISTER request as basis request\n"); 15027 copy_request(&p->initreq, req); 15028 check_via(p, req); 15029 if ((res = register_verify(p, sin, req, e)) < 0) { 15030 const char *reason; 15031 15032 switch (res) { 15033 case AUTH_SECRET_FAILED: 15034 reason = "Wrong password"; 15035 break; 15036 case AUTH_USERNAME_MISMATCH: 15037 reason = "Username/auth name mismatch"; 15038 break; 15039 case AUTH_NOT_FOUND: 15040 reason = "No matching peer found"; 15041 break; 15042 case AUTH_UNKNOWN_DOMAIN: 15043 reason = "Not a local domain"; 15044 break; 15045 case AUTH_PEER_NOT_DYNAMIC: 15046 reason = "Peer is not supposed to register"; 15047 break; 15048 case AUTH_ACL_FAILED: 15049 reason = "Device does not match ACL"; 15050 break; 15051 default: 15052 reason = "Unknown failure"; 15053 break; 15054 } 15055 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15056 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15057 reason); 15058 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15059 } else 15060 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15061 15062 if (res < 1) { 15063 /* Destroy the session, but keep us around for just a bit in case they don't 15064 get our 200 OK */ 15065 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15066 } 15067 return res; 15068 }
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 14736 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(), and XPIDF_XML.
Referenced by handle_request().
14737 { 14738 int gotdest; 14739 int res = 0; 14740 int firststate = AST_EXTENSION_REMOVED; 14741 struct sip_peer *authpeer = NULL; 14742 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14743 const char *accept = get_header(req, "Accept"); 14744 int resubscribe = (p->subscribed != NONE); 14745 char *temp, *event; 14746 14747 if (p->initreq.headers) { 14748 /* We already have a dialog */ 14749 if (p->initreq.method != SIP_SUBSCRIBE) { 14750 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14751 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14752 transmit_response(p, "403 Forbidden (within dialog)", req); 14753 /* Do not destroy session, since we will break the call if we do */ 14754 if (option_debug) 14755 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); 14756 return 0; 14757 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14758 if (option_debug) { 14759 if (resubscribe) 14760 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14761 else 14762 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14763 } 14764 } 14765 } 14766 14767 /* Check if we have a global disallow setting on subscriptions. 14768 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14769 */ 14770 if (!global_allowsubscribe) { 14771 transmit_response(p, "403 Forbidden (policy)", req); 14772 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14773 return 0; 14774 } 14775 14776 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14777 /* Use this as the basis */ 14778 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14779 ast_verbose("Creating new subscription\n"); 14780 14781 copy_request(&p->initreq, req); 14782 check_via(p, req); 14783 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14784 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14785 14786 /* Find parameters to Event: header value and remove them for now */ 14787 if (ast_strlen_zero(eventheader)) { 14788 transmit_response(p, "489 Bad Event", req); 14789 if (option_debug > 1) 14790 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14791 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14792 return 0; 14793 } 14794 14795 if ( (strchr(eventheader, ';'))) { 14796 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14797 temp = strchr(event, ';'); 14798 *temp = '\0'; /* Remove any options for now */ 14799 /* We might need to use them later :-) */ 14800 } else 14801 event = (char *) eventheader; /* XXX is this legal ? */ 14802 14803 /* Handle authentication */ 14804 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14805 /* if an authentication response was sent, we are done here */ 14806 if (res == AUTH_CHALLENGE_SENT) { 14807 if (authpeer) 14808 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14809 return 0; 14810 } 14811 if (res < 0) { 14812 if (res == AUTH_FAKE_AUTH) { 14813 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14814 transmit_fake_auth_response(p, req, 1); 14815 } else { 14816 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14817 transmit_response_reliable(p, "403 Forbidden", req); 14818 } 14819 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14820 if (authpeer) 14821 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14822 return 0; 14823 } 14824 14825 /* Check if this user/peer is allowed to subscribe at all */ 14826 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14827 transmit_response(p, "403 Forbidden (policy)", req); 14828 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14829 if (authpeer) 14830 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14831 return 0; 14832 } 14833 14834 /* Get destination right away */ 14835 gotdest = get_destination(p, NULL); 14836 14837 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14838 parse_ok_contact(p, req); 14839 14840 build_contact(p); 14841 if (gotdest) { 14842 transmit_response(p, "404 Not Found", req); 14843 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14844 if (authpeer) 14845 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14846 return 0; 14847 } 14848 14849 /* Initialize tag for new subscriptions */ 14850 if (ast_strlen_zero(p->tag)) 14851 make_our_tag(p->tag, sizeof(p->tag)); 14852 14853 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14854 if (authpeer) /* No need for authpeer here */ 14855 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14856 14857 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14858 /* Polycom phones only handle xpidf+xml, even if they say they can 14859 handle pidf+xml as well 14860 */ 14861 if (strstr(p->useragent, "Polycom")) { 14862 p->subscribed = XPIDF_XML; 14863 } else if (strstr(accept, "application/pidf+xml")) { 14864 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14865 } else if (strstr(accept, "application/dialog-info+xml")) { 14866 p->subscribed = DIALOG_INFO_XML; 14867 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14868 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14869 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14870 } else if (strstr(accept, "application/xpidf+xml")) { 14871 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14872 } else if (ast_strlen_zero(accept)) { 14873 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14874 transmit_response(p, "489 Bad Event", req); 14875 14876 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14877 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14878 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14879 return 0; 14880 } 14881 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14882 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14883 } else { 14884 /* Can't find a format for events that we know about */ 14885 char mybuf[200]; 14886 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14887 transmit_response(p, mybuf, req); 14888 14889 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14890 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14891 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14892 return 0; 14893 } 14894 } else if (!strcmp(event, "message-summary")) { 14895 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14896 /* Format requested that we do not support */ 14897 transmit_response(p, "406 Not Acceptable", req); 14898 if (option_debug > 1) 14899 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 14900 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14901 if (authpeer) /* No need for authpeer here */ 14902 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14903 return 0; 14904 } 14905 /* Looks like they actually want a mailbox status 14906 This version of Asterisk supports mailbox subscriptions 14907 The subscribed URI needs to exist in the dial plan 14908 In most devices, this is configurable to the voicemailmain extension you use 14909 */ 14910 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 14911 transmit_response(p, "404 Not found (no mailbox)", req); 14912 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14913 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 14914 if (authpeer) /* No need for authpeer here */ 14915 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14916 return 0; 14917 } 14918 14919 p->subscribed = MWI_NOTIFICATION; 14920 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 14921 /* We only allow one subscription per peer */ 14922 sip_destroy(authpeer->mwipvt); 14923 authpeer->mwipvt = p; /* Link from peer to pvt */ 14924 p->relatedpeer = authpeer; /* Link from pvt to peer */ 14925 } else { /* At this point, Asterisk does not understand the specified event */ 14926 transmit_response(p, "489 Bad Event", req); 14927 if (option_debug > 1) 14928 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 14929 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14930 if (authpeer) /* No need for authpeer here */ 14931 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14932 return 0; 14933 } 14934 14935 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 14936 if (p->stateid > -1) 14937 ast_extension_state_del(p->stateid, cb_extensionstate); 14938 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 14939 } 14940 14941 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14942 p->lastinvite = seqno; 14943 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 14944 p->expiry = atoi(get_header(req, "Expires")); 14945 14946 /* check if the requested expiry-time is within the approved limits from sip.conf */ 14947 if (p->expiry > max_expiry) 14948 p->expiry = max_expiry; 14949 if (p->expiry < min_expiry && p->expiry > 0) 14950 p->expiry = min_expiry; 14951 14952 if (sipdebug || option_debug > 1) { 14953 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 14954 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 14955 else 14956 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 14957 } 14958 if (p->autokillid > -1) 14959 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 14960 if (p->expiry > 0) 14961 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 14962 14963 if (p->subscribed == MWI_NOTIFICATION) { 14964 transmit_response(p, "200 OK", req); 14965 if (p->relatedpeer) { /* Send first notification */ 14966 ASTOBJ_WRLOCK(p->relatedpeer); 14967 sip_send_mwi_to_peer(p->relatedpeer); 14968 ASTOBJ_UNLOCK(p->relatedpeer); 14969 } 14970 } else { 14971 struct sip_pvt *p_old; 14972 14973 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 14974 14975 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)); 14976 transmit_response(p, "404 Not found", req); 14977 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14978 return 0; 14979 } 14980 14981 transmit_response(p, "200 OK", req); 14982 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 14983 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 14984 /* hide the 'complete' exten/context in the refer_to field for later display */ 14985 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 14986 14987 /* remove any old subscription from this peer for the same exten/context, 14988 as the peer has obviously forgotten about it and it's wasteful to wait 14989 for it to expire and send NOTIFY messages to the peer only to have them 14990 ignored (or generate errors) 14991 */ 14992 ast_mutex_lock(&iflock); 14993 for (p_old = iflist; p_old; p_old = p_old->next) { 14994 if (p_old == p) 14995 continue; 14996 if (p_old->initreq.method != SIP_SUBSCRIBE) 14997 continue; 14998 if (p_old->subscribed == NONE) 14999 continue; 15000 ast_mutex_lock(&p_old->lock); 15001 if (!strcmp(p_old->username, p->username)) { 15002 if (!strcmp(p_old->exten, p->exten) && 15003 !strcmp(p_old->context, p->context)) { 15004 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15005 ast_mutex_unlock(&p_old->lock); 15006 break; 15007 } 15008 } 15009 ast_mutex_unlock(&p_old->lock); 15010 } 15011 ast_mutex_unlock(&iflock); 15012 } 15013 if (!p->expiry) 15014 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15015 } 15016 return 1; 15017 }
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 12555 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.
12556 { 12557 struct ast_channel *owner; 12558 int sipmethod; 12559 int res = 1; 12560 const char *c = get_header(req, "Cseq"); 12561 const char *msg = strchr(c, ' '); 12562 12563 if (!msg) 12564 msg = ""; 12565 else 12566 msg++; 12567 sipmethod = find_sip_method(msg); 12568 12569 owner = p->owner; 12570 if (owner) 12571 owner->hangupcause = hangup_sip2cause(resp); 12572 12573 /* Acknowledge whatever it is destined for */ 12574 if ((resp >= 100) && (resp <= 199)) 12575 __sip_semi_ack(p, seqno, 0, sipmethod); 12576 else 12577 __sip_ack(p, seqno, 0, sipmethod); 12578 12579 /* Get their tag if we haven't already */ 12580 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12581 char tag[128]; 12582 12583 gettag(req, "To", tag, sizeof(tag)); 12584 ast_string_field_set(p, theirtag, tag); 12585 } 12586 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12587 /* We don't really care what the response is, just that it replied back. 12588 Well, as long as it's not a 100 response... since we might 12589 need to hang around for something more "definitive" */ 12590 if (resp != 100) 12591 handle_response_peerpoke(p, resp, req); 12592 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12593 switch(resp) { 12594 case 100: /* 100 Trying */ 12595 case 101: /* 101 Dialog establishment */ 12596 if (sipmethod == SIP_INVITE) 12597 handle_response_invite(p, resp, rest, req, seqno); 12598 break; 12599 case 183: /* 183 Session Progress */ 12600 if (sipmethod == SIP_INVITE) 12601 handle_response_invite(p, resp, rest, req, seqno); 12602 break; 12603 case 180: /* 180 Ringing */ 12604 if (sipmethod == SIP_INVITE) 12605 handle_response_invite(p, resp, rest, req, seqno); 12606 break; 12607 case 182: /* 182 Queued */ 12608 if (sipmethod == SIP_INVITE) 12609 handle_response_invite(p, resp, rest, req, seqno); 12610 break; 12611 case 200: /* 200 OK */ 12612 p->authtries = 0; /* Reset authentication counter */ 12613 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12614 /* We successfully transmitted a message 12615 or a video update request in INFO */ 12616 /* Nothing happens here - the message is inside a dialog */ 12617 } else if (sipmethod == SIP_INVITE) { 12618 handle_response_invite(p, resp, rest, req, seqno); 12619 } else if (sipmethod == SIP_NOTIFY) { 12620 /* They got the notify, this is the end */ 12621 if (p->owner) { 12622 if (!p->refer) { 12623 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12624 ast_queue_hangup(p->owner); 12625 } else if (option_debug > 3) 12626 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12627 } else { 12628 if (p->subscribed == NONE) 12629 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12630 } 12631 } else if (sipmethod == SIP_REGISTER) 12632 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12633 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12634 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12635 break; 12636 case 202: /* Transfer accepted */ 12637 if (sipmethod == SIP_REFER) 12638 handle_response_refer(p, resp, rest, req, seqno); 12639 break; 12640 case 401: /* Not www-authorized on SIP method */ 12641 if (sipmethod == SIP_INVITE) 12642 handle_response_invite(p, resp, rest, req, seqno); 12643 else if (sipmethod == SIP_REFER) 12644 handle_response_refer(p, resp, rest, req, seqno); 12645 else if (p->registry && sipmethod == SIP_REGISTER) 12646 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12647 else if (sipmethod == SIP_BYE) { 12648 if (ast_strlen_zero(p->authname)) { 12649 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12650 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12651 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12652 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12653 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12654 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12655 /* We fail to auth bye on our own call, but still needs to tear down the call. 12656 Life, they call it. */ 12657 } 12658 } else { 12659 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12660 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12661 } 12662 break; 12663 case 403: /* Forbidden - we failed authentication */ 12664 if (sipmethod == SIP_INVITE) 12665 handle_response_invite(p, resp, rest, req, seqno); 12666 else if (p->registry && sipmethod == SIP_REGISTER) 12667 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12668 else { 12669 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12670 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12671 } 12672 break; 12673 case 404: /* Not found */ 12674 if (p->registry && sipmethod == SIP_REGISTER) 12675 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12676 else if (sipmethod == SIP_INVITE) 12677 handle_response_invite(p, resp, rest, req, seqno); 12678 else if (owner) 12679 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12680 break; 12681 case 407: /* Proxy auth required */ 12682 if (sipmethod == SIP_INVITE) 12683 handle_response_invite(p, resp, rest, req, seqno); 12684 else if (sipmethod == SIP_REFER) 12685 handle_response_refer(p, resp, rest, req, seqno); 12686 else if (p->registry && sipmethod == SIP_REGISTER) 12687 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12688 else if (sipmethod == SIP_BYE) { 12689 if (ast_strlen_zero(p->authname)) { 12690 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12691 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12692 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12693 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12694 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12695 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12696 } 12697 } else /* We can't handle this, giving up in a bad way */ 12698 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12699 12700 break; 12701 case 408: /* Request timeout - terminate dialog */ 12702 if (sipmethod == SIP_INVITE) 12703 handle_response_invite(p, resp, rest, req, seqno); 12704 else if (sipmethod == SIP_REGISTER) 12705 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12706 else if (sipmethod == SIP_BYE) { 12707 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12708 if (option_debug) 12709 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12710 } else { 12711 if (owner) 12712 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12713 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12714 } 12715 break; 12716 case 481: /* Call leg does not exist */ 12717 if (sipmethod == SIP_INVITE) { 12718 handle_response_invite(p, resp, rest, req, seqno); 12719 } else if (sipmethod == SIP_REFER) { 12720 handle_response_refer(p, resp, rest, req, seqno); 12721 } else if (sipmethod == SIP_BYE) { 12722 /* The other side has no transaction to bye, 12723 just assume it's all right then */ 12724 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12725 } else if (sipmethod == SIP_CANCEL) { 12726 /* The other side has no transaction to cancel, 12727 just assume it's all right then */ 12728 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12729 } else { 12730 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12731 /* Guessing that this is not an important request */ 12732 } 12733 break; 12734 case 487: 12735 if (sipmethod == SIP_INVITE) 12736 handle_response_invite(p, resp, rest, req, seqno); 12737 break; 12738 case 488: /* Not acceptable here - codec error */ 12739 if (sipmethod == SIP_INVITE) 12740 handle_response_invite(p, resp, rest, req, seqno); 12741 break; 12742 case 491: /* Pending */ 12743 if (sipmethod == SIP_INVITE) 12744 handle_response_invite(p, resp, rest, req, seqno); 12745 else { 12746 if (option_debug) 12747 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12748 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12749 } 12750 break; 12751 case 501: /* Not Implemented */ 12752 if (sipmethod == SIP_INVITE) 12753 handle_response_invite(p, resp, rest, req, seqno); 12754 else if (sipmethod == SIP_REFER) 12755 handle_response_refer(p, resp, rest, req, seqno); 12756 else 12757 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12758 break; 12759 case 603: /* Declined transfer */ 12760 if (sipmethod == SIP_REFER) { 12761 handle_response_refer(p, resp, rest, req, seqno); 12762 break; 12763 } 12764 /* Fallthrough */ 12765 default: 12766 if ((resp >= 300) && (resp < 700)) { 12767 /* Fatal response */ 12768 if ((option_verbose > 2) && (resp != 487)) 12769 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12770 12771 if (sipmethod == SIP_INVITE) 12772 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12773 12774 /* XXX Locking issues?? XXX */ 12775 switch(resp) { 12776 case 300: /* Multiple Choices */ 12777 case 301: /* Moved permenantly */ 12778 case 302: /* Moved temporarily */ 12779 case 305: /* Use Proxy */ 12780 parse_moved_contact(p, req); 12781 /* Fall through */ 12782 case 486: /* Busy here */ 12783 case 600: /* Busy everywhere */ 12784 case 603: /* Decline */ 12785 if (p->owner) 12786 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12787 break; 12788 case 482: /* 12789 \note SIP is incapable of performing a hairpin call, which 12790 is yet another failure of not having a layer 2 (again, YAY 12791 IETF for thinking ahead). So we treat this as a call 12792 forward and hope we end up at the right place... */ 12793 if (option_debug) 12794 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12795 if (p->owner) 12796 ast_string_field_build(p->owner, call_forward, 12797 "Local/%s@%s", p->username, p->context); 12798 /* Fall through */ 12799 case 480: /* Temporarily Unavailable */ 12800 case 404: /* Not Found */ 12801 case 410: /* Gone */ 12802 case 400: /* Bad Request */ 12803 case 500: /* Server error */ 12804 if (sipmethod == SIP_REFER) { 12805 handle_response_refer(p, resp, rest, req, seqno); 12806 break; 12807 } 12808 /* Fall through */ 12809 case 503: /* Service Unavailable */ 12810 case 504: /* Server Timeout */ 12811 if (owner) 12812 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12813 break; 12814 default: 12815 /* Send hangup */ 12816 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12817 ast_queue_hangup(p->owner); 12818 break; 12819 } 12820 /* ACK on invite */ 12821 if (sipmethod == SIP_INVITE) 12822 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12823 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12824 sip_alreadygone(p); 12825 if (!p->owner) 12826 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12827 } else if ((resp >= 100) && (resp < 200)) { 12828 if (sipmethod == SIP_INVITE) { 12829 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12830 sip_cancel_destroy(p); 12831 if (find_sdp(req)) 12832 process_sdp(p, req); 12833 if (p->owner) { 12834 /* Queue a progress frame */ 12835 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12836 } 12837 } 12838 } else 12839 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)); 12840 } 12841 } else { 12842 /* Responses to OUTGOING SIP requests on INCOMING calls 12843 get handled here. As well as out-of-call message responses */ 12844 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12845 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12846 12847 if (sipmethod == SIP_INVITE && resp == 200) { 12848 /* Tags in early session is replaced by the tag in 200 OK, which is 12849 the final reply to our INVITE */ 12850 char tag[128]; 12851 12852 gettag(req, "To", tag, sizeof(tag)); 12853 ast_string_field_set(p, theirtag, tag); 12854 } 12855 12856 switch(resp) { 12857 case 200: 12858 if (sipmethod == SIP_INVITE) { 12859 handle_response_invite(p, resp, rest, req, seqno); 12860 } else if (sipmethod == SIP_CANCEL) { 12861 if (option_debug) 12862 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12863 12864 /* Wait for 487, then destroy */ 12865 } else if (sipmethod == SIP_NOTIFY) { 12866 /* They got the notify, this is the end */ 12867 if (p->owner) { 12868 if (p->refer) { 12869 if (option_debug) 12870 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12871 } else 12872 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12873 /* ast_queue_hangup(p->owner); Disabled */ 12874 } else { 12875 if (!p->subscribed && !p->refer) 12876 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12877 } 12878 } else if (sipmethod == SIP_BYE) 12879 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12880 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12881 /* We successfully transmitted a message or 12882 a video update request in INFO */ 12883 ; 12884 else if (sipmethod == SIP_BYE) 12885 /* Ok, we're ready to go */ 12886 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12887 break; 12888 case 202: /* Transfer accepted */ 12889 if (sipmethod == SIP_REFER) 12890 handle_response_refer(p, resp, rest, req, seqno); 12891 break; 12892 case 401: /* www-auth */ 12893 case 407: 12894 if (sipmethod == SIP_REFER) 12895 handle_response_refer(p, resp, rest, req, seqno); 12896 else if (sipmethod == SIP_INVITE) 12897 handle_response_invite(p, resp, rest, req, seqno); 12898 else if (sipmethod == SIP_BYE) { 12899 char *auth, *auth2; 12900 12901 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 12902 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 12903 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 12904 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12905 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12906 } 12907 } 12908 break; 12909 case 481: /* Call leg does not exist */ 12910 if (sipmethod == SIP_INVITE) { 12911 /* Re-invite failed */ 12912 handle_response_invite(p, resp, rest, req, seqno); 12913 } else if (sipmethod == SIP_BYE) { 12914 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12915 } else if (sipdebug) { 12916 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 12917 } 12918 break; 12919 case 501: /* Not Implemented */ 12920 if (sipmethod == SIP_INVITE) 12921 handle_response_invite(p, resp, rest, req, seqno); 12922 else if (sipmethod == SIP_REFER) 12923 handle_response_refer(p, resp, rest, req, seqno); 12924 break; 12925 case 603: /* Declined transfer */ 12926 if (sipmethod == SIP_REFER) { 12927 handle_response_refer(p, resp, rest, req, seqno); 12928 break; 12929 } 12930 /* Fallthrough */ 12931 default: /* Errors without handlers */ 12932 if ((resp >= 100) && (resp < 200)) { 12933 if (sipmethod == SIP_INVITE) { /* re-invite */ 12934 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12935 sip_cancel_destroy(p); 12936 } 12937 } 12938 if ((resp >= 300) && (resp < 700)) { 12939 if ((option_verbose > 2) && (resp != 487)) 12940 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)); 12941 switch(resp) { 12942 case 488: /* Not acceptable here - codec error */ 12943 case 603: /* Decline */ 12944 case 500: /* Server error */ 12945 case 503: /* Service Unavailable */ 12946 case 504: /* Server timeout */ 12947 12948 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 12949 sip_cancel_destroy(p); 12950 } 12951 break; 12952 } 12953 } 12954 break; 12955 } 12956 } 12957 }
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 11968 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().
11969 { 11970 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 11971 int res = 0; 11972 int xmitres = 0; 11973 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 11974 struct ast_channel *bridgepeer = NULL; 11975 11976 if (option_debug > 3) { 11977 if (reinvite) 11978 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 11979 else 11980 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 11981 } 11982 11983 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 11984 if (option_debug) 11985 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 11986 return; 11987 } 11988 11989 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 11990 if (p->initid > -1) { 11991 /* Don't auto congest anymore since we've gotten something useful back */ 11992 ast_sched_del(sched, p->initid); 11993 p->initid = -1; 11994 } 11995 11996 /* RFC3261 says we must treat every 1xx response (but not 100) 11997 that we don't recognize as if it was 183. 11998 */ 11999 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12000 resp = 183; 12001 12002 /* Any response between 100 and 199 is PROCEEDING */ 12003 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12004 p->invitestate = INV_PROCEEDING; 12005 12006 /* Final response, not 200 ? */ 12007 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12008 p->invitestate = INV_COMPLETED; 12009 12010 12011 switch (resp) { 12012 case 100: /* Trying */ 12013 case 101: /* Dialog establishment */ 12014 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12015 sip_cancel_destroy(p); 12016 check_pendings(p); 12017 break; 12018 12019 case 180: /* 180 Ringing */ 12020 case 182: /* 182 Queued */ 12021 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12022 sip_cancel_destroy(p); 12023 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12024 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12025 if (p->owner->_state != AST_STATE_UP) { 12026 ast_setstate(p->owner, AST_STATE_RINGING); 12027 } 12028 } 12029 if (find_sdp(req)) { 12030 p->invitestate = INV_EARLY_MEDIA; 12031 res = process_sdp(p, req); 12032 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12033 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12034 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12035 } 12036 } 12037 check_pendings(p); 12038 break; 12039 12040 case 183: /* Session progress */ 12041 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12042 sip_cancel_destroy(p); 12043 /* Ignore 183 Session progress without SDP */ 12044 if (find_sdp(req)) { 12045 p->invitestate = INV_EARLY_MEDIA; 12046 res = process_sdp(p, req); 12047 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12048 /* Queue a progress frame */ 12049 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12050 } 12051 } 12052 check_pendings(p); 12053 break; 12054 12055 case 200: /* 200 OK on invite - someone's answering our call */ 12056 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12057 sip_cancel_destroy(p); 12058 p->authtries = 0; 12059 if (find_sdp(req)) { 12060 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12061 if (!reinvite) 12062 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12063 /* For re-invites, we try to recover */ 12064 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12065 } 12066 12067 /* Parse contact header for continued conversation */ 12068 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12069 /* This is important when we have a SIP proxy between us and the phone */ 12070 if (outgoing) { 12071 update_call_counter(p, DEC_CALL_RINGING); 12072 parse_ok_contact(p, req); 12073 if(set_address_from_contact(p)) { 12074 /* Bad contact - we don't know how to reach this device */ 12075 /* We need to ACK, but then send a bye */ 12076 /* OEJ: Possible issue that may need a check: 12077 If we have a proxy route between us and the device, 12078 should we care about resolving the contact 12079 or should we just send it? 12080 */ 12081 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12082 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12083 } 12084 12085 /* Save Record-Route for any later requests we make on this dialogue */ 12086 build_route(p, req, 1); 12087 } 12088 12089 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12090 struct sip_pvt *bridgepvt = NULL; 12091 12092 if (!bridgepeer->tech) { 12093 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12094 break; 12095 } 12096 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12097 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12098 if (bridgepvt->udptl) { 12099 if (p->t38.state == T38_PEER_REINVITE) { 12100 sip_handle_t38_reinvite(bridgepeer, p, 0); 12101 ast_rtp_set_rtptimers_onhold(p->rtp); 12102 if (p->vrtp) 12103 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12104 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12105 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12106 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12107 /* XXXX Should we really destroy this session here, without any response at all??? */ 12108 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12109 } 12110 } else { 12111 if (option_debug > 1) 12112 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12113 ast_mutex_lock(&bridgepvt->lock); 12114 bridgepvt->t38.state = T38_DISABLED; 12115 ast_mutex_unlock(&bridgepvt->lock); 12116 if (option_debug) 12117 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12118 p->t38.state = T38_DISABLED; 12119 if (option_debug > 1) 12120 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12121 } 12122 } else { 12123 /* Other side is not a SIP channel */ 12124 if (option_debug > 1) 12125 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12126 p->t38.state = T38_DISABLED; 12127 if (option_debug > 1) 12128 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12129 } 12130 } 12131 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12132 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12133 p->t38.state = T38_ENABLED; 12134 if (option_debug) 12135 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12136 } 12137 12138 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12139 if (!reinvite) { 12140 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12141 } else { /* RE-invite */ 12142 ast_queue_frame(p->owner, &ast_null_frame); 12143 } 12144 } else { 12145 /* It's possible we're getting an 200 OK after we've tried to disconnect 12146 by sending CANCEL */ 12147 /* First send ACK, then send bye */ 12148 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12149 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12150 } 12151 /* If I understand this right, the branch is different for a non-200 ACK only */ 12152 p->invitestate = INV_TERMINATED; 12153 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12154 check_pendings(p); 12155 break; 12156 case 407: /* Proxy authentication */ 12157 case 401: /* Www auth */ 12158 /* First we ACK */ 12159 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12160 if (p->options) 12161 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12162 12163 /* Then we AUTH */ 12164 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12165 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12166 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12167 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12168 if (p->authtries < MAX_AUTHTRIES) 12169 p->invitestate = INV_CALLING; 12170 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12171 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12172 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12173 sip_alreadygone(p); 12174 if (p->owner) 12175 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12176 } 12177 } 12178 break; 12179 12180 case 403: /* Forbidden */ 12181 /* First we ACK */ 12182 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12183 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12184 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12185 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12186 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12187 sip_alreadygone(p); 12188 break; 12189 12190 case 404: /* Not found */ 12191 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12192 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12193 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12194 sip_alreadygone(p); 12195 break; 12196 12197 case 408: /* Request timeout */ 12198 case 481: /* Call leg does not exist */ 12199 /* Could be REFER caused INVITE with replaces */ 12200 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12201 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12202 if (p->owner) 12203 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12204 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12205 break; 12206 case 487: /* Cancelled transaction */ 12207 /* We have sent CANCEL on an outbound INVITE 12208 This transaction is already scheduled to be killed by sip_hangup(). 12209 */ 12210 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12211 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12212 ast_queue_hangup(p->owner); 12213 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12214 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12215 update_call_counter(p, DEC_CALL_LIMIT); 12216 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12217 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12218 sip_alreadygone(p); 12219 } 12220 break; 12221 case 488: /* Not acceptable here */ 12222 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12223 if (reinvite && p->udptl) { 12224 /* If this is a T.38 call, we should go back to 12225 audio. If this is an audio call - something went 12226 terribly wrong since we don't renegotiate codecs, 12227 only IP/port . 12228 */ 12229 p->t38.state = T38_DISABLED; 12230 /* Try to reset RTP timers */ 12231 ast_rtp_set_rtptimers_onhold(p->rtp); 12232 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12233 12234 /*! \bug Is there any way we can go back to the audio call on both 12235 sides here? 12236 */ 12237 /* While figuring that out, hangup the call */ 12238 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12239 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12240 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12241 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12242 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12243 right now we can't fall back to audio so totally abort. 12244 */ 12245 p->t38.state = T38_DISABLED; 12246 /* Try to reset RTP timers */ 12247 ast_rtp_set_rtptimers_onhold(p->rtp); 12248 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12249 12250 /* The dialog is now terminated */ 12251 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12252 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12253 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12254 sip_alreadygone(p); 12255 } else { 12256 /* We can't set up this call, so give up */ 12257 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12258 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12259 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12260 } 12261 break; 12262 case 491: /* Pending */ 12263 /* we really should have to wait a while, then retransmit */ 12264 /* We should support the retry-after at some point */ 12265 /* At this point, we treat this as a congestion */ 12266 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12267 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12268 if (p->owner->_state != AST_STATE_UP) { 12269 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12270 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12271 } else { 12272 /* This is a re-invite that failed. */ 12273 /* Reset the flag after a while 12274 */ 12275 int wait = 3 + ast_random() % 5; 12276 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12277 if (option_debug > 2) 12278 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12279 } 12280 } 12281 break; 12282 12283 case 501: /* Not implemented */ 12284 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12285 if (p->owner) 12286 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12287 break; 12288 } 12289 if (xmitres == XMIT_ERROR) 12290 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12291 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12495 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().
12496 { 12497 struct sip_peer *peer = p->relatedpeer; 12498 int statechanged, is_reachable, was_reachable; 12499 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12500 12501 /* 12502 * Compute the response time to a ping (goes in peer->lastms.) 12503 * -1 means did not respond, 0 means unknown, 12504 * 1..maxms is a valid response, >maxms means late response. 12505 */ 12506 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12507 pingtime = 1; 12508 12509 /* Now determine new state and whether it has changed. 12510 * Use some helper variables to simplify the writing 12511 * of the expressions. 12512 */ 12513 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12514 is_reachable = pingtime <= peer->maxms; 12515 statechanged = peer->lastms == 0 /* yes, unknown before */ 12516 || was_reachable != is_reachable; 12517 12518 peer->lastms = pingtime; 12519 peer->call = NULL; 12520 if (statechanged) { 12521 const char *s = is_reachable ? "Reachable" : "Lagged"; 12522 12523 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12524 peer->name, s, pingtime, peer->maxms); 12525 ast_device_state_changed("SIP/%s", peer->name); 12526 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12527 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12528 peer->name, s, pingtime); 12529 } 12530 12531 if (peer->pokeexpire > -1) 12532 ast_sched_del(sched, peer->pokeexpire); 12533 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12534 12535 /* Try again eventually */ 12536 peer->pokeexpire = ast_sched_add(sched, 12537 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12538 sip_poke_peer_s, peer); 12539 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12296 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().
12297 { 12298 char *auth = "Proxy-Authenticate"; 12299 char *auth2 = "Proxy-Authorization"; 12300 12301 /* If no refer structure exists, then do nothing */ 12302 if (!p->refer) 12303 return; 12304 12305 switch (resp) { 12306 case 202: /* Transfer accepted */ 12307 /* We need to do something here */ 12308 /* The transferee is now sending INVITE to target */ 12309 p->refer->status = REFER_ACCEPTED; 12310 /* Now wait for next message */ 12311 if (option_debug > 2) 12312 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12313 /* We should hang along, waiting for NOTIFY's here */ 12314 break; 12315 12316 case 401: /* Not www-authorized on SIP method */ 12317 case 407: /* Proxy auth */ 12318 if (ast_strlen_zero(p->authname)) { 12319 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12320 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12321 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12322 } 12323 if (resp == 401) { 12324 auth = "WWW-Authenticate"; 12325 auth2 = "Authorization"; 12326 } 12327 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12328 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12329 p->refer->status = REFER_NOAUTH; 12330 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12331 } 12332 break; 12333 case 481: /* Call leg does not exist */ 12334 12335 /* A transfer with Replaces did not work */ 12336 /* OEJ: We should Set flag, cancel the REFER, go back 12337 to original call - but right now we can't */ 12338 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12339 if (p->owner) 12340 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12341 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12342 break; 12343 12344 case 500: /* Server error */ 12345 case 501: /* Method not implemented */ 12346 /* Return to the current call onhold */ 12347 /* Status flag needed to be reset */ 12348 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12349 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12350 p->refer->status = REFER_FAILED; 12351 break; 12352 case 603: /* Transfer declined */ 12353 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12354 p->refer->status = REFER_FAILED; 12355 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12356 break; 12357 } 12358 }
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 12361 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().
12362 { 12363 int expires, expires_ms; 12364 struct sip_registry *r; 12365 r=p->registry; 12366 12367 switch (resp) { 12368 case 401: /* Unauthorized */ 12369 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12370 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12371 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12372 } 12373 break; 12374 case 403: /* Forbidden */ 12375 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12376 if (global_regattempts_max) 12377 p->registry->regattempts = global_regattempts_max+1; 12378 ast_sched_del(sched, r->timeout); 12379 r->timeout = -1; 12380 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12381 break; 12382 case 404: /* Not found */ 12383 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12384 if (global_regattempts_max) 12385 p->registry->regattempts = global_regattempts_max+1; 12386 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12387 r->call = NULL; 12388 ast_sched_del(sched, r->timeout); 12389 r->timeout = -1; 12390 break; 12391 case 407: /* Proxy auth */ 12392 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12393 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12394 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12395 } 12396 break; 12397 case 408: /* Request timeout */ 12398 if (global_regattempts_max) 12399 p->registry->regattempts = global_regattempts_max+1; 12400 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12401 r->call = NULL; 12402 ast_sched_del(sched, r->timeout); 12403 r->timeout = -1; 12404 break; 12405 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12406 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12407 if (global_regattempts_max) 12408 p->registry->regattempts = global_regattempts_max+1; 12409 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12410 r->call = NULL; 12411 ast_sched_del(sched, r->timeout); 12412 r->timeout = -1; 12413 break; 12414 case 200: /* 200 OK */ 12415 if (!r) { 12416 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12417 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12418 return 0; 12419 } 12420 12421 r->regstate = REG_STATE_REGISTERED; 12422 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12423 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12424 r->regattempts = 0; 12425 if (option_debug) 12426 ast_log(LOG_DEBUG, "Registration successful\n"); 12427 if (r->timeout > -1) { 12428 if (option_debug) 12429 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12430 ast_sched_del(sched, r->timeout); 12431 } 12432 r->timeout=-1; 12433 r->call = NULL; 12434 p->registry = NULL; 12435 /* Let this one hang around until we have all the responses */ 12436 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12437 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12438 12439 /* set us up for re-registering */ 12440 /* figure out how long we got registered for */ 12441 if (r->expire > -1) 12442 ast_sched_del(sched, r->expire); 12443 /* according to section 6.13 of RFC, contact headers override 12444 expires headers, so check those first */ 12445 expires = 0; 12446 12447 /* XXX todo: try to save the extra call */ 12448 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12449 const char *contact = NULL; 12450 const char *tmptmp = NULL; 12451 int start = 0; 12452 for(;;) { 12453 contact = __get_header(req, "Contact", &start); 12454 /* this loop ensures we get a contact header about our register request */ 12455 if(!ast_strlen_zero(contact)) { 12456 if( (tmptmp=strstr(contact, p->our_contact))) { 12457 contact=tmptmp; 12458 break; 12459 } 12460 } else 12461 break; 12462 } 12463 tmptmp = strcasestr(contact, "expires="); 12464 if (tmptmp) { 12465 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12466 expires = 0; 12467 } 12468 12469 } 12470 if (!expires) 12471 expires=atoi(get_header(req, "expires")); 12472 if (!expires) 12473 expires=default_expiry; 12474 12475 expires_ms = expires * 1000; 12476 if (expires <= EXPIRY_GUARD_LIMIT) 12477 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12478 else 12479 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12480 if (sipdebug) 12481 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12482 12483 r->refresh= (int) expires_ms / 1000; 12484 12485 /* Schedule re-registration before we expire */ 12486 if (r->expire > -1) 12487 ast_sched_del(sched, r->expire); 12488 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12489 ASTOBJ_UNREF(r, sip_registry_destroy); 12490 } 12491 return 1; 12492 }
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 3402 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().
03403 { 03404 switch (cause) { 03405 case AST_CAUSE_UNALLOCATED: /* 1 */ 03406 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03407 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03408 return "404 Not Found"; 03409 case AST_CAUSE_CONGESTION: /* 34 */ 03410 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03411 return "503 Service Unavailable"; 03412 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03413 return "408 Request Timeout"; 03414 case AST_CAUSE_NO_ANSWER: /* 19 */ 03415 return "480 Temporarily unavailable"; 03416 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03417 return "403 Forbidden"; 03418 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03419 return "410 Gone"; 03420 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03421 return "480 Temporarily unavailable"; 03422 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03423 return "484 Address incomplete"; 03424 case AST_CAUSE_USER_BUSY: 03425 return "486 Busy here"; 03426 case AST_CAUSE_FAILURE: 03427 return "500 Server internal failure"; 03428 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03429 return "501 Not Implemented"; 03430 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03431 return "503 Service Unavailable"; 03432 /* Used in chan_iax2 */ 03433 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03434 return "502 Bad Gateway"; 03435 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03436 return "488 Not Acceptable Here"; 03437 03438 case AST_CAUSE_NOTDEFINED: 03439 default: 03440 if (option_debug) 03441 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03442 return NULL; 03443 } 03444 03445 /* Never reached */ 03446 return 0; 03447 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3290 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().
03291 { 03292 /* Possible values taken from causes.h */ 03293 03294 switch(cause) { 03295 case 401: /* Unauthorized */ 03296 return AST_CAUSE_CALL_REJECTED; 03297 case 403: /* Not found */ 03298 return AST_CAUSE_CALL_REJECTED; 03299 case 404: /* Not found */ 03300 return AST_CAUSE_UNALLOCATED; 03301 case 405: /* Method not allowed */ 03302 return AST_CAUSE_INTERWORKING; 03303 case 407: /* Proxy authentication required */ 03304 return AST_CAUSE_CALL_REJECTED; 03305 case 408: /* No reaction */ 03306 return AST_CAUSE_NO_USER_RESPONSE; 03307 case 409: /* Conflict */ 03308 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03309 case 410: /* Gone */ 03310 return AST_CAUSE_UNALLOCATED; 03311 case 411: /* Length required */ 03312 return AST_CAUSE_INTERWORKING; 03313 case 413: /* Request entity too large */ 03314 return AST_CAUSE_INTERWORKING; 03315 case 414: /* Request URI too large */ 03316 return AST_CAUSE_INTERWORKING; 03317 case 415: /* Unsupported media type */ 03318 return AST_CAUSE_INTERWORKING; 03319 case 420: /* Bad extension */ 03320 return AST_CAUSE_NO_ROUTE_DESTINATION; 03321 case 480: /* No answer */ 03322 return AST_CAUSE_NO_ANSWER; 03323 case 481: /* No answer */ 03324 return AST_CAUSE_INTERWORKING; 03325 case 482: /* Loop detected */ 03326 return AST_CAUSE_INTERWORKING; 03327 case 483: /* Too many hops */ 03328 return AST_CAUSE_NO_ANSWER; 03329 case 484: /* Address incomplete */ 03330 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03331 case 485: /* Ambigous */ 03332 return AST_CAUSE_UNALLOCATED; 03333 case 486: /* Busy everywhere */ 03334 return AST_CAUSE_BUSY; 03335 case 487: /* Request terminated */ 03336 return AST_CAUSE_INTERWORKING; 03337 case 488: /* No codecs approved */ 03338 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03339 case 491: /* Request pending */ 03340 return AST_CAUSE_INTERWORKING; 03341 case 493: /* Undecipherable */ 03342 return AST_CAUSE_INTERWORKING; 03343 case 500: /* Server internal failure */ 03344 return AST_CAUSE_FAILURE; 03345 case 501: /* Call rejected */ 03346 return AST_CAUSE_FACILITY_REJECTED; 03347 case 502: 03348 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03349 case 503: /* Service unavailable */ 03350 return AST_CAUSE_CONGESTION; 03351 case 504: /* Gateway timeout */ 03352 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03353 case 505: /* SIP version not supported */ 03354 return AST_CAUSE_INTERWORKING; 03355 case 600: /* Busy everywhere */ 03356 return AST_CAUSE_USER_BUSY; 03357 case 603: /* Decline */ 03358 return AST_CAUSE_CALL_REJECTED; 03359 case 604: /* Does not exist anywhere */ 03360 return AST_CAUSE_UNALLOCATED; 03361 case 606: /* Not acceptable */ 03362 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03363 default: 03364 return AST_CAUSE_NORMAL; 03365 } 03366 /* Never reached */ 03367 return 0; 03368 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5789 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.
05790 { 05791 /* Initialize a request */ 05792 memset(req, 0, sizeof(*req)); 05793 req->method = sipmethod; 05794 req->header[0] = req->data; 05795 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05796 req->len = strlen(req->header[0]); 05797 req->headers++; 05798 return 0; 05799 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5776 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
05777 { 05778 /* Initialize a response */ 05779 memset(resp, 0, sizeof(*resp)); 05780 resp->method = SIP_RESPONSE; 05781 resp->header[0] = resp->data; 05782 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05783 resp->len = strlen(resp->header[0]); 05784 resp->headers++; 05785 return 0; 05786 }
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 1639 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().
01640 { 01641 if (p->initreq.headers && option_debug) { 01642 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01643 } 01644 /* Use this as the basis */ 01645 copy_request(&p->initreq, req); 01646 parse_request(&p->initreq); 01647 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01648 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01649 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6870 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().
06871 { 06872 char invite_buf[256] = ""; 06873 char *invite = invite_buf; 06874 size_t invite_max = sizeof(invite_buf); 06875 char from[256]; 06876 char to[256]; 06877 char tmp[BUFSIZ/2]; 06878 char tmp2[BUFSIZ/2]; 06879 const char *l = NULL, *n = NULL; 06880 const char *urioptions = ""; 06881 06882 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06883 const char *s = p->username; /* being a string field, cannot be NULL */ 06884 06885 /* Test p->username against allowed characters in AST_DIGIT_ANY 06886 If it matches the allowed characters list, then sipuser = ";user=phone" 06887 If not, then sipuser = "" 06888 */ 06889 /* + is allowed in first position in a tel: uri */ 06890 if (*s == '+') 06891 s++; 06892 for (; *s; s++) { 06893 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06894 break; 06895 } 06896 /* If we have only digits, add ;user=phone to the uri */ 06897 if (*s) 06898 urioptions = ";user=phone"; 06899 } 06900 06901 06902 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06903 06904 if (p->owner) { 06905 l = p->owner->cid.cid_num; 06906 n = p->owner->cid.cid_name; 06907 } 06908 /* if we are not sending RPID and user wants his callerid restricted */ 06909 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06910 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06911 l = CALLERID_UNKNOWN; 06912 n = l; 06913 } 06914 if (ast_strlen_zero(l)) 06915 l = default_callerid; 06916 if (ast_strlen_zero(n)) 06917 n = l; 06918 /* Allow user to be overridden */ 06919 if (!ast_strlen_zero(p->fromuser)) 06920 l = p->fromuser; 06921 else /* Save for any further attempts */ 06922 ast_string_field_set(p, fromuser, l); 06923 06924 /* Allow user to be overridden */ 06925 if (!ast_strlen_zero(p->fromname)) 06926 n = p->fromname; 06927 else /* Save for any further attempts */ 06928 ast_string_field_set(p, fromname, n); 06929 06930 if (pedanticsipchecking) { 06931 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06932 n = tmp; 06933 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06934 l = tmp2; 06935 } 06936 06937 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06938 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); 06939 else 06940 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06941 06942 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06943 if (!ast_strlen_zero(p->fullcontact)) { 06944 /* If we have full contact, trust it */ 06945 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06946 } else { 06947 /* Otherwise, use the username while waiting for registration */ 06948 ast_build_string(&invite, &invite_max, "sip:"); 06949 if (!ast_strlen_zero(p->username)) { 06950 n = p->username; 06951 if (pedanticsipchecking) { 06952 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06953 n = tmp; 06954 } 06955 ast_build_string(&invite, &invite_max, "%s@", n); 06956 } 06957 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06958 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06959 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06960 ast_build_string(&invite, &invite_max, "%s", urioptions); 06961 } 06962 06963 /* If custom URI options have been provided, append them */ 06964 if (p->options && p->options->uri_options) 06965 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06966 06967 ast_string_field_set(p, uri, invite_buf); 06968 06969 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06970 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06971 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 06972 } else if (p->options && p->options->vxml_url) { 06973 /* If there is a VXML URL append it to the SIP URL */ 06974 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06975 } else 06976 snprintf(to, sizeof(to), "<%s>", p->uri); 06977 06978 init_req(req, sipmethod, p->uri); 06979 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06980 06981 add_header(req, "Via", p->via); 06982 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06983 * OTOH, then we won't have anything in p->route anyway */ 06984 /* Build Remote Party-ID and From */ 06985 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06986 build_rpid(p); 06987 add_header(req, "From", p->rpid_from); 06988 } else 06989 add_header(req, "From", from); 06990 add_header(req, "To", to); 06991 ast_string_field_set(p, exten, l); 06992 build_contact(p); 06993 add_header(req, "Contact", p->our_contact); 06994 add_header(req, "Call-ID", p->callid); 06995 add_header(req, "CSeq", tmp); 06996 if (!ast_strlen_zero(global_useragent)) 06997 add_header(req, "User-Agent", global_useragent); 06998 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06999 if (!ast_strlen_zero(p->rpid)) 07000 add_header(req, "Remote-Party-ID", p->rpid); 07001 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 9995 of file chan_sip.c.
Referenced by _sip_show_peer().
09996 { 09997 if (port && invite) 09998 return "port,invite"; 09999 else if (port) 10000 return "port"; 10001 else if (invite) 10002 return "invite"; 10003 else 10004 return "no"; 10005 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8167 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08168 { 08169 if (!route) 08170 ast_verbose("list_route: no route\n"); 08171 else { 08172 for (;route; route = route->next) 08173 ast_verbose("list_route: hop: <%s>\n", route->hop); 08174 } 08175 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17899 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.
17900 { 17901 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 17902 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 17903 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 17904 17905 if (!(sched = sched_context_create())) { 17906 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 17907 return AST_MODULE_LOAD_FAILURE; 17908 } 17909 17910 if (!(io = io_context_create())) { 17911 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 17912 sched_context_destroy(sched); 17913 return AST_MODULE_LOAD_FAILURE; 17914 } 17915 17916 sip_reloadreason = CHANNEL_MODULE_LOAD; 17917 17918 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 17919 return AST_MODULE_LOAD_DECLINE; 17920 17921 /* Make sure we can register our sip channel type */ 17922 if (ast_channel_register(&sip_tech)) { 17923 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 17924 io_context_destroy(io); 17925 sched_context_destroy(sched); 17926 return AST_MODULE_LOAD_FAILURE; 17927 } 17928 17929 /* Register all CLI functions for SIP */ 17930 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 17931 17932 /* Tell the RTP subdriver that we're here */ 17933 ast_rtp_proto_register(&sip_rtp); 17934 17935 /* Tell the UDPTL subdriver that we're here */ 17936 ast_udptl_proto_register(&sip_udptl); 17937 17938 /* Register dialplan applications */ 17939 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 17940 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 17941 17942 /* Register dialplan functions */ 17943 ast_custom_function_register(&sip_header_function); 17944 ast_custom_function_register(&sippeer_function); 17945 ast_custom_function_register(&sipchaninfo_function); 17946 ast_custom_function_register(&checksipdomain_function); 17947 17948 /* Register manager commands */ 17949 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 17950 "List SIP peers (text format)", mandescr_show_peers); 17951 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 17952 "Show SIP peer (text format)", mandescr_show_peer); 17953 17954 sip_poke_all_peers(); 17955 sip_send_all_registers(); 17956 17957 /* And start the monitor for the first time */ 17958 restart_monitor(); 17959 17960 return AST_MODULE_LOAD_SUCCESS; 17961 }
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 14108 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().
14109 { 14110 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14111 /* Chan 2: Call from Asterisk to target */ 14112 int res = 0; 14113 struct sip_pvt *targetcall_pvt; 14114 14115 /* Check if the call ID of the replaces header does exist locally */ 14116 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14117 transferer->refer->replaces_callid_fromtag))) { 14118 if (transferer->refer->localtransfer) { 14119 /* We did not find the refered call. Sorry, can't accept then */ 14120 transmit_response(transferer, "202 Accepted", req); 14121 /* Let's fake a response from someone else in order 14122 to follow the standard */ 14123 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14124 append_history(transferer, "Xfer", "Refer failed"); 14125 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14126 transferer->refer->status = REFER_FAILED; 14127 return -1; 14128 } 14129 /* Fall through for remote transfers that we did not find locally */ 14130 if (option_debug > 2) 14131 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14132 return 0; 14133 } 14134 14135 /* Ok, we can accept this transfer */ 14136 transmit_response(transferer, "202 Accepted", req); 14137 append_history(transferer, "Xfer", "Refer accepted"); 14138 if (!targetcall_pvt->owner) { /* No active channel */ 14139 if (option_debug > 3) 14140 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14141 /* Cancel transfer */ 14142 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14143 append_history(transferer, "Xfer", "Refer failed"); 14144 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14145 transferer->refer->status = REFER_FAILED; 14146 ast_mutex_unlock(&targetcall_pvt->lock); 14147 ast_channel_unlock(current->chan1); 14148 return -1; 14149 } 14150 14151 /* We have a channel, find the bridge */ 14152 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14153 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14154 14155 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14156 /* Wrong state of new channel */ 14157 if (option_debug > 3) { 14158 if (target.chan2) 14159 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14160 else if (target.chan1->_state != AST_STATE_RING) 14161 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14162 else 14163 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14164 } 14165 } 14166 14167 /* Transfer */ 14168 if (option_debug > 3 && sipdebug) { 14169 if (current->chan2) /* We have two bridges */ 14170 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14171 else /* One bridge, propably transfer of IVR/voicemail etc */ 14172 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14173 } 14174 14175 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14176 14177 /* Perform the transfer */ 14178 res = attempt_transfer(current, &target); 14179 ast_mutex_unlock(&targetcall_pvt->lock); 14180 if (res) { 14181 /* Failed transfer */ 14182 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14183 append_history(transferer, "Xfer", "Refer failed"); 14184 transferer->refer->status = REFER_FAILED; 14185 if (targetcall_pvt->owner) 14186 ast_channel_unlock(targetcall_pvt->owner); 14187 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14188 if (res != -2) 14189 ast_hangup(transferer->owner); 14190 else 14191 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14192 } else { 14193 /* Transfer succeeded! */ 14194 14195 /* Tell transferer that we're done. */ 14196 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14197 append_history(transferer, "Xfer", "Refer succeeded"); 14198 transferer->refer->status = REFER_200OK; 14199 if (targetcall_pvt->owner) { 14200 if (option_debug) 14201 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14202 ast_channel_unlock(targetcall_pvt->owner); 14203 } 14204 } 14205 return 1; 14206 }
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 4713 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04714 { 04715 int h = 0, t = 0; 04716 int lws = 0; 04717 04718 for (; h < len;) { 04719 /* Eliminate all CRs */ 04720 if (msgbuf[h] == '\r') { 04721 h++; 04722 continue; 04723 } 04724 /* Check for end-of-line */ 04725 if (msgbuf[h] == '\n') { 04726 /* Check for end-of-message */ 04727 if (h + 1 == len) 04728 break; 04729 /* Check for a continuation line */ 04730 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04731 /* Merge continuation line */ 04732 h++; 04733 continue; 04734 } 04735 /* Propagate LF and start new line */ 04736 msgbuf[t++] = msgbuf[h++]; 04737 lws = 0; 04738 continue; 04739 } 04740 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04741 if (lws) { 04742 h++; 04743 continue; 04744 } 04745 msgbuf[t++] = msgbuf[h++]; 04746 lws = 1; 04747 continue; 04748 } 04749 msgbuf[t++] = msgbuf[h++]; 04750 if (lws) 04751 lws = 0; 04752 } 04753 msgbuf[t] = '\0'; 04754 return t; 04755 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4384 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().
04385 { 04386 snprintf(tagbuf, len, "as%08lx", ast_random()); 04387 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10240 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().
10241 { 10242 const char *a[4]; 10243 const char *peer; 10244 int ret; 10245 10246 peer = astman_get_header(m,"Peer"); 10247 if (ast_strlen_zero(peer)) { 10248 astman_send_error(s, m, "Peer: <name> missing.\n"); 10249 return 0; 10250 } 10251 a[0] = "sip"; 10252 a[1] = "show"; 10253 a[2] = "peer"; 10254 a[3] = peer; 10255 10256 ret = _sip_show_peer(1, -1, s, m, 4, a); 10257 astman_append(s, "\r\n\r\n" ); 10258 return ret; 10259 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9791 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().
09792 { 09793 const char *id = astman_get_header(m,"ActionID"); 09794 const char *a[] = {"sip", "show", "peers"}; 09795 char idtext[256] = ""; 09796 int total = 0; 09797 09798 if (!ast_strlen_zero(id)) 09799 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09800 09801 astman_send_ack(s, m, "Peer status list will follow"); 09802 /* List the peers in separate manager events */ 09803 _sip_show_peers(-1, &total, s, m, 3, a); 09804 /* Send final confirmation */ 09805 astman_append(s, 09806 "Event: PeerlistComplete\r\n" 09807 "ListItems: %d\r\n" 09808 "%s" 09809 "\r\n", total, idtext); 09810 return 0; 09811 }
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 1665 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01666 { 01667 int len = strlen(sip_methods[id].text); 01668 int l_name = name ? strlen(name) : 0; 01669 /* true if the string is long enough, and ends with whitespace, and matches */ 01670 return (l_name >= len && name[len] < 33 && 01671 !strncasecmp(sip_methods[id].text, name, len)); 01672 }
static char * nat2str | ( | int | nat | ) | [static] |
Convert NAT setting to text string.
Definition at line 9694 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().
09695 { 09696 switch(nat) { 09697 case SIP_NAT_NEVER: 09698 return "No"; 09699 case SIP_NAT_ROUTE: 09700 return "Route"; 09701 case SIP_NAT_ALWAYS: 09702 return "Always"; 09703 case SIP_NAT_RFC3581: 09704 return "RFC3581"; 09705 default: 09706 return "Unknown"; 09707 } 09708 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2220 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02221 { 02222 memset(dst, 0, sizeof(*dst)); 02223 memcpy(dst->data, src->data, sizeof(dst->data)); 02224 dst->len = src->len; 02225 parse_request(dst); 02226 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11869 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().
11870 { 11871 char tmp[BUFSIZ]; 11872 char *s, *e, *uri, *t; 11873 char *domain; 11874 11875 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11876 if ((t = strchr(tmp, ','))) 11877 *t = '\0'; 11878 s = get_in_brackets(tmp); 11879 uri = ast_strdupa(s); 11880 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11881 if (!strncasecmp(s, "sip:", 4)) 11882 s += 4; 11883 e = strchr(s, ';'); 11884 if (e) 11885 *e = '\0'; 11886 if (option_debug) 11887 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11888 if (p->owner) 11889 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11890 } else { 11891 e = strchr(tmp, '@'); 11892 if (e) { 11893 *e++ = '\0'; 11894 domain = e; 11895 } else { 11896 /* No username part */ 11897 domain = tmp; 11898 } 11899 e = strchr(s, ';'); /* Strip of parameters in the username part */ 11900 if (e) 11901 *e = '\0'; 11902 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 11903 if (e) 11904 *e = '\0'; 11905 11906 if (!strncasecmp(s, "sip:", 4)) 11907 s += 4; 11908 if (option_debug > 1) 11909 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 11910 if (p->owner) { 11911 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 11912 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 11913 ast_string_field_set(p->owner, call_forward, s); 11914 } 11915 } 11916 }
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 7923 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().
07924 { 07925 char contact[BUFSIZ]; 07926 char *c; 07927 07928 /* Look for brackets */ 07929 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07930 c = get_in_brackets(contact); 07931 07932 /* Save full contact to call pvt for later bye or re-invite */ 07933 ast_string_field_set(pvt, fullcontact, c); 07934 07935 /* Save URI for later ACKs, BYE or RE-invites */ 07936 ast_string_field_set(pvt, okcontacturi, c); 07937 07938 /* We should return false for URI:s we can't handle, 07939 like sips:, tel:, mailto:,ldap: etc */ 07940 return TRUE; 07941 }
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 8007 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().
08008 { 08009 char contact[BUFSIZ]; 08010 char data[BUFSIZ]; 08011 const char *expires = get_header(req, "Expires"); 08012 int expiry = atoi(expires); 08013 char *curi, *n, *pt; 08014 int port; 08015 const char *useragent; 08016 struct hostent *hp; 08017 struct ast_hostent ahp; 08018 struct sockaddr_in oldsin; 08019 08020 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08021 08022 if (ast_strlen_zero(expires)) { /* No expires header */ 08023 expires = strcasestr(contact, ";expires="); 08024 if (expires) { 08025 /* XXX bug here, we overwrite the string */ 08026 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08027 if (sscanf(expires + 9, "%d", &expiry) != 1) 08028 expiry = default_expiry; 08029 } else { 08030 /* Nothing has been specified */ 08031 expiry = default_expiry; 08032 } 08033 } 08034 08035 /* Look for brackets */ 08036 curi = contact; 08037 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08038 strsep(&curi, ";"); /* This is Header options, not URI options */ 08039 curi = get_in_brackets(contact); 08040 08041 /* if they did not specify Contact: or Expires:, they are querying 08042 what we currently have stored as their contact address, so return 08043 it 08044 */ 08045 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08046 /* If we have an active registration, tell them when the registration is going to expire */ 08047 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08048 pvt->expiry = ast_sched_when(sched, peer->expire); 08049 return PARSE_REGISTER_QUERY; 08050 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08051 /* This means remove all registrations and return OK */ 08052 memset(&peer->addr, 0, sizeof(peer->addr)); 08053 if (peer->expire > -1) 08054 ast_sched_del(sched, peer->expire); 08055 peer->expire = -1; 08056 08057 destroy_association(peer); 08058 08059 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08060 peer->fullcontact[0] = '\0'; 08061 peer->useragent[0] = '\0'; 08062 peer->sipoptions = 0; 08063 peer->lastms = 0; 08064 08065 if (option_verbose > 2) 08066 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08067 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08068 return PARSE_REGISTER_UPDATE; 08069 } 08070 08071 /* Store whatever we got as a contact from the client */ 08072 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08073 08074 /* For the 200 OK, we should use the received contact */ 08075 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08076 08077 /* Make sure it's a SIP URL */ 08078 if (strncasecmp(curi, "sip:", 4)) { 08079 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08080 } else 08081 curi += 4; 08082 /* Ditch q */ 08083 curi = strsep(&curi, ";"); 08084 /* Grab host */ 08085 n = strchr(curi, '@'); 08086 if (!n) { 08087 n = curi; 08088 curi = NULL; 08089 } else 08090 *n++ = '\0'; 08091 pt = strchr(n, ':'); 08092 if (pt) { 08093 *pt++ = '\0'; 08094 port = atoi(pt); 08095 } else 08096 port = STANDARD_SIP_PORT; 08097 oldsin = peer->addr; 08098 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08099 /* XXX This could block for a long time XXX */ 08100 hp = ast_gethostbyname(n, &ahp); 08101 if (!hp) { 08102 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08103 return PARSE_REGISTER_FAILED; 08104 } 08105 peer->addr.sin_family = AF_INET; 08106 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08107 peer->addr.sin_port = htons(port); 08108 } else { 08109 /* Don't trust the contact field. Just use what they came to us 08110 with */ 08111 peer->addr = pvt->recv; 08112 } 08113 08114 /* Save SIP options profile */ 08115 peer->sipoptions = pvt->sipoptions; 08116 08117 if (curi && ast_strlen_zero(peer->username)) 08118 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08119 08120 if (peer->expire > -1) { 08121 ast_sched_del(sched, peer->expire); 08122 peer->expire = -1; 08123 } 08124 if (expiry > max_expiry) 08125 expiry = max_expiry; 08126 if (expiry < min_expiry) 08127 expiry = min_expiry; 08128 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 08129 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 08130 pvt->expiry = expiry; 08131 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); 08132 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08133 ast_db_put("SIP/Registry", peer->name, data); 08134 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08135 08136 /* Is this a new IP address for us? */ 08137 if (inaddrcmp(&peer->addr, &oldsin)) { 08138 sip_poke_peer(peer); 08139 if (option_verbose > 2) 08140 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); 08141 register_peer_exten(peer, 1); 08142 } 08143 08144 /* Save User agent */ 08145 useragent = get_header(req, "User-Agent"); 08146 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08147 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08148 if (option_verbose > 3) 08149 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08150 } 08151 return PARSE_REGISTER_UPDATE; 08152 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4760 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().
04761 { 04762 /* Divide fields by NULL's */ 04763 char *c; 04764 int f = 0; 04765 04766 c = req->data; 04767 04768 /* First header starts immediately */ 04769 req->header[f] = c; 04770 while(*c) { 04771 if (*c == '\n') { 04772 /* We've got a new header */ 04773 *c = 0; 04774 04775 if (sipdebug && option_debug > 3) 04776 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04777 if (ast_strlen_zero(req->header[f])) { 04778 /* Line by itself means we're now in content */ 04779 c++; 04780 break; 04781 } 04782 if (f >= SIP_MAX_HEADERS - 1) { 04783 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04784 } else 04785 f++; 04786 req->header[f] = c + 1; 04787 } else if (*c == '\r') { 04788 /* Ignore but eliminate \r's */ 04789 *c = 0; 04790 } 04791 c++; 04792 } 04793 /* Check for last header */ 04794 if (!ast_strlen_zero(req->header[f])) { 04795 if (sipdebug && option_debug > 3) 04796 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04797 f++; 04798 } 04799 req->headers = f; 04800 /* Now we process any mime content */ 04801 f = 0; 04802 req->line[f] = c; 04803 while(*c) { 04804 if (*c == '\n') { 04805 /* We've got a new line */ 04806 *c = 0; 04807 if (sipdebug && option_debug > 3) 04808 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04809 if (f >= SIP_MAX_LINES - 1) { 04810 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04811 } else 04812 f++; 04813 req->line[f] = c + 1; 04814 } else if (*c == '\r') { 04815 /* Ignore and eliminate \r's */ 04816 *c = 0; 04817 } 04818 c++; 04819 } 04820 /* Check for last line */ 04821 if (!ast_strlen_zero(req->line[f])) 04822 f++; 04823 req->lines = f; 04824 if (*c) 04825 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04826 /* Split up the first line parts */ 04827 determine_firstline_parts(req); 04828 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1689 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().
01690 { 01691 char *next, *sep; 01692 char *temp; 01693 unsigned int profile = 0; 01694 int i, found; 01695 01696 if (ast_strlen_zero(supported) ) 01697 return 0; 01698 temp = ast_strdupa(supported); 01699 01700 if (option_debug > 2 && sipdebug) 01701 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01702 01703 for (next = temp; next; next = sep) { 01704 found = FALSE; 01705 if ( (sep = strchr(next, ',')) != NULL) 01706 *sep++ = '\0'; 01707 next = ast_skip_blanks(next); 01708 if (option_debug > 2 && sipdebug) 01709 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01710 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01711 if (!strcasecmp(next, sip_options[i].text)) { 01712 profile |= sip_options[i].id; 01713 found = TRUE; 01714 if (option_debug > 2 && sipdebug) 01715 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01716 break; 01717 } 01718 } 01719 if (!found && option_debug > 2 && sipdebug) { 01720 if (!strncasecmp(next, "x-", 2)) 01721 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01722 else 01723 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01724 } 01725 } 01726 01727 if (pvt) 01728 pvt->sipoptions = profile; 01729 return profile; 01730 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9713 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09714 { 09715 int res = 0; 09716 if (peer->maxms) { 09717 if (peer->lastms < 0) { 09718 ast_copy_string(status, "UNREACHABLE", statuslen); 09719 } else if (peer->lastms > peer->maxms) { 09720 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09721 res = 1; 09722 } else if (peer->lastms) { 09723 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09724 res = 1; 09725 } else { 09726 ast_copy_string(status, "UNKNOWN", statuslen); 09727 } 09728 } else { 09729 ast_copy_string(status, "Unmonitored", statuslen); 09730 /* Checking if port is 0 */ 09731 res = -1; 09732 } 09733 return res; 09734 }
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 10181 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().
10182 { 10183 int x, codec; 10184 10185 for(x = 0; x < 32 ; x++) { 10186 codec = ast_codec_pref_index(pref, x); 10187 if (!codec) 10188 break; 10189 ast_cli(fd, "%s", ast_getformatname(codec)); 10190 ast_cli(fd, ":%d", pref->framing[x]); 10191 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10192 ast_cli(fd, ","); 10193 } 10194 if (!x) 10195 ast_cli(fd, "none"); 10196 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 9972 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
09973 { 09974 char buf[256]; 09975 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 09976 }
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 4943 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.
04944 { 04945 const char *m; /* SDP media offer */ 04946 const char *c; 04947 const char *a; 04948 char host[258]; 04949 int len = -1; 04950 int portno = -1; /*!< RTP Audio port number */ 04951 int vportno = -1; /*!< RTP Video port number */ 04952 int udptlportno = -1; 04953 int peert38capability = 0; 04954 char s[256]; 04955 int old = 0; 04956 04957 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04958 int peercapability = 0, peernoncodeccapability = 0; 04959 int vpeercapability = 0, vpeernoncodeccapability = 0; 04960 struct sockaddr_in sin; /*!< media socket address */ 04961 struct sockaddr_in vsin; /*!< Video socket address */ 04962 04963 const char *codecs; 04964 struct hostent *hp; /*!< RTP Audio host IP */ 04965 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04966 struct ast_hostent audiohp; 04967 struct ast_hostent videohp; 04968 int codec; 04969 int destiterator = 0; 04970 int iterator; 04971 int sendonly = -1; 04972 int numberofports; 04973 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04974 int newjointcapability; /* Negotiated capability */ 04975 int newpeercapability; 04976 int newnoncodeccapability; 04977 int numberofmediastreams = 0; 04978 int debug = sip_debug_test_pvt(p); 04979 04980 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 04981 int last_rtpmap_codec=0; 04982 04983 if (!p->rtp) { 04984 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04985 return -1; 04986 } 04987 04988 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04989 newaudiortp = alloca(ast_rtp_alloc_size()); 04990 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04991 ast_rtp_new_init(newaudiortp); 04992 ast_rtp_pt_clear(newaudiortp); 04993 04994 newvideortp = alloca(ast_rtp_alloc_size()); 04995 memset(newvideortp, 0, ast_rtp_alloc_size()); 04996 ast_rtp_new_init(newvideortp); 04997 ast_rtp_pt_clear(newvideortp); 04998 04999 /* Update our last rtprx when we receive an SDP, too */ 05000 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05001 05002 05003 /* Try to find first media stream */ 05004 m = get_sdp(req, "m"); 05005 destiterator = req->sdp_start; 05006 c = get_sdp_iterate(&destiterator, req, "c"); 05007 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05008 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05009 return -1; 05010 } 05011 05012 /* Check for IPv4 address (not IPv6 yet) */ 05013 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05014 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05015 return -1; 05016 } 05017 05018 /* XXX This could block for a long time, and block the main thread! XXX */ 05019 hp = ast_gethostbyname(host, &audiohp); 05020 if (!hp) { 05021 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05022 return -1; 05023 } 05024 vhp = hp; /* Copy to video address as default too */ 05025 05026 iterator = req->sdp_start; 05027 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05028 05029 05030 /* Find media streams in this SDP offer */ 05031 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05032 int x; 05033 int audio = FALSE; 05034 05035 numberofports = 1; 05036 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05037 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05038 audio = TRUE; 05039 numberofmediastreams++; 05040 /* Found audio stream in this media definition */ 05041 portno = x; 05042 /* Scan through the RTP payload types specified in a "m=" line: */ 05043 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05044 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05045 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05046 return -1; 05047 } 05048 if (debug) 05049 ast_verbose("Found RTP audio format %d\n", codec); 05050 ast_rtp_set_m_type(newaudiortp, codec); 05051 } 05052 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05053 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05054 /* If it is not audio - is it video ? */ 05055 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05056 numberofmediastreams++; 05057 vportno = x; 05058 /* Scan through the RTP payload types specified in a "m=" line: */ 05059 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05060 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05061 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05062 return -1; 05063 } 05064 if (debug) 05065 ast_verbose("Found RTP video format %d\n", codec); 05066 ast_rtp_set_m_type(newvideortp, codec); 05067 } 05068 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05069 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05070 if (debug) 05071 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05072 udptlportno = x; 05073 numberofmediastreams++; 05074 05075 if (p->owner && p->lastinvite) { 05076 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05077 if (option_debug > 1) 05078 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05079 } else { 05080 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05081 if (option_debug > 1) 05082 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05083 } 05084 } else 05085 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05086 if (numberofports > 1) 05087 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05088 05089 05090 /* Check for Media-description-level-address for audio */ 05091 c = get_sdp_iterate(&destiterator, req, "c"); 05092 if (!ast_strlen_zero(c)) { 05093 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05094 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05095 } else { 05096 /* XXX This could block for a long time, and block the main thread! XXX */ 05097 if (audio) { 05098 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05099 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05100 return -2; 05101 } 05102 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05103 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05104 return -2; 05105 } 05106 } 05107 05108 } 05109 } 05110 if (portno == -1 && vportno == -1 && udptlportno == -1) 05111 /* No acceptable offer found in SDP - we have no ports */ 05112 /* Do not change RTP or VRTP if this is a re-invite */ 05113 return -2; 05114 05115 if (numberofmediastreams > 2) 05116 /* We have too many fax, audio and/or video media streams, fail this offer */ 05117 return -3; 05118 05119 /* RTP addresses and ports for audio and video */ 05120 sin.sin_family = AF_INET; 05121 vsin.sin_family = AF_INET; 05122 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05123 if (vhp) 05124 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05125 05126 /* Setup UDPTL port number */ 05127 if (p->udptl) { 05128 if (udptlportno > 0) { 05129 sin.sin_port = htons(udptlportno); 05130 ast_udptl_set_peer(p->udptl, &sin); 05131 if (debug) 05132 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05133 } else { 05134 ast_udptl_stop(p->udptl); 05135 if (debug) 05136 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05137 } 05138 } 05139 05140 05141 if (p->rtp) { 05142 if (portno > 0) { 05143 sin.sin_port = htons(portno); 05144 ast_rtp_set_peer(p->rtp, &sin); 05145 if (debug) 05146 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05147 } else { 05148 if (udptlportno > 0) { 05149 if (debug) 05150 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05151 } else { 05152 ast_rtp_stop(p->rtp); 05153 if (debug) 05154 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05155 } 05156 } 05157 } 05158 /* Setup video port number */ 05159 if (vportno != -1) 05160 vsin.sin_port = htons(vportno); 05161 05162 /* Next, scan through each "a=rtpmap:" line, noting each 05163 * specified RTP payload type (with corresponding MIME subtype): 05164 */ 05165 /* XXX This needs to be done per media stream, since it's media stream specific */ 05166 iterator = req->sdp_start; 05167 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05168 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05169 if (option_debug > 1) { 05170 int breakout = FALSE; 05171 05172 /* If we're debugging, check for unsupported sdp options */ 05173 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05174 if (debug) 05175 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05176 breakout = TRUE; 05177 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05178 /* Format parameters: Not supported */ 05179 /* Note: This is used for codec parameters, like bitrate for 05180 G722 and video formats for H263 and H264 05181 See RFC2327 for an example */ 05182 if (debug) 05183 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05184 breakout = TRUE; 05185 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05186 /* Video stuff: Not supported */ 05187 if (debug) 05188 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05189 breakout = TRUE; 05190 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05191 /* Video stuff: Not supported */ 05192 if (debug) 05193 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05194 breakout = TRUE; 05195 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05196 /* SRTP stuff, not yet supported */ 05197 if (debug) 05198 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05199 breakout = TRUE; 05200 } 05201 if (breakout) /* We have a match, skip to next header */ 05202 continue; 05203 } 05204 if (!strcasecmp(a, "sendonly")) { 05205 if (sendonly == -1) 05206 sendonly = 1; 05207 continue; 05208 } else if (!strcasecmp(a, "inactive")) { 05209 if (sendonly == -1) 05210 sendonly = 2; 05211 continue; 05212 } else if (!strcasecmp(a, "sendrecv")) { 05213 if (sendonly == -1) 05214 sendonly = 0; 05215 continue; 05216 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05217 char *tmp = strrchr(a, ':'); 05218 long int framing = 0; 05219 if (tmp) { 05220 tmp++; 05221 framing = strtol(tmp, NULL, 10); 05222 if (framing == LONG_MIN || framing == LONG_MAX) { 05223 framing = 0; 05224 if (option_debug) 05225 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05226 } 05227 } 05228 if (framing && last_rtpmap_codec) { 05229 if (p->autoframing) { 05230 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05231 int codec_n; 05232 int format = 0; 05233 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05234 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05235 if (!format) /* non-codec or not found */ 05236 continue; 05237 if (option_debug) 05238 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05239 ast_codec_pref_setsize(pref, format, framing); 05240 } 05241 ast_rtp_codec_setpref(p->rtp, pref); 05242 } 05243 } 05244 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05245 last_rtpmap_codec = 0; 05246 continue; 05247 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05248 /* We have a rtpmap to handle */ 05249 int found = FALSE; 05250 /* We should propably check if this is an audio or video codec 05251 so we know where to look */ 05252 05253 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05254 /* Note: should really look at the 'freq' and '#chans' params too */ 05255 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05256 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05257 if (debug) 05258 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05259 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05260 last_rtpmap_codec++; 05261 found = TRUE; 05262 05263 } else if (p->vrtp) { 05264 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05265 if (debug) 05266 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05267 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05268 last_rtpmap_codec++; 05269 found = TRUE; 05270 } 05271 } 05272 } else { 05273 if (debug) 05274 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05275 } 05276 05277 if (!found) { 05278 /* Remove this codec since it's an unknown media type for us */ 05279 /* XXX This is buggy since the media line for audio and video can have the 05280 same numbers. We need to check as described above, but for testing this works... */ 05281 ast_rtp_unset_m_type(newaudiortp, codec); 05282 ast_rtp_unset_m_type(newvideortp, codec); 05283 if (debug) 05284 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05285 } 05286 } 05287 } 05288 05289 if (udptlportno != -1) { 05290 int found = 0, x; 05291 05292 old = 0; 05293 05294 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05295 iterator = req->sdp_start; 05296 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05297 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05298 found = 1; 05299 if (option_debug > 2) 05300 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05301 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05302 found = 1; 05303 if (option_debug > 2) 05304 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05305 switch (x) { 05306 case 14400: 05307 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05308 break; 05309 case 12000: 05310 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05311 break; 05312 case 9600: 05313 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05314 break; 05315 case 7200: 05316 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05317 break; 05318 case 4800: 05319 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05320 break; 05321 case 2400: 05322 peert38capability |= T38FAX_RATE_2400; 05323 break; 05324 } 05325 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05326 found = 1; 05327 if (option_debug > 2) 05328 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05329 if (x == 0) 05330 peert38capability |= T38FAX_VERSION_0; 05331 else if (x == 1) 05332 peert38capability |= T38FAX_VERSION_1; 05333 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05334 found = 1; 05335 if (option_debug > 2) 05336 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05337 ast_udptl_set_far_max_datagram(p->udptl, x); 05338 ast_udptl_set_local_max_datagram(p->udptl, x); 05339 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05340 found = 1; 05341 if (option_debug > 2) 05342 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05343 if (x == 1) 05344 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05345 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05346 found = 1; 05347 if (option_debug > 2) 05348 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05349 if (x == 1) 05350 peert38capability |= T38FAX_TRANSCODING_MMR; 05351 } 05352 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05353 found = 1; 05354 if (option_debug > 2) 05355 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05356 if (x == 1) 05357 peert38capability |= T38FAX_TRANSCODING_JBIG; 05358 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05359 found = 1; 05360 if (option_debug > 2) 05361 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05362 if (!strcasecmp(s, "localTCF")) 05363 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05364 else if (!strcasecmp(s, "transferredTCF")) 05365 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05366 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05367 found = 1; 05368 if (option_debug > 2) 05369 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05370 if (!strcasecmp(s, "t38UDPRedundancy")) { 05371 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05372 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05373 } else if (!strcasecmp(s, "t38UDPFEC")) { 05374 peert38capability |= T38FAX_UDP_EC_FEC; 05375 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05376 } else { 05377 peert38capability |= T38FAX_UDP_EC_NONE; 05378 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05379 } 05380 } 05381 } 05382 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05383 p->t38.peercapability = peert38capability; 05384 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05385 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05386 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05387 } 05388 if (debug) 05389 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05390 p->t38.capability, 05391 p->t38.peercapability, 05392 p->t38.jointcapability); 05393 } else { 05394 p->t38.state = T38_DISABLED; 05395 if (option_debug > 2) 05396 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05397 } 05398 05399 /* Now gather all of the codecs that we are asked for: */ 05400 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05401 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05402 05403 newjointcapability = p->capability & (peercapability | vpeercapability); 05404 newpeercapability = (peercapability | vpeercapability); 05405 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05406 05407 05408 if (debug) { 05409 /* shame on whoever coded this.... */ 05410 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05411 05412 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05413 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05414 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05415 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05416 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05417 05418 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05419 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05420 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05421 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05422 } 05423 if (!newjointcapability) { 05424 /* If T.38 was not negotiated either, totally bail out... */ 05425 if (!p->t38.jointcapability) { 05426 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05427 /* Do NOT Change current setting */ 05428 return -1; 05429 } else { 05430 if (option_debug > 2) 05431 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05432 return 0; 05433 } 05434 } 05435 05436 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05437 they are acceptable */ 05438 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05439 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05440 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05441 05442 ast_rtp_pt_copy(p->rtp, newaudiortp); 05443 if (p->vrtp) 05444 ast_rtp_pt_copy(p->vrtp, newvideortp); 05445 05446 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05447 ast_clear_flag(&p->flags[0], SIP_DTMF); 05448 if (newnoncodeccapability & AST_RTP_DTMF) { 05449 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05450 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05451 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05452 ast_rtp_setdtmf(p->rtp, 1); 05453 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05454 } else { 05455 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05456 } 05457 } 05458 05459 /* Setup audio port number */ 05460 if (p->rtp && sin.sin_port) { 05461 ast_rtp_set_peer(p->rtp, &sin); 05462 if (debug) 05463 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05464 } 05465 05466 /* Setup video port number */ 05467 if (p->vrtp && vsin.sin_port) { 05468 ast_rtp_set_peer(p->vrtp, &vsin); 05469 if (debug) 05470 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05471 } 05472 05473 /* Ok, we're going with this offer */ 05474 if (option_debug > 1) { 05475 char buf[BUFSIZ]; 05476 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05477 } 05478 05479 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05480 return 0; 05481 05482 if (option_debug > 3) 05483 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05484 05485 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05486 if (debug) { 05487 char s1[BUFSIZ], s2[BUFSIZ]; 05488 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05489 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05490 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05491 } 05492 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05493 ast_set_read_format(p->owner, p->owner->readformat); 05494 ast_set_write_format(p->owner, p->owner->writeformat); 05495 } 05496 05497 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05498 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05499 /* Activate a re-invite */ 05500 ast_queue_frame(p->owner, &ast_null_frame); 05501 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05502 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05503 S_OR(p->mohsuggest, NULL), 05504 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05505 if (sendonly) 05506 ast_rtp_stop(p->rtp); 05507 /* RTCP needs to go ahead, even if we're on hold!!! */ 05508 /* Activate a re-invite */ 05509 ast_queue_frame(p->owner, &ast_null_frame); 05510 } 05511 05512 /* Manager Hold and Unhold events must be generated, if necessary */ 05513 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05514 change_hold_state(p, req, FALSE, sendonly); 05515 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05516 change_hold_state(p, req, TRUE, sendonly); 05517 return 0; 05518 }
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 2489 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.
02490 { 02491 struct sip_peer *peer=NULL; 02492 struct ast_variable *var = NULL; 02493 struct ast_config *peerlist = NULL; 02494 struct ast_variable *tmp; 02495 struct ast_flags flags = {0}; 02496 const char *iabuf = NULL; 02497 char portstring[6]; /*up to five digits plus null terminator*/ 02498 const char *insecure; 02499 char *cat = NULL; 02500 unsigned short portnum; 02501 02502 /* First check on peer name */ 02503 if (newpeername) { 02504 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02505 if (!var && sin) 02506 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02507 if (!var) { 02508 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02509 /*!\note 02510 * If this one loaded something, then we need to ensure that the host 02511 * field matched. The only reason why we can't have this as a criteria 02512 * is because we only have the IP address and the host field might be 02513 * set as a name (and the reverse PTR might not match). 02514 */ 02515 if (var) { 02516 for (tmp = var; tmp; tmp = tmp->next) { 02517 if (!strcasecmp(var->name, "host")) { 02518 struct in_addr sin2 = { 0, }; 02519 struct ast_dnsmgr_entry *dnsmgr = NULL; 02520 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02521 /* No match */ 02522 ast_variables_destroy(var); 02523 var = NULL; 02524 } 02525 break; 02526 } 02527 } 02528 } 02529 } 02530 } 02531 02532 if (!var && sin) { /* Then check on IP address */ 02533 iabuf = ast_inet_ntoa(sin->sin_addr); 02534 portnum = ntohs(sin->sin_port); 02535 sprintf(portstring, "%d", portnum); 02536 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02537 if (!var) 02538 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02539 if (!var) { 02540 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02541 if(peerlist){ 02542 while((cat = ast_category_browse(peerlist, cat))) 02543 { 02544 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02545 set_insecure_flags(&flags, insecure, -1); 02546 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02547 var = ast_category_root(peerlist, cat); 02548 break; 02549 } 02550 } 02551 } 02552 if(!var) { 02553 ast_config_destroy(peerlist); 02554 peerlist = NULL; /*for safety's sake*/ 02555 cat = NULL; 02556 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02557 if(peerlist) { 02558 while((cat = ast_category_browse(peerlist, cat))) 02559 { 02560 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02561 set_insecure_flags(&flags, insecure, -1); 02562 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02563 var = ast_category_root(peerlist, cat); 02564 break; 02565 } 02566 } 02567 } 02568 } 02569 } 02570 } 02571 02572 if (!var) { 02573 if(peerlist) 02574 ast_config_destroy(peerlist); 02575 return NULL; 02576 } 02577 02578 for (tmp = var; tmp; tmp = tmp->next) { 02579 /* If this is type=user, then skip this object. */ 02580 if (!strcasecmp(tmp->name, "type") && 02581 !strcasecmp(tmp->value, "user")) { 02582 ast_variables_destroy(var); 02583 return NULL; 02584 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02585 newpeername = tmp->value; 02586 } 02587 } 02588 02589 if (!newpeername) { /* Did not find peer in realtime */ 02590 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02591 if(peerlist) 02592 ast_config_destroy(peerlist); 02593 else 02594 ast_variables_destroy(var); 02595 return NULL; 02596 } 02597 02598 /* Peer found in realtime, now build it in memory */ 02599 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02600 if (!peer) { 02601 if(peerlist) 02602 ast_config_destroy(peerlist); 02603 else 02604 ast_variables_destroy(var); 02605 return NULL; 02606 } 02607 02608 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02609 /* Cache peer */ 02610 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02611 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02612 if (peer->expire > -1) { 02613 ast_sched_del(sched, peer->expire); 02614 } 02615 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02616 } 02617 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02618 } else { 02619 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02620 } 02621 if(peerlist) 02622 ast_config_destroy(peerlist); 02623 else 02624 ast_variables_destroy(var); 02625 return peer; 02626 }
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 2374 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.
02375 { 02376 char port[10]; 02377 char ipaddr[INET_ADDRSTRLEN]; 02378 char regseconds[20]; 02379 02380 char *sysname = ast_config_AST_SYSTEM_NAME; 02381 char *syslabel = NULL; 02382 02383 time_t nowtime = time(NULL) + expirey; 02384 const char *fc = fullcontact ? "fullcontact" : NULL; 02385 02386 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02387 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02388 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02389 02390 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02391 sysname = NULL; 02392 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02393 syslabel = "regserver"; 02394 02395 if (fc) 02396 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02397 "port", port, "regseconds", regseconds, 02398 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02399 else 02400 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02401 "port", port, "regseconds", regseconds, 02402 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02403 }
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 2676 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.
02677 { 02678 struct ast_variable *var; 02679 struct ast_variable *tmp; 02680 struct sip_user *user = NULL; 02681 02682 var = ast_load_realtime("sipusers", "name", username, NULL); 02683 02684 if (!var) 02685 return NULL; 02686 02687 for (tmp = var; tmp; tmp = tmp->next) { 02688 if (!strcasecmp(tmp->name, "type") && 02689 !strcasecmp(tmp->value, "peer")) { 02690 ast_variables_destroy(var); 02691 return NULL; 02692 } 02693 } 02694 02695 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02696 02697 if (!user) { /* No user found */ 02698 ast_variables_destroy(var); 02699 return NULL; 02700 } 02701 02702 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02703 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02704 suserobjs++; 02705 ASTOBJ_CONTAINER_LINK(&userl,user); 02706 } else { 02707 /* Move counter from s to r... */ 02708 suserobjs--; 02709 ruserobjs++; 02710 ast_set_flag(&user->flags[0], SIP_REALTIME); 02711 } 02712 ast_variables_destroy(var); 02713 return user; 02714 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9596 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().
09597 { 09598 char buf[1024]; 09599 struct ast_frame f; 09600 const char *content_type = get_header(req, "Content-Type"); 09601 09602 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09603 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09604 if (!p->owner) 09605 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09606 return; 09607 } 09608 09609 if (get_msg_text(buf, sizeof(buf), req)) { 09610 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09611 transmit_response(p, "202 Accepted", req); 09612 if (!p->owner) 09613 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09614 return; 09615 } 09616 09617 if (p->owner) { 09618 if (sip_debug_test_pvt(p)) 09619 ast_verbose("Message received: '%s'\n", buf); 09620 memset(&f, 0, sizeof(f)); 09621 f.frametype = AST_FRAME_TEXT; 09622 f.subclass = 0; 09623 f.offset = 0; 09624 f.data = buf; 09625 f.datalen = strlen(buf); 09626 ast_queue_frame(p->owner, &f); 09627 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09628 } else { /* Message outside of a call, we do not support that */ 09629 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); 09630 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09631 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09632 } 09633 return; 09634 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1624 of file chan_sip.c.
References referstatusstrings, and c_referstatusstring::text.
Referenced by __sip_show_channels().
01625 { 01626 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01627 int x; 01628 01629 for (x = 0; x < i; x++) { 01630 if (referstatusstrings[x].status == rstatus) 01631 return (char *) referstatusstrings[x].text; 01632 } 01633 return ""; 01634 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7863 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.
07864 { 07865 char data[256]; 07866 struct in_addr in; 07867 int expiry; 07868 int port; 07869 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07870 07871 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07872 return; 07873 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07874 return; 07875 07876 scan = data; 07877 addr = strsep(&scan, ":"); 07878 port_str = strsep(&scan, ":"); 07879 expiry_str = strsep(&scan, ":"); 07880 username = strsep(&scan, ":"); 07881 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07882 07883 if (!inet_aton(addr, &in)) 07884 return; 07885 07886 if (port_str) 07887 port = atoi(port_str); 07888 else 07889 return; 07890 07891 if (expiry_str) 07892 expiry = atoi(expiry_str); 07893 else 07894 return; 07895 07896 if (username) 07897 ast_copy_string(peer->username, username, sizeof(peer->username)); 07898 if (contact) 07899 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07900 07901 if (option_debug > 1) 07902 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07903 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07904 07905 memset(&peer->addr, 0, sizeof(peer->addr)); 07906 peer->addr.sin_family = AF_INET; 07907 peer->addr.sin_addr = in; 07908 peer->addr.sin_port = htons(port); 07909 if (sipsock < 0) { 07910 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07911 if (peer->pokeexpire > -1) 07912 ast_sched_del(sched, peer->pokeexpire); 07913 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07914 } else 07915 sip_poke_peer(peer); 07916 if (peer->expire > -1) 07917 ast_sched_del(sched, peer->expire); 07918 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07919 register_peer_exten(peer, TRUE); 07920 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2406 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().
02407 { 02408 char multi[256]; 02409 char *stringp, *ext, *context; 02410 02411 /* XXX note that global_regcontext is both a global 'enable' flag and 02412 * the name of the global regexten context, if not specified 02413 * individually. 02414 */ 02415 if (ast_strlen_zero(global_regcontext)) 02416 return; 02417 02418 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02419 stringp = multi; 02420 while ((ext = strsep(&stringp, "&"))) { 02421 if ((context = strchr(ext, '@'))) { 02422 *context++ = '\0'; /* split ext@context */ 02423 if (!ast_context_find(context)) { 02424 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02425 continue; 02426 } 02427 } else { 02428 context = global_regcontext; 02429 } 02430 if (onoff) 02431 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02432 ast_strdup(peer->name), ast_free, "SIP"); 02433 else 02434 ast_context_remove_extension(context, ext, 1, NULL); 02435 } 02436 }
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 8516 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.
08518 { 08519 enum check_auth_result res = AUTH_NOT_FOUND; 08520 struct sip_peer *peer; 08521 char tmp[256]; 08522 char *name, *c; 08523 char *t; 08524 char *domain; 08525 08526 /* Terminate URI */ 08527 t = uri; 08528 while(*t && (*t > 32) && (*t != ';')) 08529 t++; 08530 *t = '\0'; 08531 08532 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08533 if (pedanticsipchecking) 08534 ast_uri_decode(tmp); 08535 08536 c = get_in_brackets(tmp); 08537 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08538 08539 if (!strncasecmp(c, "sip:", 4)) { 08540 name = c + 4; 08541 } else { 08542 name = c; 08543 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08544 } 08545 08546 /* Strip off the domain name */ 08547 if ((c = strchr(name, '@'))) { 08548 *c++ = '\0'; 08549 domain = c; 08550 if ((c = strchr(domain, ':'))) /* Remove :port */ 08551 *c = '\0'; 08552 if (!AST_LIST_EMPTY(&domain_list)) { 08553 if (!check_sip_domain(domain, NULL, 0)) { 08554 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08555 return AUTH_UNKNOWN_DOMAIN; 08556 } 08557 } 08558 } 08559 08560 ast_string_field_set(p, exten, name); 08561 build_contact(p); 08562 peer = find_peer(name, NULL, 1); 08563 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08564 /* Peer fails ACL check */ 08565 if (peer) { 08566 ASTOBJ_UNREF(peer, sip_destroy_peer); 08567 peer = NULL; 08568 res = AUTH_ACL_FAILED; 08569 } else 08570 res = AUTH_NOT_FOUND; 08571 } 08572 if (peer) { 08573 /* Set Frame packetization */ 08574 if (p->rtp) { 08575 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08576 p->autoframing = peer->autoframing; 08577 } 08578 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08579 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08580 res = AUTH_PEER_NOT_DYNAMIC; 08581 } else { 08582 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08583 transmit_response(p, "100 Trying", req); 08584 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08585 sip_cancel_destroy(p); 08586 08587 /* We have a succesful registration attemp with proper authentication, 08588 now, update the peer */ 08589 switch (parse_register_contact(p, peer, req)) { 08590 case PARSE_REGISTER_FAILED: 08591 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08592 transmit_response_with_date(p, "400 Bad Request", req); 08593 peer->lastmsgssent = -1; 08594 res = 0; 08595 break; 08596 case PARSE_REGISTER_QUERY: 08597 transmit_response_with_date(p, "200 OK", req); 08598 peer->lastmsgssent = -1; 08599 res = 0; 08600 break; 08601 case PARSE_REGISTER_UPDATE: 08602 update_peer(peer, p->expiry); 08603 /* Say OK and ask subsystem to retransmit msg counter */ 08604 transmit_response_with_date(p, "200 OK", req); 08605 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08606 peer->lastmsgssent = -1; 08607 res = 0; 08608 break; 08609 } 08610 } 08611 } 08612 } 08613 if (!peer && autocreatepeer) { 08614 /* Create peer if we have autocreate mode enabled */ 08615 peer = temp_peer(name); 08616 if (peer) { 08617 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08618 sip_cancel_destroy(p); 08619 switch (parse_register_contact(p, peer, req)) { 08620 case PARSE_REGISTER_FAILED: 08621 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08622 transmit_response_with_date(p, "400 Bad Request", req); 08623 peer->lastmsgssent = -1; 08624 res = 0; 08625 break; 08626 case PARSE_REGISTER_QUERY: 08627 transmit_response_with_date(p, "200 OK", req); 08628 peer->lastmsgssent = -1; 08629 res = 0; 08630 break; 08631 case PARSE_REGISTER_UPDATE: 08632 /* Say OK and ask subsystem to retransmit msg counter */ 08633 transmit_response_with_date(p, "200 OK", req); 08634 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08635 peer->lastmsgssent = -1; 08636 res = 0; 08637 break; 08638 } 08639 } 08640 } 08641 if (!res) { 08642 ast_device_state_changed("SIP/%s", peer->name); 08643 } 08644 if (res < 0) { 08645 switch (res) { 08646 case AUTH_SECRET_FAILED: 08647 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08648 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08649 break; 08650 case AUTH_USERNAME_MISMATCH: 08651 /* Username and digest username does not match. 08652 Asterisk uses the From: username for authentication. We need the 08653 users to use the same authentication user name until we support 08654 proper authentication by digest auth name */ 08655 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08656 break; 08657 case AUTH_NOT_FOUND: 08658 case AUTH_PEER_NOT_DYNAMIC: 08659 case AUTH_ACL_FAILED: 08660 if (global_alwaysauthreject) { 08661 transmit_fake_auth_response(p, &p->initreq, 1); 08662 } else { 08663 /* URI not found */ 08664 if (res == AUTH_PEER_NOT_DYNAMIC) 08665 transmit_response(p, "403 Forbidden", &p->initreq); 08666 else 08667 transmit_response(p, "404 Not found", &p->initreq); 08668 } 08669 break; 08670 default: 08671 break; 08672 } 08673 } 08674 if (peer) 08675 ASTOBJ_UNREF(peer, sip_destroy_peer); 08676 08677 return res; 08678 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 7361 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.
07362 { 07363 switch(regstate) { 07364 case REG_STATE_FAILED: 07365 return "Failed"; 07366 case REG_STATE_UNREGISTERED: 07367 return "Unregistered"; 07368 case REG_STATE_REGSENT: 07369 return "Request Sent"; 07370 case REG_STATE_AUTHSENT: 07371 return "Auth. Sent"; 07372 case REG_STATE_REGISTERED: 07373 return "Registered"; 07374 case REG_STATE_REJECTED: 07375 return "Rejected"; 07376 case REG_STATE_TIMEOUT: 07377 return "Timeout"; 07378 case REG_STATE_NOAUTH: 07379 return "No Authentication"; 07380 default: 07381 return "Unknown"; 07382 } 07383 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17785 of file chan_sip.c.
References sip_reload().
17786 { 17787 return sip_reload(0, 0, NULL); 17788 }
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 16682 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.
16683 { 16684 struct ast_config *cfg, *ucfg; 16685 struct ast_variable *v; 16686 struct sip_peer *peer; 16687 struct sip_user *user; 16688 struct ast_hostent ahp; 16689 char *cat, *stringp, *context, *oldregcontext; 16690 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16691 struct hostent *hp; 16692 int format; 16693 struct ast_flags dummy[2]; 16694 int auto_sip_domains = FALSE; 16695 struct sockaddr_in old_bindaddr = bindaddr; 16696 int registry_count = 0, peer_count = 0, user_count = 0; 16697 unsigned int temp_tos = 0; 16698 struct ast_flags debugflag = {0}; 16699 16700 cfg = ast_config_load(config); 16701 16702 /* We *must* have a config file otherwise stop immediately */ 16703 if (!cfg) { 16704 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16705 return -1; 16706 } 16707 16708 if (option_debug > 3) 16709 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 16710 16711 clear_realm_authentication(authl); 16712 clear_sip_domains(); 16713 authl = NULL; 16714 16715 /* First, destroy all outstanding registry calls */ 16716 /* This is needed, since otherwise active registry entries will not be destroyed */ 16717 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 16718 ASTOBJ_RDLOCK(iterator); 16719 if (iterator->call) { 16720 if (option_debug > 2) 16721 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 16722 /* This will also remove references to the registry */ 16723 sip_destroy(iterator->call); 16724 } 16725 ASTOBJ_UNLOCK(iterator); 16726 16727 } while(0)); 16728 16729 /* Then, actually destroy users and registry */ 16730 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 16731 if (option_debug > 3) 16732 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 16733 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 16734 if (option_debug > 3) 16735 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 16736 ASTOBJ_CONTAINER_MARKALL(&peerl); 16737 16738 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16739 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16740 oldregcontext = oldcontexts; 16741 16742 /* Clear all flags before setting default values */ 16743 /* Preserve debugging settings for console */ 16744 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16745 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16746 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16747 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16748 16749 /* Reset IP addresses */ 16750 memset(&bindaddr, 0, sizeof(bindaddr)); 16751 ast_free_ha(localaddr); 16752 memset(&localaddr, 0, sizeof(localaddr)); 16753 memset(&externip, 0, sizeof(externip)); 16754 memset(&default_prefs, 0 , sizeof(default_prefs)); 16755 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16756 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16757 ourport = STANDARD_SIP_PORT; 16758 srvlookup = DEFAULT_SRVLOOKUP; 16759 global_tos_sip = DEFAULT_TOS_SIP; 16760 global_tos_audio = DEFAULT_TOS_AUDIO; 16761 global_tos_video = DEFAULT_TOS_VIDEO; 16762 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16763 externexpire = 0; /* Expiration for DNS re-issuing */ 16764 externrefresh = 10; 16765 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16766 16767 /* Reset channel settings to default before re-configuring */ 16768 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16769 global_regcontext[0] = '\0'; 16770 expiry = DEFAULT_EXPIRY; 16771 global_notifyringing = DEFAULT_NOTIFYRINGING; 16772 global_limitonpeers = FALSE; 16773 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16774 global_notifyhold = FALSE; 16775 global_alwaysauthreject = 0; 16776 global_allowsubscribe = FALSE; 16777 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16778 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16779 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16780 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16781 else 16782 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16783 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16784 compactheaders = DEFAULT_COMPACTHEADERS; 16785 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16786 global_regattempts_max = 0; 16787 pedanticsipchecking = DEFAULT_PEDANTIC; 16788 global_mwitime = DEFAULT_MWITIME; 16789 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16790 global_autoframing = 0; 16791 global_allowguest = DEFAULT_ALLOWGUEST; 16792 global_rtptimeout = 0; 16793 global_rtpholdtimeout = 0; 16794 global_rtpkeepalive = 0; 16795 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16796 global_rtautoclear = 120; 16797 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16798 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16799 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16800 16801 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16802 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16803 default_subscribecontext[0] = '\0'; 16804 default_language[0] = '\0'; 16805 default_fromdomain[0] = '\0'; 16806 default_qualify = DEFAULT_QUALIFY; 16807 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16808 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16809 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16810 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16811 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16812 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16813 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16814 16815 /* Debugging settings, always default to off */ 16816 dumphistory = FALSE; 16817 recordhistory = FALSE; 16818 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16819 16820 /* Misc settings for the channel */ 16821 global_relaxdtmf = FALSE; 16822 global_callevents = FALSE; 16823 global_t1min = DEFAULT_T1MIN; 16824 16825 global_matchexterniplocally = FALSE; 16826 16827 /* Copy the default jb config over global_jbconf */ 16828 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16829 16830 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16831 16832 /* Read the [general] config section of sip.conf (or from realtime config) */ 16833 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16834 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16835 continue; 16836 /* handle jb conf */ 16837 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16838 continue; 16839 16840 /* Create the interface list */ 16841 if (!strcasecmp(v->name, "context")) { 16842 ast_copy_string(default_context, v->value, sizeof(default_context)); 16843 } else if (!strcasecmp(v->name, "subscribecontext")) { 16844 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 16845 } else if (!strcasecmp(v->name, "allowguest")) { 16846 global_allowguest = ast_true(v->value) ? 1 : 0; 16847 } else if (!strcasecmp(v->name, "realm")) { 16848 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16849 } else if (!strcasecmp(v->name, "useragent")) { 16850 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16851 if (option_debug) 16852 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16853 } else if (!strcasecmp(v->name, "allowtransfer")) { 16854 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16855 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16856 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16857 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16858 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16859 } else if (!strcasecmp(v->name, "rtupdate")) { 16860 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16861 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16862 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16863 } else if (!strcasecmp(v->name, "t1min")) { 16864 global_t1min = atoi(v->value); 16865 } else if (!strcasecmp(v->name, "rtautoclear")) { 16866 int i = atoi(v->value); 16867 if (i > 0) 16868 global_rtautoclear = i; 16869 else 16870 i = 0; 16871 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16872 } else if (!strcasecmp(v->name, "usereqphone")) { 16873 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16874 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16875 global_relaxdtmf = ast_true(v->value); 16876 } else if (!strcasecmp(v->name, "checkmwi")) { 16877 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16878 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16879 global_mwitime = DEFAULT_MWITIME; 16880 } 16881 } else if (!strcasecmp(v->name, "vmexten")) { 16882 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16883 } else if (!strcasecmp(v->name, "rtptimeout")) { 16884 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16885 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16886 global_rtptimeout = 0; 16887 } 16888 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16889 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16890 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16891 global_rtpholdtimeout = 0; 16892 } 16893 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16894 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16895 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16896 global_rtpkeepalive = 0; 16897 } 16898 } else if (!strcasecmp(v->name, "compactheaders")) { 16899 compactheaders = ast_true(v->value); 16900 } else if (!strcasecmp(v->name, "notifymimetype")) { 16901 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 16902 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 16903 global_limitonpeers = ast_true(v->value); 16904 } else if (!strcasecmp(v->name, "directrtpsetup")) { 16905 global_directrtpsetup = ast_true(v->value); 16906 } else if (!strcasecmp(v->name, "notifyringing")) { 16907 global_notifyringing = ast_true(v->value); 16908 } else if (!strcasecmp(v->name, "notifyhold")) { 16909 global_notifyhold = ast_true(v->value); 16910 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 16911 global_alwaysauthreject = ast_true(v->value); 16912 } else if (!strcasecmp(v->name, "mohinterpret") 16913 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16914 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 16915 } else if (!strcasecmp(v->name, "mohsuggest")) { 16916 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 16917 } else if (!strcasecmp(v->name, "language")) { 16918 ast_copy_string(default_language, v->value, sizeof(default_language)); 16919 } else if (!strcasecmp(v->name, "regcontext")) { 16920 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 16921 stringp = newcontexts; 16922 /* Let's remove any contexts that are no longer defined in regcontext */ 16923 cleanup_stale_contexts(stringp, oldregcontext); 16924 /* Create contexts if they don't exist already */ 16925 while ((context = strsep(&stringp, "&"))) { 16926 if (!ast_context_find(context)) 16927 ast_context_create(NULL, context,"SIP"); 16928 } 16929 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 16930 } else if (!strcasecmp(v->name, "callerid")) { 16931 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 16932 } else if (!strcasecmp(v->name, "fromdomain")) { 16933 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 16934 } else if (!strcasecmp(v->name, "outboundproxy")) { 16935 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 16936 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 16937 } else if (!strcasecmp(v->name, "outboundproxyport")) { 16938 /* Port needs to be after IP */ 16939 sscanf(v->value, "%d", &format); 16940 outboundproxyip.sin_port = htons(format); 16941 } else if (!strcasecmp(v->name, "autocreatepeer")) { 16942 autocreatepeer = ast_true(v->value); 16943 } else if (!strcasecmp(v->name, "srvlookup")) { 16944 srvlookup = ast_true(v->value); 16945 } else if (!strcasecmp(v->name, "pedantic")) { 16946 pedanticsipchecking = ast_true(v->value); 16947 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 16948 max_expiry = atoi(v->value); 16949 if (max_expiry < 1) 16950 max_expiry = DEFAULT_MAX_EXPIRY; 16951 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 16952 min_expiry = atoi(v->value); 16953 if (min_expiry < 1) 16954 min_expiry = DEFAULT_MIN_EXPIRY; 16955 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 16956 default_expiry = atoi(v->value); 16957 if (default_expiry < 1) 16958 default_expiry = DEFAULT_DEFAULT_EXPIRY; 16959 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 16960 if (ast_true(v->value)) 16961 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16962 } else if (!strcasecmp(v->name, "dumphistory")) { 16963 dumphistory = ast_true(v->value); 16964 } else if (!strcasecmp(v->name, "recordhistory")) { 16965 recordhistory = ast_true(v->value); 16966 } else if (!strcasecmp(v->name, "registertimeout")) { 16967 global_reg_timeout = atoi(v->value); 16968 if (global_reg_timeout < 1) 16969 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16970 } else if (!strcasecmp(v->name, "registerattempts")) { 16971 global_regattempts_max = atoi(v->value); 16972 } else if (!strcasecmp(v->name, "bindaddr")) { 16973 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 16974 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 16975 } else { 16976 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 16977 } 16978 } else if (!strcasecmp(v->name, "localnet")) { 16979 struct ast_ha *na; 16980 if (!(na = ast_append_ha("d", v->value, localaddr))) 16981 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 16982 else 16983 localaddr = na; 16984 } else if (!strcasecmp(v->name, "localmask")) { 16985 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 16986 } else if (!strcasecmp(v->name, "externip")) { 16987 if (!(hp = ast_gethostbyname(v->value, &ahp))) 16988 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 16989 else 16990 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16991 externexpire = 0; 16992 } else if (!strcasecmp(v->name, "externhost")) { 16993 ast_copy_string(externhost, v->value, sizeof(externhost)); 16994 if (!(hp = ast_gethostbyname(externhost, &ahp))) 16995 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 16996 else 16997 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16998 externexpire = time(NULL); 16999 } else if (!strcasecmp(v->name, "externrefresh")) { 17000 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17001 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17002 externrefresh = 10; 17003 } 17004 } else if (!strcasecmp(v->name, "allow")) { 17005 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17006 } else if (!strcasecmp(v->name, "disallow")) { 17007 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17008 } else if (!strcasecmp(v->name, "autoframing")) { 17009 global_autoframing = ast_true(v->value); 17010 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17011 allow_external_domains = ast_true(v->value); 17012 } else if (!strcasecmp(v->name, "autodomain")) { 17013 auto_sip_domains = ast_true(v->value); 17014 } else if (!strcasecmp(v->name, "domain")) { 17015 char *domain = ast_strdupa(v->value); 17016 char *context = strchr(domain, ','); 17017 17018 if (context) 17019 *context++ = '\0'; 17020 17021 if (option_debug && ast_strlen_zero(context)) 17022 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17023 if (ast_strlen_zero(domain)) 17024 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17025 else 17026 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17027 } else if (!strcasecmp(v->name, "register")) { 17028 if (sip_register(v->value, v->lineno) == 0) 17029 registry_count++; 17030 } else if (!strcasecmp(v->name, "tos")) { 17031 if (!ast_str2tos(v->value, &temp_tos)) { 17032 global_tos_sip = temp_tos; 17033 global_tos_audio = temp_tos; 17034 global_tos_video = temp_tos; 17035 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17036 } else 17037 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17038 } else if (!strcasecmp(v->name, "tos_sip")) { 17039 if (ast_str2tos(v->value, &global_tos_sip)) 17040 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17041 } else if (!strcasecmp(v->name, "tos_audio")) { 17042 if (ast_str2tos(v->value, &global_tos_audio)) 17043 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17044 } else if (!strcasecmp(v->name, "tos_video")) { 17045 if (ast_str2tos(v->value, &global_tos_video)) 17046 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17047 } else if (!strcasecmp(v->name, "bindport")) { 17048 if (sscanf(v->value, "%d", &ourport) == 1) { 17049 bindaddr.sin_port = htons(ourport); 17050 } else { 17051 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17052 } 17053 } else if (!strcasecmp(v->name, "qualify")) { 17054 if (!strcasecmp(v->value, "no")) { 17055 default_qualify = 0; 17056 } else if (!strcasecmp(v->value, "yes")) { 17057 default_qualify = DEFAULT_MAXMS; 17058 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17059 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17060 default_qualify = 0; 17061 } 17062 } else if (!strcasecmp(v->name, "callevents")) { 17063 global_callevents = ast_true(v->value); 17064 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17065 default_maxcallbitrate = atoi(v->value); 17066 if (default_maxcallbitrate < 0) 17067 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17068 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17069 global_matchexterniplocally = ast_true(v->value); 17070 } 17071 } 17072 17073 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17074 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17075 allow_external_domains = 1; 17076 } 17077 17078 /* Build list of authentication to various SIP realms, i.e. service providers */ 17079 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17080 /* Format for authentication is auth = username:password@realm */ 17081 if (!strcasecmp(v->name, "auth")) 17082 authl = add_realm_authentication(authl, v->value, v->lineno); 17083 } 17084 17085 ucfg = ast_config_load("users.conf"); 17086 if (ucfg) { 17087 struct ast_variable *gen; 17088 int genhassip, genregistersip; 17089 const char *hassip, *registersip; 17090 17091 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17092 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17093 gen = ast_variable_browse(ucfg, "general"); 17094 cat = ast_category_browse(ucfg, NULL); 17095 while (cat) { 17096 if (strcasecmp(cat, "general")) { 17097 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17098 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17099 if (ast_true(hassip) || (!hassip && genhassip)) { 17100 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17101 if (peer) { 17102 ast_device_state_changed("SIP/%s", peer->name); 17103 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17104 ASTOBJ_UNREF(peer, sip_destroy_peer); 17105 peer_count++; 17106 } 17107 } 17108 if (ast_true(registersip) || (!registersip && genregistersip)) { 17109 char tmp[256]; 17110 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17111 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17112 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17113 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17114 if (!host) 17115 host = ast_variable_retrieve(ucfg, "general", "host"); 17116 if (!username) 17117 username = ast_variable_retrieve(ucfg, "general", "username"); 17118 if (!secret) 17119 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17120 if (!contact) 17121 contact = "s"; 17122 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17123 if (!ast_strlen_zero(secret)) 17124 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17125 else 17126 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17127 if (sip_register(tmp, 0) == 0) 17128 registry_count++; 17129 } 17130 } 17131 } 17132 cat = ast_category_browse(ucfg, cat); 17133 } 17134 ast_config_destroy(ucfg); 17135 } 17136 17137 17138 /* Load peers, users and friends */ 17139 cat = NULL; 17140 while ( (cat = ast_category_browse(cfg, cat)) ) { 17141 const char *utype; 17142 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17143 continue; 17144 utype = ast_variable_retrieve(cfg, cat, "type"); 17145 if (!utype) { 17146 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17147 continue; 17148 } else { 17149 int is_user = 0, is_peer = 0; 17150 if (!strcasecmp(utype, "user")) 17151 is_user = 1; 17152 else if (!strcasecmp(utype, "friend")) 17153 is_user = is_peer = 1; 17154 else if (!strcasecmp(utype, "peer")) 17155 is_peer = 1; 17156 else { 17157 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17158 continue; 17159 } 17160 if (is_user) { 17161 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 17162 if (user) { 17163 ASTOBJ_CONTAINER_LINK(&userl,user); 17164 ASTOBJ_UNREF(user, sip_destroy_user); 17165 user_count++; 17166 } 17167 } 17168 if (is_peer) { 17169 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17170 if (peer) { 17171 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17172 ASTOBJ_UNREF(peer, sip_destroy_peer); 17173 peer_count++; 17174 } 17175 } 17176 } 17177 } 17178 if (ast_find_ourip(&__ourip, bindaddr)) { 17179 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17180 ast_config_destroy(cfg); 17181 return 0; 17182 } 17183 if (!ntohs(bindaddr.sin_port)) 17184 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17185 bindaddr.sin_family = AF_INET; 17186 ast_mutex_lock(&netlock); 17187 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 17188 close(sipsock); 17189 sipsock = -1; 17190 } 17191 if (sipsock < 0) { 17192 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17193 if (sipsock < 0) { 17194 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17195 ast_config_destroy(cfg); 17196 return -1; 17197 } else { 17198 /* Allow SIP clients on the same host to access us: */ 17199 const int reuseFlag = 1; 17200 17201 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17202 (const char*)&reuseFlag, 17203 sizeof reuseFlag); 17204 17205 ast_enable_packet_fragmentation(sipsock); 17206 17207 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17208 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 17209 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17210 strerror(errno)); 17211 close(sipsock); 17212 sipsock = -1; 17213 } else { 17214 if (option_verbose > 1) { 17215 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 17216 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17217 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 17218 } 17219 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17220 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 17221 } 17222 } 17223 } 17224 ast_mutex_unlock(&netlock); 17225 17226 /* Add default domains - host name, IP address and IP:port */ 17227 /* Only do this if user added any sip domain with "localdomains" */ 17228 /* In order to *not* break backwards compatibility */ 17229 /* Some phones address us at IP only, some with additional port number */ 17230 if (auto_sip_domains) { 17231 char temp[MAXHOSTNAMELEN]; 17232 17233 /* First our default IP address */ 17234 if (bindaddr.sin_addr.s_addr) 17235 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 17236 else 17237 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 17238 17239 /* Our extern IP address, if configured */ 17240 if (externip.sin_addr.s_addr) 17241 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17242 17243 /* Extern host name (NAT traversal support) */ 17244 if (!ast_strlen_zero(externhost)) 17245 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17246 17247 /* Our host name */ 17248 if (!gethostname(temp, sizeof(temp))) 17249 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17250 } 17251 17252 /* Release configuration from memory */ 17253 ast_config_destroy(cfg); 17254 17255 /* Load the list of manual NOTIFY types to support */ 17256 if (notify_types) 17257 ast_config_destroy(notify_types); 17258 notify_types = ast_config_load(notify_config); 17259 17260 /* Done, tell the manager */ 17261 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); 17262 17263 return 0; 17264 }
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 11384 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().
11385 { 11386 char tmp[512]; 11387 char *c; 11388 char oldnonce[256]; 11389 11390 /* table of recognised keywords, and places where they should be copied */ 11391 const struct x { 11392 const char *key; 11393 int field_index; 11394 } *i, keys[] = { 11395 { "realm=", ast_string_field_index(p, realm) }, 11396 { "nonce=", ast_string_field_index(p, nonce) }, 11397 { "opaque=", ast_string_field_index(p, opaque) }, 11398 { "qop=", ast_string_field_index(p, qop) }, 11399 { "domain=", ast_string_field_index(p, domain) }, 11400 { NULL, 0 }, 11401 }; 11402 11403 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11404 if (ast_strlen_zero(tmp)) 11405 return -1; 11406 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11407 ast_log(LOG_WARNING, "missing Digest.\n"); 11408 return -1; 11409 } 11410 c = tmp + strlen("Digest "); 11411 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11412 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11413 for (i = keys; i->key != NULL; i++) { 11414 char *src, *separator; 11415 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11416 continue; 11417 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11418 c += strlen(i->key); 11419 if (*c == '"') { 11420 src = ++c; 11421 separator = "\""; 11422 } else { 11423 src = c; 11424 separator = ","; 11425 } 11426 strsep(&c, separator); /* clear separator and move ptr */ 11427 ast_string_field_index_set(p, i->field_index, src); 11428 break; 11429 } 11430 if (i->key == NULL) /* not found, try ',' */ 11431 strsep(&c, ","); 11432 } 11433 /* Reset nonce count */ 11434 if (strcmp(p->nonce, oldnonce)) 11435 p->noncecount = 0; 11436 11437 /* Save auth data for following registrations */ 11438 if (p->registry) { 11439 struct sip_registry *r = p->registry; 11440 11441 if (strcmp(r->nonce, p->nonce)) { 11442 ast_string_field_set(r, realm, p->realm); 11443 ast_string_field_set(r, nonce, p->nonce); 11444 ast_string_field_set(r, domain, p->domain); 11445 ast_string_field_set(r, opaque, p->opaque); 11446 ast_string_field_set(r, qop, p->qop); 11447 r->noncecount = 0; 11448 } 11449 } 11450 return build_reply_digest(p, sipmethod, digest, digest_len); 11451 }
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 5851 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.
05852 { 05853 struct sip_request *orig = &p->initreq; 05854 char stripped[80]; 05855 char tmp[80]; 05856 char newto[256]; 05857 const char *c; 05858 const char *ot, *of; 05859 int is_strict = FALSE; /*!< Strict routing flag */ 05860 05861 memset(req, 0, sizeof(struct sip_request)); 05862 05863 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05864 05865 if (!seqno) { 05866 p->ocseq++; 05867 seqno = p->ocseq; 05868 } 05869 05870 if (newbranch) { 05871 p->branch ^= ast_random(); 05872 build_via(p); 05873 } 05874 05875 /* Check for strict or loose router */ 05876 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05877 is_strict = TRUE; 05878 if (sipdebug) 05879 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05880 } 05881 05882 if (sipmethod == SIP_CANCEL) 05883 c = p->initreq.rlPart2; /* Use original URI */ 05884 else if (sipmethod == SIP_ACK) { 05885 /* Use URI from Contact: in 200 OK (if INVITE) 05886 (we only have the contacturi on INVITEs) */ 05887 if (!ast_strlen_zero(p->okcontacturi)) 05888 c = is_strict ? p->route->hop : p->okcontacturi; 05889 else 05890 c = p->initreq.rlPart2; 05891 } else if (!ast_strlen_zero(p->okcontacturi)) 05892 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05893 else if (!ast_strlen_zero(p->uri)) 05894 c = p->uri; 05895 else { 05896 char *n; 05897 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05898 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05899 sizeof(stripped)); 05900 n = get_in_brackets(stripped); 05901 c = strsep(&n, ";"); /* trim ; and beyond */ 05902 } 05903 init_req(req, sipmethod, c); 05904 05905 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05906 05907 add_header(req, "Via", p->via); 05908 if (p->route) { 05909 set_destination(p, p->route->hop); 05910 add_route(req, is_strict ? p->route->next : p->route); 05911 } 05912 05913 ot = get_header(orig, "To"); 05914 of = get_header(orig, "From"); 05915 05916 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05917 as our original request, including tag (or presumably lack thereof) */ 05918 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05919 /* Add the proper tag if we don't have it already. If they have specified 05920 their tag, use it. Otherwise, use our own tag */ 05921 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05922 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05923 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05924 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05925 else 05926 snprintf(newto, sizeof(newto), "%s", ot); 05927 ot = newto; 05928 } 05929 05930 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05931 add_header(req, "From", of); 05932 add_header(req, "To", ot); 05933 } else { 05934 add_header(req, "From", ot); 05935 add_header(req, "To", of); 05936 } 05937 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05938 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05939 add_header(req, "Contact", p->our_contact); 05940 05941 copy_header(req, orig, "Call-ID"); 05942 add_header(req, "CSeq", tmp); 05943 05944 if (!ast_strlen_zero(global_useragent)) 05945 add_header(req, "User-Agent", global_useragent); 05946 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05947 05948 if (!ast_strlen_zero(p->rpid)) 05949 add_header(req, "Remote-Party-ID", p->rpid); 05950 05951 return 0; 05952 }
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 5803 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.
05804 { 05805 char newto[256]; 05806 const char *ot; 05807 05808 init_resp(resp, msg); 05809 copy_via_headers(p, resp, req, "Via"); 05810 if (msg[0] == '1' || msg[0] == '2') 05811 copy_all_header(resp, req, "Record-Route"); 05812 copy_header(resp, req, "From"); 05813 ot = get_header(req, "To"); 05814 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05815 /* Add the proper tag if we don't have it already. If they have specified 05816 their tag, use it. Otherwise, use our own tag */ 05817 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05818 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05819 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05820 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05821 else 05822 ast_copy_string(newto, ot, sizeof(newto)); 05823 ot = newto; 05824 } 05825 add_header(resp, "To", ot); 05826 copy_header(resp, req, "Call-ID"); 05827 copy_header(resp, req, "CSeq"); 05828 if (!ast_strlen_zero(global_useragent)) 05829 add_header(resp, "User-Agent", global_useragent); 05830 add_header(resp, "Allow", ALLOWED_METHODS); 05831 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05832 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05833 /* For registration responses, we also need expiry and 05834 contact info */ 05835 char tmp[256]; 05836 05837 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05838 add_header(resp, "Expires", tmp); 05839 if (p->expiry) { /* Only add contact if we have an expiry time */ 05840 char contact[BUFSIZ]; 05841 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05842 add_header(resp, "Contact", contact); /* Not when we unregister */ 05843 } 05844 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 05845 add_header(resp, "Contact", p->our_contact); 05846 } 05847 return 0; 05848 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15628 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.
15629 { 15630 /* If we're supposed to be stopped -- stay stopped */ 15631 if (monitor_thread == AST_PTHREADT_STOP) 15632 return 0; 15633 ast_mutex_lock(&monlock); 15634 if (monitor_thread == pthread_self()) { 15635 ast_mutex_unlock(&monlock); 15636 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15637 return -1; 15638 } 15639 if (monitor_thread != AST_PTHREADT_NULL) { 15640 /* Wake up the thread */ 15641 pthread_kill(monitor_thread, SIGURG); 15642 } else { 15643 /* Start a new monitor */ 15644 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15645 ast_mutex_unlock(&monlock); 15646 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15647 return -1; 15648 } 15649 } 15650 ast_mutex_unlock(&monlock); 15651 return 0; 15652 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1892 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.
01893 { 01894 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01895 int reschedule = DEFAULT_RETRANS; 01896 int xmitres = 0; 01897 01898 /* Lock channel PVT */ 01899 ast_mutex_lock(&pkt->owner->lock); 01900 01901 if (pkt->retrans < MAX_RETRANS) { 01902 pkt->retrans++; 01903 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01904 if (sipdebug && option_debug > 3) 01905 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); 01906 } else { 01907 int siptimer_a; 01908 01909 if (sipdebug && option_debug > 3) 01910 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01911 if (!pkt->timer_a) 01912 pkt->timer_a = 2 ; 01913 else 01914 pkt->timer_a = 2 * pkt->timer_a; 01915 01916 /* For non-invites, a maximum of 4 secs */ 01917 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01918 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01919 siptimer_a = 4000; 01920 01921 /* Reschedule re-transmit */ 01922 reschedule = siptimer_a; 01923 if (option_debug > 3) 01924 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); 01925 } 01926 01927 if (sip_debug_test_pvt(pkt->owner)) { 01928 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01929 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01930 pkt->retrans, sip_nat_mode(pkt->owner), 01931 ast_inet_ntoa(dst->sin_addr), 01932 ntohs(dst->sin_port), pkt->data); 01933 } 01934 01935 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01936 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01937 ast_mutex_unlock(&pkt->owner->lock); 01938 if (xmitres == XMIT_ERROR) 01939 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01940 else 01941 return reschedule; 01942 } 01943 /* Too many retries */ 01944 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01945 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01946 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"); 01947 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01948 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01949 } 01950 if (xmitres == XMIT_ERROR) { 01951 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01952 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01953 } else 01954 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01955 01956 pkt->retransid = -1; 01957 01958 if (ast_test_flag(pkt, FLAG_FATAL)) { 01959 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01960 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01961 usleep(1); 01962 ast_mutex_lock(&pkt->owner->lock); 01963 } 01964 01965 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01966 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01967 01968 if (pkt->owner->owner) { 01969 sip_alreadygone(pkt->owner); 01970 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01971 ast_queue_hangup(pkt->owner->owner); 01972 ast_channel_unlock(pkt->owner->owner); 01973 } else { 01974 /* If no channel owner, destroy now */ 01975 01976 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01977 if (pkt->method != SIP_OPTIONS) { 01978 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01979 sip_alreadygone(pkt->owner); 01980 if (option_debug) 01981 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01982 } 01983 } 01984 } 01985 01986 if (pkt->method == SIP_BYE) { 01987 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01988 if (pkt->owner->owner) 01989 ast_channel_unlock(pkt->owner->owner); 01990 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01991 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01992 } 01993 01994 /* In any case, go ahead and remove the packet */ 01995 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01996 if (cur == pkt) 01997 break; 01998 } 01999 if (cur) { 02000 if (prev) 02001 prev->next = cur->next; 02002 else 02003 pkt->owner->packets = cur->next; 02004 ast_mutex_unlock(&pkt->owner->lock); 02005 free(cur); 02006 pkt = NULL; 02007 } else 02008 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02009 if (pkt) 02010 ast_mutex_unlock(&pkt->owner->lock); 02011 return 0; 02012 }
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 2267 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.
02268 { 02269 int res; 02270 02271 add_blank(req); 02272 if (sip_debug_test_pvt(p)) { 02273 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02274 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); 02275 else 02276 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); 02277 } 02278 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02279 struct sip_request tmp; 02280 parse_copy(&tmp, req); 02281 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02282 } 02283 res = (reliable) ? 02284 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02285 __sip_xmit(p, req->data, req->len); 02286 return res; 02287 }
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 2239 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.
02240 { 02241 int res; 02242 02243 add_blank(req); 02244 if (sip_debug_test_pvt(p)) { 02245 const struct sockaddr_in *dst = sip_real_dst(p); 02246 02247 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02248 reliable ? "Reliably " : "", sip_nat_mode(p), 02249 ast_inet_ntoa(dst->sin_addr), 02250 ntohs(dst->sin_port), req->data); 02251 } 02252 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02253 struct sip_request tmp; 02254 parse_copy(&tmp, req); 02255 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02256 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02257 } 02258 res = (reliable) ? 02259 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02260 __sip_xmit(p, req->data, req->len); 02261 if (res > 0) 02262 return 0; 02263 return res; 02264 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7944 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().
07945 { 07946 struct hostent *hp; 07947 struct ast_hostent ahp; 07948 int port; 07949 char *c, *host, *pt; 07950 char *contact; 07951 07952 07953 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07954 /* NAT: Don't trust the contact field. Just use what they came to us 07955 with. */ 07956 pvt->sa = pvt->recv; 07957 return 0; 07958 } 07959 07960 07961 /* Work on a copy */ 07962 contact = ast_strdupa(pvt->fullcontact); 07963 07964 /* Make sure it's a SIP URL */ 07965 if (strncasecmp(contact, "sip:", 4)) { 07966 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07967 } else 07968 contact += 4; 07969 07970 /* Ditch arguments */ 07971 /* XXX this code is replicated also shortly below */ 07972 07973 /* Grab host */ 07974 host = strchr(contact, '@'); 07975 if (!host) { /* No username part */ 07976 host = contact; 07977 c = NULL; 07978 } else { 07979 *host++ = '\0'; 07980 } 07981 pt = strchr(host, ':'); 07982 if (pt) { 07983 *pt++ = '\0'; 07984 port = atoi(pt); 07985 } else 07986 port = STANDARD_SIP_PORT; 07987 07988 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 07989 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 07990 07991 /* XXX This could block for a long time XXX */ 07992 /* We should only do this if it's a name, not an IP */ 07993 hp = ast_gethostbyname(host, &ahp); 07994 if (!hp) { 07995 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07996 return -1; 07997 } 07998 pvt->sa.sin_family = AF_INET; 07999 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 08000 pvt->sa.sin_port = htons(port); 08001 08002 return 0; 08003 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5712 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().
05713 { 05714 char *h, *maddr, hostname[256]; 05715 int port, hn; 05716 struct hostent *hp; 05717 struct ast_hostent ahp; 05718 int debug=sip_debug_test_pvt(p); 05719 05720 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05721 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05722 05723 if (debug) 05724 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05725 05726 /* Find and parse hostname */ 05727 h = strchr(uri, '@'); 05728 if (h) 05729 ++h; 05730 else { 05731 h = uri; 05732 if (strncasecmp(h, "sip:", 4) == 0) 05733 h += 4; 05734 else if (strncasecmp(h, "sips:", 5) == 0) 05735 h += 5; 05736 } 05737 hn = strcspn(h, ":;>") + 1; 05738 if (hn > sizeof(hostname)) 05739 hn = sizeof(hostname); 05740 ast_copy_string(hostname, h, hn); 05741 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05742 h += hn - 1; 05743 05744 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05745 if (*h == ':') { 05746 /* Parse port */ 05747 ++h; 05748 port = strtol(h, &h, 10); 05749 } 05750 else 05751 port = STANDARD_SIP_PORT; 05752 05753 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05754 maddr = strstr(h, "maddr="); 05755 if (maddr) { 05756 maddr += 6; 05757 hn = strspn(maddr, "0123456789.") + 1; 05758 if (hn > sizeof(hostname)) 05759 hn = sizeof(hostname); 05760 ast_copy_string(hostname, maddr, hn); 05761 } 05762 05763 hp = ast_gethostbyname(hostname, &ahp); 05764 if (hp == NULL) { 05765 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05766 return; 05767 } 05768 p->sa.sin_family = AF_INET; 05769 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05770 p->sa.sin_port = htons(port); 05771 if (debug) 05772 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05773 }
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 15935 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().
15936 { 15937 static int dep_insecure_very = 0; 15938 static int dep_insecure_yes = 0; 15939 15940 if (ast_strlen_zero(value)) 15941 return; 15942 15943 if (!strcasecmp(value, "very")) { 15944 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15945 if(!dep_insecure_very) { 15946 if(lineno != -1) 15947 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 15948 else 15949 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 15950 dep_insecure_very = 1; 15951 } 15952 } 15953 else if (ast_true(value)) { 15954 ast_set_flag(flags, SIP_INSECURE_PORT); 15955 if(!dep_insecure_yes) { 15956 if(lineno != -1) 15957 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 15958 else 15959 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 15960 dep_insecure_yes = 1; 15961 } 15962 } 15963 else if (!ast_false(value)) { 15964 char buf[64]; 15965 char *word, *next; 15966 ast_copy_string(buf, value, sizeof(buf)); 15967 next = buf; 15968 while ((word = strsep(&next, ","))) { 15969 if (!strcasecmp(word, "port")) 15970 ast_set_flag(flags, SIP_INSECURE_PORT); 15971 else if (!strcasecmp(word, "invite")) 15972 ast_set_flag(flags, SIP_INSECURE_INVITE); 15973 else 15974 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 15975 } 15976 } 15977 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16362 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().
16363 { 16364 if (peer->expire == 0) { 16365 /* Don't reset expire or port time during reload 16366 if we have an active registration 16367 */ 16368 peer->expire = -1; 16369 peer->pokeexpire = -1; 16370 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16371 } 16372 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16373 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16374 strcpy(peer->context, default_context); 16375 strcpy(peer->subscribecontext, default_subscribecontext); 16376 strcpy(peer->language, default_language); 16377 strcpy(peer->mohinterpret, default_mohinterpret); 16378 strcpy(peer->mohsuggest, default_mohsuggest); 16379 peer->addr.sin_family = AF_INET; 16380 peer->defaddr.sin_family = AF_INET; 16381 peer->capability = global_capability; 16382 peer->maxcallbitrate = default_maxcallbitrate; 16383 peer->rtptimeout = global_rtptimeout; 16384 peer->rtpholdtimeout = global_rtpholdtimeout; 16385 peer->rtpkeepalive = global_rtpkeepalive; 16386 peer->allowtransfer = global_allowtransfer; 16387 peer->autoframing = global_autoframing; 16388 strcpy(peer->vmexten, default_vmexten); 16389 peer->secret[0] = '\0'; 16390 peer->md5secret[0] = '\0'; 16391 peer->cid_num[0] = '\0'; 16392 peer->cid_name[0] = '\0'; 16393 peer->fromdomain[0] = '\0'; 16394 peer->fromuser[0] = '\0'; 16395 peer->regexten[0] = '\0'; 16396 peer->mailbox[0] = '\0'; 16397 peer->callgroup = 0; 16398 peer->pickupgroup = 0; 16399 peer->maxms = default_qualify; 16400 peer->prefs = default_prefs; 16401 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17603 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().
17604 { 17605 int no = 0; 17606 int ok = FALSE; 17607 char varbuf[30]; 17608 char *inbuf = (char *) data; 17609 17610 if (ast_strlen_zero(inbuf)) { 17611 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17612 return 0; 17613 } 17614 ast_channel_lock(chan); 17615 17616 /* Check for headers */ 17617 while (!ok && no <= 50) { 17618 no++; 17619 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17620 17621 /* Compare without the leading underscore */ 17622 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17623 ok = TRUE; 17624 } 17625 if (ok) { 17626 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17627 if (sipdebug) 17628 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17629 } else { 17630 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17631 } 17632 ast_channel_unlock(chan); 17633 return 0; 17634 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2629 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02630 { 02631 /* We know name is the first field, so we can cast */ 02632 struct sip_peer *p = (struct sip_peer *) name; 02633 return !(!inaddrcmp(&p->addr, sin) || 02634 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02635 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02636 }
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 4390 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().
04392 { 04393 struct sip_pvt *p; 04394 04395 if (!(p = ast_calloc(1, sizeof(*p)))) 04396 return NULL; 04397 04398 if (ast_string_field_init(p, 512)) { 04399 free(p); 04400 return NULL; 04401 } 04402 04403 ast_mutex_init(&p->lock); 04404 04405 p->method = intended_method; 04406 p->initid = -1; 04407 p->waitid = -1; 04408 p->autokillid = -1; 04409 p->subscribed = NONE; 04410 p->stateid = -1; 04411 p->prefs = default_prefs; /* Set default codecs for this call */ 04412 04413 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04414 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04415 04416 if (sin) { 04417 p->sa = *sin; 04418 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04419 p->ourip = __ourip; 04420 } else 04421 p->ourip = __ourip; 04422 04423 /* Copy global flags to this PVT at setup. */ 04424 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04425 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04426 04427 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04428 04429 p->branch = ast_random(); 04430 make_our_tag(p->tag, sizeof(p->tag)); 04431 p->ocseq = INITIAL_CSEQ; 04432 04433 if (sip_methods[intended_method].need_rtp) { 04434 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04435 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04436 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04437 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04438 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04439 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04440 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04441 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04442 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04443 ast_mutex_destroy(&p->lock); 04444 if (p->chanvars) { 04445 ast_variables_destroy(p->chanvars); 04446 p->chanvars = NULL; 04447 } 04448 free(p); 04449 return NULL; 04450 } 04451 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04452 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04453 ast_rtp_settos(p->rtp, global_tos_audio); 04454 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04455 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04456 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04457 if (p->vrtp) { 04458 ast_rtp_settos(p->vrtp, global_tos_video); 04459 ast_rtp_setdtmf(p->vrtp, 0); 04460 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04461 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04462 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04463 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04464 } 04465 if (p->udptl) 04466 ast_udptl_settos(p->udptl, global_tos_audio); 04467 p->maxcallbitrate = default_maxcallbitrate; 04468 } 04469 04470 if (useglobal_nat && sin) { 04471 /* Setup NAT structure according to global settings if we have an address */ 04472 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04473 p->recv = *sin; 04474 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04475 } 04476 04477 if (p->method != SIP_REGISTER) 04478 ast_string_field_set(p, fromdomain, default_fromdomain); 04479 build_via(p); 04480 if (!callid) 04481 build_callid_pvt(p); 04482 else 04483 ast_string_field_set(p, callid, callid); 04484 /* Assign default music on hold class */ 04485 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04486 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04487 p->capability = global_capability; 04488 p->allowtransfer = global_allowtransfer; 04489 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04490 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04491 p->noncodeccapability |= AST_RTP_DTMF; 04492 if (p->udptl) { 04493 p->t38.capability = global_t38_capability; 04494 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04495 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04496 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04497 p->t38.capability |= T38FAX_UDP_EC_FEC; 04498 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04499 p->t38.capability |= T38FAX_UDP_EC_NONE; 04500 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04501 p->t38.jointcapability = p->t38.capability; 04502 } 04503 ast_string_field_set(p, context, default_context); 04504 04505 /* Add to active dialog list */ 04506 ast_mutex_lock(&iflock); 04507 p->next = iflist; 04508 iflist = p; 04509 ast_mutex_unlock(&iflock); 04510 if (option_debug) 04511 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"); 04512 return p; 04513 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1651 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().
01652 { 01653 if (option_debug > 2) 01654 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01655 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01656 }
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 3638 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.
03639 { 03640 int res = 0; 03641 struct sip_pvt *p = ast->tech_pvt; 03642 03643 ast_mutex_lock(&p->lock); 03644 if (ast->_state != AST_STATE_UP) { 03645 try_suggested_sip_codec(p); 03646 03647 ast_setstate(ast, AST_STATE_UP); 03648 if (option_debug) 03649 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03650 if (p->t38.state == T38_PEER_DIRECT) { 03651 p->t38.state = T38_ENABLED; 03652 if (option_debug > 1) 03653 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03654 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03655 } else 03656 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03657 } 03658 ast_mutex_unlock(&p->lock); 03659 return res; 03660 }
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 2933 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.
02934 { 02935 int res, xmitres = 0; 02936 struct sip_pvt *p; 02937 struct varshead *headp; 02938 struct ast_var_t *current; 02939 const char *referer = NULL; /* SIP refererer */ 02940 02941 p = ast->tech_pvt; 02942 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02943 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02944 return -1; 02945 } 02946 02947 /* Check whether there is vxml_url, distinctive ring variables */ 02948 headp=&ast->varshead; 02949 AST_LIST_TRAVERSE(headp,current,entries) { 02950 /* Check whether there is a VXML_URL variable */ 02951 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02952 p->options->vxml_url = ast_var_value(current); 02953 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02954 p->options->uri_options = ast_var_value(current); 02955 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02956 /* Check whether there is a ALERT_INFO variable */ 02957 p->options->distinctive_ring = ast_var_value(current); 02958 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02959 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02960 p->options->addsipheaders = 1; 02961 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02962 /* This is a transfered call */ 02963 p->options->transfer = 1; 02964 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02965 /* This is the referer */ 02966 referer = ast_var_value(current); 02967 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02968 /* We're replacing a call. */ 02969 p->options->replaces = ast_var_value(current); 02970 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02971 p->t38.state = T38_LOCAL_DIRECT; 02972 if (option_debug) 02973 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02974 } 02975 02976 } 02977 02978 res = 0; 02979 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02980 02981 if (p->options->transfer) { 02982 char buf[BUFSIZ/2]; 02983 02984 if (referer) { 02985 if (sipdebug && option_debug > 2) 02986 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02987 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02988 } else 02989 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02990 ast_string_field_set(p, cid_name, buf); 02991 } 02992 if (option_debug) 02993 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02994 02995 res = update_call_counter(p, INC_CALL_RINGING); 02996 if ( res != -1 ) { 02997 p->callingpres = ast->cid.cid_pres; 02998 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 02999 p->jointnoncodeccapability = p->noncodeccapability; 03000 03001 /* If there are no audio formats left to offer, punt */ 03002 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03003 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03004 res = -1; 03005 } else { 03006 p->t38.jointcapability = p->t38.capability; 03007 if (option_debug > 1) 03008 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03009 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03010 if (xmitres == XMIT_ERROR) 03011 return -1; /* Transmission error */ 03012 03013 p->invitestate = INV_CALLING; 03014 03015 /* Initialize auto-congest time */ 03016 if (p->initid > -1) 03017 ast_sched_del(sched, p->initid); 03018 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03019 } 03020 } 03021 return res; 03022 }
static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2127 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().
02128 { 02129 if (p->autokillid > -1) { 02130 ast_sched_del(sched, p->autokillid); 02131 append_history(p, "CancelDestroy", ""); 02132 p->autokillid = -1; 02133 } 02134 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1733 of file chan_sip.c.
References debugaddr, and sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01734 { 01735 if (!sipdebug) 01736 return 0; 01737 if (debugaddr.sin_addr.s_addr) { 01738 if (((ntohs(debugaddr.sin_port) != 0) 01739 && (debugaddr.sin_port != addr->sin_port)) 01740 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01741 return 0; 01742 } 01743 return 1; 01744 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1759 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().
01760 { 01761 if (!sipdebug) 01762 return 0; 01763 return sip_debug_test_addr(sip_real_dst(p)); 01764 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3280 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().
03281 { 03282 ast_mutex_lock(&iflock); 03283 if (option_debug > 2) 03284 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03285 __sip_destroy(p, 1); 03286 ast_mutex_unlock(&iflock); 03287 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2439 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().
02440 { 02441 if (option_debug > 2) 02442 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02443 02444 /* Delete it, it needs to disappear */ 02445 if (peer->call) 02446 sip_destroy(peer->call); 02447 02448 if (peer->mwipvt) /* We have an active subscription, delete it */ 02449 sip_destroy(peer->mwipvt); 02450 02451 if (peer->chanvars) { 02452 ast_variables_destroy(peer->chanvars); 02453 peer->chanvars = NULL; 02454 } 02455 if (peer->expire > -1) 02456 ast_sched_del(sched, peer->expire); 02457 02458 if (peer->pokeexpire > -1) 02459 ast_sched_del(sched, peer->pokeexpire); 02460 register_peer_exten(peer, FALSE); 02461 ast_free_ha(peer->ha); 02462 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02463 apeerobjs--; 02464 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02465 rpeerobjs--; 02466 else 02467 speerobjs--; 02468 clear_realm_authentication(peer->auth); 02469 peer->auth = NULL; 02470 free(peer); 02471 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2657 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().
02658 { 02659 if (option_debug > 2) 02660 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02661 ast_free_ha(user->ha); 02662 if (user->chanvars) { 02663 ast_variables_destroy(user->chanvars); 02664 user->chanvars = NULL; 02665 } 02666 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02667 ruserobjs--; 02668 else 02669 suserobjs--; 02670 free(user); 02671 }
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 15777 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().
15778 { 15779 char *host; 15780 char *tmp; 15781 15782 struct hostent *hp; 15783 struct ast_hostent ahp; 15784 struct sip_peer *p; 15785 15786 int res = AST_DEVICE_INVALID; 15787 15788 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15789 host = ast_strdupa(data ? data : ""); 15790 if ((tmp = strchr(host, '@'))) 15791 host = tmp + 1; 15792 15793 if (option_debug > 2) 15794 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15795 15796 if ((p = find_peer(host, NULL, 1))) { 15797 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15798 /* we have an address for the peer */ 15799 15800 /* Check status in this order 15801 - Hold 15802 - Ringing 15803 - Busy (enforced only by call limit) 15804 - Inuse (we have a call) 15805 - Unreachable (qualify) 15806 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15807 for registered devices */ 15808 15809 if (p->onHold) 15810 /* First check for hold or ring states */ 15811 res = AST_DEVICE_ONHOLD; 15812 else if (p->inRinging) { 15813 if (p->inRinging == p->inUse) 15814 res = AST_DEVICE_RINGING; 15815 else 15816 res = AST_DEVICE_RINGINUSE; 15817 } else if (p->call_limit && (p->inUse == p->call_limit)) 15818 /* check call limit */ 15819 res = AST_DEVICE_BUSY; 15820 else if (p->call_limit && p->inUse) 15821 /* Not busy, but we do have a call */ 15822 res = AST_DEVICE_INUSE; 15823 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 15824 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15825 res = AST_DEVICE_UNAVAILABLE; 15826 else /* Default reply if we're registered and have no other data */ 15827 res = AST_DEVICE_NOT_INUSE; 15828 } else { 15829 /* there is no address, it's unavailable */ 15830 res = AST_DEVICE_UNAVAILABLE; 15831 } 15832 ASTOBJ_UNREF(p,sip_destroy_peer); 15833 } else { 15834 char *port = strchr(host, ':'); 15835 if (port) 15836 *port = '\0'; 15837 hp = ast_gethostbyname(host, &ahp); 15838 if (hp) 15839 res = AST_DEVICE_UNKNOWN; 15840 } 15841 15842 return res; 15843 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11197 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.
11198 { 11199 int oldsipdebug = sipdebug_console; 11200 if (argc != 3) { 11201 if (argc != 5) 11202 return RESULT_SHOWUSAGE; 11203 else if (strcmp(argv[3], "ip") == 0) 11204 return sip_do_debug_ip(fd, argc, argv); 11205 else if (strcmp(argv[3], "peer") == 0) 11206 return sip_do_debug_peer(fd, argc, argv); 11207 else 11208 return RESULT_SHOWUSAGE; 11209 } 11210 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11211 memset(&debugaddr, 0, sizeof(debugaddr)); 11212 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11213 return RESULT_SUCCESS; 11214 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11216 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.
11217 { 11218 int oldsipdebug = sipdebug_console; 11219 char *newargv[6] = { "sip", "set", "debug", NULL }; 11220 if (argc != 2) { 11221 if (argc != 4) 11222 return RESULT_SHOWUSAGE; 11223 else if (strcmp(argv[2], "ip") == 0) { 11224 newargv[3] = argv[2]; 11225 newargv[4] = argv[3]; 11226 return sip_do_debug_ip(fd, argc + 1, newargv); 11227 } else if (strcmp(argv[2], "peer") == 0) { 11228 newargv[3] = argv[2]; 11229 newargv[4] = argv[3]; 11230 return sip_do_debug_peer(fd, argc + 1, newargv); 11231 } else 11232 return RESULT_SHOWUSAGE; 11233 } 11234 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11235 memset(&debugaddr, 0, sizeof(debugaddr)); 11236 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11237 return RESULT_SUCCESS; 11238 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11143 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().
11144 { 11145 struct hostent *hp; 11146 struct ast_hostent ahp; 11147 int port = 0; 11148 char *p, *arg; 11149 11150 /* sip set debug ip <ip> */ 11151 if (argc != 5) 11152 return RESULT_SHOWUSAGE; 11153 p = arg = argv[4]; 11154 strsep(&p, ":"); 11155 if (p) 11156 port = atoi(p); 11157 hp = ast_gethostbyname(arg, &ahp); 11158 if (hp == NULL) 11159 return RESULT_SHOWUSAGE; 11160 11161 debugaddr.sin_family = AF_INET; 11162 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11163 debugaddr.sin_port = htons(port); 11164 if (port == 0) 11165 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11166 else 11167 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11168 11169 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11170 11171 return RESULT_SUCCESS; 11172 }
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 11175 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().
11176 { 11177 struct sip_peer *peer; 11178 if (argc != 5) 11179 return RESULT_SHOWUSAGE; 11180 peer = find_peer(argv[4], NULL, 1); 11181 if (peer) { 11182 if (peer->addr.sin_addr.s_addr) { 11183 debugaddr.sin_family = AF_INET; 11184 debugaddr.sin_addr = peer->addr.sin_addr; 11185 debugaddr.sin_port = peer->addr.sin_port; 11186 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11187 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11188 } else 11189 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11190 ASTOBJ_UNREF(peer,sip_destroy_peer); 11191 } else 11192 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11193 return RESULT_SUCCESS; 11194 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11316 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11317 { 11318 if (argc != 2) { 11319 return RESULT_SHOWUSAGE; 11320 } 11321 recordhistory = TRUE; 11322 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11323 return RESULT_SUCCESS; 11324 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17744 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().
17745 { 17746 reload_config(reason); 17747 17748 /* Prune peers who still are supposed to be deleted */ 17749 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17750 if (option_debug > 3) 17751 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17752 17753 /* Send qualify (OPTIONS) to all peers */ 17754 sip_poke_all_peers(); 17755 17756 /* Register with all services */ 17757 sip_send_all_registers(); 17758 17759 if (option_debug > 3) 17760 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17761 17762 return 0; 17763 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17548 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().
17549 { 17550 struct sip_pvt *p; 17551 char *mode; 17552 if (data) 17553 mode = (char *)data; 17554 else { 17555 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17556 return 0; 17557 } 17558 ast_channel_lock(chan); 17559 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17560 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17561 ast_channel_unlock(chan); 17562 return 0; 17563 } 17564 p = chan->tech_pvt; 17565 if (!p) { 17566 ast_channel_unlock(chan); 17567 return 0; 17568 } 17569 ast_mutex_lock(&p->lock); 17570 if (!strcasecmp(mode,"info")) { 17571 ast_clear_flag(&p->flags[0], SIP_DTMF); 17572 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17573 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17574 } else if (!strcasecmp(mode,"rfc2833")) { 17575 ast_clear_flag(&p->flags[0], SIP_DTMF); 17576 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17577 p->jointnoncodeccapability |= AST_RTP_DTMF; 17578 } else if (!strcasecmp(mode,"inband")) { 17579 ast_clear_flag(&p->flags[0], SIP_DTMF); 17580 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17581 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17582 } else 17583 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17584 if (p->rtp) 17585 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17586 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17587 if (!p->vad) { 17588 p->vad = ast_dsp_new(); 17589 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17590 } 17591 } else { 17592 if (p->vad) { 17593 ast_dsp_free(p->vad); 17594 p->vad = NULL; 17595 } 17596 } 17597 ast_mutex_unlock(&p->lock); 17598 ast_channel_unlock(chan); 17599 return 0; 17600 }
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 11008 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().
11009 { 11010 int x = 0; 11011 struct sip_history *hist; 11012 static int errmsg = 0; 11013 11014 if (!dialog) 11015 return; 11016 11017 if (!option_debug && !sipdebug) { 11018 if (!errmsg) { 11019 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11020 errmsg = 1; 11021 } 11022 return; 11023 } 11024 11025 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11026 if (dialog->subscribed) 11027 ast_log(LOG_DEBUG, " * Subscription\n"); 11028 else 11029 ast_log(LOG_DEBUG, " * SIP Call\n"); 11030 if (dialog->history) 11031 AST_LIST_TRAVERSE(dialog->history, hist, list) 11032 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11033 if (!x) 11034 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11035 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11036 }
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 3740 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.
03741 { 03742 int ret = -1; 03743 struct sip_pvt *p; 03744 03745 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03746 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03747 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03748 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03749 03750 if (!newchan || !newchan->tech_pvt) { 03751 if (!newchan) 03752 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03753 else 03754 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03755 return -1; 03756 } 03757 p = newchan->tech_pvt; 03758 03759 if (!p) { 03760 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03761 return -1; 03762 } 03763 03764 ast_mutex_lock(&p->lock); 03765 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03766 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03767 if (p->owner != oldchan) 03768 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03769 else { 03770 p->owner = newchan; 03771 ret = 0; 03772 } 03773 if (option_debug > 2) 03774 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03775 03776 ast_mutex_unlock(&p->lock); 03777 return ret; 03778 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17693 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17694 { 17695 struct sip_pvt *p = chan->tech_pvt; 17696 return p->peercapability ? p->peercapability : p->capability; 17697 }
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 17401 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.
17402 { 17403 struct sip_pvt *p = NULL; 17404 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17405 17406 if (!(p = chan->tech_pvt)) 17407 return AST_RTP_GET_FAILED; 17408 17409 ast_mutex_lock(&p->lock); 17410 if (!(p->rtp)) { 17411 ast_mutex_unlock(&p->lock); 17412 return AST_RTP_GET_FAILED; 17413 } 17414 17415 *rtp = p->rtp; 17416 17417 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17418 res = AST_RTP_TRY_PARTIAL; 17419 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17420 res = AST_RTP_TRY_NATIVE; 17421 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17422 res = AST_RTP_GET_FAILED; 17423 17424 ast_mutex_unlock(&p->lock); 17425 17426 return res; 17427 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 17266 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.
17267 { 17268 struct sip_pvt *p; 17269 struct ast_udptl *udptl = NULL; 17270 17271 p = chan->tech_pvt; 17272 if (!p) 17273 return NULL; 17274 17275 ast_mutex_lock(&p->lock); 17276 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17277 udptl = p->udptl; 17278 ast_mutex_unlock(&p->lock); 17279 return udptl; 17280 }
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 17430 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.
17431 { 17432 struct sip_pvt *p = NULL; 17433 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17434 17435 if (!(p = chan->tech_pvt)) 17436 return AST_RTP_GET_FAILED; 17437 17438 ast_mutex_lock(&p->lock); 17439 if (!(p->vrtp)) { 17440 ast_mutex_unlock(&p->lock); 17441 return AST_RTP_GET_FAILED; 17442 } 17443 17444 *rtp = p->vrtp; 17445 17446 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17447 res = AST_RTP_TRY_NATIVE; 17448 17449 ast_mutex_unlock(&p->lock); 17450 17451 return res; 17452 }
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 17318 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().
17319 { 17320 struct sip_pvt *p; 17321 int flag = 0; 17322 17323 p = chan->tech_pvt; 17324 if (!p || !pvt->udptl) 17325 return -1; 17326 17327 /* Setup everything on the other side like offered/responded from first side */ 17328 ast_mutex_lock(&p->lock); 17329 17330 /*! \todo check if this is not set earlier when setting up the PVT. If not 17331 maybe it should move there. */ 17332 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17333 17334 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17335 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17336 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17337 17338 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17339 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17340 not really T38 re-invites which are different. In this 17341 case it's used properly, to see if we can reinvite over 17342 NAT 17343 */ 17344 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17345 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17346 flag =1; 17347 } else { 17348 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17349 } 17350 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17351 if (!p->pendinginvite) { 17352 if (option_debug > 2) { 17353 if (flag) 17354 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)); 17355 else 17356 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)); 17357 } 17358 transmit_reinvite_with_t38_sdp(p); 17359 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17360 if (option_debug > 2) { 17361 if (flag) 17362 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)); 17363 else 17364 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)); 17365 } 17366 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17367 } 17368 } 17369 /* Reset lastrtprx timer */ 17370 p->lastrtprx = p->lastrtptx = time(NULL); 17371 ast_mutex_unlock(&p->lock); 17372 return 0; 17373 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17374 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17375 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17376 flag = 1; 17377 } else { 17378 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17379 } 17380 if (option_debug > 2) { 17381 if (flag) 17382 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)); 17383 else 17384 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)); 17385 } 17386 pvt->t38.state = T38_ENABLED; 17387 p->t38.state = T38_ENABLED; 17388 if (option_debug > 1) { 17389 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17390 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17391 } 17392 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17393 p->lastrtprx = p->lastrtptx = time(NULL); 17394 ast_mutex_unlock(&p->lock); 17395 return 0; 17396 } 17397 }
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 3452 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.
03453 { 03454 struct sip_pvt *p = ast->tech_pvt; 03455 int needcancel = FALSE; 03456 int needdestroy = 0; 03457 struct ast_channel *oldowner = ast; 03458 03459 if (!p) { 03460 if (option_debug) 03461 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03462 return 0; 03463 } 03464 03465 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03466 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03467 if (option_debug && sipdebug) 03468 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03469 update_call_counter(p, DEC_CALL_LIMIT); 03470 } 03471 if (option_debug >3) 03472 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03473 if (p->autokillid > -1) 03474 sip_cancel_destroy(p); 03475 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03476 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03477 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03478 p->owner->tech_pvt = NULL; 03479 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03480 return 0; 03481 } 03482 if (option_debug) { 03483 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03484 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03485 else { 03486 if (option_debug) 03487 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03488 } 03489 } 03490 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03491 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03492 03493 ast_mutex_lock(&p->lock); 03494 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03495 if (option_debug && sipdebug) 03496 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03497 update_call_counter(p, DEC_CALL_LIMIT); 03498 } 03499 03500 /* Determine how to disconnect */ 03501 if (p->owner != ast) { 03502 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03503 ast_mutex_unlock(&p->lock); 03504 return 0; 03505 } 03506 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03507 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03508 needcancel = TRUE; 03509 if (option_debug > 3) 03510 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03511 } 03512 03513 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03514 03515 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03516 03517 /* Disconnect */ 03518 if (p->vad) 03519 ast_dsp_free(p->vad); 03520 03521 p->owner = NULL; 03522 ast->tech_pvt = NULL; 03523 03524 ast_module_unref(ast_module_info->self); 03525 03526 /* Do not destroy this pvt until we have timeout or 03527 get an answer to the BYE or INVITE/CANCEL 03528 If we get no answer during retransmit period, drop the call anyway. 03529 (Sorry, mother-in-law, you can't deny a hangup by sending 03530 603 declined to BYE...) 03531 */ 03532 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03533 needdestroy = 1; /* Set destroy flag at end of this function */ 03534 else if (p->invitestate != INV_CALLING) 03535 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03536 03537 /* Start the process if it's not already started */ 03538 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03539 if (needcancel) { /* Outgoing call, not up */ 03540 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03541 /* stop retransmitting an INVITE that has not received a response */ 03542 __sip_pretend_ack(p); 03543 03544 /* if we can't send right now, mark it pending */ 03545 if (p->invitestate == INV_CALLING) { 03546 /* We can't send anything in CALLING state */ 03547 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03548 /* 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. */ 03549 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03550 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03551 } else { 03552 /* Send a new request: CANCEL */ 03553 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03554 /* Actually don't destroy us yet, wait for the 487 on our original 03555 INVITE, but do set an autodestruct just in case we never get it. */ 03556 needdestroy = 0; 03557 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03558 p->invitestate = INV_CANCELLED; 03559 } 03560 if ( p->initid != -1 ) { 03561 /* channel still up - reverse dec of inUse counter 03562 only if the channel is not auto-congested */ 03563 update_call_counter(p, INC_CALL_LIMIT); 03564 } 03565 } else { /* Incoming call, not up */ 03566 const char *res; 03567 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03568 transmit_response_reliable(p, res, &p->initreq); 03569 else 03570 transmit_response_reliable(p, "603 Declined", &p->initreq); 03571 p->invitestate = INV_TERMINATED; 03572 } 03573 } else { /* Call is in UP state, send BYE */ 03574 if (!p->pendinginvite) { 03575 char *audioqos = ""; 03576 char *videoqos = ""; 03577 if (p->rtp) 03578 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03579 if (p->vrtp) 03580 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03581 /* Send a hangup */ 03582 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03583 03584 /* Get RTCP quality before end of call */ 03585 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03586 if (p->rtp) 03587 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03588 if (p->vrtp) 03589 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03590 } 03591 if (p->rtp && oldowner) 03592 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03593 if (p->vrtp && oldowner) 03594 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03595 } else { 03596 /* Note we will need a BYE when this all settles out 03597 but we can't send one while we have "INVITE" outstanding. */ 03598 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03599 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03600 if (p->waitid) 03601 ast_sched_del(sched, p->waitid); 03602 p->waitid = -1; 03603 sip_cancel_destroy(p); 03604 } 03605 } 03606 } 03607 if (needdestroy) 03608 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03609 ast_mutex_unlock(&p->lock); 03610 return 0; 03611 }
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 3849 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.
03850 { 03851 struct sip_pvt *p = ast->tech_pvt; 03852 int res = 0; 03853 03854 ast_mutex_lock(&p->lock); 03855 switch(condition) { 03856 case AST_CONTROL_RINGING: 03857 if (ast->_state == AST_STATE_RING) { 03858 p->invitestate = INV_EARLY_MEDIA; 03859 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03860 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03861 /* Send 180 ringing if out-of-band seems reasonable */ 03862 transmit_response(p, "180 Ringing", &p->initreq); 03863 ast_set_flag(&p->flags[0], SIP_RINGING); 03864 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03865 break; 03866 } else { 03867 /* Well, if it's not reasonable, just send in-band */ 03868 } 03869 } 03870 res = -1; 03871 break; 03872 case AST_CONTROL_BUSY: 03873 if (ast->_state != AST_STATE_UP) { 03874 transmit_response(p, "486 Busy Here", &p->initreq); 03875 p->invitestate = INV_COMPLETED; 03876 sip_alreadygone(p); 03877 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03878 break; 03879 } 03880 res = -1; 03881 break; 03882 case AST_CONTROL_CONGESTION: 03883 if (ast->_state != AST_STATE_UP) { 03884 transmit_response(p, "503 Service Unavailable", &p->initreq); 03885 p->invitestate = INV_COMPLETED; 03886 sip_alreadygone(p); 03887 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03888 break; 03889 } 03890 res = -1; 03891 break; 03892 case AST_CONTROL_PROCEEDING: 03893 if ((ast->_state != AST_STATE_UP) && 03894 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03895 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03896 transmit_response(p, "100 Trying", &p->initreq); 03897 p->invitestate = INV_PROCEEDING; 03898 break; 03899 } 03900 res = -1; 03901 break; 03902 case AST_CONTROL_PROGRESS: 03903 if ((ast->_state != AST_STATE_UP) && 03904 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03905 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03906 p->invitestate = INV_EARLY_MEDIA; 03907 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03908 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03909 break; 03910 } 03911 res = -1; 03912 break; 03913 case AST_CONTROL_HOLD: 03914 ast_moh_start(ast, data, p->mohinterpret); 03915 break; 03916 case AST_CONTROL_UNHOLD: 03917 ast_moh_stop(ast); 03918 break; 03919 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03920 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03921 transmit_info_with_vidupdate(p); 03922 /* ast_rtcp_send_h261fur(p->vrtp); */ 03923 } else 03924 res = -1; 03925 break; 03926 case -1: 03927 res = -1; 03928 break; 03929 default: 03930 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03931 res = -1; 03932 break; 03933 } 03934 ast_mutex_unlock(&p->lock); 03935 return res; 03936 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1753 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().
01754 { 01755 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01756 }
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 3944 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().
03945 { 03946 struct ast_channel *tmp; 03947 struct ast_variable *v = NULL; 03948 int fmt; 03949 int what; 03950 int needvideo = 0, video = 0; 03951 char *decoded_exten; 03952 { 03953 const char *my_name; /* pick a good name */ 03954 03955 if (title) 03956 my_name = title; 03957 else if ( (my_name = strchr(i->fromdomain,':')) ) 03958 my_name++; /* skip ':' */ 03959 else 03960 my_name = i->fromdomain; 03961 03962 ast_mutex_unlock(&i->lock); 03963 /* Don't hold a sip pvt lock while we allocate a channel */ 03964 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); 03965 03966 } 03967 if (!tmp) { 03968 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03969 return NULL; 03970 } 03971 ast_mutex_lock(&i->lock); 03972 03973 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03974 tmp->tech = &sip_tech_info; 03975 else 03976 tmp->tech = &sip_tech; 03977 03978 /* Select our native format based on codec preference until we receive 03979 something from another device to the contrary. */ 03980 if (i->jointcapability) { /* The joint capabilities of us and peer */ 03981 what = i->jointcapability; 03982 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 03983 } else if (i->capability) { /* Our configured capability for this peer */ 03984 what = i->capability; 03985 video = i->capability & AST_FORMAT_VIDEO_MASK; 03986 } else { 03987 what = global_capability; /* Global codec support */ 03988 video = global_capability & AST_FORMAT_VIDEO_MASK; 03989 } 03990 03991 /* Set the native formats for audio and merge in video */ 03992 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 03993 if (option_debug > 2) { 03994 char buf[BUFSIZ]; 03995 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03996 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03997 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03998 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 03999 if (i->prefcodec) 04000 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 04001 } 04002 04003 /* XXX Why are we choosing a codec from the native formats?? */ 04004 fmt = ast_best_codec(tmp->nativeformats); 04005 04006 /* If we have a prefcodec setting, we have an inbound channel that set a 04007 preferred format for this call. Otherwise, we check the jointcapability 04008 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04009 */ 04010 if (i->vrtp) { 04011 if (i->prefcodec) 04012 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04013 else 04014 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04015 } 04016 04017 if (option_debug > 2) { 04018 if (needvideo) 04019 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04020 else 04021 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04022 } 04023 04024 04025 04026 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04027 i->vad = ast_dsp_new(); 04028 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04029 if (global_relaxdtmf) 04030 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04031 } 04032 if (i->rtp) { 04033 tmp->fds[0] = ast_rtp_fd(i->rtp); 04034 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04035 } 04036 if (needvideo && i->vrtp) { 04037 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04038 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04039 } 04040 if (i->udptl) { 04041 tmp->fds[5] = ast_udptl_fd(i->udptl); 04042 } 04043 if (state == AST_STATE_RING) 04044 tmp->rings = 1; 04045 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04046 tmp->writeformat = fmt; 04047 tmp->rawwriteformat = fmt; 04048 tmp->readformat = fmt; 04049 tmp->rawreadformat = fmt; 04050 tmp->tech_pvt = i; 04051 04052 tmp->callgroup = i->callgroup; 04053 tmp->pickupgroup = i->pickupgroup; 04054 tmp->cid.cid_pres = i->callingpres; 04055 if (!ast_strlen_zero(i->accountcode)) 04056 ast_string_field_set(tmp, accountcode, i->accountcode); 04057 if (i->amaflags) 04058 tmp->amaflags = i->amaflags; 04059 if (!ast_strlen_zero(i->language)) 04060 ast_string_field_set(tmp, language, i->language); 04061 i->owner = tmp; 04062 ast_module_ref(ast_module_info->self); 04063 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04064 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04065 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04066 * structure so that there aren't issues when forming URI's 04067 */ 04068 decoded_exten = ast_strdupa(i->exten); 04069 ast_uri_decode(decoded_exten); 04070 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04071 04072 /* Don't use ast_set_callerid() here because it will 04073 * generate an unnecessary NewCallerID event */ 04074 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04075 if (!ast_strlen_zero(i->rdnis)) 04076 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04077 04078 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04079 tmp->cid.cid_dnid = ast_strdup(i->exten); 04080 04081 tmp->priority = 1; 04082 if (!ast_strlen_zero(i->uri)) 04083 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04084 if (!ast_strlen_zero(i->domain)) 04085 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04086 if (!ast_strlen_zero(i->useragent)) 04087 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04088 if (!ast_strlen_zero(i->callid)) 04089 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04090 if (i->rtp) 04091 ast_jb_configure(tmp, &global_jbconf); 04092 04093 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04094 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04095 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04096 04097 /* Set channel variables for this call from configuration */ 04098 for (v = i->chanvars ; v ; v = v->next) 04099 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04100 04101 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04102 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04103 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04104 ast_hangup(tmp); 04105 tmp = NULL; 04106 } 04107 04108 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04109 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04110 04111 return tmp; 04112 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11297 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11298 { 11299 if (argc != 4) 11300 return RESULT_SHOWUSAGE; 11301 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11302 ast_cli(fd, "SIP Debugging Disabled\n"); 11303 return RESULT_SUCCESS; 11304 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11306 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11307 { 11308 if (argc != 3) 11309 return RESULT_SHOWUSAGE; 11310 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11311 ast_cli(fd, "SIP Debugging Disabled\n"); 11312 return RESULT_SUCCESS; 11313 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11327 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11328 { 11329 if (argc != 3) { 11330 return RESULT_SHOWUSAGE; 11331 } 11332 recordhistory = FALSE; 11333 ast_cli(fd, "SIP History Recording Disabled\n"); 11334 return RESULT_SUCCESS; 11335 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11241 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.
11242 { 11243 struct ast_variable *varlist; 11244 int i; 11245 11246 if (argc < 4) 11247 return RESULT_SHOWUSAGE; 11248 11249 if (!notify_types) { 11250 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11251 return RESULT_FAILURE; 11252 } 11253 11254 varlist = ast_variable_browse(notify_types, argv[2]); 11255 11256 if (!varlist) { 11257 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11258 return RESULT_FAILURE; 11259 } 11260 11261 for (i = 3; i < argc; i++) { 11262 struct sip_pvt *p; 11263 struct sip_request req; 11264 struct ast_variable *var; 11265 11266 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11267 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11268 return RESULT_FAILURE; 11269 } 11270 11271 if (create_addr(p, argv[i])) { 11272 /* Maybe they're not registered, etc. */ 11273 sip_destroy(p); 11274 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11275 continue; 11276 } 11277 11278 initreqprep(&req, p, SIP_NOTIFY); 11279 11280 for (var = varlist; var; var = var->next) 11281 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11282 11283 /* Recalculate our side, and recalculate Call ID */ 11284 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11285 p->ourip = __ourip; 11286 build_via(p); 11287 build_callid_pvt(p); 11288 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11289 transmit_sip_request(p, &req); 11290 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11291 } 11292 11293 return RESULT_SUCCESS; 11294 }
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 13032 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().
13033 { 13034 struct sip_dual *d; 13035 struct ast_channel *transferee, *transferer; 13036 /* Chan2m: The transferer, chan1m: The transferee */ 13037 pthread_t th; 13038 13039 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13040 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13041 if ((!transferer) || (!transferee)) { 13042 if (transferee) { 13043 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13044 ast_hangup(transferee); 13045 } 13046 if (transferer) { 13047 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13048 ast_hangup(transferer); 13049 } 13050 return -1; 13051 } 13052 13053 /* Make formats okay */ 13054 transferee->readformat = chan1->readformat; 13055 transferee->writeformat = chan1->writeformat; 13056 13057 /* Prepare for taking over the channel */ 13058 ast_channel_masquerade(transferee, chan1); 13059 13060 /* Setup the extensions and such */ 13061 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13062 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13063 transferee->priority = chan1->priority; 13064 13065 /* We make a clone of the peer channel too, so we can play 13066 back the announcement */ 13067 13068 /* Make formats okay */ 13069 transferer->readformat = chan2->readformat; 13070 transferer->writeformat = chan2->writeformat; 13071 13072 /* Prepare for taking over the channel. Go ahead and grab this channel 13073 * lock here to avoid a deadlock with callbacks into the channel driver 13074 * that hold the channel lock and want the pvt lock. */ 13075 while (ast_channel_trylock(chan2)) { 13076 struct sip_pvt *pvt = chan2->tech_pvt; 13077 ast_mutex_unlock(&pvt->lock); 13078 usleep(1); 13079 ast_mutex_lock(&pvt->lock); 13080 } 13081 ast_channel_masquerade(transferer, chan2); 13082 ast_channel_unlock(chan2); 13083 13084 /* Setup the extensions and such */ 13085 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13086 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13087 transferer->priority = chan2->priority; 13088 13089 ast_channel_lock(transferer); 13090 if (ast_do_masquerade(transferer)) { 13091 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13092 ast_channel_unlock(transferer); 13093 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13094 ast_hangup(transferer); 13095 return -1; 13096 } 13097 ast_channel_unlock(transferer); 13098 if (!transferer || !transferee) { 13099 if (!transferer) { 13100 if (option_debug) 13101 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13102 } 13103 if (!transferee) { 13104 if (option_debug) 13105 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13106 } 13107 return -1; 13108 } 13109 if ((d = ast_calloc(1, sizeof(*d)))) { 13110 pthread_attr_t attr; 13111 13112 pthread_attr_init(&attr); 13113 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13114 13115 /* Save original request for followup */ 13116 copy_request(&d->req, req); 13117 d->chan1 = transferee; /* Transferee */ 13118 d->chan2 = transferer; /* Transferer */ 13119 d->seqno = seqno; 13120 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13121 /* Could not start thread */ 13122 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13123 by sip_park_thread() */ 13124 pthread_attr_destroy(&attr); 13125 return 0; 13126 } 13127 pthread_attr_destroy(&attr); 13128 } 13129 return -1; 13130 }
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 12965 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().
12966 { 12967 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 12968 struct sip_dual *d; 12969 struct sip_request req; 12970 int ext; 12971 int res; 12972 12973 d = stuff; 12974 transferee = d->chan1; 12975 transferer = d->chan2; 12976 copy_request(&req, &d->req); 12977 free(d); 12978 12979 if (!transferee || !transferer) { 12980 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 12981 return NULL; 12982 } 12983 if (option_debug > 3) 12984 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 12985 12986 ast_channel_lock(transferee); 12987 if (ast_do_masquerade(transferee)) { 12988 ast_log(LOG_WARNING, "Masquerade failed.\n"); 12989 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 12990 ast_channel_unlock(transferee); 12991 return NULL; 12992 } 12993 ast_channel_unlock(transferee); 12994 12995 res = ast_park_call(transferee, transferer, 0, &ext); 12996 12997 12998 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 12999 if (!res) { 13000 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13001 } else { 13002 /* Then tell the transferer what happened */ 13003 sprintf(buf, "Call parked on extension '%d'", ext); 13004 transmit_message_with_text(transferer->tech_pvt, buf); 13005 } 13006 #endif 13007 13008 /* Any way back to the current call??? */ 13009 /* Transmit response to the REFER request */ 13010 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13011 if (!res) { 13012 /* Transfer succeeded */ 13013 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13014 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13015 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13016 ast_hangup(transferer); /* This will cause a BYE */ 13017 if (option_debug) 13018 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13019 } else { 13020 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13021 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13022 if (option_debug) 13023 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13024 /* Do not hangup call */ 13025 } 13026 return NULL; 13027 }
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 8448 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().
08449 { 08450 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08451 08452 if (!peer) 08453 return; 08454 08455 /* If they put someone on hold, increment the value... otherwise decrement it */ 08456 if (hold) 08457 peer->onHold++; 08458 else 08459 peer->onHold--; 08460 08461 /* Request device state update */ 08462 ast_device_state_changed("SIP/%s", peer->name); 08463 08464 return; 08465 }
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 17703 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().
17704 { 17705 int ms = 0; 17706 17707 if (!speerobjs) /* No peers, just give up */ 17708 return; 17709 17710 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17711 ASTOBJ_WRLOCK(iterator); 17712 if (iterator->pokeexpire > -1) 17713 ast_sched_del(sched, iterator->pokeexpire); 17714 ms += 100; 17715 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17716 ASTOBJ_UNLOCK(iterator); 17717 } while (0) 17718 ); 17719 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15655 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().
15656 { 15657 struct sip_peer *peer = (struct sip_peer *)data; 15658 15659 peer->pokeexpire = -1; 15660 if (peer->lastms > -1) { 15661 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15662 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15663 } 15664 if (peer->call) 15665 sip_destroy(peer->call); 15666 peer->call = NULL; 15667 peer->lastms = -1; 15668 ast_device_state_changed("SIP/%s", peer->name); 15669 /* Try again quickly */ 15670 if (peer->pokeexpire > -1) 15671 ast_sched_del(sched, peer->pokeexpire); 15672 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15673 return 0; 15674 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15679 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().
15680 { 15681 struct sip_pvt *p; 15682 int xmitres = 0; 15683 15684 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15685 /* IF we have no IP, or this isn't to be monitored, return 15686 imeediately after clearing things out */ 15687 if (peer->pokeexpire > -1) 15688 ast_sched_del(sched, peer->pokeexpire); 15689 peer->lastms = 0; 15690 peer->pokeexpire = -1; 15691 peer->call = NULL; 15692 return 0; 15693 } 15694 if (peer->call) { 15695 if (sipdebug) 15696 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15697 sip_destroy(peer->call); 15698 } 15699 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15700 return -1; 15701 15702 p->sa = peer->addr; 15703 p->recv = peer->addr; 15704 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15705 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15706 15707 /* Send OPTIONs to peer's fullcontact */ 15708 if (!ast_strlen_zero(peer->fullcontact)) 15709 ast_string_field_set(p, fullcontact, peer->fullcontact); 15710 15711 if (!ast_strlen_zero(peer->tohost)) 15712 ast_string_field_set(p, tohost, peer->tohost); 15713 else 15714 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15715 15716 /* Recalculate our side, and recalculate Call ID */ 15717 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15718 p->ourip = __ourip; 15719 build_via(p); 15720 build_callid_pvt(p); 15721 15722 if (peer->pokeexpire > -1) 15723 ast_sched_del(sched, peer->pokeexpire); 15724 p->relatedpeer = peer; 15725 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15726 #ifdef VOCAL_DATA_HACK 15727 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15728 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15729 #else 15730 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15731 #endif 15732 gettimeofday(&peer->ps, NULL); 15733 if (xmitres == XMIT_ERROR) 15734 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 15735 else { 15736 if (peer->pokeexpire > -1) 15737 ast_sched_del(sched, peer->pokeexpire); 15738 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, peer); 15739 } 15740 15741 return 0; 15742 }
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 7853 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().
07854 { 07855 struct sip_peer *peer = (struct sip_peer *)data; 07856 07857 peer->pokeexpire = -1; 07858 sip_poke_peer(peer); 07859 return 0; 07860 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10034 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.
10035 { 10036 struct sip_peer *peer; 10037 struct sip_user *user; 10038 int pruneuser = FALSE; 10039 int prunepeer = FALSE; 10040 int multi = FALSE; 10041 char *name = NULL; 10042 regex_t regexbuf; 10043 10044 switch (argc) { 10045 case 4: 10046 if (!strcasecmp(argv[3], "user")) 10047 return RESULT_SHOWUSAGE; 10048 if (!strcasecmp(argv[3], "peer")) 10049 return RESULT_SHOWUSAGE; 10050 if (!strcasecmp(argv[3], "like")) 10051 return RESULT_SHOWUSAGE; 10052 if (!strcasecmp(argv[3], "all")) { 10053 multi = TRUE; 10054 pruneuser = prunepeer = TRUE; 10055 } else { 10056 pruneuser = prunepeer = TRUE; 10057 name = argv[3]; 10058 } 10059 break; 10060 case 5: 10061 if (!strcasecmp(argv[4], "like")) 10062 return RESULT_SHOWUSAGE; 10063 if (!strcasecmp(argv[3], "all")) 10064 return RESULT_SHOWUSAGE; 10065 if (!strcasecmp(argv[3], "like")) { 10066 multi = TRUE; 10067 name = argv[4]; 10068 pruneuser = prunepeer = TRUE; 10069 } else if (!strcasecmp(argv[3], "user")) { 10070 pruneuser = TRUE; 10071 if (!strcasecmp(argv[4], "all")) 10072 multi = TRUE; 10073 else 10074 name = argv[4]; 10075 } else if (!strcasecmp(argv[3], "peer")) { 10076 prunepeer = TRUE; 10077 if (!strcasecmp(argv[4], "all")) 10078 multi = TRUE; 10079 else 10080 name = argv[4]; 10081 } else 10082 return RESULT_SHOWUSAGE; 10083 break; 10084 case 6: 10085 if (strcasecmp(argv[4], "like")) 10086 return RESULT_SHOWUSAGE; 10087 if (!strcasecmp(argv[3], "user")) { 10088 pruneuser = TRUE; 10089 name = argv[5]; 10090 } else if (!strcasecmp(argv[3], "peer")) { 10091 prunepeer = TRUE; 10092 name = argv[5]; 10093 } else 10094 return RESULT_SHOWUSAGE; 10095 break; 10096 default: 10097 return RESULT_SHOWUSAGE; 10098 } 10099 10100 if (multi && name) { 10101 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10102 return RESULT_SHOWUSAGE; 10103 } 10104 10105 if (multi) { 10106 if (prunepeer) { 10107 int pruned = 0; 10108 10109 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10110 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10111 ASTOBJ_RDLOCK(iterator); 10112 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10113 ASTOBJ_UNLOCK(iterator); 10114 continue; 10115 }; 10116 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10117 ASTOBJ_MARK(iterator); 10118 pruned++; 10119 } 10120 ASTOBJ_UNLOCK(iterator); 10121 } while (0) ); 10122 if (pruned) { 10123 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10124 ast_cli(fd, "%d peers pruned.\n", pruned); 10125 } else 10126 ast_cli(fd, "No peers found to prune.\n"); 10127 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10128 } 10129 if (pruneuser) { 10130 int pruned = 0; 10131 10132 ASTOBJ_CONTAINER_WRLOCK(&userl); 10133 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10134 ASTOBJ_RDLOCK(iterator); 10135 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10136 ASTOBJ_UNLOCK(iterator); 10137 continue; 10138 }; 10139 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10140 ASTOBJ_MARK(iterator); 10141 pruned++; 10142 } 10143 ASTOBJ_UNLOCK(iterator); 10144 } while (0) ); 10145 if (pruned) { 10146 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10147 ast_cli(fd, "%d users pruned.\n", pruned); 10148 } else 10149 ast_cli(fd, "No users found to prune.\n"); 10150 ASTOBJ_CONTAINER_UNLOCK(&userl); 10151 } 10152 } else { 10153 if (prunepeer) { 10154 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10155 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10156 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10157 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10158 } else 10159 ast_cli(fd, "Peer '%s' pruned.\n", name); 10160 ASTOBJ_UNREF(peer, sip_destroy_peer); 10161 } else 10162 ast_cli(fd, "Peer '%s' not found.\n", name); 10163 } 10164 if (pruneuser) { 10165 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10166 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10167 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10168 ASTOBJ_CONTAINER_LINK(&userl, user); 10169 } else 10170 ast_cli(fd, "User '%s' pruned.\n", name); 10171 ASTOBJ_UNREF(user, sip_destroy_user); 10172 } else 10173 ast_cli(fd, "User '%s' not found.\n", name); 10174 } 10175 } 10176 10177 return RESULT_SUCCESS; 10178 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4315 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().
04316 { 04317 struct ast_frame *fr; 04318 struct sip_pvt *p = ast->tech_pvt; 04319 int faxdetected = FALSE; 04320 04321 ast_mutex_lock(&p->lock); 04322 fr = sip_rtp_read(ast, p, &faxdetected); 04323 p->lastrtprx = time(NULL); 04324 04325 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04326 /* 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 */ 04327 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04328 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04329 if (!p->pendinginvite) { 04330 if (option_debug > 2) 04331 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04332 p->t38.state = T38_LOCAL_REINVITE; 04333 transmit_reinvite_with_t38_sdp(p); 04334 if (option_debug > 1) 04335 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04336 } 04337 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04338 if (option_debug > 2) 04339 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04340 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04341 } 04342 } 04343 04344 ast_mutex_unlock(&p->lock); 04345 return fr; 04346 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 1747 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().
01748 { 01749 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01750 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7662 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().
07663 { 07664 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07665 return p->refer ? 1 : 0; 07666 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7418 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().
07419 { 07420 07421 /* if we are here, our registration timed out, so we'll just do it over */ 07422 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07423 struct sip_pvt *p; 07424 int res; 07425 07426 /* if we couldn't get a reference to the registry object, punt */ 07427 if (!r) 07428 return 0; 07429 07430 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07431 if (r->call) { 07432 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07433 in the single SIP manager thread. */ 07434 p = r->call; 07435 if (p->registry) 07436 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07437 r->call = NULL; 07438 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07439 /* Pretend to ACK anything just in case */ 07440 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07441 } 07442 /* If we have a limit, stop registration and give up */ 07443 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07444 /* Ok, enough is enough. Don't try any more */ 07445 /* We could add an external notification here... 07446 steal it from app_voicemail :-) */ 07447 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07448 r->regstate = REG_STATE_FAILED; 07449 } else { 07450 r->regstate = REG_STATE_UNREGISTERED; 07451 r->timeout = -1; 07452 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07453 } 07454 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)); 07455 ASTOBJ_UNREF(r, sip_registry_destroy); 07456 return 0; 07457 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4635 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().
04636 { 04637 struct sip_registry *reg; 04638 int portnum = 0; 04639 char username[256] = ""; 04640 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04641 char *porta=NULL; 04642 char *contact=NULL; 04643 04644 if (!value) 04645 return -1; 04646 ast_copy_string(username, value, sizeof(username)); 04647 /* First split around the last '@' then parse the two components. */ 04648 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04649 if (hostname) 04650 *hostname++ = '\0'; 04651 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04652 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04653 return -1; 04654 } 04655 /* split user[:secret[:authuser]] */ 04656 secret = strchr(username, ':'); 04657 if (secret) { 04658 *secret++ = '\0'; 04659 authuser = strchr(secret, ':'); 04660 if (authuser) 04661 *authuser++ = '\0'; 04662 } 04663 /* split host[:port][/contact] */ 04664 contact = strchr(hostname, '/'); 04665 if (contact) 04666 *contact++ = '\0'; 04667 if (ast_strlen_zero(contact)) 04668 contact = "s"; 04669 porta = strchr(hostname, ':'); 04670 if (porta) { 04671 *porta++ = '\0'; 04672 portnum = atoi(porta); 04673 if (portnum == 0) { 04674 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04675 return -1; 04676 } 04677 } 04678 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04679 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04680 return -1; 04681 } 04682 04683 if (ast_string_field_init(reg, 256)) { 04684 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04685 free(reg); 04686 return -1; 04687 } 04688 04689 regobjs++; 04690 ASTOBJ_INIT(reg); 04691 ast_string_field_set(reg, contact, contact); 04692 if (!ast_strlen_zero(username)) 04693 ast_string_field_set(reg, username, username); 04694 if (hostname) 04695 ast_string_field_set(reg, hostname, hostname); 04696 if (authuser) 04697 ast_string_field_set(reg, authuser, authuser); 04698 if (secret) 04699 ast_string_field_set(reg, secret, secret); 04700 reg->expire = -1; 04701 reg->timeout = -1; 04702 reg->refresh = default_expiry; 04703 reg->portno = portnum; 04704 reg->callid_valid = FALSE; 04705 reg->ocseq = INITIAL_CSEQ; 04706 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04707 ASTOBJ_UNREF(reg,sip_registry_destroy); 04708 return 0; 04709 }
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 3026 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().
03027 { 03028 /* Really delete */ 03029 if (option_debug > 2) 03030 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03031 03032 if (reg->call) { 03033 /* Clear registry before destroying to ensure 03034 we don't get reentered trying to grab the registry lock */ 03035 reg->call->registry = NULL; 03036 if (option_debug > 2) 03037 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03038 sip_destroy(reg->call); 03039 } 03040 if (reg->expire > -1) 03041 ast_sched_del(sched, reg->expire); 03042 if (reg->timeout > -1) 03043 ast_sched_del(sched, reg->timeout); 03044 ast_string_field_free_memory(reg); 03045 regobjs--; 03046 free(reg); 03047 03048 }
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 11957 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
11958 { 11959 struct sip_pvt *p = (struct sip_pvt *) data; 11960 11961 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 11962 p->waitid = -1; 11963 return 0; 11964 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17766 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().
17767 { 17768 ast_mutex_lock(&sip_reload_lock); 17769 if (sip_reloading) 17770 ast_verbose("Previous SIP reload not yet done\n"); 17771 else { 17772 sip_reloading = TRUE; 17773 if (fd) 17774 sip_reloadreason = CHANNEL_CLI_RELOAD; 17775 else 17776 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17777 } 17778 ast_mutex_unlock(&sip_reload_lock); 17779 restart_monitor(); 17780 17781 return 0; 17782 }
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 15847 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.
15848 { 15849 int oldformat; 15850 struct sip_pvt *p; 15851 struct ast_channel *tmpc = NULL; 15852 char *ext, *host; 15853 char tmp[256]; 15854 char *dest = data; 15855 15856 oldformat = format; 15857 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15858 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)); 15859 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15860 return NULL; 15861 } 15862 if (option_debug) 15863 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15864 15865 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15866 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15867 *cause = AST_CAUSE_SWITCH_CONGESTION; 15868 return NULL; 15869 } 15870 15871 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15872 15873 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15874 sip_destroy(p); 15875 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15876 *cause = AST_CAUSE_SWITCH_CONGESTION; 15877 return NULL; 15878 } 15879 15880 ast_copy_string(tmp, dest, sizeof(tmp)); 15881 host = strchr(tmp, '@'); 15882 if (host) { 15883 *host++ = '\0'; 15884 ext = tmp; 15885 } else { 15886 ext = strchr(tmp, '/'); 15887 if (ext) 15888 *ext++ = '\0'; 15889 host = tmp; 15890 } 15891 15892 if (create_addr(p, host)) { 15893 *cause = AST_CAUSE_UNREGISTERED; 15894 if (option_debug > 2) 15895 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15896 sip_destroy(p); 15897 return NULL; 15898 } 15899 if (ast_strlen_zero(p->peername) && ext) 15900 ast_string_field_set(p, peername, ext); 15901 /* Recalculate our side, and recalculate Call ID */ 15902 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15903 p->ourip = __ourip; 15904 build_via(p); 15905 build_callid_pvt(p); 15906 15907 /* We have an extension to call, don't use the full contact here */ 15908 /* This to enable dialing registered peers with extension dialling, 15909 like SIP/peername/extension 15910 SIP/peername will still use the full contact */ 15911 if (ext) { 15912 ast_string_field_set(p, username, ext); 15913 ast_string_field_free(p, fullcontact); 15914 } 15915 #if 0 15916 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 15917 #endif 15918 p->prefcodec = oldformat; /* Format for this call */ 15919 ast_mutex_lock(&p->lock); 15920 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 15921 ast_mutex_unlock(&p->lock); 15922 if (!tmpc) 15923 sip_destroy(p); 15924 ast_update_use_count(); 15925 restart_monitor(); 15926 return tmpc; 15927 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7386 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().
07387 { 07388 /* if we are here, we know that we need to reregister. */ 07389 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07390 07391 /* if we couldn't get a reference to the registry object, punt */ 07392 if (!r) 07393 return 0; 07394 07395 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07396 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07397 /* Since registry's are only added/removed by the the monitor thread, this 07398 may be overkill to reference/dereference at all here */ 07399 if (sipdebug) 07400 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07401 07402 r->expire = -1; 07403 __sip_do_register(r); 07404 ASTOBJ_UNREF(r, sip_registry_destroy); 07405 return 0; 07406 }
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 4245 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().
04246 { 04247 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04248 struct ast_frame *f; 04249 04250 if (!p->rtp) { 04251 /* We have no RTP allocated for this channel */ 04252 return &ast_null_frame; 04253 } 04254 04255 switch(ast->fdno) { 04256 case 0: 04257 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04258 break; 04259 case 1: 04260 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04261 break; 04262 case 2: 04263 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04264 break; 04265 case 3: 04266 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04267 break; 04268 case 5: 04269 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04270 break; 04271 default: 04272 f = &ast_null_frame; 04273 } 04274 /* Don't forward RFC2833 if we're not supposed to */ 04275 if (f && (f->frametype == AST_FRAME_DTMF) && 04276 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04277 return &ast_null_frame; 04278 04279 /* We already hold the channel lock */ 04280 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04281 return f; 04282 04283 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04284 if (!(f->subclass & p->jointcapability)) { 04285 if (option_debug) { 04286 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04287 ast_getformatname(f->subclass), p->owner->name); 04288 } 04289 return &ast_null_frame; 04290 } 04291 if (option_debug) 04292 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04293 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04294 ast_set_read_format(p->owner, p->owner->readformat); 04295 ast_set_write_format(p->owner, p->owner->writeformat); 04296 } 04297 04298 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04299 f = ast_dsp_process(p->owner, p->vad, f); 04300 if (f && f->frametype == AST_FRAME_DTMF) { 04301 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04302 if (option_debug) 04303 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04304 *faxdetect = 1; 04305 } else if (option_debug) { 04306 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04307 } 04308 } 04309 } 04310 04311 return f; 04312 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2109 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(), and sip_sipredirect().
02110 { 02111 if (ms < 0) { 02112 if (p->timer_t1 == 0) 02113 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02114 ms = p->timer_t1 * 64; 02115 } 02116 if (sip_debug_test_pvt(p)) 02117 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02118 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02119 append_history(p, "SchedDestroy", "%d ms", ms); 02120 02121 if (p->autokillid > -1) 02122 ast_sched_del(sched, p->autokillid); 02123 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02124 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17722 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().
17723 { 17724 int ms; 17725 int regspacing; 17726 if (!regobjs) 17727 return; 17728 regspacing = default_expiry * 1000/regobjs; 17729 if (regspacing > 100) 17730 regspacing = 100; 17731 ms = regspacing; 17732 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17733 ASTOBJ_WRLOCK(iterator); 17734 if (iterator->expire > -1) 17735 ast_sched_del(sched, iterator->expire); 17736 ms += regspacing; 17737 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17738 ASTOBJ_UNLOCK(iterator); 17739 } while (0) 17740 ); 17741 }
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 15392 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().
15393 { 15394 /* Called with peerl lock, but releases it */ 15395 struct sip_pvt *p; 15396 int newmsgs, oldmsgs; 15397 15398 /* Do we have an IP address? If not, skip this peer */ 15399 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15400 return 0; 15401 15402 /* Check for messages */ 15403 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15404 15405 peer->lastmsgcheck = time(NULL); 15406 15407 /* Return now if it's the same thing we told them last time */ 15408 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15409 return 0; 15410 } 15411 15412 15413 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15414 15415 if (peer->mwipvt) { 15416 /* Base message on subscription */ 15417 p = peer->mwipvt; 15418 } else { 15419 /* Build temporary dialog for this message */ 15420 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15421 return -1; 15422 if (create_addr_from_peer(p, peer)) { 15423 /* Maybe they're not registered, etc. */ 15424 sip_destroy(p); 15425 return 0; 15426 } 15427 /* Recalculate our side, and recalculate Call ID */ 15428 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15429 p->ourip = __ourip; 15430 build_via(p); 15431 build_callid_pvt(p); 15432 /* Destroy this session after 32 secs */ 15433 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15434 } 15435 /* Send MWI */ 15436 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15437 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15438 return 0; 15439 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3780 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.
03781 { 03782 struct sip_pvt *p = ast->tech_pvt; 03783 int res = 0; 03784 03785 ast_mutex_lock(&p->lock); 03786 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03787 case SIP_DTMF_INBAND: 03788 res = -1; /* Tell Asterisk to generate inband indications */ 03789 break; 03790 case SIP_DTMF_RFC2833: 03791 if (p->rtp) 03792 ast_rtp_senddigit_begin(p->rtp, digit); 03793 break; 03794 default: 03795 break; 03796 } 03797 ast_mutex_unlock(&p->lock); 03798 03799 return res; 03800 }
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 3804 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().
03805 { 03806 struct sip_pvt *p = ast->tech_pvt; 03807 int res = 0; 03808 03809 ast_mutex_lock(&p->lock); 03810 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03811 case SIP_DTMF_INFO: 03812 transmit_info_with_digit(p, digit, duration); 03813 break; 03814 case SIP_DTMF_RFC2833: 03815 if (p->rtp) 03816 ast_rtp_senddigit_end(p->rtp, digit); 03817 break; 03818 case SIP_DTMF_INBAND: 03819 res = -1; /* Tell Asterisk to stop inband indications */ 03820 break; 03821 } 03822 ast_mutex_unlock(&p->lock); 03823 03824 return res; 03825 }
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 2352 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().
02353 { 02354 struct sip_pvt *p = ast->tech_pvt; 02355 int debug = sip_debug_test_pvt(p); 02356 02357 if (debug) 02358 ast_verbose("Sending text %s on %s\n", text, ast->name); 02359 if (!p) 02360 return -1; 02361 if (ast_strlen_zero(text)) 02362 return 0; 02363 if (debug) 02364 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02365 transmit_message_with_text(p, text); 02366 return 0; 02367 }
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 17455 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.
17456 { 17457 struct sip_pvt *p; 17458 int changed = 0; 17459 17460 p = chan->tech_pvt; 17461 if (!p) 17462 return -1; 17463 17464 /* Disable early RTP bridge */ 17465 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17466 return 0; 17467 17468 ast_mutex_lock(&p->lock); 17469 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17470 /* If we're destroyed, don't bother */ 17471 ast_mutex_unlock(&p->lock); 17472 return 0; 17473 } 17474 17475 /* if this peer cannot handle reinvites of the media stream to devices 17476 that are known to be behind a NAT, then stop the process now 17477 */ 17478 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17479 ast_mutex_unlock(&p->lock); 17480 return 0; 17481 } 17482 17483 if (rtp) { 17484 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17485 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17486 memset(&p->redirip, 0, sizeof(p->redirip)); 17487 changed = 1; 17488 } 17489 if (vrtp) { 17490 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17491 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17492 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17493 changed = 1; 17494 } 17495 if (codecs) { 17496 if ((p->redircodecs != codecs)) { 17497 p->redircodecs = codecs; 17498 changed = 1; 17499 } 17500 if ((p->capability & codecs) != p->capability) { 17501 p->jointcapability &= codecs; 17502 p->capability &= codecs; 17503 changed = 1; 17504 } 17505 } 17506 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 17507 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17508 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17509 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17510 if (option_debug) 17511 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)); 17512 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17513 if (option_debug > 2) { 17514 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)); 17515 } 17516 transmit_reinvite_with_sdp(p); 17517 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17518 if (option_debug > 2) { 17519 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)); 17520 } 17521 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17522 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17523 } 17524 } 17525 /* Reset lastrtprx timer */ 17526 p->lastrtprx = p->lastrtptx = time(NULL); 17527 ast_mutex_unlock(&p->lock); 17528 return 0; 17529 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17282 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.
17283 { 17284 struct sip_pvt *p; 17285 17286 p = chan->tech_pvt; 17287 if (!p) 17288 return -1; 17289 ast_mutex_lock(&p->lock); 17290 if (udptl) 17291 ast_udptl_get_peer(udptl, &p->udptlredirip); 17292 else 17293 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17294 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17295 if (!p->pendinginvite) { 17296 if (option_debug > 2) { 17297 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); 17298 } 17299 transmit_reinvite_with_t38_sdp(p); 17300 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17301 if (option_debug > 2) { 17302 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); 17303 } 17304 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17305 } 17306 } 17307 /* Reset lastrtprx timer */ 17308 p->lastrtprx = p->lastrtptx = time(NULL); 17309 ast_mutex_unlock(&p->lock); 17310 return 0; 17311 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 10903 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().
10904 { 10905 struct sip_pvt *cur; 10906 size_t len; 10907 int found = 0; 10908 10909 if (argc != 4) 10910 return RESULT_SHOWUSAGE; 10911 len = strlen(argv[3]); 10912 ast_mutex_lock(&iflock); 10913 for (cur = iflist; cur; cur = cur->next) { 10914 if (!strncasecmp(cur->callid, argv[3], len)) { 10915 char formatbuf[BUFSIZ/2]; 10916 ast_cli(fd,"\n"); 10917 if (cur->subscribed != NONE) 10918 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 10919 else 10920 ast_cli(fd, " * SIP Call\n"); 10921 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 10922 ast_cli(fd, " Call-ID: %s\n", cur->callid); 10923 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 10924 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 10925 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 10926 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 10927 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 10928 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 10929 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 10930 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 10931 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 10932 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 10933 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 10934 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)" ); 10935 ast_cli(fd, " Our Tag: %s\n", cur->tag); 10936 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 10937 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 10938 if (!ast_strlen_zero(cur->username)) 10939 ast_cli(fd, " Username: %s\n", cur->username); 10940 if (!ast_strlen_zero(cur->peername)) 10941 ast_cli(fd, " Peername: %s\n", cur->peername); 10942 if (!ast_strlen_zero(cur->uri)) 10943 ast_cli(fd, " Original uri: %s\n", cur->uri); 10944 if (!ast_strlen_zero(cur->cid_num)) 10945 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 10946 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 10947 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 10948 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10949 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 10950 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 10951 ast_cli(fd, " SIP Options: "); 10952 if (cur->sipoptions) { 10953 int x; 10954 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10955 if (cur->sipoptions & sip_options[x].id) 10956 ast_cli(fd, "%s ", sip_options[x].text); 10957 } 10958 } else 10959 ast_cli(fd, "(none)\n"); 10960 ast_cli(fd, "\n\n"); 10961 found++; 10962 } 10963 } 10964 ast_mutex_unlock(&iflock); 10965 if (!found) 10966 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10967 return RESULT_SUCCESS; 10968 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10700 of file chan_sip.c.
References __sip_show_channels().
10701 { 10702 return __sip_show_channels(fd, argc, argv, 0); 10703 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10212 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.
10213 { 10214 struct domain *d; 10215 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10216 10217 if (AST_LIST_EMPTY(&domain_list)) { 10218 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10219 return RESULT_SUCCESS; 10220 } else { 10221 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10222 AST_LIST_LOCK(&domain_list); 10223 AST_LIST_TRAVERSE(&domain_list, d, list) 10224 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10225 domain_mode_to_text(d->mode)); 10226 AST_LIST_UNLOCK(&domain_list); 10227 ast_cli(fd, "\n"); 10228 return RESULT_SUCCESS; 10229 } 10230 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 10971 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.
10972 { 10973 struct sip_pvt *cur; 10974 size_t len; 10975 int found = 0; 10976 10977 if (argc != 4) 10978 return RESULT_SHOWUSAGE; 10979 if (!recordhistory) 10980 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 10981 len = strlen(argv[3]); 10982 ast_mutex_lock(&iflock); 10983 for (cur = iflist; cur; cur = cur->next) { 10984 if (!strncasecmp(cur->callid, argv[3], len)) { 10985 struct sip_history *hist; 10986 int x = 0; 10987 10988 ast_cli(fd,"\n"); 10989 if (cur->subscribed != NONE) 10990 ast_cli(fd, " * Subscription\n"); 10991 else 10992 ast_cli(fd, " * SIP Call\n"); 10993 if (cur->history) 10994 AST_LIST_TRAVERSE(cur->history, hist, list) 10995 ast_cli(fd, "%d. %s\n", ++x, hist->event); 10996 if (x == 0) 10997 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 10998 found++; 10999 } 11000 } 11001 ast_mutex_unlock(&iflock); 11002 if (!found) 11003 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11004 return RESULT_SUCCESS; 11005 }
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 9637 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.
09638 { 09639 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09640 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09641 char ilimits[40]; 09642 char iused[40]; 09643 int showall = FALSE; 09644 09645 if (argc < 3) 09646 return RESULT_SHOWUSAGE; 09647 09648 if (argc == 4 && !strcmp(argv[3],"all")) 09649 showall = TRUE; 09650 09651 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09652 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09653 ASTOBJ_RDLOCK(iterator); 09654 if (iterator->call_limit) 09655 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09656 else 09657 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09658 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09659 if (showall || iterator->call_limit) 09660 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09661 ASTOBJ_UNLOCK(iterator); 09662 } while (0) ); 09663 09664 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09665 09666 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09667 ASTOBJ_RDLOCK(iterator); 09668 if (iterator->call_limit) 09669 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09670 else 09671 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09672 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09673 if (showall || iterator->call_limit) 09674 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09675 ASTOBJ_UNLOCK(iterator); 09676 } while (0) ); 09677 09678 return RESULT_SUCCESS; 09679 #undef FORMAT 09680 #undef FORMAT2 09681 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 9958 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
09959 { 09960 char tmp[256]; 09961 if (argc != 3) 09962 return RESULT_SHOWUSAGE; 09963 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 09964 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 09965 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 09966 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 09967 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 09968 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 09969 return RESULT_SUCCESS; 09970 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10264 of file chan_sip.c.
References _sip_show_peer().
10265 { 10266 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10267 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9814 of file chan_sip.c.
References _sip_show_peers().
09815 { 09816 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09817 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10537 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.
10538 { 10539 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10540 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10541 char host[80]; 10542 char tmpdat[256]; 10543 struct tm tm; 10544 10545 10546 if (argc != 3) 10547 return RESULT_SHOWUSAGE; 10548 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10549 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10550 ASTOBJ_RDLOCK(iterator); 10551 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10552 if (iterator->regtime) { 10553 ast_localtime(&iterator->regtime, &tm, NULL); 10554 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10555 } else { 10556 tmpdat[0] = 0; 10557 } 10558 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10559 ASTOBJ_UNLOCK(iterator); 10560 } while(0)); 10561 return RESULT_SUCCESS; 10562 #undef FORMAT 10563 #undef FORMAT2 10564 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10567 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().
10568 { 10569 int realtimepeers; 10570 int realtimeusers; 10571 char codec_buf[BUFSIZ]; 10572 10573 realtimepeers = ast_check_realtime("sippeers"); 10574 realtimeusers = ast_check_realtime("sipusers"); 10575 10576 if (argc != 3) 10577 return RESULT_SHOWUSAGE; 10578 ast_cli(fd, "\n\nGlobal Settings:\n"); 10579 ast_cli(fd, "----------------\n"); 10580 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10581 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10582 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10583 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10584 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10585 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10586 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10587 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10588 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10589 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10590 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10591 ast_cli(fd, " Our auth realm %s\n", global_realm); 10592 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10593 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10594 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10595 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10596 ast_cli(fd, " User Agent: %s\n", global_useragent); 10597 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10598 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10599 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10600 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10601 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10602 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10603 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10604 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10605 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10606 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10607 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10608 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10609 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10610 #endif 10611 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10612 if (!realtimepeers && !realtimeusers) 10613 ast_cli(fd, " SIP realtime: Disabled\n" ); 10614 else 10615 ast_cli(fd, " SIP realtime: Enabled\n" ); 10616 10617 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10618 ast_cli(fd, "---------------------------\n"); 10619 ast_cli(fd, " Codecs: "); 10620 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10621 ast_cli(fd, "%s\n", codec_buf); 10622 ast_cli(fd, " Codec Order: "); 10623 print_codec_to_cli(fd, &default_prefs); 10624 ast_cli(fd, "\n"); 10625 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10626 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10627 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10628 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10629 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10630 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10631 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10632 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10633 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10634 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10635 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10636 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10637 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10638 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10639 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10640 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10641 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10642 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10643 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10644 ast_cli(fd, "\nDefault Settings:\n"); 10645 ast_cli(fd, "-----------------\n"); 10646 ast_cli(fd, " Context: %s\n", default_context); 10647 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10648 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10649 ast_cli(fd, " Qualify: %d\n", default_qualify); 10650 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10651 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" ); 10652 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10653 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10654 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10655 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10656 10657 10658 if (realtimepeers || realtimeusers) { 10659 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10660 ast_cli(fd, "----------------------\n"); 10661 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10662 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10663 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10664 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10665 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10666 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10667 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10668 } 10669 ast_cli(fd, "\n----\n"); 10670 return RESULT_SUCCESS; 10671 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10706 of file chan_sip.c.
References __sip_show_channels().
10707 { 10708 return __sip_show_channels(fd, argc, argv, 1); 10709 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10482 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.
10483 { 10484 char cbuf[256]; 10485 struct sip_user *user; 10486 struct ast_variable *v; 10487 int load_realtime; 10488 10489 if (argc < 4) 10490 return RESULT_SHOWUSAGE; 10491 10492 /* Load from realtime storage? */ 10493 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10494 10495 user = find_user(argv[3], load_realtime); 10496 if (user) { 10497 ast_cli(fd,"\n\n"); 10498 ast_cli(fd, " * Name : %s\n", user->name); 10499 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10500 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10501 ast_cli(fd, " Context : %s\n", user->context); 10502 ast_cli(fd, " Language : %s\n", user->language); 10503 if (!ast_strlen_zero(user->accountcode)) 10504 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10505 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10506 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10507 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10508 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10509 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10510 ast_cli(fd, " Callgroup : "); 10511 print_group(fd, user->callgroup, 0); 10512 ast_cli(fd, " Pickupgroup : "); 10513 print_group(fd, user->pickupgroup, 0); 10514 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10515 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10516 ast_cli(fd, " Codec Order : ("); 10517 print_codec_to_cli(fd, &user->prefs); 10518 ast_cli(fd, ")\n"); 10519 10520 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10521 if (user->chanvars) { 10522 ast_cli(fd, " Variables :\n"); 10523 for (v = user->chanvars ; v ; v = v->next) 10524 ast_cli(fd, " %s = %s\n", v->name, v->value); 10525 } 10526 ast_cli(fd,"\n"); 10527 ASTOBJ_UNREF(user,sip_destroy_user); 10528 } else { 10529 ast_cli(fd,"User %s not found.\n", argv[3]); 10530 ast_cli(fd,"\n"); 10531 } 10532 10533 return RESULT_SUCCESS; 10534 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9737 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.
09738 { 09739 regex_t regexbuf; 09740 int havepattern = FALSE; 09741 09742 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09743 09744 switch (argc) { 09745 case 5: 09746 if (!strcasecmp(argv[3], "like")) { 09747 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09748 return RESULT_SHOWUSAGE; 09749 havepattern = TRUE; 09750 } else 09751 return RESULT_SHOWUSAGE; 09752 case 3: 09753 break; 09754 default: 09755 return RESULT_SHOWUSAGE; 09756 } 09757 09758 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09759 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09760 ASTOBJ_RDLOCK(iterator); 09761 09762 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09763 ASTOBJ_UNLOCK(iterator); 09764 continue; 09765 } 09766 09767 ast_cli(fd, FORMAT, iterator->name, 09768 iterator->secret, 09769 iterator->accountcode, 09770 iterator->context, 09771 iterator->ha ? "Yes" : "No", 09772 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09773 ASTOBJ_UNLOCK(iterator); 09774 } while (0) 09775 ); 09776 09777 if (havepattern) 09778 regfree(®exbuf); 09779 09780 return RESULT_SUCCESS; 09781 #undef FORMAT 09782 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17642 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().
17643 { 17644 char *cdest; 17645 char *extension, *host, *port; 17646 char tmp[80]; 17647 17648 cdest = ast_strdupa(dest); 17649 17650 extension = strsep(&cdest, "@"); 17651 host = strsep(&cdest, ":"); 17652 port = strsep(&cdest, ":"); 17653 if (ast_strlen_zero(extension)) { 17654 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17655 return 0; 17656 } 17657 17658 /* we'll issue the redirect message here */ 17659 if (!host) { 17660 char *localtmp; 17661 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17662 if (ast_strlen_zero(tmp)) { 17663 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17664 return 0; 17665 } 17666 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17667 char lhost[80], lport[80]; 17668 memset(lhost, 0, sizeof(lhost)); 17669 memset(lport, 0, sizeof(lport)); 17670 localtmp++; 17671 /* This is okey because lhost and lport are as big as tmp */ 17672 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17673 if (ast_strlen_zero(lhost)) { 17674 ast_log(LOG_ERROR, "Can't find the host address\n"); 17675 return 0; 17676 } 17677 host = ast_strdupa(lhost); 17678 if (!ast_strlen_zero(lport)) { 17679 port = ast_strdupa(lport); 17680 } 17681 } 17682 } 17683 17684 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17685 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17686 17687 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17688 sip_alreadygone(p); 17689 return 0; 17690 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3828 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().
03829 { 03830 struct sip_pvt *p = ast->tech_pvt; 03831 int res; 03832 03833 if (dest == NULL) /* functions below do not take a NULL */ 03834 dest = ""; 03835 ast_mutex_lock(&p->lock); 03836 if (ast->_state == AST_STATE_RING) 03837 res = sip_sipredirect(p, dest); 03838 else 03839 res = transmit_refer(p, dest); 03840 ast_mutex_unlock(&p->lock); 03841 return res; 03842 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3663 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.
03664 { 03665 struct sip_pvt *p = ast->tech_pvt; 03666 int res = 0; 03667 03668 switch (frame->frametype) { 03669 case AST_FRAME_VOICE: 03670 if (!(frame->subclass & ast->nativeformats)) { 03671 char s1[512], s2[512], s3[512]; 03672 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03673 frame->subclass, 03674 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03675 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03676 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03677 ast->readformat, 03678 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03679 ast->writeformat); 03680 return 0; 03681 } 03682 if (p) { 03683 ast_mutex_lock(&p->lock); 03684 if (p->rtp) { 03685 /* If channel is not up, activate early media session */ 03686 if ((ast->_state != AST_STATE_UP) && 03687 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03688 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03689 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03690 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03691 } 03692 p->lastrtptx = time(NULL); 03693 res = ast_rtp_write(p->rtp, frame); 03694 } 03695 ast_mutex_unlock(&p->lock); 03696 } 03697 break; 03698 case AST_FRAME_VIDEO: 03699 if (p) { 03700 ast_mutex_lock(&p->lock); 03701 if (p->vrtp) { 03702 /* Activate video early media */ 03703 if ((ast->_state != AST_STATE_UP) && 03704 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03705 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03706 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03707 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03708 } 03709 p->lastrtptx = time(NULL); 03710 res = ast_rtp_write(p->vrtp, frame); 03711 } 03712 ast_mutex_unlock(&p->lock); 03713 } 03714 break; 03715 case AST_FRAME_IMAGE: 03716 return 0; 03717 break; 03718 case AST_FRAME_MODEM: 03719 if (p) { 03720 ast_mutex_lock(&p->lock); 03721 /* UDPTL requires two-way communication, so early media is not needed here. 03722 we simply forget the frames if we get modem frames before the bridge is up. 03723 Fax will re-transmit. 03724 */ 03725 if (p->udptl && ast->_state == AST_STATE_UP) 03726 res = ast_udptl_write(p->udptl, frame); 03727 ast_mutex_unlock(&p->lock); 03728 } 03729 break; 03730 default: 03731 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03732 return 0; 03733 } 03734 03735 return res; 03736 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15291 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().
15292 { 15293 struct sip_request req; 15294 struct sockaddr_in sin = { 0, }; 15295 struct sip_pvt *p; 15296 int res; 15297 socklen_t len = sizeof(sin); 15298 int nounlock; 15299 int recount = 0; 15300 int lockretry; 15301 15302 memset(&req, 0, sizeof(req)); 15303 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15304 if (res < 0) { 15305 #if !defined(__FreeBSD__) 15306 if (errno == EAGAIN) 15307 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15308 else 15309 #endif 15310 if (errno != ECONNREFUSED) 15311 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15312 return 1; 15313 } 15314 if (option_debug && res == sizeof(req.data)) { 15315 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15316 req.data[sizeof(req.data) - 1] = '\0'; 15317 } else 15318 req.data[res] = '\0'; 15319 req.len = res; 15320 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15321 ast_set_flag(&req, SIP_PKT_DEBUG); 15322 if (pedanticsipchecking) 15323 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15324 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15325 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15326 15327 parse_request(&req); 15328 req.method = find_sip_method(req.rlPart1); 15329 15330 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15331 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15332 15333 if (req.headers < 2) /* Must have at least two headers */ 15334 return 1; 15335 15336 /* Process request, with netlock held, and with usual deadlock avoidance */ 15337 for (lockretry = 100; lockretry > 0; lockretry--) { 15338 ast_mutex_lock(&netlock); 15339 15340 /* Find the active SIP dialog or create a new one */ 15341 p = find_call(&req, &sin, req.method); /* returns p locked */ 15342 if (p == NULL) { 15343 if (option_debug) 15344 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15345 ast_mutex_unlock(&netlock); 15346 return 1; 15347 } 15348 /* Go ahead and lock the owner if it has one -- we may need it */ 15349 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15350 if (!p->owner || !ast_channel_trylock(p->owner)) 15351 break; /* locking succeeded */ 15352 if (option_debug) 15353 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15354 ast_mutex_unlock(&p->lock); 15355 ast_mutex_unlock(&netlock); 15356 /* Sleep for a very short amount of time */ 15357 usleep(1); 15358 } 15359 p->recv = sin; 15360 15361 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15362 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15363 15364 if (!lockretry) { 15365 if (p->owner) 15366 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15367 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15368 if (req.method != SIP_ACK) 15369 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15370 /* XXX We could add retry-after to make sure they come back */ 15371 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15372 return 1; 15373 } 15374 nounlock = 0; 15375 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15376 /* Request failed */ 15377 if (option_debug) 15378 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15379 } 15380 15381 if (p->owner && !nounlock) 15382 ast_channel_unlock(p->owner); 15383 ast_mutex_unlock(&p->lock); 15384 ast_mutex_unlock(&netlock); 15385 if (recount) 15386 ast_update_use_count(); 15387 15388 return 1; 15389 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12542 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().
12543 { 12544 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12545 if (p->rtp) 12546 ast_rtp_stop(p->rtp); 12547 if (p->vrtp) 12548 ast_rtp_stop(p->vrtp); 12549 if (p->udptl) 12550 ast_udptl_stop(p->udptl); 12551 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10674 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
10675 { 10676 int i; 10677 10678 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10679 if (subscription_types[i].type == subtype) { 10680 return subscription_types[i].text; 10681 } 10682 } 10683 return subscription_types[0].text; 10684 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6202 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().
06203 { 06204 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06205 06206 if (maxrate & T38FAX_RATE_14400) { 06207 if (option_debug > 1) 06208 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06209 return 14400; 06210 } else if (maxrate & T38FAX_RATE_12000) { 06211 if (option_debug > 1) 06212 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06213 return 12000; 06214 } else if (maxrate & T38FAX_RATE_9600) { 06215 if (option_debug > 1) 06216 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06217 return 9600; 06218 } else if (maxrate & T38FAX_RATE_7200) { 06219 if (option_debug > 1) 06220 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06221 return 7200; 06222 } else if (maxrate & T38FAX_RATE_4800) { 06223 if (option_debug > 1) 06224 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06225 return 4800; 06226 } else if (maxrate & T38FAX_RATE_2400) { 06227 if (option_debug > 1) 06228 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06229 return 2400; 06230 } else { 06231 if (option_debug > 1) 06232 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06233 return 0; 06234 } 06235 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16404 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().
16405 { 16406 struct sip_peer *peer; 16407 16408 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16409 return NULL; 16410 16411 apeerobjs++; 16412 ASTOBJ_INIT(peer); 16413 set_peer_defaults(peer); 16414 16415 ast_copy_string(peer->name, name, sizeof(peer->name)); 16416 16417 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16418 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16419 peer->prefs = default_prefs; 16420 reg_source_db(peer); 16421 16422 return peer; 16423 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 5978 of file chan_sip.c.
References ast_string_field_free_memory, and free.
05979 { 05980 struct sip_pvt *p = data; 05981 05982 ast_string_field_free_memory(p); 05983 05984 free(data); 05985 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 9684 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().
09685 { 09686 if (mode == TRANSFER_OPENFORALL) 09687 return "open"; 09688 else if (mode == TRANSFER_CLOSED) 09689 return "closed"; 09690 return "strict"; 09691 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8505 of file chan_sip.c.
References ast_random(), ast_string_field_build, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08506 { 08507 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08508 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08509 }
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 7744 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07745 { 07746 struct sip_request req; 07747 07748 reqprep(&req, p, SIP_INFO, 0, 1); 07749 add_digit(&req, digit, duration); 07750 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07751 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7754 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07755 { 07756 struct sip_request req; 07757 07758 reqprep(&req, p, SIP_INFO, 0, 1); 07759 add_vidupdate(&req); 07760 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07761 }
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 7004 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().
07005 { 07006 struct sip_request req; 07007 07008 req.method = sipmethod; 07009 if (init) { /* Seems like init always is 2 */ 07010 /* Bump branch even on initial requests */ 07011 p->branch ^= ast_random(); 07012 build_via(p); 07013 if (init > 1) 07014 initreqprep(&req, p, sipmethod); 07015 else 07016 reqprep(&req, p, sipmethod, 0, 1); 07017 } else 07018 reqprep(&req, p, sipmethod, 0, 1); 07019 07020 if (p->options && p->options->auth) 07021 add_header(&req, p->options->authheader, p->options->auth); 07022 append_date(&req); 07023 if (sipmethod == SIP_REFER) { /* Call transfer */ 07024 if (p->refer) { 07025 char buf[BUFSIZ]; 07026 if (!ast_strlen_zero(p->refer->refer_to)) 07027 add_header(&req, "Refer-To", p->refer->refer_to); 07028 if (!ast_strlen_zero(p->refer->referred_by)) { 07029 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07030 add_header(&req, "Referred-By", buf); 07031 } 07032 } 07033 } 07034 /* This new INVITE is part of an attended transfer. Make sure that the 07035 other end knows and replace the current call with this new call */ 07036 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07037 add_header(&req, "Replaces", p->options->replaces); 07038 add_header(&req, "Require", "replaces"); 07039 } 07040 07041 add_header(&req, "Allow", ALLOWED_METHODS); 07042 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07043 if (p->options && p->options->addsipheaders && p->owner) { 07044 struct ast_channel *chan = p->owner; /* The owner channel */ 07045 struct varshead *headp; 07046 07047 ast_channel_lock(chan); 07048 07049 headp = &chan->varshead; 07050 07051 if (!headp) 07052 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07053 else { 07054 const struct ast_var_t *current; 07055 AST_LIST_TRAVERSE(headp, current, entries) { 07056 /* SIPADDHEADER: Add SIP header to outgoing call */ 07057 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07058 char *content, *end; 07059 const char *header = ast_var_value(current); 07060 char *headdup = ast_strdupa(header); 07061 07062 /* Strip of the starting " (if it's there) */ 07063 if (*headdup == '"') 07064 headdup++; 07065 if ((content = strchr(headdup, ':'))) { 07066 *content++ = '\0'; 07067 content = ast_skip_blanks(content); /* Skip white space */ 07068 /* Strip the ending " (if it's there) */ 07069 end = content + strlen(content) -1; 07070 if (*end == '"') 07071 *end = '\0'; 07072 07073 add_header(&req, headdup, content); 07074 if (sipdebug) 07075 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07076 } 07077 } 07078 } 07079 } 07080 07081 ast_channel_unlock(chan); 07082 } 07083 if (sdp) { 07084 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 07085 ast_udptl_offered_from_local(p->udptl, 1); 07086 if (option_debug) 07087 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07088 add_t38_sdp(&req, p); 07089 } else if (p->rtp) 07090 add_sdp(&req, p); 07091 } else { 07092 add_header_contentLength(&req, 0); 07093 } 07094 07095 if (!p->initreq.headers) 07096 initialize_initreq(p, &req); 07097 p->lastinvite = p->ocseq; 07098 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07099 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7652 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().
07653 { 07654 struct sip_request req; 07655 07656 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07657 add_text(&req, text); 07658 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07659 }
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 7289 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().
07290 { 07291 struct sip_request req; 07292 char tmp[500]; 07293 char *t = tmp; 07294 size_t maxbytes = sizeof(tmp); 07295 07296 initreqprep(&req, p, SIP_NOTIFY); 07297 add_header(&req, "Event", "message-summary"); 07298 add_header(&req, "Content-Type", default_notifymime); 07299 07300 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07301 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07302 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07303 /* Cisco has a bug in the SIP stack where it can't accept the 07304 (0/0) notification. This can temporarily be disabled in 07305 sip.conf with the "buggymwi" option */ 07306 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)")); 07307 07308 if (p->subscribed) { 07309 if (p->expiry) 07310 add_header(&req, "Subscription-State", "active"); 07311 else /* Expired */ 07312 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07313 } 07314 07315 if (t > tmp + sizeof(tmp)) 07316 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07317 07318 add_header_contentLength(&req, strlen(tmp)); 07319 add_line(&req, tmp); 07320 07321 if (!p->initreq.headers) 07322 initialize_initreq(p, &req); 07323 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07324 }
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 7335 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().
07336 { 07337 struct sip_request req; 07338 char tmp[BUFSIZ/2]; 07339 07340 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07341 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07342 add_header(&req, "Event", tmp); 07343 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07344 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07345 add_header(&req, "Allow", ALLOWED_METHODS); 07346 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07347 07348 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07349 add_header_contentLength(&req, strlen(tmp)); 07350 add_line(&req, tmp); 07351 07352 if (!p->initreq.headers) 07353 initialize_initreq(p, &req); 07354 07355 p->lastnoninvite = p->ocseq; 07356 07357 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07358 }
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 7673 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().
07674 { 07675 struct sip_request req = { 07676 .headers = 0, 07677 }; 07678 char from[256]; 07679 const char *of; 07680 char *c; 07681 char referto[256]; 07682 char *ttag, *ftag; 07683 char *theirtag = ast_strdupa(p->theirtag); 07684 07685 if (option_debug || sipdebug) 07686 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07687 07688 /* Are we transfering an inbound or outbound call ? */ 07689 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07690 of = get_header(&p->initreq, "To"); 07691 ttag = theirtag; 07692 ftag = p->tag; 07693 } else { 07694 of = get_header(&p->initreq, "From"); 07695 ftag = theirtag; 07696 ttag = p->tag; 07697 } 07698 07699 ast_copy_string(from, of, sizeof(from)); 07700 of = get_in_brackets(from); 07701 ast_string_field_set(p, from, of); 07702 if (strncasecmp(of, "sip:", 4)) 07703 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07704 else 07705 of += 4; 07706 /* Get just the username part */ 07707 if ((c = strchr(dest, '@'))) 07708 c = NULL; 07709 else if ((c = strchr(of, '@'))) 07710 *c++ = '\0'; 07711 if (c) 07712 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07713 else 07714 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07715 07716 /* save in case we get 407 challenge */ 07717 sip_refer_allocate(p); 07718 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07719 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07720 p->refer->status = REFER_SENT; /* Set refer status */ 07721 07722 reqprep(&req, p, SIP_REFER, 0, 1); 07723 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07724 07725 add_header(&req, "Refer-To", referto); 07726 add_header(&req, "Allow", ALLOWED_METHODS); 07727 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07728 if (!ast_strlen_zero(p->our_contact)) 07729 add_header(&req, "Referred-By", p->our_contact); 07730 07731 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07732 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07733 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07734 07735 /*! \todo In theory, we should hang around and wait for a reply, before 07736 returning to the dial plan here. Don't know really how that would 07737 affect the transfer() app or the pbx, but, well, to make this 07738 useful we should have a STATUS code on transfer(). 07739 */ 07740 }
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 7460 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().
07461 { 07462 struct sip_request req; 07463 char from[256]; 07464 char to[256]; 07465 char tmp[80]; 07466 char addr[80]; 07467 struct sip_pvt *p; 07468 07469 /* exit if we are already in process with this registrar ?*/ 07470 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07471 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07472 return 0; 07473 } 07474 07475 if (r->call) { /* We have a registration */ 07476 if (!auth) { 07477 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07478 return 0; 07479 } else { 07480 p = r->call; 07481 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07482 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07483 } 07484 } else { 07485 /* Build callid for registration if we haven't registered before */ 07486 if (!r->callid_valid) { 07487 build_callid_registry(r, __ourip, default_fromdomain); 07488 r->callid_valid = TRUE; 07489 } 07490 /* Allocate SIP packet for registration */ 07491 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07492 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07493 return 0; 07494 } 07495 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07496 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07497 /* Find address to hostname */ 07498 if (create_addr(p, r->hostname)) { 07499 /* we have what we hope is a temporary network error, 07500 * probably DNS. We need to reschedule a registration try */ 07501 sip_destroy(p); 07502 if (r->timeout > -1) { 07503 ast_sched_del(sched, r->timeout); 07504 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07505 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07506 } else { 07507 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07508 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); 07509 } 07510 r->regattempts++; 07511 return 0; 07512 } 07513 /* Copy back Call-ID in case create_addr changed it */ 07514 ast_string_field_set(r, callid, p->callid); 07515 if (r->portno) { 07516 p->sa.sin_port = htons(r->portno); 07517 p->recv.sin_port = htons(r->portno); 07518 } else /* Set registry port to the port set from the peer definition/srv or default */ 07519 r->portno = ntohs(p->sa.sin_port); 07520 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07521 r->call=p; /* Save pointer to SIP packet */ 07522 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07523 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07524 ast_string_field_set(p, peersecret, r->secret); 07525 if (!ast_strlen_zero(r->md5secret)) 07526 ast_string_field_set(p, peermd5secret, r->md5secret); 07527 /* User name in this realm 07528 - if authuser is set, use that, otherwise use username */ 07529 if (!ast_strlen_zero(r->authuser)) { 07530 ast_string_field_set(p, peername, r->authuser); 07531 ast_string_field_set(p, authname, r->authuser); 07532 } else if (!ast_strlen_zero(r->username)) { 07533 ast_string_field_set(p, peername, r->username); 07534 ast_string_field_set(p, authname, r->username); 07535 ast_string_field_set(p, fromuser, r->username); 07536 } 07537 if (!ast_strlen_zero(r->username)) 07538 ast_string_field_set(p, username, r->username); 07539 /* Save extension in packet */ 07540 ast_string_field_set(p, exten, r->contact); 07541 07542 /* 07543 check which address we should use in our contact header 07544 based on whether the remote host is on the external or 07545 internal network so we can register through nat 07546 */ 07547 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07548 p->ourip = bindaddr.sin_addr; 07549 build_contact(p); 07550 } 07551 07552 /* set up a timeout */ 07553 if (auth == NULL) { 07554 if (r->timeout > -1) { 07555 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07556 ast_sched_del(sched, r->timeout); 07557 } 07558 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07559 if (option_debug) 07560 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07561 } 07562 07563 if (strchr(r->username, '@')) { 07564 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07565 if (!ast_strlen_zero(p->theirtag)) 07566 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07567 else 07568 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07569 } else { 07570 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07571 if (!ast_strlen_zero(p->theirtag)) 07572 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07573 else 07574 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07575 } 07576 07577 /* Fromdomain is what we are registering to, regardless of actual 07578 host name from SRV */ 07579 if (!ast_strlen_zero(p->fromdomain)) { 07580 if (r->portno && r->portno != STANDARD_SIP_PORT) 07581 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07582 else 07583 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07584 } else { 07585 if (r->portno && r->portno != STANDARD_SIP_PORT) 07586 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07587 else 07588 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07589 } 07590 ast_string_field_set(p, uri, addr); 07591 07592 p->branch ^= ast_random(); 07593 07594 init_req(&req, sipmethod, addr); 07595 07596 /* Add to CSEQ */ 07597 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07598 p->ocseq = r->ocseq; 07599 07600 build_via(p); 07601 add_header(&req, "Via", p->via); 07602 add_header(&req, "From", from); 07603 add_header(&req, "To", to); 07604 add_header(&req, "Call-ID", p->callid); 07605 add_header(&req, "CSeq", tmp); 07606 if (!ast_strlen_zero(global_useragent)) 07607 add_header(&req, "User-Agent", global_useragent); 07608 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07609 07610 07611 if (auth) /* Add auth header */ 07612 add_header(&req, authheader, auth); 07613 else if (!ast_strlen_zero(r->nonce)) { 07614 char digest[1024]; 07615 07616 /* We have auth data to reuse, build a digest header! */ 07617 if (sipdebug) 07618 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07619 ast_string_field_set(p, realm, r->realm); 07620 ast_string_field_set(p, nonce, r->nonce); 07621 ast_string_field_set(p, domain, r->domain); 07622 ast_string_field_set(p, opaque, r->opaque); 07623 ast_string_field_set(p, qop, r->qop); 07624 r->noncecount++; 07625 p->noncecount = r->noncecount; 07626 07627 memset(digest,0,sizeof(digest)); 07628 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07629 add_header(&req, "Authorization", digest); 07630 else 07631 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07632 07633 } 07634 07635 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07636 add_header(&req, "Expires", tmp); 07637 add_header(&req, "Contact", p->our_contact); 07638 add_header(&req, "Event", "registration"); 07639 add_header_contentLength(&req, 0); 07640 07641 initialize_initreq(p, &req); 07642 if (sip_debug_test_pvt(p)) 07643 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07644 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07645 r->regattempts++; /* Another attempt */ 07646 if (option_debug > 3) 07647 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07648 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07649 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6724 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().
06725 { 06726 struct sip_request req; 06727 06728 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06729 06730 add_header(&req, "Allow", ALLOWED_METHODS); 06731 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06732 if (sipdebug) 06733 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06734 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06735 append_history(p, "ReInv", "Re-invite sent"); 06736 add_sdp(&req, p); 06737 /* Use this as the basis */ 06738 initialize_initreq(p, &req); 06739 p->lastinvite = p->ocseq; 06740 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06741 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06742 }
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 6748 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().
06749 { 06750 struct sip_request req; 06751 06752 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06753 06754 add_header(&req, "Allow", ALLOWED_METHODS); 06755 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06756 if (sipdebug) 06757 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06758 ast_udptl_offered_from_local(p->udptl, 1); 06759 add_t38_sdp(&req, p); 06760 /* Use this as the basis */ 06761 initialize_initreq(p, &req); 06762 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06763 p->lastinvite = p->ocseq; 06764 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06765 }
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 7766 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().
07767 { 07768 struct sip_request resp; 07769 07770 if (sipmethod == SIP_ACK) 07771 p->invitestate = INV_CONFIRMED; 07772 07773 reqprep(&resp, p, sipmethod, seqno, newbranch); 07774 add_header_contentLength(&resp, 0); 07775 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07776 }
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 7779 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().
07780 { 07781 struct sip_request resp; 07782 07783 reqprep(&resp, p, sipmethod, seqno, newbranch); 07784 if (!ast_strlen_zero(p->realm)) { 07785 char digest[1024]; 07786 07787 memset(digest, 0, sizeof(digest)); 07788 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07789 if (p->options && p->options->auth_type == PROXY_AUTH) 07790 add_header(&resp, "Proxy-Authorization", digest); 07791 else if (p->options && p->options->auth_type == WWW_AUTH) 07792 add_header(&resp, "Authorization", digest); 07793 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07794 add_header(&resp, "Proxy-Authorization", digest); 07795 } else 07796 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07797 } 07798 /* If we are hanging up and know a cause for that, send it in clear text to make 07799 debugging easier. */ 07800 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07801 char buf[10]; 07802 07803 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07804 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07805 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07806 } 07807 07808 add_header_contentLength(&resp, 0); 07809 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07810 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6038 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06039 { 06040 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06041 }
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 6057 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().
06058 { 06059 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06060 }
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 5988 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().
05989 { 05990 struct sip_pvt *p = NULL; 05991 05992 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05993 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05994 return -1; 05995 } 05996 05997 /* if the structure was just allocated, initialize it */ 05998 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 05999 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06000 if (ast_string_field_init(p, 512)) 06001 return -1; 06002 } 06003 06004 /* Initialize the bare minimum */ 06005 p->method = intended_method; 06006 06007 if (sin) { 06008 p->sa = *sin; 06009 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06010 p->ourip = __ourip; 06011 } else 06012 p->ourip = __ourip; 06013 06014 p->branch = ast_random(); 06015 make_our_tag(p->tag, sizeof(p->tag)); 06016 p->ocseq = INITIAL_CSEQ; 06017 06018 if (useglobal_nat && sin) { 06019 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06020 p->recv = *sin; 06021 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06022 } 06023 06024 ast_string_field_set(p, fromdomain, default_fromdomain); 06025 build_via(p); 06026 ast_string_field_set(p, callid, callid); 06027 06028 /* Use this temporary pvt structure to send the message */ 06029 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06030 06031 /* Free the string fields, but not the pool space */ 06032 ast_string_field_reset_all(p); 06033 06034 return 0; 06035 }
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 6085 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06086 { 06087 struct sip_request resp; 06088 respprep(&resp, p, msg, req); 06089 add_header(&resp, "Accept", "application/sdp"); 06090 add_header_contentLength(&resp, 0); 06091 return send_response(p, &resp, reliable, 0); 06092 }
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 6095 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().
06096 { 06097 struct sip_request resp; 06098 char tmp[512]; 06099 int seqno = 0; 06100 06101 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06102 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06103 return -1; 06104 } 06105 /* Stale means that they sent us correct authentication, but 06106 based it on an old challenge (nonce) */ 06107 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06108 respprep(&resp, p, msg, req); 06109 add_header(&resp, header, tmp); 06110 add_header_contentLength(&resp, 0); 06111 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06112 return send_response(p, &resp, reliable, seqno); 06113 }
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 6075 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06076 { 06077 struct sip_request resp; 06078 respprep(&resp, p, msg, req); 06079 append_date(&resp); 06080 add_header_contentLength(&resp, 0); 06081 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06082 }
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 6653 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().
06654 { 06655 struct sip_request resp; 06656 int seqno; 06657 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06658 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06659 return -1; 06660 } 06661 respprep(&resp, p, msg, req); 06662 if (p->rtp) { 06663 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06664 if (option_debug) 06665 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06666 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06667 } 06668 try_suggested_sip_codec(p); 06669 add_sdp(&resp, p); 06670 } else 06671 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06672 if (reliable && !p->pendinginvite) 06673 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06674 return send_response(p, &resp, reliable, seqno); 06675 }
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 6613 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().
06614 { 06615 struct sip_request resp; 06616 int seqno; 06617 06618 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06619 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06620 return -1; 06621 } 06622 respprep(&resp, p, msg, req); 06623 if (p->udptl) { 06624 ast_udptl_offered_from_local(p->udptl, 0); 06625 add_t38_sdp(&resp, p); 06626 } else 06627 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06628 if (retrans && !p->pendinginvite) 06629 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06630 return send_response(p, &resp, retrans, seqno); 06631 }
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 6044 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06045 { 06046 struct sip_request resp; 06047 respprep(&resp, p, msg, req); 06048 append_date(&resp); 06049 add_header(&resp, "Unsupported", unsupported); 06050 add_header_contentLength(&resp, 0); 06051 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06052 }
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 7327 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().
07328 { 07329 if (!p->initreq.headers) /* Initialize first request before sending */ 07330 initialize_initreq(p, req); 07331 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07332 }
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 7102 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().
07103 { 07104 char tmp[4000], from[256], to[256]; 07105 char *t = tmp, *c, *mfrom, *mto; 07106 size_t maxbytes = sizeof(tmp); 07107 struct sip_request req; 07108 char hint[AST_MAX_EXTENSION]; 07109 char *statestring = "terminated"; 07110 const struct cfsubscription_types *subscriptiontype; 07111 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07112 char *pidfstate = "--"; 07113 char *pidfnote= "Ready"; 07114 07115 memset(from, 0, sizeof(from)); 07116 memset(to, 0, sizeof(to)); 07117 memset(tmp, 0, sizeof(tmp)); 07118 07119 switch (state) { 07120 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07121 statestring = (global_notifyringing) ? "early" : "confirmed"; 07122 local_state = NOTIFY_INUSE; 07123 pidfstate = "busy"; 07124 pidfnote = "Ringing"; 07125 break; 07126 case AST_EXTENSION_RINGING: 07127 statestring = "early"; 07128 local_state = NOTIFY_INUSE; 07129 pidfstate = "busy"; 07130 pidfnote = "Ringing"; 07131 break; 07132 case AST_EXTENSION_INUSE: 07133 statestring = "confirmed"; 07134 local_state = NOTIFY_INUSE; 07135 pidfstate = "busy"; 07136 pidfnote = "On the phone"; 07137 break; 07138 case AST_EXTENSION_BUSY: 07139 statestring = "confirmed"; 07140 local_state = NOTIFY_CLOSED; 07141 pidfstate = "busy"; 07142 pidfnote = "On the phone"; 07143 break; 07144 case AST_EXTENSION_UNAVAILABLE: 07145 statestring = "terminated"; 07146 local_state = NOTIFY_CLOSED; 07147 pidfstate = "away"; 07148 pidfnote = "Unavailable"; 07149 break; 07150 case AST_EXTENSION_ONHOLD: 07151 statestring = "confirmed"; 07152 local_state = NOTIFY_INUSE; 07153 pidfstate = "busy"; 07154 pidfnote = "On Hold"; 07155 break; 07156 case AST_EXTENSION_NOT_INUSE: 07157 default: 07158 /* Default setting */ 07159 break; 07160 } 07161 07162 subscriptiontype = find_subscription_type(p->subscribed); 07163 07164 /* Check which device/devices we are watching and if they are registered */ 07165 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07166 char *hint2 = hint, *individual_hint = NULL; 07167 int hint_count = 0, unavailable_count = 0; 07168 07169 while ((individual_hint = strsep(&hint2, "&"))) { 07170 hint_count++; 07171 07172 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07173 unavailable_count++; 07174 } 07175 07176 /* If none of the hinted devices are registered, we will 07177 * override notification and show no availability. 07178 */ 07179 if (hint_count > 0 && hint_count == unavailable_count) { 07180 local_state = NOTIFY_CLOSED; 07181 pidfstate = "away"; 07182 pidfnote = "Not online"; 07183 } 07184 } 07185 07186 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07187 c = get_in_brackets(from); 07188 if (strncasecmp(c, "sip:", 4)) { 07189 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07190 return -1; 07191 } 07192 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07193 07194 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07195 c = get_in_brackets(to); 07196 if (strncasecmp(c, "sip:", 4)) { 07197 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07198 return -1; 07199 } 07200 mto = strsep(&c, ";"); /* trim ; and beyond */ 07201 07202 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07203 07204 07205 add_header(&req, "Event", subscriptiontype->event); 07206 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07207 switch(state) { 07208 case AST_EXTENSION_DEACTIVATED: 07209 if (timeout) 07210 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07211 else { 07212 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07213 add_header(&req, "Retry-After", "60"); 07214 } 07215 break; 07216 case AST_EXTENSION_REMOVED: 07217 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07218 break; 07219 default: 07220 if (p->expiry) 07221 add_header(&req, "Subscription-State", "active"); 07222 else /* Expired */ 07223 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07224 } 07225 switch (p->subscribed) { 07226 case XPIDF_XML: 07227 case CPIM_PIDF_XML: 07228 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07229 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07230 ast_build_string(&t, &maxbytes, "<presence>\n"); 07231 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07232 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07233 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07234 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07235 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07236 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07237 break; 07238 case PIDF_XML: /* Eyebeam supports this format */ 07239 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07240 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); 07241 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07242 if (pidfstate[0] != '-') 07243 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07244 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07245 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07246 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07247 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07248 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07249 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07250 else 07251 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07252 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07253 break; 07254 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07255 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07256 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); 07257 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07258 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07259 else 07260 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07261 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07262 if (state == AST_EXTENSION_ONHOLD) { 07263 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07264 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07265 "</target>\n</local>\n", mto); 07266 } 07267 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07268 break; 07269 case NONE: 07270 default: 07271 break; 07272 } 07273 07274 if (t > tmp + sizeof(tmp)) 07275 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07276 07277 add_header_contentLength(&req, strlen(tmp)); 07278 add_line(&req, tmp); 07279 07280 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07281 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3614 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().
03615 { 03616 int fmt; 03617 const char *codec; 03618 03619 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03620 if (!codec) 03621 return; 03622 03623 fmt = ast_getformatbyname(codec); 03624 if (fmt) { 03625 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03626 if (p->jointcapability & fmt) { 03627 p->jointcapability &= fmt; 03628 p->capability &= fmt; 03629 } else 03630 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03631 } else 03632 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03633 return; 03634 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 17964 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.
17965 { 17966 struct sip_pvt *p, *pl; 17967 17968 /* First, take us out of the channel type list */ 17969 ast_channel_unregister(&sip_tech); 17970 17971 /* Unregister dial plan functions */ 17972 ast_custom_function_unregister(&sipchaninfo_function); 17973 ast_custom_function_unregister(&sippeer_function); 17974 ast_custom_function_unregister(&sip_header_function); 17975 ast_custom_function_unregister(&checksipdomain_function); 17976 17977 /* Unregister dial plan applications */ 17978 ast_unregister_application(app_dtmfmode); 17979 ast_unregister_application(app_sipaddheader); 17980 17981 /* Unregister CLI commands */ 17982 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 17983 17984 /* Disconnect from the RTP subsystem */ 17985 ast_rtp_proto_unregister(&sip_rtp); 17986 17987 /* Disconnect from UDPTL */ 17988 ast_udptl_proto_unregister(&sip_udptl); 17989 17990 /* Unregister AMI actions */ 17991 ast_manager_unregister("SIPpeers"); 17992 ast_manager_unregister("SIPshowpeer"); 17993 17994 ast_mutex_lock(&iflock); 17995 /* Hangup all interfaces if they have an owner */ 17996 for (p = iflist; p ; p = p->next) { 17997 if (p->owner) 17998 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 17999 } 18000 ast_mutex_unlock(&iflock); 18001 18002 ast_mutex_lock(&monlock); 18003 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18004 pthread_cancel(monitor_thread); 18005 pthread_kill(monitor_thread, SIGURG); 18006 pthread_join(monitor_thread, NULL); 18007 } 18008 monitor_thread = AST_PTHREADT_STOP; 18009 ast_mutex_unlock(&monlock); 18010 18011 ast_mutex_lock(&iflock); 18012 /* Destroy all the interfaces and free their memory */ 18013 p = iflist; 18014 while (p) { 18015 pl = p; 18016 p = p->next; 18017 __sip_destroy(pl, TRUE); 18018 } 18019 iflist = NULL; 18020 ast_mutex_unlock(&iflock); 18021 18022 /* Free memory for local network address mask */ 18023 ast_free_ha(localaddr); 18024 18025 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18026 ASTOBJ_CONTAINER_DESTROY(&userl); 18027 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18028 ASTOBJ_CONTAINER_DESTROY(&peerl); 18029 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18030 ASTOBJ_CONTAINER_DESTROY(®l); 18031 18032 clear_realm_authentication(authl); 18033 clear_sip_domains(); 18034 close(sipsock); 18035 sched_context_destroy(sched); 18036 18037 return 0; 18038 }
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 3166 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().
03167 { 03168 char name[256]; 03169 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03170 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03171 struct sip_user *u = NULL; 03172 struct sip_peer *p = NULL; 03173 03174 if (option_debug > 2) 03175 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03176 03177 /* Test if we need to check call limits, in order to avoid 03178 realtime lookups if we do not need it */ 03179 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03180 return 0; 03181 03182 ast_copy_string(name, fup->username, sizeof(name)); 03183 03184 /* Check the list of users only for incoming calls */ 03185 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03186 inuse = &u->inUse; 03187 call_limit = &u->call_limit; 03188 inringing = NULL; 03189 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03190 inuse = &p->inUse; 03191 call_limit = &p->call_limit; 03192 inringing = &p->inRinging; 03193 ast_copy_string(name, fup->peername, sizeof(name)); 03194 } 03195 if (!p && !u) { 03196 if (option_debug > 1) 03197 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03198 return 0; 03199 } 03200 03201 switch(event) { 03202 /* incoming and outgoing affects the inUse counter */ 03203 case DEC_CALL_LIMIT: 03204 if ( *inuse > 0 ) { 03205 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03206 (*inuse)--; 03207 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03208 } 03209 } else { 03210 *inuse = 0; 03211 } 03212 if (inringing) { 03213 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03214 if (*inringing > 0) 03215 (*inringing)--; 03216 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03217 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03218 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03219 } 03220 } 03221 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03222 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03223 sip_peer_hold(fup, 0); 03224 } 03225 if (option_debug > 1 || sipdebug) { 03226 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03227 } 03228 break; 03229 03230 case INC_CALL_RINGING: 03231 case INC_CALL_LIMIT: 03232 if (*call_limit > 0 ) { 03233 if (*inuse >= *call_limit) { 03234 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); 03235 if (u) 03236 ASTOBJ_UNREF(u, sip_destroy_user); 03237 else 03238 ASTOBJ_UNREF(p, sip_destroy_peer); 03239 return -1; 03240 } 03241 } 03242 if (inringing && (event == INC_CALL_RINGING)) { 03243 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03244 (*inringing)++; 03245 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03246 } 03247 } 03248 /* Continue */ 03249 (*inuse)++; 03250 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03251 if (option_debug > 1 || sipdebug) { 03252 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03253 } 03254 break; 03255 03256 case DEC_CALL_RINGING: 03257 if (inringing) { 03258 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03259 if (*inringing > 0) 03260 (*inringing)--; 03261 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03262 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03263 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03264 } 03265 } 03266 break; 03267 03268 default: 03269 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03270 } 03271 if (p) { 03272 ast_device_state_changed("SIP/%s", p->name); 03273 ASTOBJ_UNREF(p, sip_destroy_peer); 03274 } else /* u must be set */ 03275 ASTOBJ_UNREF(u, sip_destroy_user); 03276 return 0; 03277 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2474 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().
02475 { 02476 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02477 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02478 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02479 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02480 } 02481 }
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 17533 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17535 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 11698 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
Definition at line 17800 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 17790 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 17795 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 11582 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 17532 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17538 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 11599 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 10233 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 9784 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 11591 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 11595 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 11531 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 11573 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 11555 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 11551 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 11526 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 11559 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 11546 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 11612 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 11568 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 11563 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 11578 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 11616 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 11608 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 11541 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 11536 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 11674 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 11604 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 1608 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 1550 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 1576 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 1617 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 17531 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17536 of file chan_sip.c.
struct ast_user_list userl [static] |