#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | domain_list |
struct | offered_media |
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_history_head |
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_pvt::request_queue |
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, INFO" |
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 "Anonymous" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define | FROMDOMAIN_INVALID "anonymous.invalid" |
#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 | PROVIS_KEEPALIVE_TIMEOUT 60000 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_CONSTANT_SSRC (1 << 31) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
#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_RPORT_PRESENT (1 << 30) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | media_type { SDP_AUDIO, SDP_VIDEO, SDP_IMAGE } |
enum | parse_register_result { PARSE_REGISTER_DENIED, 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_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 | __reg_module (void) |
static int | __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin) |
static int | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets called with p locked. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static void | __unreg_module (void) |
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, int add_audio, int add_t38) |
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_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 | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
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? | |
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, int devstate_only) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_auth_buf_init (void) |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin) |
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, int devstate_only) |
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_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct sockaddr_in *sin) |
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_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 char | get_sdp_line (int *start, int stop, struct sip_request *req, const char **value) |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference '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, int *nounlock) |
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 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 seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static void | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
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 int | process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp *newaudiortp, int *last_rtpmap_codec) |
static int | process_sdp_a_image (const char *a, struct sip_pvt *p) |
static int | process_sdp_a_sendonly (const char *a, int *sendonly) |
static int | process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp *newvideortp, int *last_rtpmap_codec) |
static int | process_sdp_c (const char *c, struct ast_hostent *hp) |
static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only) |
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, int lastms) |
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 | resp_needs_contact (const char *msg, enum sipmethod method) |
Test if this response needs a contact header. | |
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 | scheduler_process_request_queue (const void *data) |
static int | send_provisional_keepalive (const void *data) |
static int | send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp) |
static int | send_provisional_keepalive_with_sdp (const void *data) |
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_nonce_randdata (struct sip_pvt *p, int forceupdate) |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer, int force) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
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 void | temp_pvt_init (void) |
A per-thread temporary pvt structure. | |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp) |
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). | |
static void | update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } |
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 const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static unsigned int | chan_idx |
static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT, .key_init = check_auth_buf_init , } |
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 struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_directrtpsetup |
static int | global_dynamic_exclude_static = 0 |
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 int | global_prematuremediafilter |
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_shrinkcallerid |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static ast_mutex_t | iflock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
Protect the SIP dialog list (of sip_pvt's). | |
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 ast_mutex_t | monlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static ast_mutex_t | netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | seen_lastms = 0 |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static ast_mutex_t | sip_reload_lock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_threadstorage | ts_temp_pvt = { .once = PTHREAD_ONCE_INIT, .key_init = temp_pvt_init , } |
static struct ast_user_list | userl |
The user list: Users and friends. |
SIP over TLS
Better support of forking
VIA branch tag transaction checking
Transaction support
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO" |
SIP Methods we support.
Definition at line 482 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 1907 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_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), 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 "Anonymous" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 373 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 374 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 372 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 8999 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 621 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 623 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 514 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 518 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 505 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 189 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 206 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 205 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 521 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 176 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 204 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 507 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 506 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 516 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 517 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 519 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 515 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 175 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 208 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 509 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 520 of file chan_sip.c.
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 512 of file chan_sip.c.
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 511 of file chan_sip.c.
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 513 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 213 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 523 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 504 of file chan_sip.c.
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 181 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 183 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 187 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 180 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 154 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1072 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), handle_request_invite(), retrans_pkt(), and sip_hangup().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define FROMDOMAIN_INVALID "anonymous.invalid" |
#define INC_CALL_LIMIT 1 |
Definition at line 622 of file chan_sip.c.
Referenced by handle_request_invite(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 223 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 167 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 198 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 215 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 1070 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 209 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 239 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 415 of file chan_sip.c.
#define PROVIS_KEEPALIVE_TIMEOUT 60000 |
How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1)
Definition at line 214 of file chan_sip.c.
Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().
#define RTP 1 |
Definition at line 238 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 221 of file chan_sip.c.
Referenced by process_sdp_a_audio(), and process_sdp_a_video().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6895 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 729 of file chan_sip.c.
Referenced by __sip_autodestruct(), 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 770 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 758 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 759 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 744 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 745 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 749 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 747 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 748 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 746 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 775 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 743 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 773 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp_a_audio().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 736 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 772 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 763 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 762 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 217 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 218 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 219 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 751 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 755 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 752 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 753 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 754 of file chan_sip.c.
Referenced by _sip_show_peers(), build_peer(), check_user_full(), create_addr(), 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 730 of file chan_sip.c.
Referenced by __sip_autodestruct(), __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 734 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 769 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 731 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 428 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 429 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 432 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 431 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 433 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 430 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 419 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 742 of file chan_sip.c.
Referenced by 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 797 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 796 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 809 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 804 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), do_monitor(), 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 807 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 806 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CONSTANT_SSRC (1 << 31) |
31: Don't change SSRC on reinvite
Definition at line 814 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), and handle_request_invite().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 790 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 791 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 792 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
29: Has a dialog been established?
Definition at line 812 of file chan_sip.c.
Referenced by find_call(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 793 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | \ SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_CONSTANT_SSRC)
Definition at line 816 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 789 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 799 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 810 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_response_invite(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 808 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_RPORT_PRESENT (1 << 30) |
30: Was rport received in the Via header?
Definition at line 813 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 785 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 782 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 786 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 783 of file chan_sip.c.
Referenced by destroy_association(), handle_response_peerpoke(), sip_poke_noanswer(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 794 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 788 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 798 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 800 of file chan_sip.c.
Referenced by create_addr_from_peer(), sip_alloc(), and sip_write().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 802 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 803 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 801 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 811 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 795 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 735 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 822 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 824 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and transmit_fake_auth_response().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 823 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 765 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 767 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 768 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 733 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 737 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 740 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 760 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 771 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 210 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 738 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 741 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 739 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 161 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 853 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 854 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 855 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 488 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), transmit_notify_with_mwi(), 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 414 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 485 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 828 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 847 of file chan_sip.c.
Referenced by process_sdp_a_image(), 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 848 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_2400 (1 << 8) |
2400 bps t38FaxRate
Definition at line 843 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_4800 (1 << 9) |
4800 bps t38FaxRate
Definition at line 844 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_7200 (1 << 10) |
7200 bps t38FaxRate
Definition at line 845 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_9600 (1 << 11) |
9600 bps t38FaxRate
Definition at line 846 of file chan_sip.c.
Referenced by process_sdp_a_image(), and t38_get_rate().
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
Unset for transferredTCF (UDPTL), set for localTCF (TPKT)
Definition at line 833 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 832 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_TRANSCODING_JBIG (1 << 2) |
Default: 0 (unset)
Definition at line 830 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 829 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 836 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_NONE (0 << 4) |
two bits, if unset NO t38UDPEC field in T38 SDP
Definition at line 835 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 837 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 839 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 840 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 841 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1665 of file chan_sip.c.
Referenced by __sip_ack(), __sip_destroy(), and handle_request_cancel().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 165 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 163 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 348 of file chan_sip.c.
00348 { 00349 AUTH_SUCCESSFUL = 0, 00350 AUTH_CHALLENGE_SENT = 1, 00351 AUTH_SECRET_FAILED = -1, 00352 AUTH_USERNAME_MISMATCH = -2, 00353 AUTH_NOT_FOUND = -3, 00354 AUTH_FAKE_AUTH = -4, 00355 AUTH_UNKNOWN_DOMAIN = -5, 00356 AUTH_PEER_NOT_DYNAMIC = -6, 00357 AUTH_ACL_FAILED = -7, 00358 };
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 692 of file chan_sip.c.
00692 { 00693 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00694 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00695 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 258 of file chan_sip.c.
00258 { 00259 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00260 INV_CALLING = 1, /*!< Invite sent, no answer */ 00261 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00262 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00263 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00264 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00265 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00266 The only way out of this is a BYE from one side */ 00267 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00268 };
enum media_type |
Definition at line 285 of file chan_sip.c.
00285 { 00286 PARSE_REGISTER_DENIED, 00287 PARSE_REGISTER_FAILED, 00288 PARSE_REGISTER_UPDATE, 00289 PARSE_REGISTER_QUERY, 00290 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 877 of file chan_sip.c.
00877 { 00878 REFER_IDLE, /*!< No REFER is in progress */ 00879 REFER_SENT, /*!< Sent REFER to transferee */ 00880 REFER_RECEIVED, /*!< Received REFER from transferer */ 00881 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00882 REFER_ACCEPTED, /*!< Accepted by transferee */ 00883 REFER_RINGING, /*!< Target Ringing */ 00884 REFER_200OK, /*!< Answered by transfer target */ 00885 REFER_FAILED, /*!< REFER declined - go on */ 00886 REFER_NOAUTH /*!< We had no auth for REFER */ 00887 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 342 of file chan_sip.c.
00342 { 00343 PROXY_AUTH, 00344 WWW_AUTH, 00345 };
enum sip_result |
Definition at line 250 of file chan_sip.c.
00250 { 00251 AST_SUCCESS = 0, 00252 AST_FAILURE = -1, 00253 };
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 317 of file chan_sip.c.
00317 { 00318 SIP_UNKNOWN, /* Unknown response */ 00319 SIP_RESPONSE, /* Not request, response to outbound request */ 00320 SIP_REGISTER, 00321 SIP_OPTIONS, 00322 SIP_NOTIFY, 00323 SIP_INVITE, 00324 SIP_ACK, 00325 SIP_PRACK, /* Not supported at all */ 00326 SIP_BYE, 00327 SIP_REFER, 00328 SIP_SUBSCRIBE, 00329 SIP_MESSAGE, 00330 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00331 SIP_INFO, 00332 SIP_CANCEL, 00333 SIP_PUBLISH, /* Not supported at all */ 00334 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00335 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 361 of file chan_sip.c.
00361 { 00362 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00363 REG_STATE_REGSENT, /*!< Registration request sent */ 00364 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00365 REG_STATE_REGISTERED, /*!< Registered and done */ 00366 REG_STATE_REJECTED, /*!< Registration rejected */ 00367 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00368 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00369 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00370 };
enum subscriptiontype |
Definition at line 292 of file chan_sip.c.
00292 { 00293 NONE = 0, 00294 XPIDF_XML, 00295 DIALOG_INFO_XML, 00296 CPIM_PIDF_XML, 00297 PIDF_XML, 00298 MWI_NOTIFICATION 00299 };
enum t38state |
T38 States for a call.
T38_DISABLED | Not enabled |
T38_LOCAL_REINVITE | Offered from local - REINVITE |
T38_PEER_DIRECT | Offered from peer |
T38_PEER_REINVITE | Offered from peer - REINVITE |
T38_ENABLED | Negotiated (enabled) |
Definition at line 858 of file chan_sip.c.
00858 { 00859 T38_DISABLED = 0, /*!< Not enabled */ 00860 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00861 T38_PEER_DIRECT, /*!< Offered from peer */ 00862 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00863 T38_ENABLED /*!< Negotiated (enabled) */ 00864 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 244 of file chan_sip.c.
00244 { 00245 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00246 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00247 };
enum xmittype |
Definition at line 278 of file chan_sip.c.
00278 { 00279 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00280 If it fails, it's critical and will cause a teardown of the session */ 00281 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00282 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00283 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4499 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04500 { 04501 int pass; 04502 04503 /* 04504 * Technically you can place arbitrary whitespace both before and after the ':' in 04505 * a header, although RFC3261 clearly says you shouldn't before, and place just 04506 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04507 * a good idea to say you can do it, and if you can do it, why in the hell would. 04508 * you say you shouldn't. 04509 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04510 * and we always allow spaces after that for compatibility. 04511 */ 04512 for (pass = 0; name && pass < 2;pass++) { 04513 int x, len = strlen(name); 04514 for (x=*start; x<req->headers; x++) { 04515 if (!strncasecmp(req->header[x], name, len)) { 04516 char *r = req->header[x] + len; /* skip name */ 04517 if (pedanticsipchecking) 04518 r = ast_skip_blanks(r); 04519 04520 if (*r == ':') { 04521 *start = x+1; 04522 return ast_skip_blanks(r+1); 04523 } 04524 } 04525 } 04526 if (pass == 0) /* Try aliases */ 04527 name = find_alias(name, NULL); 04528 } 04529 04530 /* Don't return NULL, so get_header is always a valid pointer */ 04531 return ""; 04532 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 19653 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8613 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, and STANDARD_SIP_PORT.
Referenced by build_peer(), and set_address_from_contact().
08614 { 08615 struct hostent *hp; 08616 struct ast_hostent ahp; 08617 int port; 08618 char *c, *host, *pt; 08619 char contact_buf[256]; 08620 char *contact; 08621 08622 /* Work on a copy */ 08623 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08624 contact = contact_buf; 08625 08626 /* Make sure it's a SIP URL */ 08627 if (strncasecmp(contact, "sip:", 4)) { 08628 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08629 } else 08630 contact += 4; 08631 08632 /* Ditch arguments */ 08633 /* XXX this code is replicated also shortly below */ 08634 08635 /* Grab host */ 08636 host = strchr(contact, '@'); 08637 if (!host) { /* No username part */ 08638 host = contact; 08639 c = NULL; 08640 } else { 08641 *host++ = '\0'; 08642 } 08643 pt = strchr(host, ':'); 08644 if (pt) { 08645 *pt++ = '\0'; 08646 port = atoi(pt); 08647 } else 08648 port = STANDARD_SIP_PORT; 08649 08650 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08651 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08652 08653 /* XXX This could block for a long time XXX */ 08654 /* We should only do this if it's a name, not an IP */ 08655 hp = ast_gethostbyname(host, &ahp); 08656 if (!hp) { 08657 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08658 return -1; 08659 } 08660 sin->sin_family = AF_INET; 08661 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08662 sin->sin_port = htons(port); 08663 08664 return 0; 08665 }
static int __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2223 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL_SPINLOCK, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), handle_request_invite(), and handle_response().
02224 { 02225 struct sip_pkt *cur, *prev = NULL; 02226 02227 /* Just in case... */ 02228 char *msg; 02229 int res = FALSE; 02230 02231 msg = sip_methods[sipmethod].text; 02232 02233 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02234 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02235 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02236 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02237 if (!resp && (seqno == p->pendinginvite)) { 02238 if (option_debug) 02239 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02240 p->pendinginvite = 0; 02241 } 02242 /* this is our baby */ 02243 res = TRUE; 02244 UNLINK(cur, p->packets, prev); 02245 if (cur->retransid > -1) { 02246 if (sipdebug && option_debug > 3) 02247 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02248 } 02249 /* This odd section is designed to thwart a 02250 * race condition in the packet scheduler. There are 02251 * two conditions under which deleting the packet from the 02252 * scheduler can fail. 02253 * 02254 * 1. The packet has been removed from the scheduler because retransmission 02255 * is being attempted. The problem is that if the packet is currently attempting 02256 * retransmission and we are at this point in the code, then that MUST mean 02257 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02258 * lock temporarily to allow retransmission. 02259 * 02260 * 2. The packet has reached its maximum number of retransmissions and has 02261 * been permanently removed from the packet scheduler. If this is the case, then 02262 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02263 * of the retransid to -1 is ensured since in both cases p's lock is held. 02264 */ 02265 AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock); 02266 free(cur); 02267 break; 02268 } 02269 } 02270 if (option_debug) 02271 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found"); 02272 return res; 02273 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2136 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::lastmsg, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02137 { 02138 struct sip_pvt *p = (struct sip_pvt *)data; 02139 02140 /* If this is a subscription, tell the phone that we got a timeout */ 02141 if (p->subscribed) { 02142 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02143 p->subscribed = NONE; 02144 append_history(p, "Subscribestatus", "timeout"); 02145 if (option_debug > 2) 02146 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02147 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02148 } 02149 02150 /* If there are packets still waiting for delivery, delay the destruction */ 02151 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02152 * of code make a sort of "safety relief valve", that allows sip channels 02153 * that were created via INVITE, then thru some sequence were CANCELED, 02154 * to die, rather than infinitely be rescheduled */ 02155 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02156 char method_str[31]; 02157 if (option_debug > 2) 02158 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02159 append_history(p, "ReliableXmit", "timeout"); 02160 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 02161 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 02162 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02163 } 02164 } 02165 return 10000; 02166 } 02167 02168 /* If we're destroying a subscription, dereference peer object too */ 02169 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02170 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02171 02172 /* Reset schedule ID */ 02173 p->autokillid = -1; 02174 02175 if (option_debug) 02176 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02177 append_history(p, "AutoDestroy", "%s", p->callid); 02178 if (p->owner) { 02179 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02180 ast_queue_hangup(p->owner); 02181 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02182 if (option_debug > 2) 02183 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02184 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02185 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02186 } else 02187 sip_destroy(p); 02188 return 0; 02189 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3239 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, sip_history::list, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_pvt::next, sip_history::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03240 { 03241 struct sip_pvt *cur, *prev = NULL; 03242 struct sip_pkt *cp; 03243 struct sip_request *req; 03244 03245 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03246 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03247 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03248 return -1; 03249 } 03250 03251 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03252 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03253 return -1; 03254 } 03255 03256 if (sip_debug_test_pvt(p) || option_debug > 2) 03257 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03258 03259 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03260 update_call_counter(p, DEC_CALL_LIMIT); 03261 if (option_debug > 1) 03262 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03263 } 03264 03265 /* Unlink us from the owner if we have one */ 03266 if (p->owner) { 03267 if (lockowner) 03268 ast_channel_lock(p->owner); 03269 if (option_debug) 03270 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03271 p->owner->tech_pvt = NULL; 03272 /* Make sure that the channel knows its backend is going away */ 03273 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03274 if (lockowner) 03275 ast_channel_unlock(p->owner); 03276 /* Give the channel a chance to react before deallocation */ 03277 usleep(1); 03278 } 03279 03280 /* Remove link from peer to subscription of MWI */ 03281 if (p->relatedpeer) { 03282 if (p->relatedpeer->mwipvt == p) { 03283 p->relatedpeer->mwipvt = NULL; 03284 } 03285 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03286 } 03287 03288 if (dumphistory) 03289 sip_dump_history(p); 03290 03291 if (p->options) 03292 free(p->options); 03293 03294 if (p->stateid > -1) 03295 ast_extension_state_del(p->stateid, NULL); 03296 AST_SCHED_DEL(sched, p->initid); 03297 AST_SCHED_DEL(sched, p->waitid); 03298 AST_SCHED_DEL(sched, p->autokillid); 03299 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03300 AST_SCHED_DEL(sched, p->provisional_keepalive_sched_id); 03301 03302 if (p->rtp) { 03303 ast_rtp_destroy(p->rtp); 03304 } 03305 if (p->vrtp) { 03306 ast_rtp_destroy(p->vrtp); 03307 } 03308 if (p->udptl) 03309 ast_udptl_destroy(p->udptl); 03310 if (p->refer) 03311 free(p->refer); 03312 if (p->route) { 03313 free_old_route(p->route); 03314 p->route = NULL; 03315 } 03316 if (p->registry) { 03317 if (p->registry->call == p) 03318 p->registry->call = NULL; 03319 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03320 } 03321 03322 /* Clear history */ 03323 if (p->history) { 03324 struct sip_history *hist; 03325 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03326 free(hist); 03327 p->history_entries--; 03328 } 03329 free(p->history); 03330 p->history = NULL; 03331 } 03332 03333 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03334 ast_free(req); 03335 } 03336 03337 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03338 if (cur == p) { 03339 UNLINK(cur, iflist, prev); 03340 break; 03341 } 03342 } 03343 if (!cur) { 03344 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03345 return 0; 03346 } 03347 03348 /* remove all current packets in this dialog */ 03349 while((cp = p->packets)) { 03350 p->packets = p->packets->next; 03351 AST_SCHED_DEL(sched, cp->retransid); 03352 free(cp); 03353 } 03354 if (p->chanvars) { 03355 ast_variables_destroy(p->chanvars); 03356 p->chanvars = NULL; 03357 } 03358 ast_mutex_destroy(&p->lock); 03359 03360 ast_string_field_free_memory(p); 03361 03362 free(p); 03363 return 0; 03364 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 8038 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
08039 { 08040 int res; 08041 08042 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 08043 return res; 08044 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2277 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_request::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), and sip_reg_timeout().
02278 { 02279 struct sip_pkt *cur = NULL; 02280 02281 while (p->packets) { 02282 int method; 02283 if (cur == p->packets) { 02284 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02285 return; 02286 } 02287 cur = p->packets; 02288 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02289 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02290 } 02291 }
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 2083 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02084 { 02085 struct sip_pkt *pkt; 02086 int siptimer_a = DEFAULT_RETRANS; 02087 int xmitres = 0; 02088 int respid; 02089 02090 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02091 return AST_FAILURE; 02092 memcpy(pkt->data, data, len); 02093 pkt->method = sipmethod; 02094 pkt->packetlen = len; 02095 pkt->next = p->packets; 02096 pkt->owner = p; 02097 pkt->seqno = seqno; 02098 pkt->data[len] = '\0'; 02099 if (resp) { 02100 ast_set_flag(pkt, FLAG_RESPONSE); 02101 /* Parse out the response code */ 02102 if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) { 02103 pkt->response_code = respid; 02104 } 02105 } 02106 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02107 pkt->retransid = -1; 02108 if (fatal) 02109 ast_set_flag(pkt, FLAG_FATAL); 02110 if (pkt->timer_t1) 02111 siptimer_a = pkt->timer_t1 * 2; 02112 02113 if (option_debug > 3 && sipdebug) 02114 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02115 pkt->retransid = -1; 02116 pkt->next = p->packets; 02117 p->packets = pkt; 02118 if (sipmethod == SIP_INVITE) { 02119 /* Note this is a pending invite */ 02120 p->pendinginvite = seqno; 02121 } 02122 02123 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02124 02125 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02126 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02127 return AST_FAILURE; 02128 } else { 02129 /* Schedule retransmission */ 02130 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02131 return AST_SUCCESS; 02132 } 02133 }
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 2294 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
02295 { 02296 struct sip_pkt *cur; 02297 int res = FALSE; 02298 02299 for (cur = p->packets; cur; cur = cur->next) { 02300 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02301 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02302 /* this is our baby */ 02303 if (cur->retransid > -1) { 02304 if (option_debug > 3 && sipdebug) 02305 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02306 } 02307 AST_SCHED_DEL(sched, cur->retransid); 02308 res = TRUE; 02309 break; 02310 } 02311 } 02312 if (option_debug) 02313 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 02314 return res; 02315 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11585 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock, ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, sip_pvt::icseq, iflist, iflock, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, and sip_pvt::username.
Referenced by sip_show_channels(), and sip_show_subscriptions().
11586 { 11587 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11588 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11589 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11590 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11591 struct sip_pvt *cur; 11592 int numchans = 0; 11593 int usedchans = 0; 11594 char *referstatus = NULL; 11595 11596 if (argc != 3) 11597 return RESULT_SHOWUSAGE; 11598 ast_mutex_lock(&iflock); 11599 cur = iflist; 11600 if (!subscriptions) 11601 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11602 else 11603 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11604 for (; cur; cur = cur->next) { 11605 referstatus = ""; 11606 if (cur->refer) { /* SIP transfer in progress */ 11607 referstatus = referstatus2str(cur->refer->status); 11608 } 11609 if (cur->subscribed == NONE && !subscriptions) { 11610 char formatbuf[SIPBUFSIZE/2]; 11611 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11612 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11613 cur->callid, 11614 cur->ocseq, cur->icseq, 11615 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11616 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11617 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11618 cur->lastmsg , 11619 referstatus 11620 ); 11621 numchans++; 11622 } 11623 if (cur->subscribed != NONE && subscriptions) { 11624 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11625 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11626 cur->callid, 11627 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11628 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11629 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11630 subscription_type2str(cur->subscribed), 11631 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11632 cur->expiry 11633 ); 11634 numchans++; 11635 } 11636 if (cur->owner) { /* Count SIP dialog owned by a real channel */ 11637 usedchans++; 11638 } 11639 } 11640 ast_mutex_unlock(&iflock); 11641 if (!subscriptions) 11642 ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 11643 else 11644 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11645 ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 11646 return RESULT_SUCCESS; 11647 #undef FORMAT 11648 #undef FORMAT2 11649 #undef FORMAT3 11650 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1832 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().
01833 { 01834 int res; 01835 const struct sockaddr_in *dst = sip_real_dst(p); 01836 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01837 01838 if (res == -1) { 01839 switch (errno) { 01840 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01841 case EHOSTUNREACH: /* Host can't be reached */ 01842 case ENETDOWN: /* Inteface down */ 01843 case ENETUNREACH: /* Network failure */ 01844 case ECONNREFUSED: /* ICMP port unreachable */ 01845 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01846 } 01847 01848 } 01849 01850 if (res != len) 01851 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)); 01852 return res; 01853 }
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 6573 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06574 { 06575 struct sip_request resp; 06576 int seqno = 0; 06577 06578 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06579 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06580 return -1; 06581 } 06582 respprep(&resp, p, msg, req); 06583 add_header_contentLength(&resp, 0); 06584 /* If we are cancelling an incoming invite for some reason, add information 06585 about the reason why we are doing this in clear text */ 06586 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06587 char buf[10]; 06588 06589 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06590 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06591 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06592 } 06593 return send_response(p, &resp, reliable, seqno); 06594 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 19653 of file chan_sip.c.
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 11142 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, sip_peer::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
11143 { 11144 char status[30] = ""; 11145 char cbuf[256]; 11146 struct sip_peer *peer; 11147 char codec_buf[512]; 11148 struct ast_codec_pref *pref; 11149 struct ast_variable *v; 11150 struct sip_auth *auth; 11151 int x = 0, codec = 0, load_realtime; 11152 int realtimepeers; 11153 11154 realtimepeers = ast_check_realtime("sippeers"); 11155 11156 if (argc < 4) 11157 return RESULT_SHOWUSAGE; 11158 11159 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11160 peer = find_peer(argv[3], NULL, load_realtime, 0); 11161 if (s) { /* Manager */ 11162 if (peer) { 11163 const char *id = astman_get_header(m,"ActionID"); 11164 11165 astman_append(s, "Response: Success\r\n"); 11166 if (!ast_strlen_zero(id)) 11167 astman_append(s, "ActionID: %s\r\n",id); 11168 } else { 11169 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 11170 astman_send_error(s, m, cbuf); 11171 return 0; 11172 } 11173 } 11174 if (peer && type==0 ) { /* Normal listing */ 11175 ast_cli(fd,"\n\n"); 11176 ast_cli(fd, " * Name : %s\n", peer->name); 11177 if (realtimepeers) { /* Realtime is enabled */ 11178 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 11179 } 11180 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 11181 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 11182 for (auth = peer->auth; auth; auth = auth->next) { 11183 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 11184 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 11185 } 11186 ast_cli(fd, " Context : %s\n", peer->context); 11187 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 11188 ast_cli(fd, " Language : %s\n", peer->language); 11189 if (!ast_strlen_zero(peer->accountcode)) 11190 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 11191 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 11192 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 11193 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 11194 if (!ast_strlen_zero(peer->fromuser)) 11195 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 11196 if (!ast_strlen_zero(peer->fromdomain)) 11197 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 11198 ast_cli(fd, " Callgroup : "); 11199 print_group(fd, peer->callgroup, 0); 11200 ast_cli(fd, " Pickupgroup : "); 11201 print_group(fd, peer->pickupgroup, 0); 11202 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 11203 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 11204 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 11205 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 11206 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 11207 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 11208 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 11209 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 11210 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))); 11211 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11212 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 11213 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 11214 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11215 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 11216 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 11217 #endif 11218 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 11219 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 11220 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 11221 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 11222 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 11223 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 11224 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11225 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11226 11227 /* - is enumerated */ 11228 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11229 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 11230 ast_cli(fd, " ToHost : %s\n", peer->tohost); 11231 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)); 11232 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 11233 if (!ast_strlen_zero(global_regcontext)) 11234 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 11235 ast_cli(fd, " Def. Username: %s\n", peer->username); 11236 ast_cli(fd, " SIP Options : "); 11237 if (peer->sipoptions) { 11238 int lastoption = -1; 11239 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11240 if (sip_options[x].id != lastoption) { 11241 if (peer->sipoptions & sip_options[x].id) 11242 ast_cli(fd, "%s ", sip_options[x].text); 11243 lastoption = x; 11244 } 11245 } 11246 } else 11247 ast_cli(fd, "(none)"); 11248 11249 ast_cli(fd, "\n"); 11250 ast_cli(fd, " Codecs : "); 11251 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11252 ast_cli(fd, "%s\n", codec_buf); 11253 ast_cli(fd, " Codec Order : ("); 11254 print_codec_to_cli(fd, &peer->prefs); 11255 ast_cli(fd, ")\n"); 11256 11257 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 11258 ast_cli(fd, " Status : "); 11259 peer_status(peer, status, sizeof(status)); 11260 ast_cli(fd, "%s\n",status); 11261 ast_cli(fd, " Useragent : %s\n", peer->useragent); 11262 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 11263 if (peer->chanvars) { 11264 ast_cli(fd, " Variables :\n"); 11265 for (v = peer->chanvars ; v ; v = v->next) 11266 ast_cli(fd, " %s = %s\n", v->name, v->value); 11267 } 11268 ast_cli(fd,"\n"); 11269 ASTOBJ_UNREF(peer,sip_destroy_peer); 11270 } else if (peer && type == 1) { /* manager listing */ 11271 char buf[256]; 11272 astman_append(s, "Channeltype: SIP\r\n"); 11273 astman_append(s, "ObjectName: %s\r\n", peer->name); 11274 astman_append(s, "ChanObjectType: peer\r\n"); 11275 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 11276 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 11277 astman_append(s, "Context: %s\r\n", peer->context); 11278 astman_append(s, "Language: %s\r\n", peer->language); 11279 if (!ast_strlen_zero(peer->accountcode)) 11280 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 11281 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 11282 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 11283 if (!ast_strlen_zero(peer->fromuser)) 11284 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 11285 if (!ast_strlen_zero(peer->fromdomain)) 11286 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 11287 astman_append(s, "Callgroup: "); 11288 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 11289 astman_append(s, "Pickupgroup: "); 11290 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 11291 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 11292 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 11293 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 11294 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 11295 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 11296 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 11297 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 11298 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 11299 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))); 11300 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11301 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 11302 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 11303 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 11304 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 11305 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 11306 11307 /* - is enumerated */ 11308 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11309 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 11310 astman_append(s, "ToHost: %s\r\n", peer->tohost); 11311 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)); 11312 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)); 11313 astman_append(s, "Default-Username: %s\r\n", peer->username); 11314 if (!ast_strlen_zero(global_regcontext)) 11315 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 11316 astman_append(s, "Codecs: "); 11317 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11318 astman_append(s, "%s\r\n", codec_buf); 11319 astman_append(s, "CodecOrder: "); 11320 pref = &peer->prefs; 11321 for(x = 0; x < 32 ; x++) { 11322 codec = ast_codec_pref_index(pref,x); 11323 if (!codec) 11324 break; 11325 astman_append(s, "%s", ast_getformatname(codec)); 11326 if (x < 31 && ast_codec_pref_index(pref,x+1)) 11327 astman_append(s, ","); 11328 } 11329 11330 astman_append(s, "\r\n"); 11331 astman_append(s, "Status: "); 11332 peer_status(peer, status, sizeof(status)); 11333 astman_append(s, "%s\r\n", status); 11334 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 11335 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 11336 if (peer->chanvars) { 11337 for (v = peer->chanvars ; v ; v = v->next) { 11338 astman_append(s, "ChanVariable:\n"); 11339 astman_append(s, " %s,%s\r\n", v->name, v->value); 11340 } 11341 } 11342 11343 ASTOBJ_UNREF(peer,sip_destroy_peer); 11344 11345 } else { 11346 ast_cli(fd,"Peer %s not found.\n", argv[3]); 11347 ast_cli(fd,"\n"); 11348 } 11349 11350 return RESULT_SUCCESS; 11351 }
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 10692 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
10693 { 10694 regex_t regexbuf; 10695 int havepattern = FALSE; 10696 10697 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10698 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10699 10700 char name[256]; 10701 int total_peers = 0; 10702 int peers_mon_online = 0; 10703 int peers_mon_offline = 0; 10704 int peers_unmon_offline = 0; 10705 int peers_unmon_online = 0; 10706 const char *id; 10707 char idtext[256] = ""; 10708 int realtimepeers; 10709 10710 realtimepeers = ast_check_realtime("sippeers"); 10711 10712 if (s) { /* Manager - get ActionID */ 10713 id = astman_get_header(m,"ActionID"); 10714 if (!ast_strlen_zero(id)) 10715 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10716 } 10717 10718 switch (argc) { 10719 case 5: 10720 if (!strcasecmp(argv[3], "like")) { 10721 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10722 return RESULT_SHOWUSAGE; 10723 havepattern = TRUE; 10724 } else 10725 return RESULT_SHOWUSAGE; 10726 case 3: 10727 break; 10728 default: 10729 return RESULT_SHOWUSAGE; 10730 } 10731 10732 if (!s) /* Normal list */ 10733 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10734 10735 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10736 char status[20] = ""; 10737 char srch[2000]; 10738 char pstatus; 10739 10740 ASTOBJ_RDLOCK(iterator); 10741 10742 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10743 ASTOBJ_UNLOCK(iterator); 10744 continue; 10745 } 10746 10747 if (!ast_strlen_zero(iterator->username) && !s) 10748 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10749 else 10750 ast_copy_string(name, iterator->name, sizeof(name)); 10751 10752 pstatus = peer_status(iterator, status, sizeof(status)); 10753 if (pstatus == 1) 10754 peers_mon_online++; 10755 else if (pstatus == 0) 10756 peers_mon_offline++; 10757 else { 10758 if (iterator->addr.sin_port == 0) 10759 peers_unmon_offline++; 10760 else 10761 peers_unmon_online++; 10762 } 10763 10764 snprintf(srch, sizeof(srch), FORMAT, name, 10765 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10766 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10767 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10768 iterator->ha ? " A " : " ", /* permit/deny */ 10769 ntohs(iterator->addr.sin_port), status, 10770 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10771 10772 if (!s) {/* Normal CLI list */ 10773 ast_cli(fd, FORMAT, name, 10774 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10775 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10776 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10777 iterator->ha ? " A " : " ", /* permit/deny */ 10778 10779 ntohs(iterator->addr.sin_port), status, 10780 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10781 } else { /* Manager format */ 10782 /* The names here need to be the same as other channels */ 10783 astman_append(s, 10784 "Event: PeerEntry\r\n%s" 10785 "Channeltype: SIP\r\n" 10786 "ObjectName: %s\r\n" 10787 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10788 "IPaddress: %s\r\n" 10789 "IPport: %d\r\n" 10790 "Dynamic: %s\r\n" 10791 "Natsupport: %s\r\n" 10792 "VideoSupport: %s\r\n" 10793 "ACL: %s\r\n" 10794 "Status: %s\r\n" 10795 "RealtimeDevice: %s\r\n\r\n", 10796 idtext, 10797 iterator->name, 10798 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10799 ntohs(iterator->addr.sin_port), 10800 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10801 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10802 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10803 iterator->ha ? "yes" : "no", /* permit/deny */ 10804 status, 10805 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10806 } 10807 10808 ASTOBJ_UNLOCK(iterator); 10809 10810 total_peers++; 10811 } while(0) ); 10812 10813 if (!s) 10814 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10815 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10816 10817 if (havepattern) 10818 regfree(®exbuf); 10819 10820 if (total) 10821 *total = total_peers; 10822 10823 10824 return RESULT_SUCCESS; 10825 #undef FORMAT 10826 #undef FORMAT2 10827 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15894 of file chan_sip.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
15895 { 15896 struct ast_rtp_quality qos; 15897 struct sip_pvt *p = chan->tech_pvt; 15898 char *all = "", *parse = ast_strdupa(preparse); 15899 AST_DECLARE_APP_ARGS(args, 15900 AST_APP_ARG(param); 15901 AST_APP_ARG(type); 15902 AST_APP_ARG(field); 15903 ); 15904 AST_STANDARD_APP_ARGS(args, parse); 15905 15906 /* Sanity check */ 15907 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15908 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15909 return 0; 15910 } 15911 15912 if (strcasecmp(args.param, "rtpqos")) 15913 return 0; 15914 15915 /* Default arguments of audio,all */ 15916 if (ast_strlen_zero(args.type)) 15917 args.type = "audio"; 15918 if (ast_strlen_zero(args.field)) 15919 args.field = "all"; 15920 15921 memset(buf, 0, buflen); 15922 memset(&qos, 0, sizeof(qos)); 15923 15924 if (p == NULL) { 15925 return -1; 15926 } 15927 15928 if (strcasecmp(args.type, "AUDIO") == 0) { 15929 all = ast_rtp_get_quality(p->rtp, &qos); 15930 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15931 all = ast_rtp_get_quality(p->vrtp, &qos); 15932 } 15933 15934 if (strcasecmp(args.field, "local_ssrc") == 0) 15935 snprintf(buf, buflen, "%u", qos.local_ssrc); 15936 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15937 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15938 else if (strcasecmp(args.field, "local_jitter") == 0) 15939 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15940 else if (strcasecmp(args.field, "local_count") == 0) 15941 snprintf(buf, buflen, "%u", qos.local_count); 15942 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15943 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15944 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15945 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15946 else if (strcasecmp(args.field, "remote_jitter") == 0) 15947 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15948 else if (strcasecmp(args.field, "remote_count") == 0) 15949 snprintf(buf, buflen, "%u", qos.remote_count); 15950 else if (strcasecmp(args.field, "rtt") == 0) 15951 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15952 else if (strcasecmp(args.field, "all") == 0) 15953 ast_copy_string(buf, all, buflen); 15954 else { 15955 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15956 return -1; 15957 } 15958 return 0; 15959 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2328 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02329 { 02330 if (!req->lines) { 02331 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02332 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02333 req->len += strlen(req->data + req->len); 02334 } 02335 }
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 6791 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().
06794 { 06795 int rtp_code; 06796 struct ast_format_list fmt; 06797 06798 06799 if (debug) 06800 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06801 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06802 return; 06803 06804 if (p->rtp) { 06805 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06806 fmt = ast_codec_pref_getsize(pref, codec); 06807 } 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 */ 06808 return; 06809 ast_build_string(m_buf, m_size, " %d", rtp_code); 06810 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06811 ast_rtp_lookup_mime_subtype(1, codec, 06812 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06813 sample_rate); 06814 if (codec == AST_FORMAT_G729A) { 06815 /* Indicate that we don't support VAD (G.729 annex B) */ 06816 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06817 } else if (codec == AST_FORMAT_G723_1) { 06818 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06819 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06820 } else if (codec == AST_FORMAT_ILBC) { 06821 /* Add information about us using only 20/30 ms packetization */ 06822 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06823 } 06824 06825 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06826 *min_packet_size = fmt.cur_ms; 06827 06828 /* Our first codec packetization processed cannot be less than zero */ 06829 if ((*min_packet_size) == 0 && fmt.cur_ms) 06830 *min_packet_size = fmt.cur_ms; 06831 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6759 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06760 { 06761 char tmp[256]; 06762 06763 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06764 add_header(req, "Content-Type", "application/dtmf-relay"); 06765 add_header_contentLength(req, strlen(tmp)); 06766 add_line(req, tmp); 06767 return 0; 06768 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 6072 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and SIP_MAX_HEADERS.
06073 { 06074 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 06075 06076 if (req->headers == SIP_MAX_HEADERS) { 06077 ast_log(LOG_WARNING, "Out of SIP header space\n"); 06078 return -1; 06079 } 06080 06081 if (req->lines) { 06082 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 06083 return -1; 06084 } 06085 06086 if (maxlen <= 0) { 06087 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 06088 return -1; 06089 } 06090 06091 req->header[req->headers] = req->data + req->len; 06092 06093 if (compactheaders) 06094 var = find_alias(var, var); 06095 06096 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 06097 req->len += strlen(req->header[req->headers]); 06098 req->headers++; 06099 06100 return 0; 06101 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 6104 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_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().
06105 { 06106 char clen[10]; 06107 06108 snprintf(clen, sizeof(clen), "%d", len); 06109 return add_header(req, "Content-Length", clen); 06110 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 6113 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
06114 { 06115 if (req->lines == SIP_MAX_LINES) { 06116 ast_log(LOG_WARNING, "Out of SIP line space\n"); 06117 return -1; 06118 } 06119 if (!req->lines) { 06120 /* Add extra empty return */ 06121 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 06122 req->len += strlen(req->data + req->len); 06123 } 06124 if (req->len >= sizeof(req->data) - 4) { 06125 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 06126 return -1; 06127 } 06128 req->line[req->lines] = req->data + req->len; 06129 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 06130 req->len += strlen(req->line[req->lines]); 06131 req->lines++; 06132 return 0; 06133 }
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 6870 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().
06873 { 06874 int rtp_code; 06875 06876 if (debug) 06877 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06878 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06879 return; 06880 06881 ast_build_string(m_buf, m_size, " %d", rtp_code); 06882 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06883 ast_rtp_lookup_mime_subtype(0, format, 0), 06884 sample_rate); 06885 if (format == AST_RTP_DTMF) 06886 /* Indicate we support DTMF and FLASH... */ 06887 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06888 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 17644 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, and username.
Referenced by build_peer().
17645 { 17646 char authcopy[256]; 17647 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 17648 struct sip_auth *a, *b, *auth; 17649 17650 if (ast_strlen_zero(configuration)) 17651 return authlist; 17652 17653 if (option_debug) 17654 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17655 17656 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17657 17658 username = authcopy; 17659 /* split user[:secret] and realm */ 17660 realm = strrchr(username, '@'); 17661 if (realm) 17662 *realm++ = '\0'; 17663 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17664 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17665 return authlist; 17666 } 17667 17668 /* parse username at ':' for secret, or '#" for md5secret */ 17669 if ((secret = strchr(username, ':'))) { 17670 *secret++ = '\0'; 17671 } else if ((md5secret = strchr(username, '#'))) { 17672 *md5secret++ = '\0'; 17673 } 17674 17675 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17676 return authlist; 17677 17678 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17679 ast_copy_string(auth->username, username, sizeof(auth->username)); 17680 if (secret) 17681 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17682 if (md5secret) 17683 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17684 17685 /* find the end of the list */ 17686 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17687 ; 17688 if (b) 17689 b->next = auth; /* Add structure add end of list */ 17690 else 17691 authlist = auth; 17692 17693 if (option_verbose > 2) 17694 ast_verbose("Added authentication for realm %s\n", realm); 17695 17696 return authlist; 17697 17698 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 6234 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by initreqprep(), and reqprep().
06235 { 06236 char r[SIPBUFSIZE*2], *p; 06237 int n, rem = sizeof(r); 06238 06239 if (!route) 06240 return; 06241 06242 p = r; 06243 for (;route ; route = route->next) { 06244 n = strlen(route->hop); 06245 if (rem < n+3) /* we need room for ",<route>" */ 06246 break; 06247 if (p != r) { /* add a separator after fist route */ 06248 *p++ = ','; 06249 --rem; 06250 } 06251 *p++ = '<'; 06252 ast_copy_string(p, route->hop, rem); /* cannot fail */ 06253 p += n; 06254 *p++ = '>'; 06255 rem -= (n+2); 06256 } 06257 *p = '\0'; 06258 add_header(req, "Route", r); 06259 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p, | |||
int | add_audio, | |||
int | add_t38 | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6898 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_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose(), t38properties::capability, capability, debug, FALSE, sip_pvt::flags, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, sip_pvt::maxcallbitrate, sip_pvt::offered_media, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_AUDIO, SDP_IMAGE, SDP_SAMPLE_RATE, SDP_VIDEO, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, 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, t38properties::t38support, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, sip_pvt::vredirip, and sip_pvt::vrtp.
06899 { 06900 int len = 0; 06901 int alreadysent = 0; 06902 06903 struct sockaddr_in sin; 06904 struct sockaddr_in vsin; 06905 struct sockaddr_in dest; 06906 struct sockaddr_in vdest = { 0, }; 06907 06908 /* SDP fields */ 06909 char *version = "v=0\r\n"; /* Protocol version */ 06910 char *subject = "s=session\r\n"; /* Subject of the session */ 06911 char owner[256]; /* Session owner/creator */ 06912 char connection[256]; /* Connection data */ 06913 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06914 char bandwidth[256] = ""; /* Max bitrate */ 06915 char *hold; 06916 char m_audio[256]; /* Media declaration line for audio */ 06917 char m_video[256]; /* Media declaration line for video */ 06918 char m_modem[256]; /* Media declaration line for t38 */ 06919 char a_audio[1024]; /* Attributes for audio */ 06920 char a_video[1024]; /* Attributes for video */ 06921 char a_modem[1024]; /* Attributes for t38 */ 06922 char *m_audio_next = m_audio; 06923 char *m_video_next = m_video; 06924 char *m_modem_next = m_modem; 06925 size_t m_audio_left = sizeof(m_audio); 06926 size_t m_video_left = sizeof(m_video); 06927 size_t m_modem_left = sizeof(m_modem); 06928 char *a_audio_next = a_audio; 06929 char *a_video_next = a_video; 06930 char *a_modem_next = a_modem; 06931 size_t a_audio_left = sizeof(a_audio); 06932 size_t a_video_left = sizeof(a_video); 06933 size_t a_modem_left = sizeof(a_modem); 06934 char dummy_answer[256]; 06935 06936 int x; 06937 int capability = 0; 06938 int needvideo = FALSE; 06939 int debug = sip_debug_test_pvt(p); 06940 int min_audio_packet_size = 0; 06941 int min_video_packet_size = 0; 06942 06943 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06944 m_modem[0] = '\0'; 06945 06946 if (!p->rtp) { 06947 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06948 return AST_FAILURE; 06949 } 06950 06951 /* Set RTP Session ID and version */ 06952 if (!p->sessionid) { 06953 p->sessionid = getpid(); 06954 p->sessionversion = p->sessionid; 06955 } else 06956 p->sessionversion++; 06957 06958 /* Get our addresses */ 06959 ast_rtp_get_us(p->rtp, &sin); 06960 if (p->vrtp) 06961 ast_rtp_get_us(p->vrtp, &vsin); 06962 06963 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06964 if (p->redirip.sin_addr.s_addr) { 06965 dest.sin_port = p->redirip.sin_port; 06966 dest.sin_addr = p->redirip.sin_addr; 06967 } else { 06968 dest.sin_addr = p->ourip; 06969 dest.sin_port = sin.sin_port; 06970 } 06971 06972 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06973 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06974 06975 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06976 hold = "a=recvonly\r\n"; 06977 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06978 hold = "a=inactive\r\n"; 06979 else 06980 hold = "a=sendrecv\r\n"; 06981 06982 if (add_audio) { 06983 capability = p->jointcapability; 06984 06985 06986 if (option_debug > 1) { 06987 char codecbuf[SIPBUFSIZE]; 06988 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"); 06989 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06990 } 06991 06992 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06993 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06994 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06995 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06996 } 06997 #endif 06998 06999 /* Check if we need video in this call */ 07000 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 07001 if (p->vrtp) { 07002 needvideo = TRUE; 07003 if (option_debug > 1) 07004 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 07005 } else if (option_debug > 1) 07006 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 07007 } 07008 07009 07010 /* Ok, we need video. Let's add what we need for video and set codecs. 07011 Video is handled differently than audio since we can not transcode. */ 07012 if (needvideo) { 07013 /* Determine video destination */ 07014 if (p->vredirip.sin_addr.s_addr) { 07015 vdest.sin_addr = p->vredirip.sin_addr; 07016 vdest.sin_port = p->vredirip.sin_port; 07017 } else { 07018 vdest.sin_addr = p->ourip; 07019 vdest.sin_port = vsin.sin_port; 07020 } 07021 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vsin.sin_port)); 07022 07023 /* Build max bitrate string */ 07024 if (p->maxcallbitrate) 07025 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 07026 if (debug) 07027 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 07028 } 07029 07030 if (debug) 07031 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 07032 07033 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 07034 07035 /* Now, start adding audio codecs. These are added in this order: 07036 - First what was requested by the calling channel 07037 - Then preferences in order from sip.conf device config for this peer/user 07038 - Then other codecs in capabilities, including video 07039 */ 07040 07041 /* Prefer the audio codec we were requested to use, first, no matter what 07042 Note that p->prefcodec can include video codecs, so mask them out 07043 */ 07044 if (capability & p->prefcodec) { 07045 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 07046 07047 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07048 &m_audio_next, &m_audio_left, 07049 &a_audio_next, &a_audio_left, 07050 debug, &min_audio_packet_size); 07051 alreadysent |= codec; 07052 } 07053 07054 /* Start by sending our preferred audio codecs */ 07055 for (x = 0; x < 32; x++) { 07056 int codec; 07057 07058 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 07059 break; 07060 07061 if (!(capability & codec)) 07062 continue; 07063 07064 if (alreadysent & codec) 07065 continue; 07066 07067 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07068 &m_audio_next, &m_audio_left, 07069 &a_audio_next, &a_audio_left, 07070 debug, &min_audio_packet_size); 07071 alreadysent |= codec; 07072 } 07073 07074 /* Now send any other common audio and video codecs, and non-codec formats: */ 07075 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 07076 if (!(capability & x)) /* Codec not requested */ 07077 continue; 07078 07079 if (alreadysent & x) /* Already added to SDP */ 07080 continue; 07081 07082 if (x <= AST_FORMAT_MAX_AUDIO) 07083 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 07084 &m_audio_next, &m_audio_left, 07085 &a_audio_next, &a_audio_left, 07086 debug, &min_audio_packet_size); 07087 else 07088 add_codec_to_sdp(p, x, 90000, 07089 &m_video_next, &m_video_left, 07090 &a_video_next, &a_video_left, 07091 debug, &min_video_packet_size); 07092 } 07093 07094 /* Now add DTMF RFC2833 telephony-event as a codec */ 07095 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 07096 if (!(p->jointnoncodeccapability & x)) 07097 continue; 07098 07099 add_noncodec_to_sdp(p, x, 8000, 07100 &m_audio_next, &m_audio_left, 07101 &a_audio_next, &a_audio_left, 07102 debug); 07103 } 07104 07105 if (option_debug > 2) 07106 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 07107 07108 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 07109 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 07110 07111 if (min_audio_packet_size) 07112 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 07113 07114 if (min_video_packet_size) 07115 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 07116 07117 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 07118 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 07119 07120 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 07121 if (needvideo) 07122 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 07123 } 07124 07125 if (add_t38 && p->udptl) { 07126 struct sockaddr_in udptlsin; 07127 struct sockaddr_in udptldest = { 0, }; 07128 07129 ast_udptl_get_us(p->udptl, &udptlsin); 07130 07131 if (p->udptlredirip.sin_addr.s_addr) { 07132 udptldest.sin_port = p->udptlredirip.sin_port; 07133 udptldest.sin_addr = p->udptlredirip.sin_addr; 07134 } else { 07135 udptldest.sin_addr = p->ourip; 07136 udptldest.sin_port = udptlsin.sin_port; 07137 } 07138 07139 if (debug) { 07140 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 07141 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 07142 p->t38.capability, 07143 p->t38.peercapability, 07144 p->t38.jointcapability); 07145 } 07146 07147 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 07148 07149 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 07150 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 07151 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 07152 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 07153 if ((x = t38_get_rate(p->t38.jointcapability))) 07154 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 07155 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 07156 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 07157 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 07158 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 07159 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 07160 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 07161 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 07162 x = ast_udptl_get_local_max_datagram(p->udptl); 07163 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 07164 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 07165 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 07166 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 07167 } 07168 07169 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime); 07170 if (add_audio) 07171 len += strlen(m_audio) + strlen(a_audio) + strlen(hold); 07172 if (needvideo) /* only if video response is appropriate */ 07173 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 07174 if (add_t38) { 07175 len += strlen(m_modem) + strlen(a_modem); 07176 } 07177 07178 add_header(resp, "Content-Type", "application/sdp"); 07179 add_header_contentLength(resp, len); 07180 add_line(resp, version); 07181 add_line(resp, owner); 07182 add_line(resp, subject); 07183 add_line(resp, connection); 07184 if (needvideo) /* only if video response is appropriate */ 07185 add_line(resp, bandwidth); 07186 add_line(resp, stime); 07187 if (add_audio) { 07188 add_line(resp, m_audio); 07189 add_line(resp, a_audio); 07190 add_line(resp, hold); 07191 } else if (p->offered_media[SDP_AUDIO].offered) { 07192 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text); 07193 add_line(resp, dummy_answer); 07194 } 07195 if (needvideo) { /* only if video response is appropriate */ 07196 add_line(resp, m_video); 07197 add_line(resp, a_video); 07198 add_line(resp, hold); /* Repeat hold for the video stream */ 07199 } else if (p->offered_media[SDP_VIDEO].offered) { 07200 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text); 07201 add_line(resp, dummy_answer); 07202 } 07203 if (add_t38) { 07204 add_line(resp, m_modem); 07205 add_line(resp, a_modem); 07206 } else if (p->offered_media[SDP_IMAGE].offered) { 07207 add_line(resp, "m=image 0 udptl t38\r\n"); 07208 } 07209 07210 /* Update lastrtprx when we send our SDP */ 07211 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 07212 07213 if (option_debug > 2) { 07214 char buf[SIPBUFSIZE]; 07215 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 07216 } 07217 07218 return AST_SUCCESS; 07219 }
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 17580 of file chan_sip.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::list, LOG_DEBUG, and sipdebug.
17581 { 17582 struct domain *d; 17583 17584 if (ast_strlen_zero(domain)) { 17585 ast_log(LOG_WARNING, "Zero length domain.\n"); 17586 return 1; 17587 } 17588 17589 if (!(d = ast_calloc(1, sizeof(*d)))) 17590 return 0; 17591 17592 ast_copy_string(d->domain, domain, sizeof(d->domain)); 17593 17594 if (!ast_strlen_zero(context)) 17595 ast_copy_string(d->context, context, sizeof(d->context)); 17596 17597 d->mode = mode; 17598 17599 AST_LIST_LOCK(&domain_list); 17600 AST_LIST_INSERT_TAIL(&domain_list, d, list); 17601 AST_LIST_UNLOCK(&domain_list); 17602 17603 if (sipdebug) 17604 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 17605 17606 return 1; 17607 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6748 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06749 { 06750 /* XXX Convert \n's to \r\n's XXX */ 06751 add_header(req, "Content-Type", "text/plain"); 06752 add_header_contentLength(req, strlen(text)); 06753 add_line(req, text); 06754 return 0; 06755 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6772 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06773 { 06774 const char *xml_is_a_huge_waste_of_space = 06775 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06776 " <media_control>\r\n" 06777 " <vc_primitive>\r\n" 06778 " <to_encoder>\r\n" 06779 " <picture_fast_update>\r\n" 06780 " </picture_fast_update>\r\n" 06781 " </to_encoder>\r\n" 06782 " </vc_primitive>\r\n" 06783 " </media_control>\r\n"; 06784 add_header(req, "Content-Type", "application/media_control+xml"); 06785 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06786 add_line(req, xml_is_a_huge_waste_of_space); 06787 return 0; 06788 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6682 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().
06683 { 06684 char tmpdat[256]; 06685 struct tm tm; 06686 time_t t = time(NULL); 06687 06688 gmtime_r(&t, &tm); 06689 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06690 add_header(req, "Date", tmpdat); 06691 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1940 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01941 { 01942 va_list ap; 01943 01944 if (!p) 01945 return; 01946 01947 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01948 && !recordhistory && !dumphistory) { 01949 return; 01950 } 01951 01952 va_start(ap, fmt); 01953 append_history_va(p, fmt, ap); 01954 va_end(ap); 01955 01956 return; 01957 }
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 1913 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, sip_history::list, and MAX_HISTORY_ENTRIES.
Referenced by append_history_full().
01914 { 01915 char buf[80], *c = buf; /* max history length */ 01916 struct sip_history *hist; 01917 int l; 01918 01919 vsnprintf(buf, sizeof(buf), fmt, ap); 01920 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01921 l = strlen(buf) + 1; 01922 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01923 return; 01924 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01925 free(hist); 01926 return; 01927 } 01928 memcpy(hist->event, buf, l); 01929 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01930 struct sip_history *oldest; 01931 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01932 p->history_entries--; 01933 free(oldest); 01934 } 01935 AST_LIST_INSERT_TAIL(p->history, hist, list); 01936 p->history_entries++; 01937 }
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 14084 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.
Referenced by attempt_transfer(), and handle_invite_replaces().
14085 { 14086 if (chan && chan->_state == AST_STATE_UP) { 14087 if (ast_test_flag(chan, AST_FLAG_MOH)) 14088 ast_moh_stop(chan); 14089 else if (chan->generatordata) 14090 ast_deactivate_generator(chan); 14091 } 14092 }
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 1873 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01874 { 01875 struct sockaddr_in theirs, ours; 01876 01877 /* Get our local information */ 01878 ast_ouraddrfor(them, us); 01879 theirs.sin_addr = *them; 01880 ours.sin_addr = *us; 01881 01882 if (localaddr && externip.sin_addr.s_addr && 01883 (ast_apply_ha(localaddr, &theirs)) && 01884 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01885 if (externexpire && time(NULL) >= externexpire) { 01886 struct ast_hostent ahp; 01887 struct hostent *hp; 01888 01889 externexpire = time(NULL) + externrefresh; 01890 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01891 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01892 } else 01893 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01894 } 01895 *us = externip.sin_addr; 01896 if (option_debug) { 01897 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01898 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01899 } 01900 } else if (bindaddr.sin_addr.s_addr) 01901 *us = bindaddr.sin_addr; 01902 return AST_SUCCESS; 01903 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 14096 of file chan_sip.c.
References ast_channel::_state, ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, ast_channel::name, and option_debug.
14097 { 14098 int res = 0; 14099 struct ast_channel *peera = NULL, 14100 *peerb = NULL, 14101 *peerc = NULL, 14102 *peerd = NULL; 14103 14104 14105 /* We will try to connect the transferee with the target and hangup 14106 all channels to the transferer */ 14107 if (option_debug > 3) { 14108 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 14109 if (transferer->chan1) 14110 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 14111 else 14112 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 14113 if (target->chan1) 14114 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 14115 else 14116 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 14117 if (transferer->chan2) 14118 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 14119 else 14120 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 14121 if (target->chan2) 14122 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)"); 14123 else 14124 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 14125 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 14126 } 14127 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 14128 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 14129 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 14130 peerc = transferer->chan2; /* Asterisk to Transferee */ 14131 peerd = target->chan2; /* Asterisk to Target */ 14132 if (option_debug > 2) 14133 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 14134 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 14135 peera = target->chan1; /* Transferer to PBX -> target channel */ 14136 peerb = transferer->chan1; /* Transferer to IVR*/ 14137 peerc = target->chan2; /* Asterisk to Target */ 14138 peerd = transferer->chan2; /* Nothing */ 14139 if (option_debug > 2) 14140 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 14141 } 14142 14143 if (peera && peerb && peerc && (peerb != peerc)) { 14144 ast_quiet_chan(peera); /* Stop generators */ 14145 ast_quiet_chan(peerb); 14146 ast_quiet_chan(peerc); 14147 if (peerd) 14148 ast_quiet_chan(peerd); 14149 14150 if (option_debug > 3) 14151 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 14152 if (ast_channel_masquerade(peerb, peerc)) { 14153 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 14154 res = -1; 14155 } else 14156 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 14157 return res; 14158 } else { 14159 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 14160 if (transferer->chan1) 14161 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 14162 if (target->chan1) 14163 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 14164 return -2; 14165 } 14166 return 0; 14167 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 3105 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, ast_channel::name, and sip_pvt::owner.
03106 { 03107 struct sip_pvt *p = (struct sip_pvt *)nothing; 03108 03109 ast_mutex_lock(&p->lock); 03110 p->initid = -1; 03111 if (p->owner) { 03112 /* XXX fails on possible deadlock */ 03113 if (!ast_channel_trylock(p->owner)) { 03114 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03115 append_history(p, "Cong", "Auto-congesting (timer)"); 03116 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03117 ast_channel_unlock(p->owner); 03118 } 03119 } 03120 ast_mutex_unlock(&p->lock); 03121 return 0; 03122 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4667 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, sip_pvt::fromdomain, 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().
04668 { 04669 char buf[33]; 04670 04671 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04672 04673 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04674 04675 }
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 4678 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, generate_random_string(), and S_OR.
Referenced by transmit_register().
04679 { 04680 char buf[33]; 04681 04682 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04683 04684 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04685 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7396 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::exten, 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().
07397 { 07398 /* Construct Contact: header */ 07399 if (ourport != STANDARD_SIP_PORT) 07400 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); 07401 else 07402 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07403 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 17912 of file chan_sip.c.
References __set_address_from_contact(), 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_copy_string(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), 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_REF, 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::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, sip_peer::mailbox, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::portinuri, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), 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.
17913 { 17914 struct sip_peer *peer = NULL; 17915 struct ast_ha *oldha = NULL; 17916 int obproxyfound=0; 17917 int found=0; 17918 int firstpass=1; 17919 int format=0; /* Ama flags */ 17920 time_t regseconds = 0; 17921 char *varname = NULL, *varval = NULL; 17922 struct ast_variable *tmpvar = NULL; 17923 struct ast_flags peerflags[2] = {{(0)}}; 17924 struct ast_flags mask[2] = {{(0)}}; 17925 int alt_fullcontact = alt ? 1 : 0; 17926 char fullcontact[sizeof(peer->fullcontact)] = ""; 17927 17928 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17929 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17930 /* We also use a case-sensitive comparison (unlike find_peer) so 17931 that case changes made to the peer name will be properly handled 17932 during reload 17933 */ 17934 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17935 17936 if (peer) { 17937 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17938 found = 1; 17939 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17940 firstpass = 0; 17941 } else { 17942 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17943 return NULL; 17944 17945 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17946 rpeerobjs++; 17947 else 17948 speerobjs++; 17949 ASTOBJ_INIT(peer); 17950 } 17951 /* Note that our peer HAS had its reference count incrased */ 17952 if (firstpass) { 17953 peer->lastmsgssent = -1; 17954 oldha = peer->ha; 17955 peer->ha = NULL; 17956 set_peer_defaults(peer); /* Set peer defaults */ 17957 } 17958 if (!found && name) 17959 ast_copy_string(peer->name, name, sizeof(peer->name)); 17960 17961 /* If we have channel variables, remove them (reload) */ 17962 if (peer->chanvars) { 17963 ast_variables_destroy(peer->chanvars); 17964 peer->chanvars = NULL; 17965 /* XXX should unregister ? */ 17966 } 17967 17968 if (found) 17969 peer->portinuri = 0; 17970 17971 /* If we have realm authentication information, remove them (reload) */ 17972 clear_realm_authentication(peer->auth); 17973 peer->auth = NULL; 17974 17975 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17976 if (!devstate_only) { 17977 if (handle_common_options(&peerflags[0], &mask[0], v)) { 17978 continue; 17979 } 17980 if (realtime && !strcasecmp(v->name, "regseconds")) { 17981 ast_get_time_t(v->value, ®seconds, 0, NULL); 17982 } else if (realtime && !strcasecmp(v->name, "name")) 17983 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17984 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17985 if (alt_fullcontact && !alt) { 17986 /* Reset, because the alternate also has a fullcontact and we 17987 * do NOT want the field value to be doubled. It might be 17988 * tempting to skip this, but the first table might not have 17989 * fullcontact and since we're here, we know that the alternate 17990 * absolutely does. */ 17991 alt_fullcontact = 0; 17992 fullcontact[0] = '\0'; 17993 } 17994 /* Reconstruct field, because realtime separates our value at the ';' */ 17995 if (!ast_strlen_zero(fullcontact)) { 17996 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17997 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17998 } else { 17999 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 18000 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 18001 } 18002 } else if (!strcasecmp(v->name, "secret")) 18003 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 18004 else if (!strcasecmp(v->name, "md5secret")) 18005 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 18006 else if (!strcasecmp(v->name, "auth")) 18007 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 18008 else if (!strcasecmp(v->name, "callerid")) { 18009 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 18010 } else if (!strcasecmp(v->name, "fullname")) { 18011 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 18012 } else if (!strcasecmp(v->name, "trunkname")) { 18013 /* This is actually for a trunk, so we don't want to override callerid */ 18014 ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name)); 18015 } else if (!strcasecmp(v->name, "cid_number")) { 18016 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 18017 } else if (!strcasecmp(v->name, "context")) { 18018 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 18019 } else if (!strcasecmp(v->name, "subscribecontext")) { 18020 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 18021 } else if (!strcasecmp(v->name, "fromdomain")) { 18022 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 18023 } else if (!strcasecmp(v->name, "usereqphone")) { 18024 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 18025 } else if (!strcasecmp(v->name, "fromuser")) { 18026 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 18027 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 18028 if (!strcasecmp(v->value, "dynamic")) { 18029 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 18030 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 18031 } else { 18032 /* They'll register with us */ 18033 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 18034 /* Initialize stuff if this is a new peer, or if it used to be 18035 * non-dynamic before the reload. */ 18036 memset(&peer->addr.sin_addr, 0, 4); 18037 if (peer->addr.sin_port) { 18038 /* If we've already got a port, make it the default rather than absolute */ 18039 peer->defaddr.sin_port = peer->addr.sin_port; 18040 peer->addr.sin_port = 0; 18041 } 18042 } 18043 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18044 } 18045 } else { 18046 /* Non-dynamic. Make sure we become that way if we're not */ 18047 if (!AST_SCHED_DEL(sched, peer->expire)) { 18048 struct sip_peer *peer_ptr = peer; 18049 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18050 } 18051 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18052 if (!strcasecmp(v->name, "outboundproxy")) { 18053 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 18054 ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name); 18055 ASTOBJ_UNREF(peer, sip_destroy_peer); 18056 return NULL; 18057 } 18058 } 18059 if (!strcasecmp(v->name, "outboundproxy")) 18060 obproxyfound=1; 18061 else { 18062 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 18063 if (!peer->addr.sin_port) 18064 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18065 } 18066 if (global_dynamic_exclude_static) { 18067 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 18068 } 18069 } 18070 } else if (!strcasecmp(v->name, "defaultip")) { 18071 if (ast_get_ip(&peer->defaddr, v->value)) { 18072 ASTOBJ_UNREF(peer, sip_destroy_peer); 18073 return NULL; 18074 } 18075 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 18076 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 18077 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18078 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 18079 } else if (!strcasecmp(v->name, "port")) { 18080 peer->portinuri = 1; 18081 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 18082 peer->defaddr.sin_port = htons(atoi(v->value)); 18083 else 18084 peer->addr.sin_port = htons(atoi(v->value)); 18085 } else if (!strcasecmp(v->name, "callingpres")) { 18086 peer->callingpres = ast_parse_caller_presentation(v->value); 18087 if (peer->callingpres == -1) 18088 peer->callingpres = atoi(v->value); 18089 } else if (!strcasecmp(v->name, "username")) { 18090 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 18091 } else if (!strcasecmp(v->name, "language")) { 18092 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 18093 } else if (!strcasecmp(v->name, "regexten")) { 18094 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 18095 } else if (!strcasecmp(v->name, "amaflags")) { 18096 format = ast_cdr_amaflags2int(v->value); 18097 if (format < 0) { 18098 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 18099 } else { 18100 peer->amaflags = format; 18101 } 18102 } else if (!strcasecmp(v->name, "accountcode")) { 18103 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 18104 } else if (!strcasecmp(v->name, "mohinterpret") 18105 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18106 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 18107 } else if (!strcasecmp(v->name, "mohsuggest")) { 18108 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 18109 } else if (!strcasecmp(v->name, "mailbox")) { 18110 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 18111 } else if (!strcasecmp(v->name, "hasvoicemail")) { 18112 /* People expect that if 'hasvoicemail' is set, that the mailbox will 18113 * be also set, even if not explicitly specified. */ 18114 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 18115 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 18116 } 18117 } else if (!strcasecmp(v->name, "subscribemwi")) { 18118 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 18119 } else if (!strcasecmp(v->name, "vmexten")) { 18120 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 18121 } else if (!strcasecmp(v->name, "callgroup")) { 18122 peer->callgroup = ast_get_group(v->value); 18123 } else if (!strcasecmp(v->name, "allowtransfer")) { 18124 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18125 } else if (!strcasecmp(v->name, "pickupgroup")) { 18126 peer->pickupgroup = ast_get_group(v->value); 18127 } else if (!strcasecmp(v->name, "allow")) { 18128 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 18129 } else if (!strcasecmp(v->name, "disallow")) { 18130 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 18131 } else if (!strcasecmp(v->name, "autoframing")) { 18132 peer->autoframing = ast_true(v->value); 18133 } else if (!strcasecmp(v->name, "rtptimeout")) { 18134 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 18135 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18136 peer->rtptimeout = global_rtptimeout; 18137 } 18138 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18139 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 18140 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18141 peer->rtpholdtimeout = global_rtpholdtimeout; 18142 } 18143 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18144 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 18145 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18146 peer->rtpkeepalive = global_rtpkeepalive; 18147 } 18148 } else if (!strcasecmp(v->name, "setvar")) { 18149 /* Set peer channel variable */ 18150 varname = ast_strdupa(v->value); 18151 if ((varval = strchr(varname, '='))) { 18152 *varval++ = '\0'; 18153 if ((tmpvar = ast_variable_new(varname, varval))) { 18154 tmpvar->next = peer->chanvars; 18155 peer->chanvars = tmpvar; 18156 } 18157 } 18158 } 18159 } 18160 18161 /* These apply to devstate lookups */ 18162 if (realtime && !strcasecmp(v->name, "lastms")) { 18163 sscanf(v->value, "%30d", &peer->lastms); 18164 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 18165 inet_aton(v->value, &(peer->addr.sin_addr)); 18166 } else if (!strcasecmp(v->name, "qualify")) { 18167 if (!strcasecmp(v->value, "no")) { 18168 peer->maxms = 0; 18169 } else if (!strcasecmp(v->value, "yes")) { 18170 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 18171 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 18172 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); 18173 peer->maxms = 0; 18174 } 18175 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 18176 /* This would otherwise cause a network storm, where the 18177 * qualify response refreshes the peer from the database, 18178 * which in turn causes another qualify to be sent, ad 18179 * infinitum. */ 18180 ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name); 18181 peer->maxms = 0; 18182 } 18183 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 18184 peer->call_limit = atoi(v->value); 18185 if (peer->call_limit < 0) { 18186 peer->call_limit = 0; 18187 } 18188 } 18189 } 18190 18191 if (!ast_strlen_zero(fullcontact)) { 18192 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 18193 /* We have a hostname in the fullcontact, but if we don't have an 18194 * address listed on the entry (or if it's 'dynamic'), then we need to 18195 * parse the entry to obtain the IP address, so a dynamic host can be 18196 * contacted immediately after reload (as opposed to waiting for it to 18197 * register once again). But if we have an address for this peer and NAT was 18198 * specified, use that address instead. */ 18199 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 18200 __set_address_from_contact(fullcontact, &peer->addr); 18201 } 18202 } 18203 18204 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !obproxyfound && !ast_strlen_zero(peer->tohost)) { 18205 if (ast_get_ip_or_srv(&peer->addr, peer->tohost, srvlookup && !peer->portinuri ? "_sip._udp" : NULL)) { 18206 ast_log(LOG_ERROR, "host lookup failed for %s, on peer %s, removing peer\n", peer->tohost, peer->name); 18207 ASTOBJ_UNREF(peer, sip_destroy_peer); 18208 return NULL; 18209 } 18210 } 18211 18212 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 18213 time_t nowtime = time(NULL); 18214 18215 if ((nowtime - regseconds) > 0) { 18216 destroy_association(peer); 18217 memset(&peer->addr, 0, sizeof(peer->addr)); 18218 peer->lastms = -1; 18219 if (option_debug) 18220 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 18221 } 18222 } 18223 18224 /* Startup regular pokes */ 18225 if (realtime && peer->lastms > 0) { 18226 ASTOBJ_REF(peer); 18227 sip_poke_peer(peer); 18228 } 18229 18230 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 18231 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 18232 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 18233 global_allowsubscribe = TRUE; /* No global ban any more */ 18234 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 18235 reg_source_db(peer); 18236 ASTOBJ_UNMARK(peer); 18237 ast_free_ha(oldha); 18238 return peer; 18239 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 12349 of file chan_sip.c.
References append_history, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, option_debug, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
12350 { 12351 char a1[256]; 12352 char a2[256]; 12353 char a1_hash[256]; 12354 char a2_hash[256]; 12355 char resp[256]; 12356 char resp_hash[256]; 12357 char uri[256]; 12358 char opaque[256] = ""; 12359 char cnonce[80]; 12360 const char *username; 12361 const char *secret; 12362 const char *md5secret; 12363 struct sip_auth *auth = NULL; /* Realm authentication */ 12364 12365 if (!ast_strlen_zero(p->domain)) 12366 ast_copy_string(uri, p->domain, sizeof(uri)); 12367 else if (!ast_strlen_zero(p->uri)) 12368 ast_copy_string(uri, p->uri, sizeof(uri)); 12369 else 12370 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12371 12372 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12373 12374 /* Check if we have separate auth credentials */ 12375 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12376 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12377 12378 if (auth) { 12379 if (sipdebug && option_debug > 1) 12380 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 12381 username = auth->username; 12382 secret = auth->secret; 12383 md5secret = auth->md5secret; 12384 if (sipdebug) 12385 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 12386 } else { 12387 /* No authentication, use peer or register= config */ 12388 username = p->authname; 12389 secret = p->peersecret; 12390 md5secret = p->peermd5secret; 12391 } 12392 if (ast_strlen_zero(username)) /* We have no authentication */ 12393 return -1; 12394 12395 /* Calculate SIP digest response */ 12396 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 12397 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 12398 if (!ast_strlen_zero(md5secret)) 12399 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 12400 else 12401 ast_md5_hash(a1_hash,a1); 12402 ast_md5_hash(a2_hash,a2); 12403 12404 p->noncecount++; 12405 if (!ast_strlen_zero(p->qop)) 12406 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 12407 else 12408 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 12409 ast_md5_hash(resp_hash, resp); 12410 12411 /* only include the opaque string if it's set */ 12412 if (!ast_strlen_zero(p->opaque)) { 12413 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 12414 } 12415 12416 /* XXX We hard code our qop to "auth" for now. XXX */ 12417 if (!ast_strlen_zero(p->qop)) 12418 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount); 12419 else 12420 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque); 12421 12422 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 12423 12424 return 0; 12425 }
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 8879 of file chan_sip.c.
References __get_header(), ast_copy_string(), 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(), handle_request_subscribe(), and handle_response_invite().
08880 { 08881 struct sip_route *thishop, *head, *tail; 08882 int start = 0; 08883 int len; 08884 const char *rr, *contact, *c; 08885 08886 /* Once a persistant route is set, don't fool with it */ 08887 if (p->route && p->route_persistant) { 08888 if (option_debug) 08889 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08890 return; 08891 } 08892 08893 if (p->route) { 08894 free_old_route(p->route); 08895 p->route = NULL; 08896 } 08897 08898 /* We only want to create the route set the first time this is called */ 08899 p->route_persistant = 1; 08900 08901 /* Build a tailq, then assign it to p->route when done. 08902 * If backwards, we add entries from the head so they end up 08903 * in reverse order. However, we do need to maintain a correct 08904 * tail pointer because the contact is always at the end. 08905 */ 08906 head = NULL; 08907 tail = head; 08908 /* 1st we pass through all the hops in any Record-Route headers */ 08909 for (;;) { 08910 /* Each Record-Route header */ 08911 rr = __get_header(req, "Record-Route", &start); 08912 if (*rr == '\0') 08913 break; 08914 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08915 ++rr; 08916 len = strcspn(rr, ">") + 1; 08917 /* Make a struct route */ 08918 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08919 /* ast_calloc is not needed because all fields are initialized in this block */ 08920 ast_copy_string(thishop->hop, rr, len); 08921 if (option_debug > 1) 08922 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08923 /* Link in */ 08924 if (backwards) { 08925 /* Link in at head so they end up in reverse order */ 08926 thishop->next = head; 08927 head = thishop; 08928 /* If this was the first then it'll be the tail */ 08929 if (!tail) 08930 tail = thishop; 08931 } else { 08932 thishop->next = NULL; 08933 /* Link in at the end */ 08934 if (tail) 08935 tail->next = thishop; 08936 else 08937 head = thishop; 08938 tail = thishop; 08939 } 08940 } 08941 } 08942 } 08943 08944 /* Only append the contact if we are dealing with a strict router */ 08945 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08946 /* 2nd append the Contact: if there is one */ 08947 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08948 contact = get_header(req, "Contact"); 08949 if (!ast_strlen_zero(contact)) { 08950 if (option_debug > 1) 08951 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08952 /* Look for <: delimited address */ 08953 c = strchr(contact, '<'); 08954 if (c) { 08955 /* Take to > */ 08956 ++c; 08957 len = strcspn(c, ">") + 1; 08958 } else { 08959 /* No <> - just take the lot */ 08960 c = contact; 08961 len = strlen(contact) + 1; 08962 } 08963 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08964 /* ast_calloc is not needed because all fields are initialized in this block */ 08965 ast_copy_string(thishop->hop, c, len); 08966 thishop->next = NULL; 08967 /* Goes at the end */ 08968 if (tail) 08969 tail->next = thishop; 08970 else 08971 head = thishop; 08972 } 08973 } 08974 } 08975 08976 /* Store as new route */ 08977 p->route = head; 08978 08979 /* For debugging dump what we ended up with */ 08980 if (sip_debug_test_pvt(p)) 08981 list_route(p->route); 08982 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7406 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, sip_pvt::fromdomain, sip_pvt::fromuser, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
07407 { 07408 int send_pres_tags = TRUE; 07409 const char *privacy=NULL; 07410 const char *screen=NULL; 07411 char buf[256]; 07412 const char *clid = default_callerid; 07413 const char *clin = NULL; 07414 const char *fromdomain; 07415 07416 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07417 return; 07418 07419 if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num)) 07420 clid = p->owner->cid.cid_num; 07421 if (p->owner && p->owner->cid.cid_name) 07422 clin = p->owner->cid.cid_name; 07423 if (ast_strlen_zero(clin)) 07424 clin = clid; 07425 07426 switch (p->callingpres) { 07427 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07428 privacy = "off"; 07429 screen = "no"; 07430 break; 07431 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07432 privacy = "off"; 07433 screen = "yes"; 07434 break; 07435 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07436 privacy = "off"; 07437 screen = "no"; 07438 break; 07439 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07440 privacy = "off"; 07441 screen = "yes"; 07442 break; 07443 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07444 privacy = "full"; 07445 screen = "no"; 07446 break; 07447 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07448 privacy = "full"; 07449 screen = "yes"; 07450 break; 07451 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07452 privacy = "full"; 07453 screen = "no"; 07454 break; 07455 case AST_PRES_PROHIB_NETWORK_NUMBER: 07456 privacy = "full"; 07457 screen = "yes"; 07458 break; 07459 case AST_PRES_NUMBER_NOT_AVAILABLE: 07460 send_pres_tags = FALSE; 07461 break; 07462 default: 07463 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07464 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07465 privacy = "full"; 07466 else 07467 privacy = "off"; 07468 screen = "no"; 07469 break; 07470 } 07471 07472 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07473 07474 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07475 if (send_pres_tags) 07476 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07477 ast_string_field_set(p, rpid, buf); 07478 07479 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07480 S_OR(p->fromuser, clid), 07481 fromdomain, p->tag); 07482 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 17729 of file chan_sip.c.
References ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
17730 { 17731 struct sip_user *user; 17732 int format; 17733 struct ast_ha *oldha = NULL; 17734 char *varname = NULL, *varval = NULL; 17735 struct ast_variable *tmpvar = NULL; 17736 struct ast_flags userflags[2] = {{(0)}}; 17737 struct ast_flags mask[2] = {{(0)}}; 17738 17739 17740 if (!(user = ast_calloc(1, sizeof(*user)))) 17741 return NULL; 17742 17743 suserobjs++; 17744 ASTOBJ_INIT(user); 17745 ast_copy_string(user->name, name, sizeof(user->name)); 17746 oldha = user->ha; 17747 user->ha = NULL; 17748 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17749 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17750 user->capability = global_capability; 17751 user->allowtransfer = global_allowtransfer; 17752 user->maxcallbitrate = default_maxcallbitrate; 17753 user->autoframing = global_autoframing; 17754 user->prefs = default_prefs; 17755 /* set default context */ 17756 strcpy(user->context, default_context); 17757 strcpy(user->language, default_language); 17758 strcpy(user->mohinterpret, default_mohinterpret); 17759 strcpy(user->mohsuggest, default_mohsuggest); 17760 /* First we walk through the v parameters list and then the alt parameters list */ 17761 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17762 if (handle_common_options(&userflags[0], &mask[0], v)) 17763 continue; 17764 17765 if (!strcasecmp(v->name, "context")) { 17766 ast_copy_string(user->context, v->value, sizeof(user->context)); 17767 } else if (!strcasecmp(v->name, "subscribecontext")) { 17768 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17769 } else if (!strcasecmp(v->name, "setvar")) { 17770 varname = ast_strdupa(v->value); 17771 if ((varval = strchr(varname,'='))) { 17772 *varval++ = '\0'; 17773 if ((tmpvar = ast_variable_new(varname, varval))) { 17774 tmpvar->next = user->chanvars; 17775 user->chanvars = tmpvar; 17776 } 17777 } 17778 } else if (!strcasecmp(v->name, "permit") || 17779 !strcasecmp(v->name, "deny")) { 17780 user->ha = ast_append_ha(v->name, v->value, user->ha); 17781 } else if (!strcasecmp(v->name, "allowtransfer")) { 17782 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17783 } else if (!strcasecmp(v->name, "secret")) { 17784 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17785 } else if (!strcasecmp(v->name, "md5secret")) { 17786 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17787 } else if (!strcasecmp(v->name, "callerid")) { 17788 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17789 } else if (!strcasecmp(v->name, "fullname")) { 17790 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17791 } else if (!strcasecmp(v->name, "trunkname")) { 17792 /* This is actually for a trunk, so we don't want to override callerid */ 17793 ast_copy_string(user->cid_name, "", sizeof(user->cid_name)); 17794 } else if (!strcasecmp(v->name, "cid_number")) { 17795 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17796 } else if (!strcasecmp(v->name, "callgroup")) { 17797 user->callgroup = ast_get_group(v->value); 17798 } else if (!strcasecmp(v->name, "pickupgroup")) { 17799 user->pickupgroup = ast_get_group(v->value); 17800 } else if (!strcasecmp(v->name, "language")) { 17801 ast_copy_string(user->language, v->value, sizeof(user->language)); 17802 } else if (!strcasecmp(v->name, "mohinterpret") 17803 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17804 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17805 } else if (!strcasecmp(v->name, "mohsuggest")) { 17806 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17807 } else if (!strcasecmp(v->name, "accountcode")) { 17808 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17809 } else if (!strcasecmp(v->name, "call-limit")) { 17810 user->call_limit = atoi(v->value); 17811 if (user->call_limit < 0) 17812 user->call_limit = 0; 17813 } else if (!strcasecmp(v->name, "amaflags")) { 17814 format = ast_cdr_amaflags2int(v->value); 17815 if (format < 0) { 17816 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17817 } else { 17818 user->amaflags = format; 17819 } 17820 } else if (!strcasecmp(v->name, "allow")) { 17821 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17822 } else if (!strcasecmp(v->name, "disallow")) { 17823 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17824 } else if (!strcasecmp(v->name, "autoframing")) { 17825 user->autoframing = ast_true(v->value); 17826 } else if (!strcasecmp(v->name, "callingpres")) { 17827 user->callingpres = ast_parse_caller_presentation(v->value); 17828 if (user->callingpres == -1) 17829 user->callingpres = atoi(v->value); 17830 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17831 user->maxcallbitrate = atoi(v->value); 17832 if (user->maxcallbitrate < 0) 17833 user->maxcallbitrate = default_maxcallbitrate; 17834 } 17835 /* We can't just report unknown options here because this may be a 17836 * type=friend entry. All user options are valid for a peer, but not 17837 * the other way around. */ 17838 } 17839 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17840 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17841 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17842 global_allowsubscribe = TRUE; /* No global ban any more */ 17843 ast_free_ha(oldha); 17844 return user; 17845 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1857 of file chan_sip.c.
References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, SIP_NAT_RFC3581, and sip_pvt::via.
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().
01858 { 01859 /* Work around buggy UNIDEN UIP200 firmware */ 01860 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01861 01862 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01863 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01864 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01865 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 9204 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe(), and handle_response().
09205 { 09206 struct sip_pvt *p = data; 09207 09208 ast_mutex_lock(&p->lock); 09209 09210 switch(state) { 09211 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 09212 case AST_EXTENSION_REMOVED: /* Extension is gone */ 09213 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 09214 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09215 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 09216 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); 09217 p->stateid = -1; 09218 p->subscribed = NONE; 09219 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 09220 break; 09221 default: /* Tell user */ 09222 p->laststate = state; 09223 break; 09224 } 09225 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 09226 if (!p->pendinginvite) { 09227 transmit_state_notify(p, state, 1, FALSE); 09228 } else { 09229 /* We already have a NOTIFY sent that is not answered. Queue the state up. 09230 if many state changes happen meanwhile, we will only send a notification of the last one */ 09231 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 09232 } 09233 } 09234 if (option_verbose > 1) 09235 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 09236 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 09237 09238 09239 ast_mutex_unlock(&p->lock); 09240 09241 return 0; 09242 }
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 5263 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
05264 { 05265 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05266 sip_peer_hold(dialog, holdstate); 05267 if (global_callevents) 05268 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05269 "Channel: %s\r\n" 05270 "Uniqueid: %s\r\n", 05271 dialog->owner->name, 05272 dialog->owner->uniqueid); 05273 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05274 if (!holdstate) { /* Put off remote hold */ 05275 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05276 return; 05277 } 05278 /* No address for RTP, we're on hold */ 05279 05280 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05281 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05282 else if (sendonly == 2) /* Inactive stream */ 05283 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05284 else 05285 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05286 return; 05287 }
static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const char * | username, | |||
const char * | secret, | |||
const char * | md5secret, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
int | ignore | |||
) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 9006 of file chan_sip.c.
References append_history, ast_copy_string(), ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, sip_pvt::randdata, s, S_OR, set_nonce_randdata(), sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stalenonce, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
09009 { 09010 const char *response = "407 Proxy Authentication Required"; 09011 const char *reqheader = "Proxy-Authorization"; 09012 const char *respheader = "Proxy-Authenticate"; 09013 const char *authtoken; 09014 char a1_hash[256]; 09015 char resp_hash[256]=""; 09016 char *c; 09017 int wrongnonce = FALSE; 09018 int good_response; 09019 const char *usednonce = p->randdata; 09020 struct ast_dynamic_str *buf; 09021 int res; 09022 09023 /* table of recognised keywords, and their value in the digest */ 09024 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 09025 struct x { 09026 const char *key; 09027 const char *s; 09028 } *i, keys[] = { 09029 [K_RESP] = { "response=", "" }, 09030 [K_URI] = { "uri=", "" }, 09031 [K_USER] = { "username=", "" }, 09032 [K_NONCE] = { "nonce=", "" }, 09033 [K_LAST] = { NULL, NULL} 09034 }; 09035 09036 /* Always OK if no secret */ 09037 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 09038 return AUTH_SUCCESSFUL; 09039 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09040 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 09041 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 09042 different circumstances! What a surprise. */ 09043 response = "401 Unauthorized"; 09044 reqheader = "Authorization"; 09045 respheader = "WWW-Authenticate"; 09046 } 09047 authtoken = get_header(req, reqheader); 09048 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09049 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09050 information */ 09051 if (!reliable) { 09052 /* Resend message if this was NOT a reliable delivery. Otherwise the 09053 retransmission should get it */ 09054 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09055 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09056 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09057 } 09058 return AUTH_CHALLENGE_SENT; 09059 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09060 /* We have no auth, so issue challenge and request authentication */ 09061 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 09062 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09063 /* Schedule auto destroy in 32 seconds */ 09064 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09065 return AUTH_CHALLENGE_SENT; 09066 } 09067 09068 /* --- We have auth, so check it */ 09069 09070 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 09071 an example in the spec of just what it is you're doing a hash on. */ 09072 09073 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 09074 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09075 09076 /* Make a copy of the response and parse it */ 09077 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 09078 09079 if (res == AST_DYNSTR_BUILD_FAILED) 09080 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09081 09082 c = buf->str; 09083 09084 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 09085 for (i = keys; i->key != NULL; i++) { 09086 const char *separator = ","; /* default */ 09087 09088 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09089 continue; 09090 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09091 c += strlen(i->key); 09092 if (*c == '"') { /* in quotes. Skip first and look for last */ 09093 c++; 09094 separator = "\""; 09095 } 09096 i->s = c; 09097 strsep(&c, separator); 09098 break; 09099 } 09100 if (i->key == NULL) /* not found, jump after space or comma */ 09101 strsep(&c, " ,"); 09102 } 09103 09104 /* Verify that digest username matches the username we auth as */ 09105 if (strcmp(username, keys[K_USER].s)) { 09106 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 09107 username, keys[K_USER].s); 09108 /* Oops, we're trying something here */ 09109 return AUTH_USERNAME_MISMATCH; 09110 } 09111 09112 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 09113 * If this check fails, send 401 with new nonce */ 09114 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 09115 wrongnonce = TRUE; 09116 usednonce = keys[K_NONCE].s; 09117 } else { 09118 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 09119 } 09120 09121 if (!ast_strlen_zero(md5secret)) 09122 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09123 else { 09124 char a1[256]; 09125 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 09126 ast_md5_hash(a1_hash, a1); 09127 } 09128 09129 /* compute the expected response to compare with what we received */ 09130 { 09131 char a2[256]; 09132 char a2_hash[256]; 09133 char resp[256]; 09134 09135 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 09136 S_OR(keys[K_URI].s, uri)); 09137 ast_md5_hash(a2_hash, a2); 09138 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 09139 ast_md5_hash(resp_hash, resp); 09140 } 09141 09142 good_response = keys[K_RESP].s && 09143 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 09144 if (wrongnonce) { 09145 if (good_response) { 09146 if (sipdebug) 09147 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 09148 /* We got working auth token, based on stale nonce . */ 09149 set_nonce_randdata(p, 0); 09150 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 09151 } else { 09152 /* Everything was wrong, so give the device one more try with a new challenge */ 09153 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09154 if (sipdebug) 09155 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 09156 set_nonce_randdata(p, 1); 09157 } else { 09158 if (sipdebug) 09159 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 09160 } 09161 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09162 } 09163 09164 /* Schedule auto destroy in 32 seconds */ 09165 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09166 return AUTH_CHALLENGE_SENT; 09167 } 09168 if (good_response) { 09169 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 09170 return AUTH_SUCCESSFUL; 09171 } 09172 09173 /* Ok, we have a bad username/secret pair */ 09174 /* Tell the UAS not to re-send this authentication data, because 09175 it will continue to fail 09176 */ 09177 09178 return AUTH_SECRET_FAILED; 09179 }
static void check_auth_buf_init | ( | void | ) | [static] |
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12824 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), handle_response_invite(), and sip_reinvite_retry().
12825 { 12826 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12827 /* if we can't BYE, then this is really a pending CANCEL */ 12828 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12829 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12830 /* Actually don't destroy us yet, wait for the 487 on our original 12831 INVITE, but do set an autodestruct just in case we never get it. */ 12832 else { 12833 /* We have a pending outbound invite, don't send someting 12834 new in-transaction */ 12835 if (p->pendinginvite) 12836 return; 12837 12838 /* Perhaps there is an SD change INVITE outstanding */ 12839 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12840 } 12841 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12842 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12843 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12844 /* if we can't REINVITE, hold it for later */ 12845 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12846 if (option_debug) 12847 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12848 } else { 12849 if (option_debug) 12850 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12851 /* Didn't get to reinvite yet, so do it now */ 12852 transmit_reinvite_with_sdp(p); 12853 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12854 } 12855 } 12856 }
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 17610 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and domain::list.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
17611 { 17612 struct domain *d; 17613 int result = 0; 17614 17615 AST_LIST_LOCK(&domain_list); 17616 AST_LIST_TRAVERSE(&domain_list, d, list) { 17617 if (strcasecmp(d->domain, domain)) 17618 continue; 17619 17620 if (len && !ast_strlen_zero(d->context)) 17621 ast_copy_string(context, d->context, len); 17622 17623 result = 1; 17624 break; 17625 } 17626 AST_LIST_UNLOCK(&domain_list); 17627 17628 return result; 17629 }
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 10438 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
10439 { 10440 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 10441 }
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 10109 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, sip_peer::name, sip_user::name, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RPORT_PRESENT, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
10112 { 10113 struct sip_user *user = NULL; 10114 struct sip_peer *peer; 10115 char from[256], *c; 10116 char *of; 10117 char rpid_num[50]; 10118 const char *rpid; 10119 enum check_auth_result res = AUTH_SUCCESSFUL; 10120 char *t; 10121 char calleridname[50]; 10122 int debug=sip_debug_test_addr(sin); 10123 struct ast_variable *tmpvar = NULL, *v = NULL; 10124 char *uri2 = ast_strdupa(uri); 10125 10126 /* Terminate URI */ 10127 t = uri2; 10128 while (*t && *t > 32 && *t != ';') 10129 t++; 10130 *t = '\0'; 10131 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 10132 if (pedanticsipchecking) 10133 ast_uri_decode(from); 10134 /* XXX here tries to map the username for invite things */ 10135 memset(calleridname, 0, sizeof(calleridname)); 10136 get_calleridname(from, calleridname, sizeof(calleridname)); 10137 if (calleridname[0]) 10138 ast_string_field_set(p, cid_name, calleridname); 10139 10140 rpid = get_header(req, "Remote-Party-ID"); 10141 memset(rpid_num, 0, sizeof(rpid_num)); 10142 if (!ast_strlen_zero(rpid)) 10143 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 10144 10145 of = get_in_brackets(from); 10146 if (ast_strlen_zero(p->exten)) { 10147 t = uri2; 10148 if (!strncasecmp(t, "sip:", 4)) 10149 t+= 4; 10150 ast_string_field_set(p, exten, t); 10151 t = strchr(p->exten, '@'); 10152 if (t) 10153 *t = '\0'; 10154 if (ast_strlen_zero(p->our_contact)) 10155 build_contact(p); 10156 } 10157 /* save the URI part of the From header */ 10158 ast_string_field_set(p, from, of); 10159 if (strncasecmp(of, "sip:", 4)) { 10160 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 10161 } else 10162 of += 4; 10163 /* Get just the username part */ 10164 if ((c = strchr(of, '@'))) { 10165 char *tmp; 10166 *c = '\0'; 10167 if ((c = strchr(of, ':'))) 10168 *c = '\0'; 10169 tmp = ast_strdupa(of); 10170 /* We need to be able to handle auth-headers looking like 10171 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 10172 */ 10173 tmp = strsep(&tmp, ";"); 10174 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10175 ast_shrink_phone_number(tmp); 10176 ast_string_field_set(p, cid_num, tmp); 10177 } 10178 10179 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 10180 user = find_user(of, 1); 10181 10182 /* Find user based on user name in the from header */ 10183 if (user && ast_apply_ha(user->ha, sin)) { 10184 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10185 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10186 if (sipmethod == SIP_INVITE) { 10187 /* copy channel vars */ 10188 for (v = user->chanvars ; v ; v = v->next) { 10189 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10190 tmpvar->next = p->chanvars; 10191 p->chanvars = tmpvar; 10192 } 10193 } 10194 } 10195 p->prefs = user->prefs; 10196 /* Set Frame packetization */ 10197 if (p->rtp) { 10198 ast_rtp_codec_setpref(p->rtp, &p->prefs); 10199 p->autoframing = user->autoframing; 10200 } 10201 /* replace callerid if rpid found, and not restricted */ 10202 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10203 char *tmp; 10204 if (*calleridname) 10205 ast_string_field_set(p, cid_name, calleridname); 10206 tmp = ast_strdupa(rpid_num); 10207 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10208 ast_shrink_phone_number(tmp); 10209 ast_string_field_set(p, cid_num, tmp); 10210 } 10211 10212 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 10213 10214 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10215 if (sip_cancel_destroy(p)) 10216 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10217 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10218 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10219 /* Copy SIP extensions profile from INVITE */ 10220 if (p->sipoptions) 10221 user->sipoptions = p->sipoptions; 10222 10223 /* If we have a call limit, set flag */ 10224 if (user->call_limit) 10225 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10226 if (!ast_strlen_zero(user->context)) 10227 ast_string_field_set(p, context, user->context); 10228 if (!ast_strlen_zero(user->cid_num)) { 10229 char *tmp = ast_strdupa(user->cid_num); 10230 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10231 ast_shrink_phone_number(tmp); 10232 ast_string_field_set(p, cid_num, tmp); 10233 } 10234 if (!ast_strlen_zero(user->cid_name)) 10235 ast_string_field_set(p, cid_name, user->cid_name); 10236 ast_string_field_set(p, username, user->name); 10237 ast_string_field_set(p, peername, user->name); 10238 ast_string_field_set(p, peersecret, user->secret); 10239 ast_string_field_set(p, peermd5secret, user->md5secret); 10240 ast_string_field_set(p, subscribecontext, user->subscribecontext); 10241 ast_string_field_set(p, accountcode, user->accountcode); 10242 ast_string_field_set(p, language, user->language); 10243 ast_string_field_set(p, mohsuggest, user->mohsuggest); 10244 ast_string_field_set(p, mohinterpret, user->mohinterpret); 10245 p->allowtransfer = user->allowtransfer; 10246 p->amaflags = user->amaflags; 10247 p->callgroup = user->callgroup; 10248 p->pickupgroup = user->pickupgroup; 10249 if (user->callingpres) /* User callingpres setting will override RPID header */ 10250 p->callingpres = user->callingpres; 10251 10252 /* Set default codec settings for this call */ 10253 p->capability = user->capability; /* User codec choice */ 10254 p->jointcapability = user->capability; /* Our codecs */ 10255 if (p->peercapability) /* AND with peer's codecs */ 10256 p->jointcapability &= p->peercapability; 10257 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10258 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10259 p->noncodeccapability |= AST_RTP_DTMF; 10260 else 10261 p->noncodeccapability &= ~AST_RTP_DTMF; 10262 p->jointnoncodeccapability = p->noncodeccapability; 10263 if (p->t38.peercapability) 10264 p->t38.jointcapability &= p->t38.peercapability; 10265 p->maxcallbitrate = user->maxcallbitrate; 10266 /* If we do not support video, remove video from call structure */ 10267 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10268 ast_rtp_destroy(p->vrtp); 10269 p->vrtp = NULL; 10270 } 10271 } 10272 if (user && debug) 10273 ast_verbose("Found user '%s'\n", user->name); 10274 } else { 10275 if (user) { 10276 if (!authpeer && debug) 10277 ast_verbose("Found user '%s', but fails host access\n", user->name); 10278 ASTOBJ_UNREF(user,sip_destroy_user); 10279 } 10280 user = NULL; 10281 } 10282 10283 if (!user) { 10284 /* If we didn't find a user match, check for peers */ 10285 if (sipmethod == SIP_SUBSCRIBE) 10286 /* For subscribes, match on peer name only */ 10287 peer = find_peer(of, NULL, 1, 0); 10288 else 10289 /* Look for peer based on the IP address we received data from */ 10290 /* If peer is registered from this IP address or have this as a default 10291 IP address, this call is from the peer 10292 */ 10293 peer = find_peer(NULL, &p->recv, 1, 0); 10294 10295 if (peer) { 10296 /* Set Frame packetization */ 10297 if (p->rtp) { 10298 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 10299 p->autoframing = peer->autoframing; 10300 } 10301 if (debug) 10302 ast_verbose("Found peer '%s'\n", peer->name); 10303 10304 /* Take the peer */ 10305 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10306 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10307 10308 /* Copy SIP extensions profile to peer */ 10309 if (p->sipoptions) 10310 peer->sipoptions = p->sipoptions; 10311 10312 /* replace callerid if rpid found, and not restricted */ 10313 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10314 char *tmp = ast_strdupa(rpid_num); 10315 if (*calleridname) 10316 ast_string_field_set(p, cid_name, calleridname); 10317 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10318 ast_shrink_phone_number(tmp); 10319 ast_string_field_set(p, cid_num, tmp); 10320 } 10321 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 10322 10323 ast_string_field_set(p, peersecret, peer->secret); 10324 ast_string_field_set(p, peermd5secret, peer->md5secret); 10325 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 10326 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 10327 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 10328 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 10329 p->callingpres = peer->callingpres; 10330 if (peer->maxms && peer->lastms) 10331 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 10332 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 10333 /* Pretend there is no required authentication */ 10334 ast_string_field_free(p, peersecret); 10335 ast_string_field_free(p, peermd5secret); 10336 } 10337 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10338 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10339 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10340 /* If we have a call limit, set flag */ 10341 if (peer->call_limit) 10342 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10343 ast_string_field_set(p, peername, peer->name); 10344 ast_string_field_set(p, authname, peer->name); 10345 10346 if (sipmethod == SIP_INVITE) { 10347 /* copy channel vars */ 10348 for (v = peer->chanvars ; v ; v = v->next) { 10349 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10350 tmpvar->next = p->chanvars; 10351 p->chanvars = tmpvar; 10352 } 10353 } 10354 } 10355 if (authpeer) { 10356 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10357 } 10358 10359 if (!ast_strlen_zero(peer->username)) { 10360 ast_string_field_set(p, username, peer->username); 10361 /* Use the default username for authentication on outbound calls */ 10362 /* XXX this takes the name from the caller... can we override ? */ 10363 ast_string_field_set(p, authname, peer->username); 10364 } 10365 if (!ast_strlen_zero(peer->cid_num)) { 10366 char *tmp = ast_strdupa(peer->cid_num); 10367 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10368 ast_shrink_phone_number(tmp); 10369 ast_string_field_set(p, cid_num, tmp); 10370 } 10371 if (!ast_strlen_zero(peer->cid_name)) 10372 ast_string_field_set(p, cid_name, peer->cid_name); 10373 ast_string_field_set(p, fullcontact, peer->fullcontact); 10374 if (!ast_strlen_zero(peer->context)) 10375 ast_string_field_set(p, context, peer->context); 10376 ast_string_field_set(p, peersecret, peer->secret); 10377 ast_string_field_set(p, peermd5secret, peer->md5secret); 10378 ast_string_field_set(p, language, peer->language); 10379 ast_string_field_set(p, accountcode, peer->accountcode); 10380 p->amaflags = peer->amaflags; 10381 p->callgroup = peer->callgroup; 10382 p->pickupgroup = peer->pickupgroup; 10383 p->capability = peer->capability; 10384 p->prefs = peer->prefs; 10385 p->jointcapability = peer->capability; 10386 if (p->peercapability) 10387 p->jointcapability &= p->peercapability; 10388 p->maxcallbitrate = peer->maxcallbitrate; 10389 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10390 ast_rtp_destroy(p->vrtp); 10391 p->vrtp = NULL; 10392 } 10393 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10394 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10395 p->noncodeccapability |= AST_RTP_DTMF; 10396 else 10397 p->noncodeccapability &= ~AST_RTP_DTMF; 10398 p->jointnoncodeccapability = p->noncodeccapability; 10399 if (p->t38.peercapability) 10400 p->t38.jointcapability &= p->t38.peercapability; 10401 } 10402 ASTOBJ_UNREF(peer, sip_destroy_peer); 10403 } else { 10404 if (debug) 10405 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 10406 10407 /* do we allow guests? */ 10408 if (!global_allowguest) { 10409 if (global_alwaysauthreject) 10410 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 10411 else 10412 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 10413 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10414 char *tmp = ast_strdupa(rpid_num); 10415 if (*calleridname) 10416 ast_string_field_set(p, cid_name, calleridname); 10417 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10418 ast_shrink_phone_number(tmp); 10419 ast_string_field_set(p, cid_num, tmp); 10420 } 10421 } 10422 10423 } 10424 10425 if (user) 10426 ASTOBJ_UNREF(user, sip_destroy_user); 10427 10428 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 10429 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 10430 } 10431 10432 return res; 10433 }
static void check_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 9977 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose(), sip_pvt::flags, get_header(), hp, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_PAGE2_RPORT_PRESENT, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().
09978 { 09979 char via[512]; 09980 char *c, *pt; 09981 struct hostent *hp; 09982 struct ast_hostent ahp; 09983 09984 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09985 09986 /* Work on the leftmost value of the topmost Via header */ 09987 c = strchr(via, ','); 09988 if (c) 09989 *c = '\0'; 09990 09991 /* Check for rport */ 09992 c = strstr(via, ";rport"); 09993 if (c && (c[6] != '=')) /* rport query, not answer */ 09994 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 09995 09996 c = strchr(via, ';'); 09997 if (c) 09998 *c = '\0'; 09999 10000 c = strchr(via, ' '); 10001 if (c) { 10002 *c = '\0'; 10003 c = ast_skip_blanks(c+1); 10004 if (strcasecmp(via, "SIP/2.0/UDP")) { 10005 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 10006 return; 10007 } 10008 pt = strchr(c, ':'); 10009 if (pt) 10010 *pt++ = '\0'; /* remember port pointer */ 10011 hp = ast_gethostbyname(c, &ahp); 10012 if (!hp) { 10013 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 10014 return; 10015 } 10016 memset(&p->sa, 0, sizeof(p->sa)); 10017 p->sa.sin_family = AF_INET; 10018 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 10019 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 10020 10021 if (sip_debug_test_pvt(p)) { 10022 const struct sockaddr_in *dst = sip_real_dst(p); 10023 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 10024 } 10025 } 10026 }
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 10882 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10883 { 10884 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10885 10886 while ((oldcontext = strsep(&old, "&"))) { 10887 stalecontext = '\0'; 10888 ast_copy_string(newlist, new, sizeof(newlist)); 10889 stringp = newlist; 10890 while ((newcontext = strsep(&stringp, "&"))) { 10891 if (strcmp(newcontext, oldcontext) == 0) { 10892 /* This is not the context you're looking for */ 10893 stalecontext = '\0'; 10894 break; 10895 } else if (strcmp(newcontext, oldcontext)) { 10896 stalecontext = oldcontext; 10897 } 10898 10899 } 10900 if (stalecontext) 10901 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10902 } 10903 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17701 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17702 { 17703 struct sip_auth *a = authlist; 17704 struct sip_auth *b; 17705 17706 while (a) { 17707 b = a; 17708 a = a->next; 17709 free(b); 17710 } 17711 17712 return 1; 17713 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 17632 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and domain::list.
Referenced by reload_config(), and unload_module().
17633 { 17634 struct domain *d; 17635 17636 AST_LIST_LOCK(&domain_list); 17637 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 17638 free(d); 17639 AST_LIST_UNLOCK(&domain_list); 17640 }
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 11702 of file chan_sip.c.
References complete_sip_peer().
11703 { 11704 if (pos == 3) 11705 return complete_sip_peer(word, state, 0); 11706 11707 return NULL; 11708 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11676 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().
11677 { 11678 char *result = NULL; 11679 int wordlen = strlen(word); 11680 int which = 0; 11681 11682 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11683 /* locking of the object is not required because only the name and flags are being compared */ 11684 if (!strncasecmp(word, iterator->name, wordlen) && 11685 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11686 ++which > state) 11687 result = ast_strdup(iterator->name); 11688 } while(0) ); 11689 return result; 11690 }
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 11770 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11771 { 11772 if (pos == 4) 11773 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11774 return NULL; 11775 }
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 11778 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11779 { 11780 if (pos == 4) 11781 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11782 11783 return NULL; 11784 }
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 11693 of file chan_sip.c.
References complete_sip_peer().
11694 { 11695 if (pos == 3) 11696 return complete_sip_peer(word, state, 0); 11697 11698 return NULL; 11699 }
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 11731 of file chan_sip.c.
References complete_sip_user().
11732 { 11733 if (pos == 3) 11734 return complete_sip_user(word, state, 0); 11735 11736 return NULL; 11737 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11711 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().
11712 { 11713 char *result = NULL; 11714 int wordlen = strlen(word); 11715 int which = 0; 11716 11717 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11718 /* locking of the object is not required because only the name and flags are being compared */ 11719 if (!strncasecmp(word, iterator->name, wordlen)) { 11720 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11721 continue; 11722 if (++which > state) { 11723 result = ast_strdup(iterator->name); 11724 } 11725 } 11726 } while(0) ); 11727 return result; 11728 }
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 11653 of file chan_sip.c.
References ast_mutex_lock, ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11654 { 11655 int which=0; 11656 struct sip_pvt *cur; 11657 char *c = NULL; 11658 int wordlen = strlen(word); 11659 11660 if (pos != 3) { 11661 return NULL; 11662 } 11663 11664 ast_mutex_lock(&iflock); 11665 for (cur = iflist; cur; cur = cur->next) { 11666 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11667 c = ast_strdup(cur->callid); 11668 break; 11669 } 11670 } 11671 ast_mutex_unlock(&iflock); 11672 return c; 11673 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11740 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11741 { 11742 char *c = NULL; 11743 11744 if (pos == 2) { 11745 int which = 0; 11746 char *cat = NULL; 11747 int wordlen = strlen(word); 11748 11749 /* do completion for notify type */ 11750 11751 if (!notify_types) 11752 return NULL; 11753 11754 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11755 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11756 c = ast_strdup(cat); 11757 break; 11758 } 11759 } 11760 return c; 11761 } 11762 11763 if (pos > 2) 11764 return complete_sip_peer(word, state, 0); 11765 11766 return NULL; 11767 }
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 6147 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
06148 { 06149 int start = 0; 06150 int copied = 0; 06151 for (;;) { 06152 const char *tmp = __get_header(orig, field, &start); 06153 06154 if (ast_strlen_zero(tmp)) 06155 break; 06156 /* Add what we're responding to */ 06157 add_header(req, field, tmp); 06158 copied++; 06159 } 06160 return copied ? 0 : -1; 06161 }
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 6136 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
06137 { 06138 const char *tmp = get_header(orig, field); 06139 06140 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 06141 return add_header(req, field, tmp); 06142 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 06143 return -1; 06144 }
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 7242 of file chan_sip.c.
References offset.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), queue_request(), sip_park(), and sip_park_thread().
07243 { 07244 long offset; 07245 int x; 07246 offset = ((void *)dst) - ((void *)src); 07247 /* First copy stuff */ 07248 memcpy(dst, src, sizeof(*dst)); 07249 /* Now fix pointer arithmetic */ 07250 for (x=0; x < src->headers; x++) 07251 dst->header[x] += offset; 07252 for (x=0; x < src->lines; x++) 07253 dst->line[x] += offset; 07254 dst->rlPart1 += offset; 07255 dst->rlPart2 += offset; 07256 }
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 6169 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), 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().
06170 { 06171 int copied = 0; 06172 int start = 0; 06173 06174 for (;;) { 06175 char new[512]; 06176 const char *oh = __get_header(orig, field, &start); 06177 06178 if (ast_strlen_zero(oh)) 06179 break; 06180 06181 if (!copied) { /* Only check for empty rport in topmost via header */ 06182 char leftmost[512], *others, *rport; 06183 06184 /* Only work on leftmost value */ 06185 ast_copy_string(leftmost, oh, sizeof(leftmost)); 06186 others = strchr(leftmost, ','); 06187 if (others) 06188 *others++ = '\0'; 06189 06190 /* Find ;rport; (empty request) */ 06191 rport = strstr(leftmost, ";rport"); 06192 if (rport && *(rport+6) == '=') 06193 rport = NULL; /* We already have a parameter to rport */ 06194 06195 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 06196 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 06197 /* We need to add received port - rport */ 06198 char *end; 06199 06200 rport = strstr(leftmost, ";rport"); 06201 06202 if (rport) { 06203 end = strchr(rport + 1, ';'); 06204 if (end) 06205 memmove(rport, end, strlen(end) + 1); 06206 else 06207 *rport = '\0'; 06208 } 06209 06210 /* Add rport to first VIA header if requested */ 06211 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 06212 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06213 ntohs(p->recv.sin_port), 06214 others ? "," : "", others ? others : ""); 06215 } else { 06216 /* We should *always* add a received to the topmost via */ 06217 snprintf(new, sizeof(new), "%s;received=%s%s%s", 06218 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06219 others ? "," : "", others ? others : ""); 06220 } 06221 oh = new; /* the header to copy */ 06222 } /* else add the following via headers untouched */ 06223 add_header(req, field, oh); 06224 copied++; 06225 } 06226 if (!copied) { 06227 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 06228 return -1; 06229 } 06230 return 0; 06231 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer, | |||
struct sockaddr_in * | sin | |||
) | [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 3029 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, hp, sip_pvt::portinuri, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), SIP_NAT, SIP_NAT_ROUTE, STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
03030 { 03031 struct hostent *hp; 03032 struct ast_hostent ahp; 03033 struct sip_peer *p; 03034 char *port; 03035 int portno = 0; 03036 char host[MAXHOSTNAMELEN], *hostn; 03037 char peer[256]; 03038 03039 ast_copy_string(peer, opeer, sizeof(peer)); 03040 port = strchr(peer, ':'); 03041 if (port) { 03042 *port++ = '\0'; 03043 dialog->portinuri = 1; 03044 } 03045 dialog->sa.sin_family = AF_INET; 03046 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03047 p = find_peer(peer, NULL, 1, 0); 03048 03049 if (p) { 03050 int res = create_addr_from_peer(dialog, p); 03051 if (port) { 03052 portno = atoi(port); 03053 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 03054 } 03055 ASTOBJ_UNREF(p, sip_destroy_peer); 03056 return res; 03057 } 03058 03059 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 03060 03061 ast_string_field_set(dialog, tohost, peer); 03062 03063 if (sin) { 03064 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 03065 if (!sin->sin_port) { 03066 if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { 03067 portno = STANDARD_SIP_PORT; 03068 } 03069 } else { 03070 portno = ntohs(sin->sin_port); 03071 } 03072 } else { 03073 hostn = peer; 03074 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 03075 * an A record lookup should be used instead of SRV. 03076 */ 03077 if (!port && srvlookup) { 03078 char service[MAXHOSTNAMELEN]; 03079 int tportno; 03080 int ret; 03081 03082 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 03083 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 03084 if (ret > 0) { 03085 hostn = host; 03086 portno = tportno; 03087 } 03088 } 03089 if (!portno) 03090 portno = port ? atoi(port) : STANDARD_SIP_PORT; 03091 03092 hp = ast_gethostbyname(hostn, &ahp); 03093 if (!hp) { 03094 ast_log(LOG_WARNING, "No such host: %s\n", peer); 03095 return -1; 03096 } 03097 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 03098 } 03099 dialog->sa.sin_port = htons(portno); 03100 dialog->recv = dialog->sa; 03101 return 0; 03102 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2912 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_constantssrc(), 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::auth, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, 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_peer::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::portinuri, sip_pvt::portinuri, 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_CONSTANT_SSRC, 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_pvt::tohost, 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().
02913 { 02914 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02915 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02916 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02917 dialog->recv = dialog->sa; 02918 } else 02919 return -1; 02920 02921 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02922 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02923 dialog->capability = peer->capability; 02924 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02925 ast_rtp_destroy(dialog->vrtp); 02926 dialog->vrtp = NULL; 02927 } 02928 dialog->prefs = peer->prefs; 02929 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02930 dialog->t38.capability = global_t38_capability; 02931 if (dialog->udptl) { 02932 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02933 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02934 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02935 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02936 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02937 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02938 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02939 if (option_debug > 1) 02940 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02941 } 02942 dialog->t38.jointcapability = dialog->t38.capability; 02943 } else if (dialog->udptl) { 02944 ast_udptl_destroy(dialog->udptl); 02945 dialog->udptl = NULL; 02946 } 02947 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02948 02949 if (dialog->rtp) { 02950 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02951 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02952 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02953 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02954 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02955 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 02956 ast_rtp_set_constantssrc(dialog->rtp); 02957 } 02958 /* Set Frame packetization */ 02959 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02960 dialog->autoframing = peer->autoframing; 02961 } 02962 if (dialog->vrtp) { 02963 ast_rtp_setdtmf(dialog->vrtp, 0); 02964 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02965 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02966 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02967 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02968 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 02969 ast_rtp_set_constantssrc(dialog->vrtp); 02970 } 02971 } 02972 02973 ast_string_field_set(dialog, peername, peer->name); 02974 ast_string_field_set(dialog, authname, peer->username); 02975 ast_string_field_set(dialog, username, peer->username); 02976 ast_string_field_set(dialog, peersecret, peer->secret); 02977 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02978 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02979 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02980 ast_string_field_set(dialog, tohost, peer->tohost); 02981 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02982 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02983 char *tmpcall; 02984 char *c; 02985 tmpcall = ast_strdupa(dialog->callid); 02986 c = strchr(tmpcall, '@'); 02987 if (c) { 02988 *c = '\0'; 02989 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02990 } 02991 } 02992 if (ast_strlen_zero(dialog->tohost)) 02993 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02994 if (!ast_strlen_zero(peer->fromdomain)) 02995 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02996 if (!ast_strlen_zero(peer->fromuser)) 02997 ast_string_field_set(dialog, fromuser, peer->fromuser); 02998 if (!ast_strlen_zero(peer->language)) 02999 ast_string_field_set(dialog, language, peer->language); 03000 dialog->maxtime = peer->maxms; 03001 dialog->callgroup = peer->callgroup; 03002 dialog->pickupgroup = peer->pickupgroup; 03003 dialog->peerauth = peer->auth; 03004 dialog->allowtransfer = peer->allowtransfer; 03005 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 03006 /* Minimum is settable or default to 100 ms */ 03007 if (peer->maxms && peer->lastms) 03008 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 03009 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 03010 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 03011 dialog->noncodeccapability |= AST_RTP_DTMF; 03012 else 03013 dialog->noncodeccapability &= ~AST_RTP_DTMF; 03014 dialog->jointnoncodeccapability = dialog->noncodeccapability; 03015 ast_string_field_set(dialog, context, peer->context); 03016 dialog->rtptimeout = peer->rtptimeout; 03017 if (peer->call_limit) 03018 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 03019 dialog->maxcallbitrate = peer->maxcallbitrate; 03020 if (!dialog->portinuri) 03021 dialog->portinuri = peer->portinuri; 03022 03023 return 0; 03024 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8460 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, sip_peer::name, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, and SIP_PAGE2_RTUPDATE.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08461 { 08462 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08463 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 08464 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08465 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08466 } else 08467 ast_db_del("SIP/Registry", peer->name); 08468 } 08469 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 7291 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
07292 { 07293 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07294 07295 if (!*e) 07296 return -1; 07297 req->rlPart1 = e; /* method or protocol */ 07298 e = ast_skip_nonblanks(e); 07299 if (*e) 07300 *e++ = '\0'; 07301 /* Get URI or status code */ 07302 e = ast_skip_blanks(e); 07303 if ( !*e ) 07304 return -1; 07305 ast_trim_blanks(e); 07306 07307 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07308 if (strlen(e) < 3) /* status code is 3 digits */ 07309 return -1; 07310 req->rlPart2 = e; 07311 } else { /* We have a request */ 07312 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07313 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07314 e++; 07315 if (!*e) 07316 return -1; 07317 } 07318 req->rlPart2 = e; /* URI */ 07319 e = ast_skip_nonblanks(e); 07320 if (*e) 07321 *e++ = '\0'; 07322 e = ast_skip_blanks(e); 07323 if (strcasecmp(e, "SIP/2.0") ) { 07324 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07325 return -1; 07326 } 07327 } 07328 return 1; 07329 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16904 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, iflock, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_reload_lock, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16905 { 16906 int res; 16907 struct sip_pvt *sip; 16908 struct sip_peer *peer = NULL; 16909 time_t t; 16910 int fastrestart = FALSE; 16911 int lastpeernum = -1; 16912 int curpeernum; 16913 int reloading; 16914 16915 /* Add an I/O event to our SIP UDP socket */ 16916 if (sipsock > -1) 16917 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16918 16919 /* From here on out, we die whenever asked */ 16920 for(;;) { 16921 /* Check for a reload request */ 16922 ast_mutex_lock(&sip_reload_lock); 16923 reloading = sip_reloading; 16924 sip_reloading = FALSE; 16925 ast_mutex_unlock(&sip_reload_lock); 16926 if (reloading) { 16927 if (option_verbose > 0) 16928 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16929 sip_do_reload(sip_reloadreason); 16930 16931 /* Change the I/O fd of our UDP socket */ 16932 if (sipsock > -1) { 16933 if (sipsock_read_id) 16934 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16935 else 16936 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16937 } else if (sipsock_read_id) { 16938 ast_io_remove(io, sipsock_read_id); 16939 sipsock_read_id = NULL; 16940 } 16941 } 16942 restartsearch: 16943 /* Check for interfaces needing to be killed */ 16944 ast_mutex_lock(&iflock); 16945 t = time(NULL); 16946 /* don't scan the interface list if it hasn't been a reasonable period 16947 of time since the last time we did it (when MWI is being sent, we can 16948 get back to this point every millisecond or less) 16949 */ 16950 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16951 /*! \note If we can't get a lock on an interface, skip it and come 16952 * back later. Note that there is the possibility of a deadlock with 16953 * sip_hangup otherwise, because sip_hangup is called with the channel 16954 * locked first, and the iface lock is attempted second. 16955 */ 16956 if (ast_mutex_trylock(&sip->lock)) 16957 continue; 16958 16959 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16960 if (sip->rtp && sip->owner && 16961 (sip->owner->_state == AST_STATE_UP) && 16962 !sip->redirip.sin_addr.s_addr && 16963 sip->t38.state != T38_ENABLED) { 16964 if (sip->lastrtptx && 16965 ast_rtp_get_rtpkeepalive(sip->rtp) && 16966 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16967 /* Need to send an empty RTP packet */ 16968 sip->lastrtptx = time(NULL); 16969 ast_rtp_sendcng(sip->rtp, 0); 16970 } 16971 if (sip->lastrtprx && 16972 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16973 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16974 /* Might be a timeout now -- see if we're on hold */ 16975 struct sockaddr_in sin; 16976 ast_rtp_get_peer(sip->rtp, &sin); 16977 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 16978 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16979 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16980 /* Needs a hangup */ 16981 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16982 while (sip->owner && ast_channel_trylock(sip->owner)) { 16983 DEADLOCK_AVOIDANCE(&sip->lock); 16984 } 16985 if (sip->owner) { 16986 ast_log(LOG_NOTICE, 16987 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16988 sip->owner->name, 16989 (long) (t - sip->lastrtprx)); 16990 /* Issue a softhangup */ 16991 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16992 ast_channel_unlock(sip->owner); 16993 /* forget the timeouts for this call, since a hangup 16994 has already been requested and we don't want to 16995 repeatedly request hangups 16996 */ 16997 ast_rtp_set_rtptimeout(sip->rtp, 0); 16998 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16999 if (sip->vrtp) { 17000 ast_rtp_set_rtptimeout(sip->vrtp, 0); 17001 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 17002 } 17003 } 17004 } 17005 } 17006 } 17007 } 17008 /* If we have sessions that needs to be destroyed, do it now */ 17009 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 17010 !sip->owner) { 17011 ast_mutex_unlock(&sip->lock); 17012 __sip_destroy(sip, 1); 17013 ast_mutex_unlock(&iflock); 17014 usleep(1); 17015 goto restartsearch; 17016 } 17017 ast_mutex_unlock(&sip->lock); 17018 } 17019 ast_mutex_unlock(&iflock); 17020 17021 /* XXX TODO The scheduler usage in this module does not have sufficient 17022 * synchronization being done between running the scheduler and places 17023 * scheduling tasks. As it is written, any scheduled item may not run 17024 * any sooner than about 1 second, regardless of whether a sooner time 17025 * was asked for. */ 17026 17027 pthread_testcancel(); 17028 /* Wait for sched or io */ 17029 res = ast_sched_wait(sched); 17030 if ((res < 0) || (res > 1000)) 17031 res = 1000; 17032 /* If we might need to send more mailboxes, don't wait long at all.*/ 17033 if (fastrestart) 17034 res = 1; 17035 res = ast_io_wait(io, res); 17036 if (option_debug && res > 20) 17037 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 17038 ast_mutex_lock(&monlock); 17039 res = ast_sched_runq(sched); 17040 if (option_debug && res >= 20) 17041 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 17042 17043 /* Send MWI notifications to peers - static and cached realtime peers */ 17044 t = time(NULL); 17045 fastrestart = FALSE; 17046 curpeernum = 0; 17047 peer = NULL; 17048 /* Find next peer that needs mwi */ 17049 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 17050 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 17051 fastrestart = TRUE; 17052 lastpeernum = curpeernum; 17053 peer = ASTOBJ_REF(iterator); 17054 }; 17055 curpeernum++; 17056 } while (0) 17057 ); 17058 /* Send MWI to the peer */ 17059 if (peer) { 17060 ASTOBJ_WRLOCK(peer); 17061 sip_send_mwi_to_peer(peer, FALSE); 17062 ASTOBJ_UNLOCK(peer); 17063 ASTOBJ_UNREF(peer,sip_destroy_peer); 17064 } else { 17065 /* Reset where we come from */ 17066 lastpeernum = -1; 17067 } 17068 ast_mutex_unlock(&monlock); 17069 } 17070 /* Never reached */ 17071 return NULL; 17072 17073 }
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 12250 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().
12251 { 12252 char digest[1024]; 12253 12254 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 12255 return -2; 12256 12257 p->authtries++; 12258 if (option_debug > 1) 12259 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 12260 memset(digest, 0, sizeof(digest)); 12261 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 12262 /* No way to authenticate */ 12263 return -1; 12264 } 12265 /* Now we have a reply digest */ 12266 p->options->auth = digest; 12267 p->options->authheader = respheader; 12268 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 12269 }
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 12229 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
12230 { 12231 char digest[1024]; 12232 p->authtries++; 12233 memset(digest,0,sizeof(digest)); 12234 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 12235 /* There's nothing to use for authentication */ 12236 /* No digest challenge in request */ 12237 if (sip_debug_test_pvt(p) && p->registry) 12238 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 12239 /* No old challenge */ 12240 return -1; 12241 } 12242 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 12243 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 12244 if (sip_debug_test_pvt(p) && p->registry) 12245 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 12246 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 12247 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2888 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02889 { 02890 const char *mode = natflags ? "On" : "Off"; 02891 02892 if (p->rtp) { 02893 if (option_debug) 02894 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02895 ast_rtp_setnat(p->rtp, natflags); 02896 } 02897 if (p->vrtp) { 02898 if (option_debug) 02899 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02900 ast_rtp_setnat(p->vrtp, natflags); 02901 } 02902 if (p->udptl) { 02903 if (option_debug) 02904 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02905 ast_udptl_setnat(p->udptl, natflags); 02906 } 02907 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16883 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.
16884 { 16885 time_t t = time(NULL); 16886 16887 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16888 !peer->mwipvt) { /* We don't have a subscription */ 16889 peer->lastmsgcheck = t; /* Reset timer */ 16890 return FALSE; 16891 } 16892 16893 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16894 return TRUE; 16895 16896 return FALSE; 16897 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 11071 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
11072 { 11073 switch (mode) { 11074 case SIP_DOMAIN_AUTO: 11075 return "[Automatic]"; 11076 case SIP_DOMAIN_CONFIG: 11077 return "[Configured]"; 11078 } 11079 11080 return ""; 11081 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10851 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().
10852 { 10853 switch (mode) { 10854 case SIP_DTMF_RFC2833: 10855 return "rfc2833"; 10856 case SIP_DTMF_INFO: 10857 return "info"; 10858 case SIP_DTMF_INBAND: 10859 return "inband"; 10860 case SIP_DTMF_AUTO: 10861 return "auto"; 10862 } 10863 return "<error>"; 10864 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8472 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(), sip_peer::name, peerl, sip_peer::portinuri, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
08473 { 08474 struct sip_peer *peer = (struct sip_peer *)data; 08475 08476 if (!peer) /* Hmmm. We have no peer. Weird. */ 08477 return 0; 08478 08479 memset(&peer->addr, 0, sizeof(peer->addr)); 08480 08481 destroy_association(peer); /* remove registration data from storage */ 08482 08483 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08484 register_peer_exten(peer, FALSE); /* Remove regexten */ 08485 peer->expire = -1; 08486 peer->portinuri = 0; 08487 ast_device_state_changed("SIP/%s", peer->name); 08488 08489 /* Do we need to release this peer from memory? 08490 Only for realtime peers and autocreated peers 08491 */ 08492 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08493 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08494 struct sip_peer *peer_ptr = peer_ptr; 08495 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08496 if (peer_ptr) { 08497 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08498 } 08499 } 08500 08501 ASTOBJ_UNREF(peer, sip_destroy_peer); 08502 08503 return 0; 08504 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7383 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and SIPBUFSIZE.
Referenced by handle_request(), and handle_request_invite().
07384 { 07385 char stripped[SIPBUFSIZE]; 07386 char *c; 07387 07388 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07389 c = get_in_brackets(stripped); 07390 c = strsep(&c, ";"); /* trim ; and beyond */ 07391 if (!ast_strlen_zero(c)) 07392 ast_string_field_set(p, uri, c); 07393 }
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 4462 of file chan_sip.c.
References aliases.
04463 { 04464 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04465 static const struct cfalias { 04466 char * const fullname; 04467 char * const shortname; 04468 } aliases[] = { 04469 { "Content-Type", "c" }, 04470 { "Content-Encoding", "e" }, 04471 { "From", "f" }, 04472 { "Call-ID", "i" }, 04473 { "Contact", "m" }, 04474 { "Content-Length", "l" }, 04475 { "Subject", "s" }, 04476 { "To", "t" }, 04477 { "Supported", "k" }, 04478 { "Refer-To", "r" }, 04479 { "Referred-By", "b" }, 04480 { "Allow-Events", "u" }, 04481 { "Event", "o" }, 04482 { "Via", "v" }, 04483 { "Accept-Contact", "a" }, 04484 { "Reject-Contact", "j" }, 04485 { "Request-Disposition", "d" }, 04486 { "Session-Expires", "x" }, 04487 { "Identity", "y" }, 04488 { "Identity-Info", "n" }, 04489 }; 04490 int x; 04491 04492 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04493 if (!strcasecmp(aliases[x].fullname, name)) 04494 return aliases[x].shortname; 04495 04496 return _default; 04497 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4835 of file chan_sip.c.
References ast_log(), ast_mutex_lock, ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, FALSE, sip_pvt::flags, sip_pvt::from, get_header(), gettag(), iflist, iflock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by sipsock_read().
04836 { 04837 struct sip_pvt *p = NULL; 04838 char *tag = ""; /* note, tag is never NULL */ 04839 char totag[128]; 04840 char fromtag[128]; 04841 const char *callid = get_header(req, "Call-ID"); 04842 const char *from = get_header(req, "From"); 04843 const char *to = get_header(req, "To"); 04844 const char *cseq = get_header(req, "Cseq"); 04845 04846 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04847 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04848 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04849 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04850 return NULL; /* Invalid packet */ 04851 04852 if (pedanticsipchecking) { 04853 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04854 we need more to identify a branch - so we have to check branch, from 04855 and to tags to identify a call leg. 04856 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04857 in sip.conf 04858 */ 04859 if (gettag(req, "To", totag, sizeof(totag))) 04860 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04861 gettag(req, "From", fromtag, sizeof(fromtag)); 04862 04863 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04864 04865 if (option_debug > 4 ) 04866 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); 04867 } 04868 04869 ast_mutex_lock(&iflock); 04870 for (p = iflist; p; p = p->next) { 04871 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04872 int found = FALSE; 04873 if (ast_strlen_zero(p->callid)) 04874 continue; 04875 if (req->method == SIP_REGISTER) 04876 found = (!strcmp(p->callid, callid)); 04877 else { 04878 found = !strcmp(p->callid, callid); 04879 if (pedanticsipchecking && found) { 04880 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04881 } 04882 } 04883 04884 if (option_debug > 4) 04885 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); 04886 04887 /* If we get a new request within an existing to-tag - check the to tag as well */ 04888 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04889 if (p->tag[0] == '\0' && totag[0]) { 04890 /* We have no to tag, but they have. Wrong dialog */ 04891 found = FALSE; 04892 } else if (totag[0]) { /* Both have tags, compare them */ 04893 if (strcmp(totag, p->tag)) { 04894 found = FALSE; /* This is not our packet */ 04895 } 04896 } 04897 if (!found && option_debug > 4) 04898 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); 04899 } 04900 if (found) { 04901 /* Found the call */ 04902 ast_mutex_lock(&p->lock); 04903 ast_mutex_unlock(&iflock); 04904 return p; 04905 } 04906 } 04907 ast_mutex_unlock(&iflock); 04908 04909 /* See if the method is capable of creating a dialog */ 04910 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04911 if (intended_method == SIP_REFER) { 04912 /* We do support REFER, but not outside of a dialog yet */ 04913 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04914 } else if (intended_method == SIP_NOTIFY) { 04915 /* We do not support out-of-dialog NOTIFY either, 04916 like voicemail notification, so cancel that early */ 04917 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04918 } else { 04919 /* Ok, time to create a new SIP dialog object, a pvt */ 04920 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04921 /* Ok, we've created a dialog, let's go and process it */ 04922 ast_mutex_lock(&p->lock); 04923 } else { 04924 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04925 getting a dialog from sip_alloc. 04926 04927 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04928 send an error message. 04929 04930 Sorry, we apologize for the inconvienience 04931 */ 04932 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04933 if (option_debug > 3) 04934 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04935 } 04936 } 04937 return p; 04938 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04939 /* A method we do not support, let's take it on the volley */ 04940 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04941 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04942 /* This is a request outside of a dialog that we don't know about 04943 ...never reply to an ACK! 04944 */ 04945 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04946 } 04947 /* We do not respond to responses for dialogs that we don't know about, we just drop 04948 the session quickly */ 04949 04950 return p; 04951 }
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 2438 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02439 { 02440 char last_char = '\0'; 02441 const char *s; 02442 for (s = start; *s && s != lim; last_char = *s++) { 02443 if (*s == '"' && last_char != '\\') 02444 break; 02445 } 02446 return s; 02447 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2800 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02801 { 02802 struct sip_peer *p = NULL; 02803 02804 if (peer) 02805 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02806 else 02807 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02808 02809 if (!p && (realtime || devstate_only)) 02810 p = realtime_peer(peer, sin, devstate_only); 02811 02812 return p; 02813 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17716 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17717 { 17718 struct sip_auth *a; 17719 17720 for (a = authlist; a; a = a->next) { 17721 if (!strcasecmp(a->realm, realm)) 17722 break; 17723 } 17724 17725 return a; 17726 }
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 5171 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_count, sip_request::sdp_start, and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
05172 { 05173 const char *content_type; 05174 const char *content_length; 05175 const char *search; 05176 char *boundary; 05177 unsigned int x; 05178 int boundaryisquoted = FALSE; 05179 int found_application_sdp = FALSE; 05180 int found_end_of_headers = FALSE; 05181 05182 content_length = get_header(req, "Content-Length"); 05183 05184 if (!ast_strlen_zero(content_length)) { 05185 if (sscanf(content_length, "%30u", &x) != 1) { 05186 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05187 return 0; 05188 } 05189 05190 /* Content-Length of zero means there can't possibly be an 05191 SDP here, even if the Content-Type says there is */ 05192 if (x == 0) 05193 return 0; 05194 } 05195 05196 content_type = get_header(req, "Content-Type"); 05197 05198 /* if the body contains only SDP, this is easy */ 05199 if (!strncasecmp(content_type, "application/sdp", 15)) { 05200 req->sdp_start = 0; 05201 req->sdp_count = req->lines; 05202 return req->lines ? 1 : 0; 05203 } 05204 05205 /* if it's not multipart/mixed, there cannot be an SDP */ 05206 if (strncasecmp(content_type, "multipart/mixed", 15)) 05207 return 0; 05208 05209 /* if there is no boundary marker, it's invalid */ 05210 if ((search = strcasestr(content_type, ";boundary="))) 05211 search += 10; 05212 else if ((search = strcasestr(content_type, "; boundary="))) 05213 search += 11; 05214 else 05215 return 0; 05216 05217 if (ast_strlen_zero(search)) 05218 return 0; 05219 05220 /* If the boundary is quoted with ", remove quote */ 05221 if (*search == '\"') { 05222 search++; 05223 boundaryisquoted = TRUE; 05224 } 05225 05226 /* make a duplicate of the string, with two extra characters 05227 at the beginning */ 05228 boundary = ast_strdupa(search - 2); 05229 boundary[0] = boundary[1] = '-'; 05230 /* Remove final quote */ 05231 if (boundaryisquoted) 05232 boundary[strlen(boundary) - 1] = '\0'; 05233 05234 /* search for the boundary marker, the empty line delimiting headers from 05235 sdp part and the end boundry if it exists */ 05236 05237 for (x = 0; x < (req->lines ); x++) { 05238 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05239 if(found_application_sdp && found_end_of_headers){ 05240 req->sdp_count = (x - 1) - req->sdp_start; 05241 return 1; 05242 } 05243 found_application_sdp = FALSE; 05244 } 05245 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05246 found_application_sdp = TRUE; 05247 05248 if(strlen(req->line[x]) == 0 ){ 05249 if(found_application_sdp && !found_end_of_headers){ 05250 req->sdp_start = x; 05251 found_end_of_headers = TRUE; 05252 } 05253 } 05254 } 05255 if(found_application_sdp && found_end_of_headers) { 05256 req->sdp_count = x - req->sdp_start; 05257 return TRUE; 05258 } 05259 return FALSE; 05260 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1740 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), sip_hangup(), and sipsock_read().
01741 { 01742 int i, res = 0; 01743 01744 if (ast_strlen_zero(msg)) 01745 return 0; 01746 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01747 if (method_match(i, msg)) 01748 res = sip_methods[i].id; 01749 } 01750 return res; 01751 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11560 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11561 { 11562 int i; 11563 11564 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11565 if (subscription_types[i].type == subtype) { 11566 return &subscription_types[i]; 11567 } 11568 } 11569 return &subscription_types[0]; 11570 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2879 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02880 { 02881 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02882 if (!u && realtime) 02883 u = realtime_user(name); 02884 return u; 02885 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8856 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08857 { 08858 struct sip_route *next; 08859 08860 while (route) { 08861 next = route->next; 08862 free(route); 08863 route = next; 08864 } 08865 }
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 12586 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12587 { 12588 if (ast_strlen_zero(data)) { 12589 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12590 return -1; 12591 } 12592 if (check_sip_domain(data, NULL, 0)) 12593 ast_copy_string(buf, data, len); 12594 else 12595 buf[0] = '\0'; 12596 return 0; 12597 }
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 12522 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
12523 { 12524 struct sip_pvt *p; 12525 const char *content = NULL; 12526 AST_DECLARE_APP_ARGS(args, 12527 AST_APP_ARG(header); 12528 AST_APP_ARG(number); 12529 ); 12530 int i, number, start = 0; 12531 12532 if (ast_strlen_zero(data)) { 12533 ast_log(LOG_WARNING, "This function requires a header name.\n"); 12534 return -1; 12535 } 12536 12537 ast_channel_lock(chan); 12538 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12539 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12540 ast_channel_unlock(chan); 12541 return -1; 12542 } 12543 12544 AST_STANDARD_APP_ARGS(args, data); 12545 if (!args.number) { 12546 number = 1; 12547 } else { 12548 sscanf(args.number, "%30d", &number); 12549 if (number < 1) 12550 number = 1; 12551 } 12552 12553 p = chan->tech_pvt; 12554 12555 /* If there is no private structure, this channel is no longer alive */ 12556 if (!p) { 12557 ast_channel_unlock(chan); 12558 return -1; 12559 } 12560 12561 for (i = 0; i < number; i++) 12562 content = __get_header(&p->initreq, args.header, &start); 12563 12564 if (ast_strlen_zero(content)) { 12565 ast_channel_unlock(chan); 12566 return -1; 12567 } 12568 12569 ast_copy_string(buf, content, len); 12570 ast_channel_unlock(chan); 12571 12572 return 0; 12573 }
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 12705 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), sip_pvt::from, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::uri, and sip_pvt::useragent.
12706 { 12707 struct sip_pvt *p; 12708 12709 *buf = 0; 12710 12711 if (!data) { 12712 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12713 return -1; 12714 } 12715 12716 ast_channel_lock(chan); 12717 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12718 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12719 ast_channel_unlock(chan); 12720 return -1; 12721 } 12722 12723 p = chan->tech_pvt; 12724 12725 /* If there is no private structure, this channel is no longer alive */ 12726 if (!p) { 12727 ast_channel_unlock(chan); 12728 return -1; 12729 } 12730 12731 if (!strcasecmp(data, "peerip")) { 12732 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12733 } else if (!strcasecmp(data, "recvip")) { 12734 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12735 } else if (!strcasecmp(data, "from")) { 12736 ast_copy_string(buf, p->from, len); 12737 } else if (!strcasecmp(data, "uri")) { 12738 ast_copy_string(buf, p->uri, len); 12739 } else if (!strcasecmp(data, "useragent")) { 12740 ast_copy_string(buf, p->useragent, len); 12741 } else if (!strcasecmp(data, "peername")) { 12742 ast_copy_string(buf, p->peername, len); 12743 } else if (!strcasecmp(data, "t38passthrough")) { 12744 if (p->t38.state == T38_DISABLED) 12745 ast_copy_string(buf, "0", sizeof("0")); 12746 else /* T38 is offered or enabled in this call */ 12747 ast_copy_string(buf, "1", sizeof("1")); 12748 } else { 12749 ast_channel_unlock(chan); 12750 return -1; 12751 } 12752 ast_channel_unlock(chan); 12753 12754 return 0; 12755 }
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 12611 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_copy_string(), 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, and sip_peer::useragent.
12612 { 12613 struct sip_peer *peer; 12614 char *colname; 12615 12616 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12617 *colname++ = '\0'; 12618 else if ((colname = strchr(data, '|'))) 12619 *colname++ = '\0'; 12620 else 12621 colname = "ip"; 12622 12623 if (!(peer = find_peer(data, NULL, 1, 0))) 12624 return -1; 12625 12626 if (!strcasecmp(colname, "ip")) { 12627 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12628 } else if (!strcasecmp(colname, "status")) { 12629 peer_status(peer, buf, len); 12630 } else if (!strcasecmp(colname, "language")) { 12631 ast_copy_string(buf, peer->language, len); 12632 } else if (!strcasecmp(colname, "regexten")) { 12633 ast_copy_string(buf, peer->regexten, len); 12634 } else if (!strcasecmp(colname, "limit")) { 12635 snprintf(buf, len, "%d", peer->call_limit); 12636 } else if (!strcasecmp(colname, "curcalls")) { 12637 snprintf(buf, len, "%d", peer->inUse); 12638 } else if (!strcasecmp(colname, "accountcode")) { 12639 ast_copy_string(buf, peer->accountcode, len); 12640 } else if (!strcasecmp(colname, "useragent")) { 12641 ast_copy_string(buf, peer->useragent, len); 12642 } else if (!strcasecmp(colname, "mailbox")) { 12643 ast_copy_string(buf, peer->mailbox, len); 12644 } else if (!strcasecmp(colname, "context")) { 12645 ast_copy_string(buf, peer->context, len); 12646 } else if (!strcasecmp(colname, "expire")) { 12647 snprintf(buf, len, "%d", peer->expire); 12648 } else if (!strcasecmp(colname, "dynamic")) { 12649 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12650 } else if (!strcasecmp(colname, "callerid_name")) { 12651 ast_copy_string(buf, peer->cid_name, len); 12652 } else if (!strcasecmp(colname, "callerid_num")) { 12653 ast_copy_string(buf, peer->cid_num, len); 12654 } else if (!strcasecmp(colname, "codecs")) { 12655 ast_getformatname_multiple(buf, len -1, peer->capability); 12656 } else if (!strncasecmp(colname, "codec[", 6)) { 12657 char *codecnum; 12658 int index = 0, codec = 0; 12659 12660 codecnum = colname + 6; /* move past the '[' */ 12661 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12662 index = atoi(codecnum); 12663 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12664 ast_copy_string(buf, ast_getformatname(codec), len); 12665 } else { 12666 buf[0] = '\0'; 12667 } 12668 } else { 12669 buf[0] = '\0'; 12670 } 12671 12672 ASTOBJ_UNREF(peer, sip_destroy_peer); 12673 12674 return 0; 12675 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4654 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04655 { 04656 long val[4]; 04657 int x; 04658 04659 for (x=0; x<4; x++) 04660 val[x] = ast_random(); 04661 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04662 04663 return buf; 04664 }
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 9917 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
09918 { 09919 char tmp[256] = "", *c, *a; 09920 struct sip_request *req = oreq ? oreq : &p->initreq; 09921 struct sip_refer *referdata = NULL; 09922 const char *transfer_context = NULL; 09923 09924 if (!p->refer && !sip_refer_allocate(p)) 09925 return -1; 09926 09927 referdata = p->refer; 09928 09929 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09930 c = get_in_brackets(tmp); 09931 09932 if (pedanticsipchecking) 09933 ast_uri_decode(c); 09934 09935 if (strncasecmp(c, "sip:", 4)) { 09936 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09937 return -1; 09938 } 09939 c += 4; 09940 if ((a = strchr(c, ';'))) /* Remove arguments */ 09941 *a = '\0'; 09942 09943 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09944 *a++ = '\0'; 09945 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09946 } 09947 09948 if (sip_debug_test_pvt(p)) 09949 ast_verbose("Looking for %s in %s\n", c, p->context); 09950 09951 if (p->owner) /* Mimic behaviour in res_features.c */ 09952 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09953 09954 /* By default, use the context in the channel sending the REFER */ 09955 if (ast_strlen_zero(transfer_context)) { 09956 transfer_context = S_OR(p->owner->macrocontext, 09957 S_OR(p->context, default_context)); 09958 } 09959 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09960 /* This is a blind transfer */ 09961 if (option_debug) 09962 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09963 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09964 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09965 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09966 referdata->refer_call = NULL; 09967 /* Set new context */ 09968 ast_string_field_set(p, context, transfer_context); 09969 return 0; 09970 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09971 return 1; 09972 } 09973 09974 return -1; 09975 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4446 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04447 { 04448 int x; 04449 int len = strlen(name); 04450 char *r; 04451 04452 for (x = 0; x < req->lines; x++) { 04453 r = get_body_by_line(req->line[x], name, len); 04454 if (r[0] != '\0') 04455 return r; 04456 } 04457 04458 return ""; 04459 }
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 4391 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04392 { 04393 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04394 return ast_skip_blanks(line + nameLen + 1); 04395 04396 return ""; 04397 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 10029 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
10030 { 10031 const char *end = strchr(input,'<'); /* first_bracket */ 10032 const char *tmp = strchr(input,'"'); /* first quote */ 10033 int bytes = 0; 10034 int maxbytes = outputsize - 1; 10035 10036 if (!end || end == input) /* we require a part in brackets */ 10037 return NULL; 10038 10039 end--; /* move just before "<" */ 10040 10041 if (tmp && tmp <= end) { 10042 /* The quote (tmp) precedes the bracket (end+1). 10043 * Find the matching quote and return the content. 10044 */ 10045 end = strchr(tmp+1, '"'); 10046 if (!end) 10047 return NULL; 10048 bytes = (int) (end - tmp); 10049 /* protect the output buffer */ 10050 if (bytes > maxbytes) 10051 bytes = maxbytes; 10052 ast_copy_string(output, tmp + 1, bytes); 10053 } else { 10054 /* No quoted string, or it is inside brackets. */ 10055 /* clear the empty characters in the begining*/ 10056 input = ast_skip_blanks(input); 10057 /* clear the empty characters in the end */ 10058 while(*end && *end < 33 && end > input) 10059 end--; 10060 if (end >= input) { 10061 bytes = (int) (end - input) + 2; 10062 /* protect the output buffer */ 10063 if (bytes > maxbytes) 10064 bytes = maxbytes; 10065 ast_copy_string(output, input, bytes); 10066 } else 10067 return NULL; 10068 } 10069 return output; 10070 }
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 9560 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), 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(), sip_pvt::cid_num, sip_pvt::context, context, sip_pvt::domain, exten, sip_pvt::exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, and sip_pvt::subscribecontext.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
09561 { 09562 char tmp[256] = "", *uri, *a; 09563 char tmpf[256] = "", *from; 09564 struct sip_request *req; 09565 char *colon; 09566 char *decoded_uri; 09567 09568 req = oreq; 09569 if (!req) 09570 req = &p->initreq; 09571 09572 /* Find the request URI */ 09573 if (req->rlPart2) 09574 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09575 09576 if (pedanticsipchecking) 09577 ast_uri_decode(tmp); 09578 09579 uri = get_in_brackets(tmp); 09580 09581 if (strncasecmp(uri, "sip:", 4)) { 09582 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09583 return -1; 09584 } 09585 uri += 4; 09586 09587 /* Now find the From: caller ID and name */ 09588 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09589 if (!ast_strlen_zero(tmpf)) { 09590 if (pedanticsipchecking) 09591 ast_uri_decode(tmpf); 09592 from = get_in_brackets(tmpf); 09593 } else { 09594 from = NULL; 09595 } 09596 09597 if (!ast_strlen_zero(from)) { 09598 if (strncasecmp(from, "sip:", 4)) { 09599 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09600 return -1; 09601 } 09602 from += 4; 09603 if ((a = strchr(from, '@'))) 09604 *a++ = '\0'; 09605 else 09606 a = from; /* just a domain */ 09607 from = strsep(&from, ";"); /* Remove userinfo options */ 09608 a = strsep(&a, ";"); /* Remove URI options */ 09609 ast_string_field_set(p, fromdomain, a); 09610 } 09611 09612 /* Skip any options and find the domain */ 09613 09614 /* Get the target domain */ 09615 if ((a = strchr(uri, '@'))) { 09616 *a++ = '\0'; 09617 } else { /* No username part */ 09618 a = uri; 09619 uri = "s"; /* Set extension to "s" */ 09620 } 09621 colon = strchr(a, ':'); /* Remove :port */ 09622 if (colon) 09623 *colon = '\0'; 09624 09625 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09626 a = strsep(&a, ";"); /* Remove URI options */ 09627 09628 ast_string_field_set(p, domain, a); 09629 09630 if (!AST_LIST_EMPTY(&domain_list)) { 09631 char domain_context[AST_MAX_EXTENSION]; 09632 09633 domain_context[0] = '\0'; 09634 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09635 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09636 if (option_debug) 09637 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09638 return -2; 09639 } 09640 } 09641 /* If we have a context defined, overwrite the original context */ 09642 if (!ast_strlen_zero(domain_context)) 09643 ast_string_field_set(p, context, domain_context); 09644 } 09645 09646 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09647 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09648 ast_string_field_set(p, context, p->subscribecontext); 09649 09650 if (sip_debug_test_pvt(p)) 09651 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09652 09653 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09654 if (req->method == SIP_SUBSCRIBE) { 09655 char hint[AST_MAX_EXTENSION]; 09656 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09657 } else { 09658 decoded_uri = ast_strdupa(uri); 09659 ast_uri_decode(decoded_uri); 09660 /* Check the dialplan for the username part of the request URI, 09661 the domain will be stored in the SIPDOMAIN variable 09662 Since extensions.conf can have unescaped characters, try matching a decoded 09663 uri in addition to the non-decoded uri 09664 Return 0 if we have a matching extension */ 09665 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)) || 09666 !strcmp(decoded_uri, ast_pickup_ext())) { 09667 if (!oreq) 09668 ast_string_field_set(p, exten, decoded_uri); 09669 return 0; 09670 } 09671 } 09672 09673 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09674 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09675 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09676 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09677 return 1; 09678 } 09679 09680 return -1; 09681 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4535 of file chan_sip.c.
References __get_header().
04536 { 04537 int start = 0; 04538 return __get_header(req, name, &start); 04539 }
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 2460 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().
02461 { 02462 const char *parse = tmp; 02463 char *first_bracket; 02464 02465 /* 02466 * Skip any quoted text until we find the part in brackets. 02467 * On any error give up and return the full string. 02468 */ 02469 while ( (first_bracket = strchr(parse, '<')) ) { 02470 char *first_quote = strchr(parse, '"'); 02471 02472 if (!first_quote || first_quote > first_bracket) 02473 break; /* no need to look at quoted part */ 02474 /* the bracket is within quotes, so ignore it */ 02475 parse = find_closing_quote(first_quote + 1, NULL); 02476 if (!*parse) { /* not found, return full string ? */ 02477 /* XXX or be robust and return in-bracket part ? */ 02478 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02479 break; 02480 } 02481 parse++; 02482 } 02483 if (first_bracket) { 02484 char *second_bracket = strchr(first_bracket + 1, '>'); 02485 if (second_bracket) { 02486 *second_bracket = '\0'; 02487 tmp = first_bracket + 1; 02488 } else { 02489 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02490 } 02491 } 02492 return tmp; 02493 }
static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
const enum media_type | media, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 5295 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, len(), SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.
Referenced by handle_request_invite().
05296 { 05297 const char *m; 05298 const char *c; 05299 int miterator = req->sdp_start; 05300 int citerator = req->sdp_start; 05301 int x = 0; 05302 int numberofports; 05303 int len; 05304 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 05305 struct ast_hostent audiohp; 05306 struct hostent *hp; 05307 05308 c = get_sdp_iterate(&citerator, req, "c"); 05309 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05310 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05311 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 05312 } 05313 /* We only want the m and c lines for audio */ 05314 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 05315 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05316 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 05317 (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05318 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 05319 /* See if there's a c= line for this media stream. 05320 * XXX There is no guarantee that we'll be grabbing the c= line for this 05321 * particular media stream here. However, this is the same logic used in process_sdp. 05322 */ 05323 c = get_sdp_iterate(&citerator, req, "c"); 05324 if (!ast_strlen_zero(c)) { 05325 sscanf(c, "IN IP4 %256s", host); 05326 } 05327 break; 05328 } 05329 } 05330 05331 if (ast_strlen_zero(host) || x == 0) { 05332 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 05333 return -1; 05334 } 05335 05336 hp = ast_gethostbyname(host, &audiohp); 05337 if (!hp) { 05338 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 05339 return -1; 05340 } 05341 05342 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 05343 sin->sin_port = htons(x); 05344 return 0; 05345 }
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 10444 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
10445 { 10446 int x; 10447 int y; 10448 10449 buf[0] = '\0'; 10450 y = len - strlen(buf) - 5; 10451 if (y < 0) 10452 y = 0; 10453 for (x=0;x<req->lines;x++) { 10454 strncat(buf, req->line[x], y); /* safe */ 10455 y -= strlen(req->line[x]) + 1; 10456 if (y < 0) 10457 y = 0; 10458 if (y != 0) 10459 strcat(buf, "\n"); /* safe */ 10460 } 10461 return 0; 10462 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 9531 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, and sip_debug_test_pvt().
Referenced by handle_request_invite().
09532 { 09533 char tmp[256], *c, *a; 09534 struct sip_request *req; 09535 09536 req = oreq; 09537 if (!req) 09538 req = &p->initreq; 09539 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09540 if (ast_strlen_zero(tmp)) 09541 return 0; 09542 c = get_in_brackets(tmp); 09543 if (strncasecmp(c, "sip:", 4)) { 09544 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09545 return -1; 09546 } 09547 c += 4; 09548 a = c; 09549 strsep(&a, "@;"); /* trim anything after @ or ; */ 09550 if (sip_debug_test_pvt(p)) 09551 ast_verbose("RDNIS is %s\n", c); 09552 ast_string_field_set(p, rdnis, c); 09553 09554 return 0; 09555 }
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 9754 of file chan_sip.c.
References ast_copy_string(), ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_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, and sip_debug_test_pvt().
Referenced by handle_request_refer().
09755 { 09756 09757 const char *p_referred_by = NULL; 09758 char *h_refer_to = NULL; 09759 char *h_referred_by = NULL; 09760 char *refer_to; 09761 const char *p_refer_to; 09762 char *referred_by_uri = NULL; 09763 char *ptr; 09764 struct sip_request *req = NULL; 09765 const char *transfer_context = NULL; 09766 struct sip_refer *referdata; 09767 09768 09769 req = outgoing_req; 09770 referdata = transferer->refer; 09771 09772 if (!req) 09773 req = &transferer->initreq; 09774 09775 p_refer_to = get_header(req, "Refer-To"); 09776 if (ast_strlen_zero(p_refer_to)) { 09777 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09778 return -2; /* Syntax error */ 09779 } 09780 h_refer_to = ast_strdupa(p_refer_to); 09781 refer_to = get_in_brackets(h_refer_to); 09782 if (pedanticsipchecking) 09783 ast_uri_decode(refer_to); 09784 09785 if (strncasecmp(refer_to, "sip:", 4)) { 09786 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09787 return -3; 09788 } 09789 refer_to += 4; /* Skip sip: */ 09790 09791 /* Get referred by header if it exists */ 09792 p_referred_by = get_header(req, "Referred-By"); 09793 if (!ast_strlen_zero(p_referred_by)) { 09794 char *lessthan; 09795 h_referred_by = ast_strdupa(p_referred_by); 09796 if (pedanticsipchecking) 09797 ast_uri_decode(h_referred_by); 09798 09799 /* Store referrer's caller ID name */ 09800 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09801 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09802 *(lessthan - 1) = '\0'; /* Space */ 09803 } 09804 09805 referred_by_uri = get_in_brackets(h_referred_by); 09806 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09807 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09808 referred_by_uri = (char *) NULL; 09809 } else { 09810 referred_by_uri += 4; /* Skip sip: */ 09811 } 09812 } 09813 09814 /* Check for arguments in the refer_to header */ 09815 if ((ptr = strcasestr(refer_to, "replaces="))) { 09816 char *to = NULL, *from = NULL; 09817 09818 /* This is an attended transfer */ 09819 referdata->attendedtransfer = 1; 09820 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09821 ast_uri_decode(referdata->replaces_callid); 09822 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09823 *ptr++ = '\0'; 09824 } 09825 09826 if (ptr) { 09827 /* Find the different tags before we destroy the string */ 09828 to = strcasestr(ptr, "to-tag="); 09829 from = strcasestr(ptr, "from-tag="); 09830 } 09831 09832 /* Grab the to header */ 09833 if (to) { 09834 ptr = to + 7; 09835 if ((to = strchr(ptr, '&'))) 09836 *to = '\0'; 09837 if ((to = strchr(ptr, ';'))) 09838 *to = '\0'; 09839 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09840 } 09841 09842 if (from) { 09843 ptr = from + 9; 09844 if ((to = strchr(ptr, '&'))) 09845 *to = '\0'; 09846 if ((to = strchr(ptr, ';'))) 09847 *to = '\0'; 09848 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09849 } 09850 09851 if (option_debug > 1) { 09852 if (!pedanticsipchecking) 09853 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09854 else 09855 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>" ); 09856 } 09857 } 09858 09859 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09860 char *urioption = NULL, *domain; 09861 *ptr++ = '\0'; 09862 09863 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09864 *urioption++ = '\0'; 09865 09866 domain = ptr; 09867 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09868 *ptr = '\0'; 09869 09870 /* Save the domain for the dial plan */ 09871 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09872 if (urioption) 09873 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09874 } 09875 09876 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09877 *ptr = '\0'; 09878 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09879 09880 if (referred_by_uri) { 09881 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09882 *ptr = '\0'; 09883 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09884 } else { 09885 referdata->referred_by[0] = '\0'; 09886 } 09887 09888 /* Determine transfer context */ 09889 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09890 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09891 09892 /* By default, use the context in the channel sending the REFER */ 09893 if (ast_strlen_zero(transfer_context)) { 09894 transfer_context = S_OR(transferer->owner->macrocontext, 09895 S_OR(transferer->context, default_context)); 09896 } 09897 09898 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09899 09900 /* Either an existing extension or the parking extension */ 09901 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09902 if (sip_debug_test_pvt(transferer)) { 09903 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09904 } 09905 /* We are ready to transfer to the extension */ 09906 return 0; 09907 } 09908 if (sip_debug_test_pvt(transferer)) 09909 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09910 09911 /* Failure, we can't find this extension */ 09912 return -1; 09913 }
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 10076 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
10077 { 10078 char *start; 10079 char *end; 10080 10081 start = strchr(input,':'); 10082 if (!start) { 10083 output[0] = '\0'; 10084 return 0; 10085 } 10086 start++; 10087 10088 /* we found "number" */ 10089 ast_copy_string(output,start,maxlen); 10090 output[maxlen-1] = '\0'; 10091 10092 end = strchr(output,'@'); 10093 if (end) 10094 *end = '\0'; 10095 else 10096 output[0] = '\0'; 10097 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 10098 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 10099 10100 return 0; 10101 }
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 4403 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, sip_request::sdp_count, and sip_request::sdp_start.
04404 { 04405 int len = strlen(name); 04406 04407 while (*start < (req->sdp_start + req->sdp_count)) { 04408 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04409 if (r[0] != '\0') 04410 return r; 04411 } 04412 04413 /* if the line was not found, ensure that *start points past the SDP */ 04414 (*start)++; 04415 04416 return ""; 04417 }
static char get_sdp_line | ( | int * | start, | |
int | stop, | |||
struct sip_request * | req, | |||
const char ** | value | |||
) | [static] |
Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
Definition at line 4424 of file chan_sip.c.
References ast_skip_blanks(), sip_request::line, sip_request::sdp_count, sip_request::sdp_start, and type.
Referenced by process_sdp().
04425 { 04426 char type = '\0'; 04427 const char *line = NULL; 04428 04429 if (stop > (req->sdp_start + req->sdp_count)) { 04430 stop = req->sdp_start + req->sdp_count; 04431 } 04432 04433 while (*start < stop) { 04434 line = req->line[(*start)++]; 04435 if (line[1] == '=') { 04436 type = line[0]; 04437 *value = ast_skip_blanks(line + 2); 04438 break; 04439 } 04440 } 04441 04442 return type; 04443 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static] |
Lock interface lock and find matching pvt lock.
Definition at line 9685 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::callid, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, iflock, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_PAGE2_OUTGOING_CALL, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_invite(), and local_attended_transfer().
09686 { 09687 struct sip_pvt *sip_pvt_ptr; 09688 09689 ast_mutex_lock(&iflock); 09690 09691 if (option_debug > 3 && totag) { 09692 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09693 } 09694 09695 /* Search interfaces and find the match */ 09696 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09697 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09698 int match = 1; 09699 09700 if (option_debug > 3) 09701 ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag); 09702 09703 /* Go ahead and lock it (and its owner) before returning */ 09704 ast_mutex_lock(&sip_pvt_ptr->lock); 09705 09706 /* Check if tags match. If not, this is not the call we want 09707 * (With a forking SIP proxy, several call legs share the 09708 * call id, but have different tags) 09709 */ 09710 if (pedanticsipchecking) { 09711 /* RFC 3891 09712 * > 3. User Agent Server Behavior: Receiving a Replaces Header 09713 * > The Replaces header contains information used to match an existing 09714 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 09715 * > with a Replaces header, the User Agent (UA) attempts to match this 09716 * > information with a confirmed or early dialog. The User Agent Server 09717 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 09718 * > present in an incoming request. In other words, the to-tag parameter 09719 * > is compared to the local tag, and the from-tag parameter is compared 09720 * > to the remote tag. 09721 * 09722 * Thus, the totag is always compared to the local tag, regardless if 09723 * this our call is an incoming or outgoing call. 09724 */ 09725 if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag))) 09726 match = 0; 09727 } 09728 09729 if (!match) { 09730 ast_mutex_unlock(&sip_pvt_ptr->lock); 09731 continue; 09732 } 09733 09734 if (option_debug > 3 && totag) 09735 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09736 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09737 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09738 09739 /* deadlock avoidance... */ 09740 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09741 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09742 } 09743 break; 09744 } 09745 } 09746 ast_mutex_unlock(&iflock); 09747 if (option_debug > 3 && !sip_pvt_ptr) 09748 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09749 return sip_pvt_ptr; 09750 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 14174 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
14175 { 14176 const char *thetag; 14177 14178 if (!tagbuf) 14179 return NULL; 14180 tagbuf[0] = '\0'; /* reset the buffer */ 14181 thetag = get_header(req, header); 14182 thetag = strcasestr(thetag, ";tag="); 14183 if (thetag) { 14184 thetag += 5; 14185 ast_copy_string(tagbuf, thetag, tagbufsize); 14186 return strsep(&tagbuf, ";"); 14187 } 14188 return NULL; 14189 }
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 17464 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, ast_variable::name, ast_channel::next, 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_CONSTANT_SSRC, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_UDPTL_DESTINATION, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, and ast_variable::value.
Referenced by build_peer(), and build_user().
17465 { 17466 int res = 1; 17467 17468 if (!strcasecmp(v->name, "trustrpid")) { 17469 ast_set_flag(&mask[0], SIP_TRUSTRPID); 17470 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 17471 } else if (!strcasecmp(v->name, "sendrpid")) { 17472 ast_set_flag(&mask[0], SIP_SENDRPID); 17473 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 17474 } else if (!strcasecmp(v->name, "g726nonstandard")) { 17475 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 17476 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 17477 } else if (!strcasecmp(v->name, "useclientcode")) { 17478 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 17479 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 17480 } else if (!strcasecmp(v->name, "dtmfmode")) { 17481 ast_set_flag(&mask[0], SIP_DTMF); 17482 ast_clear_flag(&flags[0], SIP_DTMF); 17483 if (!strcasecmp(v->value, "inband")) 17484 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 17485 else if (!strcasecmp(v->value, "rfc2833")) 17486 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17487 else if (!strcasecmp(v->value, "info")) 17488 ast_set_flag(&flags[0], SIP_DTMF_INFO); 17489 else if (!strcasecmp(v->value, "auto")) 17490 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 17491 else { 17492 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 17493 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17494 } 17495 } else if (!strcasecmp(v->name, "nat")) { 17496 ast_set_flag(&mask[0], SIP_NAT); 17497 ast_clear_flag(&flags[0], SIP_NAT); 17498 if (!strcasecmp(v->value, "never")) 17499 ast_set_flag(&flags[0], SIP_NAT_NEVER); 17500 else if (!strcasecmp(v->value, "route")) 17501 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 17502 else if (ast_true(v->value)) 17503 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 17504 else 17505 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 17506 } else if (!strcasecmp(v->name, "canreinvite")) { 17507 ast_set_flag(&mask[0], SIP_REINVITE); 17508 ast_clear_flag(&flags[0], SIP_REINVITE); 17509 if(ast_true(v->value)) { 17510 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 17511 } else if (!ast_false(v->value)) { 17512 char buf[64]; 17513 char *word, *next = buf; 17514 17515 ast_copy_string(buf, v->value, sizeof(buf)); 17516 while ((word = strsep(&next, ","))) { 17517 if(!strcasecmp(word, "update")) { 17518 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 17519 } else if(!strcasecmp(word, "nonat")) { 17520 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 17521 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 17522 } else { 17523 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 17524 } 17525 } 17526 } 17527 } else if (!strcasecmp(v->name, "insecure")) { 17528 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17529 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17530 set_insecure_flags(flags, v->value, v->lineno); 17531 } else if (!strcasecmp(v->name, "progressinband")) { 17532 ast_set_flag(&mask[0], SIP_PROG_INBAND); 17533 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 17534 if (ast_true(v->value)) 17535 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 17536 else if (strcasecmp(v->value, "never")) 17537 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 17538 } else if (!strcasecmp(v->name, "promiscredir")) { 17539 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 17540 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 17541 } else if (!strcasecmp(v->name, "videosupport")) { 17542 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 17543 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 17544 } else if (!strcasecmp(v->name, "allowoverlap")) { 17545 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 17546 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 17547 } else if (!strcasecmp(v->name, "allowsubscribe")) { 17548 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 17549 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 17550 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 17551 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 17552 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 17553 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 17554 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 17555 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 17556 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 17557 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 17558 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 17559 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 17560 #endif 17561 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 17562 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 17563 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 17564 } else if (!strcasecmp(v->name, "buggymwi")) { 17565 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 17566 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 17567 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 17568 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 17569 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 17570 } else if (!strcasecmp(v->name, "constantssrc")) { 17571 ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC); 17572 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); 17573 } else 17574 res = 0; 17575 17576 return res; 17577 }
static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
struct sockaddr_in * | sin, | |||
int * | nounlock | |||
) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
Definition at line 14364 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_do_masquerade(), ast_hangup(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_quiet_chan(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::name, 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().
14365 { 14366 int earlyreplace = 0; 14367 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 14368 struct ast_channel *c = p->owner; /* Our incoming call */ 14369 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 14370 struct ast_channel *targetcall; /* The bridge to the take-over target */ 14371 14372 /* Check if we're in ring state */ 14373 if (replacecall->_state == AST_STATE_RING) 14374 earlyreplace = 1; 14375 14376 /* Check if we have a bridge */ 14377 if (!(targetcall = ast_bridged_channel(replacecall))) { 14378 /* We have no bridge */ 14379 if (!earlyreplace) { 14380 if (option_debug > 1) 14381 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 14382 oneleggedreplace = 1; 14383 } 14384 } 14385 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 14386 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 14387 14388 if (option_debug > 3) { 14389 if (targetcall) 14390 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); 14391 else 14392 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 14393 } 14394 14395 if (ignore) { 14396 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 14397 /* We should answer something here. If we are here, the 14398 call we are replacing exists, so an accepted 14399 can't harm */ 14400 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14401 /* Do something more clever here */ 14402 if (c) { 14403 *nounlock = 1; 14404 ast_channel_unlock(c); 14405 } 14406 ast_channel_unlock(replacecall); 14407 ast_mutex_unlock(&p->refer->refer_call->lock); 14408 return 1; 14409 } 14410 if (!c) { 14411 /* What to do if no channel ??? */ 14412 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 14413 transmit_response_reliable(p, "503 Service Unavailable", req); 14414 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 14415 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14416 ast_channel_unlock(replacecall); 14417 ast_mutex_unlock(&p->refer->refer_call->lock); 14418 return 1; 14419 } 14420 append_history(p, "Xfer", "INVITE/Replace received"); 14421 /* We have three channels to play with 14422 channel c: New incoming call 14423 targetcall: Call from PBX to target 14424 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 14425 replacecall: The owner of the previous 14426 We need to masq C into refer_call to connect to 14427 targetcall; 14428 If we are talking to internal audio stream, target call is null. 14429 */ 14430 14431 /* Fake call progress */ 14432 transmit_response(p, "100 Trying", req); 14433 ast_setstate(c, AST_STATE_RING); 14434 14435 /* Masquerade the new call into the referred call to connect to target call 14436 Targetcall is not touched by the masq */ 14437 14438 /* Answer the incoming call and set channel to UP state */ 14439 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14440 14441 ast_setstate(c, AST_STATE_UP); 14442 14443 /* Stop music on hold and other generators */ 14444 ast_quiet_chan(replacecall); 14445 ast_quiet_chan(targetcall); 14446 if (option_debug > 3) 14447 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 14448 14449 /* Make sure that the masq does not free our PVT for the old call */ 14450 if (! earlyreplace && ! oneleggedreplace ) 14451 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14452 14453 /* Prepare the masquerade - if this does not happen, we will be gone */ 14454 if(ast_channel_masquerade(replacecall, c)) 14455 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 14456 else if (option_debug > 3) 14457 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 14458 14459 /* C should now be in place of replacecall */ 14460 if (ast_do_masquerade(replacecall)) { 14461 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 14462 } 14463 14464 if (earlyreplace || oneleggedreplace ) { 14465 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14466 } 14467 14468 ast_setstate(c, AST_STATE_DOWN); 14469 if (option_debug > 3) { 14470 struct ast_channel *test; 14471 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 14472 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 14473 if (replacecall) 14474 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 14475 if (p->owner) { 14476 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 14477 test = ast_bridged_channel(p->owner); 14478 if (test) 14479 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 14480 else 14481 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 14482 } else 14483 ast_log(LOG_DEBUG, " -- No channel yet \n"); 14484 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 14485 } 14486 14487 /* unlock sip pvt and owner so hangup can do its thing */ 14488 ast_channel_unlock(replacecall); 14489 ast_channel_unlock(c); 14490 ast_mutex_unlock(&p->refer->refer_call->lock); 14491 ast_mutex_unlock(&p->lock); 14492 *nounlock = 1; 14493 14494 /* The call should be down with no ast_channel, so hang it up */ 14495 c->tech_pvt = NULL; 14496 ast_hangup(c); 14497 14498 ast_mutex_lock(&p->lock); /* lock PVT structure again after hangup */ 14499 14500 return 0; 14501 }
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 16408 of file chan_sip.c.
References __sip_ack(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent.
16409 { 16410 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 16411 relatively static */ 16412 const char *cmd; 16413 const char *cseq; 16414 const char *useragent; 16415 int seqno; 16416 int len; 16417 int ignore = FALSE; 16418 int respid; 16419 int res = 0; 16420 int debug = sip_debug_test_pvt(p); 16421 char *e; 16422 int error = 0; 16423 16424 /* Get Method and Cseq */ 16425 cseq = get_header(req, "Cseq"); 16426 cmd = req->header[0]; 16427 16428 /* Must have Cseq */ 16429 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 16430 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 16431 error = 1; 16432 } 16433 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 16434 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 16435 error = 1; 16436 } 16437 if (error) { 16438 if (!p->initreq.headers) /* New call */ 16439 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 16440 return -1; 16441 } 16442 /* Get the command XXX */ 16443 16444 cmd = req->rlPart1; 16445 e = ast_skip_blanks(req->rlPart2); 16446 16447 /* Save useragent of the client */ 16448 useragent = get_header(req, "User-Agent"); 16449 if (!ast_strlen_zero(useragent)) 16450 ast_string_field_set(p, useragent, useragent); 16451 16452 /* Find out SIP method for incoming request */ 16453 if (req->method == SIP_RESPONSE) { /* Response to our request */ 16454 /* Response to our request -- Do some sanity checks */ 16455 if (ast_strlen_zero(e)) { 16456 return 0; 16457 } 16458 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 16459 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 16460 return 0; 16461 } 16462 if (respid <= 0) { 16463 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 16464 return 0; 16465 } 16466 if (!p->initreq.headers) { 16467 if (option_debug) 16468 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 16469 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16470 return 0; 16471 } 16472 if (p->ocseq && (p->ocseq < seqno)) { 16473 if (option_debug) 16474 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 16475 return -1; 16476 } else { 16477 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 16478 extract_uri(p, req); 16479 } 16480 handle_response(p, respid, e + len, req, seqno); 16481 } 16482 return 0; 16483 } 16484 16485 /* New SIP request coming in 16486 (could be new request in existing SIP dialog as well...) 16487 */ 16488 16489 p->method = req->method; /* Find out which SIP method they are using */ 16490 if (option_debug > 3) 16491 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 16492 16493 if (p->icseq && (p->icseq > seqno) ) { 16494 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 16495 if (option_debug > 2) 16496 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 16497 } else { 16498 if (option_debug) 16499 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 16500 if (req->method != SIP_ACK) 16501 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 16502 return -1; 16503 } 16504 } else if (p->icseq && 16505 p->icseq == seqno && 16506 req->method != SIP_ACK && 16507 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 16508 /* ignore means "don't do anything with it" but still have to 16509 respond appropriately. We do this if we receive a repeat of 16510 the last sequence number */ 16511 ignore = 2; 16512 ast_set_flag(req, SIP_PKT_IGNORE); 16513 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 16514 if (option_debug > 2) 16515 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 16516 } 16517 16518 if (seqno >= p->icseq) 16519 /* Next should follow monotonically (but not necessarily 16520 incrementally -- thanks again to the genius authors of SIP -- 16521 increasing */ 16522 p->icseq = seqno; 16523 16524 /* Find their tag if we haven't got it */ 16525 if (ast_strlen_zero(p->theirtag)) { 16526 char tag[128]; 16527 16528 gettag(req, "From", tag, sizeof(tag)); 16529 ast_string_field_set(p, theirtag, tag); 16530 } 16531 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 16532 16533 if (pedanticsipchecking) { 16534 /* If this is a request packet without a from tag, it's not 16535 correct according to RFC 3261 */ 16536 /* Check if this a new request in a new dialog with a totag already attached to it, 16537 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 16538 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 16539 /* If this is a first request and it got a to-tag, it is not for us */ 16540 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 16541 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 16542 /* Will cease to exist after ACK */ 16543 } else if (req->method != SIP_ACK) { 16544 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 16545 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16546 } 16547 return res; 16548 } 16549 } 16550 16551 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 16552 transmit_response(p, "400 Bad request", req); 16553 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16554 return -1; 16555 } 16556 16557 /* Handle various incoming SIP methods in requests */ 16558 switch (p->method) { 16559 case SIP_OPTIONS: 16560 res = handle_request_options(p, req); 16561 break; 16562 case SIP_INVITE: 16563 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 16564 break; 16565 case SIP_REFER: 16566 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 16567 break; 16568 case SIP_CANCEL: 16569 res = handle_request_cancel(p, req); 16570 break; 16571 case SIP_BYE: 16572 res = handle_request_bye(p, req); 16573 break; 16574 case SIP_MESSAGE: 16575 res = handle_request_message(p, req); 16576 break; 16577 case SIP_SUBSCRIBE: 16578 res = handle_request_subscribe(p, req, sin, seqno, e); 16579 break; 16580 case SIP_REGISTER: 16581 res = handle_request_register(p, req, sin, e); 16582 break; 16583 case SIP_INFO: 16584 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16585 ast_verbose("Receiving INFO!\n"); 16586 if (!ignore) 16587 handle_request_info(p, req); 16588 else /* if ignoring, transmit response */ 16589 transmit_response(p, "200 OK", req); 16590 break; 16591 case SIP_NOTIFY: 16592 res = handle_request_notify(p, req, sin, seqno, e); 16593 break; 16594 case SIP_ACK: 16595 /* Make sure we don't ignore this */ 16596 if (seqno == p->pendinginvite) { 16597 p->invitestate = INV_TERMINATED; 16598 p->pendinginvite = 0; 16599 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 16600 if (find_sdp(req)) { 16601 if (process_sdp(p, req)) 16602 return -1; 16603 } 16604 check_pendings(p); 16605 } else if (p->glareinvite == seqno) { 16606 /* handle ack for the 491 pending send for glareinvite */ 16607 p->glareinvite = 0; 16608 __sip_ack(p, seqno, 1, 0); 16609 } 16610 /* Got an ACK that we did not match. Ignore silently */ 16611 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 16612 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16613 break; 16614 default: 16615 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 16616 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 16617 cmd, ast_inet_ntoa(p->sa.sin_addr)); 16618 /* If this is some new method, and we don't have a call, destroy it now */ 16619 if (!p->initreq.headers) 16620 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16621 break; 16622 } 16623 return res; 16624 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15962 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, 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(), ast_channel::context, context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, LOG_DEBUG, LOG_NOTICE, option_debug, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().
Referenced by handle_request().
15963 { 15964 struct ast_channel *c=NULL; 15965 int res; 15966 struct ast_channel *bridged_to; 15967 15968 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15969 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 15970 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15971 15972 __sip_pretend_ack(p); 15973 15974 p->invitestate = INV_TERMINATED; 15975 15976 copy_request(&p->initreq, req); 15977 check_via(p, req); 15978 sip_alreadygone(p); 15979 15980 /* Get RTCP quality before end of call */ 15981 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15982 char *audioqos, *videoqos; 15983 if (p->rtp) { 15984 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15985 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15986 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15987 if (p->owner) 15988 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15989 } 15990 if (p->vrtp) { 15991 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15992 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15993 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15994 if (p->owner) 15995 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15996 } 15997 } 15998 15999 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16000 16001 if (!ast_strlen_zero(get_header(req, "Also"))) { 16002 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 16003 ast_inet_ntoa(p->recv.sin_addr)); 16004 if (ast_strlen_zero(p->context)) 16005 ast_string_field_set(p, context, default_context); 16006 res = get_also_info(p, req); 16007 if (!res) { 16008 c = p->owner; 16009 if (c) { 16010 bridged_to = ast_bridged_channel(c); 16011 if (bridged_to) { 16012 /* Don't actually hangup here... */ 16013 ast_queue_control(c, AST_CONTROL_UNHOLD); 16014 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 16015 } else 16016 ast_queue_hangup(p->owner); 16017 } 16018 } else { 16019 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 16020 if (p->owner) 16021 ast_queue_hangup(p->owner); 16022 } 16023 } else if (p->owner) { 16024 ast_queue_hangup(p->owner); 16025 if (option_debug > 2) 16026 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 16027 } else { 16028 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16029 if (option_debug > 2) 16030 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 16031 } 16032 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16033 transmit_response(p, "200 OK", req); 16034 16035 return 1; 16036 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15832 of file chan_sip.c.
References __sip_pretend_ack(), ast_free, ast_log(), ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, sip_pkt::next, option_debug, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_request().
15833 { 15834 15835 check_via(p, req); 15836 sip_alreadygone(p); 15837 15838 /* At this point, we could have cancelled the invite at the same time 15839 as the other side sends a CANCEL. Our final reply with error code 15840 might not have been received by the other side before the CANCEL 15841 was sent, so let's just give up retransmissions and waiting for 15842 ACK on our error code. The call is hanging up any way. */ 15843 if (p->invitestate == INV_TERMINATED) 15844 __sip_pretend_ack(p); 15845 else 15846 p->invitestate = INV_CANCELLED; 15847 15848 if (p->owner && p->owner->_state == AST_STATE_UP) { 15849 /* This call is up, cancel is ignored, we need a bye */ 15850 transmit_response(p, "200 OK", req); 15851 if (option_debug) 15852 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15853 return 0; 15854 } 15855 15856 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15857 update_call_counter(p, DEC_CALL_LIMIT); 15858 15859 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15860 if (p->owner) 15861 ast_queue_hangup(p->owner); 15862 else 15863 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15864 if (p->initreq.len > 0) { 15865 struct sip_pkt *pkt, *prev_pkt; 15866 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 15867 * a reliable 487, then we don't want to schedule another one on top of the previous 15868 * one. 15869 * 15870 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 15871 * response in this situation. What if we've sent all of our reliable responses 15872 * already and now all of a sudden, we get this second CANCEL? 15873 * 15874 * The only way to do this correctly is to cancel our previously-scheduled reliably- 15875 * transmitted response and send a new one in its place. 15876 */ 15877 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 15878 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 15879 AST_SCHED_DEL(sched, pkt->retransid); 15880 UNLINK(pkt, p->packets, prev_pkt); 15881 ast_free(pkt); 15882 break; 15883 } 15884 } 15885 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15886 transmit_response(p, "200 OK", req); 15887 return 1; 15888 } else { 15889 transmit_response(p, "481 Call Leg Does Not Exist", req); 15890 return 0; 15891 } 15892 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11925 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, sip_history::event, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
11926 { 11927 char buf[1024]; 11928 unsigned int event; 11929 const char *c = get_header(req, "Content-Type"); 11930 11931 /* Need to check the media/type */ 11932 if (!strcasecmp(c, "application/dtmf-relay") || 11933 !strcasecmp(c, "application/DTMF") || 11934 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11935 unsigned int duration = 0; 11936 11937 /* Try getting the "signal=" part */ 11938 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11939 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11940 transmit_response(p, "200 OK", req); /* Should return error */ 11941 return; 11942 } else { 11943 ast_copy_string(buf, c, sizeof(buf)); 11944 } 11945 11946 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11947 duration = atoi(c); 11948 if (!duration) 11949 duration = 100; /* 100 ms */ 11950 11951 if (!p->owner) { /* not a PBX call */ 11952 transmit_response(p, "481 Call leg/transaction does not exist", req); 11953 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11954 return; 11955 } 11956 11957 if (ast_strlen_zero(buf)) { 11958 transmit_response(p, "200 OK", req); 11959 return; 11960 } 11961 11962 if (buf[0] == '*') 11963 event = 10; 11964 else if (buf[0] == '#') 11965 event = 11; 11966 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11967 event = 12 + buf[0] - 'A'; 11968 else 11969 event = atoi(buf); 11970 if (event == 16) { 11971 /* send a FLASH event */ 11972 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11973 ast_queue_frame(p->owner, &f); 11974 if (sipdebug) 11975 ast_verbose("* DTMF-relay event received: FLASH\n"); 11976 } else { 11977 /* send a DTMF event */ 11978 struct ast_frame f = { AST_FRAME_DTMF, }; 11979 if (event < 10) { 11980 f.subclass = '0' + event; 11981 } else if (event < 11) { 11982 f.subclass = '*'; 11983 } else if (event < 12) { 11984 f.subclass = '#'; 11985 } else if (event < 16) { 11986 f.subclass = 'A' + (event - 12); 11987 } 11988 f.len = duration; 11989 ast_queue_frame(p->owner, &f); 11990 if (sipdebug) 11991 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11992 } 11993 transmit_response(p, "200 OK", req); 11994 return; 11995 } else if (!strcasecmp(c, "application/media_control+xml")) { 11996 /* Eh, we'll just assume it's a fast picture update for now */ 11997 if (p->owner) 11998 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11999 transmit_response(p, "200 OK", req); 12000 return; 12001 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 12002 /* Client code (from SNOM phone) */ 12003 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 12004 if (p->owner && p->owner->cdr) 12005 ast_cdr_setuserfield(p->owner, c); 12006 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 12007 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 12008 transmit_response(p, "200 OK", req); 12009 } else { 12010 transmit_response(p, "403 Unauthorized", req); 12011 } 12012 return; 12013 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 12014 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 12015 transmit_response(p, "200 OK", req); 12016 return; 12017 } 12018 12019 /* Other type of INFO message, not really understood by Asterisk */ 12020 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 12021 12022 /* Nothing in the header is interesting, now check if content-length is 0 */ 12023 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 12024 transmit_response(p, "200 OK", req); 12025 return; 12026 } /* else ... there issomething in the message body, do something with it if you need to */ 12027 12028 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 12029 transmit_response(p, "415 Unsupported media type", req); 12030 return; 12031 }
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 14794 of file chan_sip.c.
References __sip_ack(), 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_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, 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_control(), ast_queue_frame(), ast_rtp_set_alt_peer(), ast_rtp_set_constantssrc(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_setstate(), ast_skip_blanks(), 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(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rdnis(), get_sip_pvt_byid_locked(), sip_pvt::glareinvite, handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_VIDEO, 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_CONSTANT_SSRC, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, 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_provisional_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(), sip_pvt::username, sip_pvt::vrtp, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14795 { 14796 int res = 1; 14797 int gotdest; 14798 const char *p_replaces; 14799 char *replace_id = NULL; 14800 const char *required; 14801 unsigned int required_profile = 0; 14802 struct ast_channel *c = NULL; /* New channel */ 14803 int reinvite = 0; 14804 14805 /* Find out what they support */ 14806 if (!p->sipoptions) { 14807 const char *supported = get_header(req, "Supported"); 14808 if (!ast_strlen_zero(supported)) 14809 parse_sip_options(p, supported); 14810 } 14811 14812 /* Find out what they require */ 14813 required = get_header(req, "Require"); 14814 if (!ast_strlen_zero(required)) { 14815 required_profile = parse_sip_options(NULL, required); 14816 if (required_profile && !(required_profile & SIP_OPT_REPLACES)) { 14817 /* At this point we only support REPLACES */ 14818 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14819 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14820 p->invitestate = INV_COMPLETED; 14821 if (!p->lastinvite) 14822 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14823 return -1; 14824 } 14825 } 14826 14827 /* Check if this is a loop */ 14828 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 14829 /* This is a call to ourself. Send ourselves an error code and stop 14830 processing immediately, as SIP really has no good mechanism for 14831 being able to call yourself */ 14832 /* If pedantic is on, we need to check the tags. If they're different, this is 14833 in fact a forked call through a SIP proxy somewhere. */ 14834 int different; 14835 if (pedanticsipchecking) 14836 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14837 else 14838 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14839 if (!different) { 14840 transmit_response(p, "482 Loop Detected", req); 14841 p->invitestate = INV_COMPLETED; 14842 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14843 return 0; 14844 } else { 14845 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14846 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14847 * that should be all we need to do. 14848 */ 14849 char *uri = ast_strdupa(req->rlPart2); 14850 char *at = strchr(uri, '@'); 14851 char *peerorhost; 14852 if (option_debug > 2) { 14853 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14854 } 14855 transmit_response(p, "100 Trying", req); 14856 if (at) { 14857 *at = '\0'; 14858 } 14859 /* Parse out "sip:" */ 14860 if ((peerorhost = strchr(uri, ':'))) { 14861 *peerorhost++ = '\0'; 14862 } 14863 ast_string_field_free(p, theirtag); 14864 /* Treat this as if there were a call forward instead... 14865 */ 14866 ast_string_field_set(p->owner, call_forward, peerorhost); 14867 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14868 return 0; 14869 } 14870 } 14871 14872 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14873 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 14874 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 14875 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 14876 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 14877 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 14878 * credentials based on one we challenged earlier. 14879 * 14880 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 14881 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 14882 * from the previous transaction from the list of outstanding packets. 14883 */ 14884 __sip_ack(p, p->pendinginvite, FLAG_RESPONSE, 0); 14885 } else { 14886 /* We already have a pending invite. Sorry. You are on hold. */ 14887 p->glareinvite = seqno; 14888 if (p->rtp && find_sdp(req)) { 14889 struct sockaddr_in sin; 14890 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 14891 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 14892 } else { 14893 ast_rtp_set_alt_peer(p->rtp, &sin); 14894 } 14895 if (p->vrtp) { 14896 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 14897 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 14898 } else { 14899 ast_rtp_set_alt_peer(p->vrtp, &sin); 14900 } 14901 } 14902 } 14903 transmit_response_reliable(p, "491 Request Pending", req); 14904 if (option_debug) 14905 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14906 /* Don't destroy dialog here */ 14907 return 0; 14908 } 14909 } 14910 14911 p_replaces = get_header(req, "Replaces"); 14912 if (!ast_strlen_zero(p_replaces)) { 14913 /* We have a replaces header */ 14914 char *ptr; 14915 char *fromtag = NULL; 14916 char *totag = NULL; 14917 char *start, *to; 14918 int error = 0; 14919 14920 if (p->owner) { 14921 if (option_debug > 2) 14922 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14923 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14924 /* Do not destroy existing call */ 14925 return -1; 14926 } 14927 14928 if (sipdebug && option_debug > 2) 14929 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14930 /* Create a buffer we can manipulate */ 14931 replace_id = ast_strdupa(p_replaces); 14932 ast_uri_decode(replace_id); 14933 14934 if (!p->refer && !sip_refer_allocate(p)) { 14935 transmit_response_reliable(p, "500 Server Internal Error", req); 14936 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14937 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14938 p->invitestate = INV_COMPLETED; 14939 return -1; 14940 } 14941 14942 /* Todo: (When we find phones that support this) 14943 if the replaces header contains ";early-only" 14944 we can only replace the call in early 14945 stage, not after it's up. 14946 14947 If it's not in early mode, 486 Busy. 14948 */ 14949 14950 /* Skip leading whitespace */ 14951 replace_id = ast_skip_blanks(replace_id); 14952 14953 start = replace_id; 14954 while ( (ptr = strsep(&start, ";")) ) { 14955 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14956 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14957 totag = to + 7; /* skip the keyword */ 14958 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14959 fromtag = to + 9; /* skip the keyword */ 14960 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14961 } 14962 } 14963 14964 if (sipdebug && option_debug > 3) 14965 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>"); 14966 14967 14968 /* Try to find call that we are replacing 14969 If we have a Replaces header, we need to cancel that call if we succeed with this call 14970 */ 14971 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14972 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14973 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14974 error = 1; 14975 } 14976 14977 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14978 14979 /* The matched call is the call from the transferer to Asterisk . 14980 We want to bridge the bridged part of the call to the 14981 incoming invite, thus taking over the refered call */ 14982 14983 if (p->refer->refer_call == p) { 14984 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14985 p->refer->refer_call = NULL; 14986 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14987 error = 1; 14988 } 14989 14990 if (!error && !p->refer->refer_call->owner) { 14991 /* Oops, someting wrong anyway, no owner, no call */ 14992 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14993 /* Check for better return code */ 14994 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14995 error = 1; 14996 } 14997 14998 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 ) { 14999 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 15000 transmit_response_reliable(p, "603 Declined (Replaces)", req); 15001 error = 1; 15002 } 15003 15004 if (error) { /* Give up this dialog */ 15005 append_history(p, "Xfer", "INVITE/Replace Failed."); 15006 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15007 ast_mutex_unlock(&p->lock); 15008 if (p->refer->refer_call) { 15009 ast_mutex_unlock(&p->refer->refer_call->lock); 15010 if (p->refer->refer_call->owner) { 15011 ast_channel_unlock(p->refer->refer_call->owner); 15012 } 15013 } 15014 p->invitestate = INV_COMPLETED; 15015 return -1; 15016 } 15017 } 15018 15019 15020 /* Check if this is an INVITE that sets up a new dialog or 15021 a re-invite in an existing dialog */ 15022 15023 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15024 int newcall = (p->initreq.headers ? TRUE : FALSE); 15025 15026 if (sip_cancel_destroy(p)) 15027 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15028 /* This also counts as a pending invite */ 15029 p->pendinginvite = seqno; 15030 check_via(p, req); 15031 15032 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 15033 if (!p->owner) { /* Not a re-invite */ 15034 if (debug) 15035 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 15036 if (newcall) 15037 append_history(p, "Invite", "New call: %s", p->callid); 15038 parse_ok_contact(p, req); 15039 } else { /* Re-invite on existing call */ 15040 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 15041 /* Handle SDP here if we already have an owner */ 15042 if (find_sdp(req)) { 15043 if (process_sdp(p, req)) { 15044 transmit_response_reliable(p, "488 Not acceptable here", req); 15045 if (!p->lastinvite) 15046 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15047 return -1; 15048 } 15049 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 15050 } else { 15051 p->jointcapability = p->capability; 15052 if (option_debug > 2) 15053 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 15054 /* Some devices signal they want to be put off hold by sending a re-invite 15055 *without* an SDP, which is supposed to mean "Go back to your state" 15056 and since they put os on remote hold, we go back to off hold */ 15057 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 15058 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 15059 /* Activate a re-invite */ 15060 ast_queue_frame(p->owner, &ast_null_frame); 15061 change_hold_state(p, req, FALSE, 0); 15062 } 15063 } 15064 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 15065 append_history(p, "ReInv", "Re-invite received"); 15066 } 15067 } else if (debug) 15068 ast_verbose("Ignoring this INVITE request\n"); 15069 15070 15071 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 15072 /* This is a new invite */ 15073 /* Handle authentication if this is our first invite */ 15074 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 15075 if (res == AUTH_CHALLENGE_SENT) { 15076 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 15077 return 0; 15078 } 15079 if (res < 0) { /* Something failed in authentication */ 15080 if (res == AUTH_FAKE_AUTH) { 15081 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15082 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 15083 } else { 15084 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 15085 transmit_response_reliable(p, "403 Forbidden", req); 15086 } 15087 p->invitestate = INV_COMPLETED; 15088 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15089 ast_string_field_free(p, theirtag); 15090 return 0; 15091 } 15092 15093 /* We have a succesful authentication, process the SDP portion if there is one */ 15094 if (find_sdp(req)) { 15095 if (process_sdp(p, req)) { 15096 /* Unacceptable codecs */ 15097 transmit_response_reliable(p, "488 Not acceptable here", req); 15098 p->invitestate = INV_COMPLETED; 15099 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15100 if (option_debug) 15101 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 15102 return -1; 15103 } 15104 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { 15105 if (p->rtp) { 15106 ast_rtp_set_constantssrc(p->rtp); 15107 } 15108 if (p->vrtp) { 15109 ast_rtp_set_constantssrc(p->vrtp); 15110 } 15111 } 15112 } else { /* No SDP in invite, call control session */ 15113 p->jointcapability = p->capability; 15114 if (option_debug > 1) 15115 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 15116 } 15117 15118 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 15119 /* This seems redundant ... see !p-owner above */ 15120 if (p->owner) 15121 ast_queue_frame(p->owner, &ast_null_frame); 15122 15123 15124 /* Initialize the context if it hasn't been already */ 15125 if (ast_strlen_zero(p->context)) 15126 ast_string_field_set(p, context, default_context); 15127 15128 15129 /* Check number of concurrent calls -vs- incoming limit HERE */ 15130 if (option_debug) 15131 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 15132 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 15133 if (res < 0) { 15134 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 15135 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 15136 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15137 p->invitestate = INV_COMPLETED; 15138 } 15139 return 0; 15140 } 15141 gotdest = get_destination(p, NULL); /* Get destination right away */ 15142 get_rdnis(p, NULL); /* Get redirect information */ 15143 extract_uri(p, req); /* Get the Contact URI */ 15144 build_contact(p); /* Build our contact header */ 15145 15146 if (p->rtp) { 15147 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 15148 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 15149 } 15150 15151 if (!replace_id && gotdest) { /* No matching extension found */ 15152 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 15153 transmit_response_reliable(p, "484 Address Incomplete", req); 15154 else { 15155 char *decoded_exten = ast_strdupa(p->exten); 15156 15157 transmit_response_reliable(p, "404 Not Found", req); 15158 ast_uri_decode(decoded_exten); 15159 ast_log(LOG_NOTICE, "Call from '%s' to extension" 15160 " '%s' rejected because extension not found.\n", 15161 S_OR(p->username, p->peername), decoded_exten); 15162 } 15163 p->invitestate = INV_COMPLETED; 15164 update_call_counter(p, DEC_CALL_LIMIT); 15165 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15166 return 0; 15167 } else { 15168 /* If no extension was specified, use the s one */ 15169 /* Basically for calling to IP/Host name only */ 15170 if (ast_strlen_zero(p->exten)) 15171 ast_string_field_set(p, exten, "s"); 15172 /* Initialize our tag */ 15173 15174 make_our_tag(p->tag, sizeof(p->tag)); 15175 /* First invitation - create the channel */ 15176 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 15177 *recount = 1; 15178 15179 /* Save Record-Route for any later requests we make on this dialogue */ 15180 build_route(p, req, 0); 15181 15182 if (c) { 15183 /* Pre-lock the call */ 15184 ast_channel_lock(c); 15185 } 15186 } 15187 } else { 15188 if (option_debug > 1 && sipdebug) { 15189 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15190 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 15191 else 15192 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 15193 } 15194 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15195 reinvite = 1; 15196 c = p->owner; 15197 } 15198 15199 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15200 p->lastinvite = seqno; 15201 15202 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 15203 /* Go and take over the target call */ 15204 if (sipdebug && option_debug > 3) 15205 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 15206 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin, nounlock); 15207 } 15208 15209 15210 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 15211 enum ast_channel_state c_state = c->_state; 15212 15213 if (c_state != AST_STATE_UP && reinvite && 15214 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 15215 /* If these conditions are true, and the channel is still in the 'ringing' 15216 * state, then this likely means that we have a situation where the initial 15217 * INVITE transaction has completed *but* the channel's state has not yet been 15218 * changed to UP. The reason this could happen is if the reinvite is received 15219 * on the SIP socket prior to an application calling ast_read on this channel 15220 * to read the answer frame we earlier queued on it. In this case, the reinvite 15221 * is completely legitimate so we need to handle this the same as if the channel 15222 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 15223 */ 15224 c_state = AST_STATE_UP; 15225 } 15226 15227 switch(c_state) { 15228 case AST_STATE_DOWN: 15229 if (option_debug > 1) 15230 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 15231 transmit_provisional_response(p, "100 Trying", req, 0); 15232 p->invitestate = INV_PROCEEDING; 15233 ast_setstate(c, AST_STATE_RING); 15234 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 15235 enum ast_pbx_result res; 15236 15237 res = ast_pbx_start(c); 15238 15239 switch(res) { 15240 case AST_PBX_FAILED: 15241 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 15242 p->invitestate = INV_COMPLETED; 15243 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15244 transmit_response(p, "503 Unavailable", req); 15245 else 15246 transmit_response_reliable(p, "503 Unavailable", req); 15247 break; 15248 case AST_PBX_CALL_LIMIT: 15249 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 15250 p->invitestate = INV_COMPLETED; 15251 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15252 transmit_response(p, "480 Temporarily Unavailable", req); 15253 else 15254 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 15255 break; 15256 case AST_PBX_SUCCESS: 15257 /* nothing to do */ 15258 break; 15259 } 15260 15261 if (res) { 15262 15263 /* Unlock locks so ast_hangup can do its magic */ 15264 ast_mutex_unlock(&c->lock); 15265 ast_mutex_unlock(&p->lock); 15266 ast_hangup(c); 15267 ast_mutex_lock(&p->lock); 15268 c = NULL; 15269 } 15270 } else { /* Pickup call in call group */ 15271 ast_channel_unlock(c); 15272 *nounlock = 1; 15273 if (ast_pickup_call(c)) { 15274 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 15275 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15276 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 15277 else 15278 transmit_response_reliable(p, "503 Unavailable", req); 15279 sip_alreadygone(p); 15280 /* Unlock locks so ast_hangup can do its magic */ 15281 ast_mutex_unlock(&p->lock); 15282 c->hangupcause = AST_CAUSE_CALL_REJECTED; 15283 } else { 15284 ast_mutex_unlock(&p->lock); 15285 ast_setstate(c, AST_STATE_DOWN); 15286 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15287 } 15288 p->invitestate = INV_COMPLETED; 15289 ast_hangup(c); 15290 ast_mutex_lock(&p->lock); 15291 c = NULL; 15292 } 15293 break; 15294 case AST_STATE_RING: 15295 transmit_provisional_response(p, "100 Trying", req, 0); 15296 p->invitestate = INV_PROCEEDING; 15297 break; 15298 case AST_STATE_RINGING: 15299 transmit_provisional_response(p, "180 Ringing", req, 0); 15300 p->invitestate = INV_PROCEEDING; 15301 break; 15302 case AST_STATE_UP: 15303 if (option_debug > 1) 15304 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 15305 15306 transmit_response(p, "100 Trying", req); 15307 15308 if (p->t38.state == T38_PEER_REINVITE) { 15309 struct ast_channel *bridgepeer = NULL; 15310 struct sip_pvt *bridgepvt = NULL; 15311 15312 if ((bridgepeer = ast_bridged_channel(p->owner))) { 15313 /* 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*/ 15314 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 15315 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 15316 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 15317 if (bridgepvt->t38.state == T38_DISABLED) { 15318 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 15319 /* Send re-invite to the bridged channel */ 15320 sip_handle_t38_reinvite(bridgepeer, p, 1); 15321 } else { /* Something is wrong with peers udptl struct */ 15322 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 15323 ast_mutex_lock(&bridgepvt->lock); 15324 bridgepvt->t38.state = T38_DISABLED; 15325 ast_mutex_unlock(&bridgepvt->lock); 15326 if (option_debug > 1) 15327 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 15328 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15329 transmit_response(p, "488 Not acceptable here", req); 15330 else 15331 transmit_response_reliable(p, "488 Not acceptable here", req); 15332 15333 } 15334 } else { 15335 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 15336 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15337 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15338 p->t38.state = T38_ENABLED; 15339 if (option_debug) 15340 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15341 } 15342 } else { 15343 /* Other side is not a SIP channel */ 15344 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15345 transmit_response(p, "488 Not acceptable here", req); 15346 else 15347 transmit_response_reliable(p, "488 Not acceptable here", req); 15348 p->t38.state = T38_DISABLED; 15349 if (option_debug > 1) 15350 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15351 15352 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 15353 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15354 } 15355 } else { 15356 /* we are not bridged in a call */ 15357 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15358 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15359 p->t38.state = T38_ENABLED; 15360 if (option_debug) 15361 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15362 } 15363 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 15364 /* If this is not a re-invite or something to ignore - it's critical */ 15365 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15366 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 15367 } 15368 p->invitestate = INV_TERMINATED; 15369 break; 15370 default: 15371 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 15372 transmit_response(p, "100 Trying", req); 15373 break; 15374 } 15375 } else { 15376 if (p && (p->autokillid == -1)) { 15377 const char *msg; 15378 15379 if (!p->jointcapability) 15380 msg = "488 Not Acceptable Here (codec error)"; 15381 else { 15382 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 15383 msg = "503 Unavailable"; 15384 } 15385 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15386 transmit_response(p, msg, req); 15387 else 15388 transmit_response_reliable(p, msg, req); 15389 p->invitestate = INV_COMPLETED; 15390 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15391 } 15392 } 15393 return res; 15394 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 16039 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().
16040 { 16041 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16042 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16043 ast_verbose("Receiving message!\n"); 16044 receive_message(p, req); 16045 } else 16046 transmit_response(p, "202 Accepted", req); 16047 return 1; 16048 }
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 14192 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
14193 { 14194 /* This is mostly a skeleton for future improvements */ 14195 /* Mostly created to return proper answers on notifications on outbound REFER's */ 14196 int res = 0; 14197 const char *event = get_header(req, "Event"); 14198 char *eventid = NULL; 14199 char *sep; 14200 14201 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 14202 *sep++ = '\0'; 14203 eventid = sep; 14204 } 14205 14206 if (option_debug > 1 && sipdebug) 14207 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 14208 14209 if (strcmp(event, "refer")) { 14210 /* We don't understand this event. */ 14211 /* Here's room to implement incoming voicemail notifications :-) */ 14212 transmit_response(p, "489 Bad event", req); 14213 res = -1; 14214 } else { 14215 /* Save nesting depth for now, since there might be other events we will 14216 support in the future */ 14217 14218 /* Handle REFER notifications */ 14219 14220 char buf[1024]; 14221 char *cmd, *code; 14222 int respcode; 14223 int success = TRUE; 14224 14225 /* EventID for each transfer... EventID is basically the REFER cseq 14226 14227 We are getting notifications on a call that we transfered 14228 We should hangup when we are getting a 200 OK in a sipfrag 14229 Check if we have an owner of this event */ 14230 14231 /* Check the content type */ 14232 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 14233 /* We need a sipfrag */ 14234 transmit_response(p, "400 Bad request", req); 14235 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14236 return -1; 14237 } 14238 14239 /* Get the text of the attachment */ 14240 if (get_msg_text(buf, sizeof(buf), req)) { 14241 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 14242 transmit_response(p, "400 Bad request", req); 14243 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14244 return -1; 14245 } 14246 14247 /* 14248 From the RFC... 14249 A minimal, but complete, implementation can respond with a single 14250 NOTIFY containing either the body: 14251 SIP/2.0 100 Trying 14252 14253 if the subscription is pending, the body: 14254 SIP/2.0 200 OK 14255 if the reference was successful, the body: 14256 SIP/2.0 503 Service Unavailable 14257 if the reference failed, or the body: 14258 SIP/2.0 603 Declined 14259 14260 if the REFER request was accepted before approval to follow the 14261 reference could be obtained and that approval was subsequently denied 14262 (see Section 2.4.7). 14263 14264 If there are several REFERs in the same dialog, we need to 14265 match the ID of the event header... 14266 */ 14267 if (option_debug > 2) 14268 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 14269 cmd = ast_skip_blanks(buf); 14270 code = cmd; 14271 /* We are at SIP/2.0 */ 14272 while(*code && (*code > 32)) { /* Search white space */ 14273 code++; 14274 } 14275 *code++ = '\0'; 14276 code = ast_skip_blanks(code); 14277 sep = code; 14278 sep++; 14279 while(*sep && (*sep > 32)) { /* Search white space */ 14280 sep++; 14281 } 14282 *sep++ = '\0'; /* Response string */ 14283 respcode = atoi(code); 14284 switch (respcode) { 14285 case 100: /* Trying: */ 14286 case 101: /* dialog establishment */ 14287 /* Don't do anything yet */ 14288 break; 14289 case 183: /* Ringing: */ 14290 /* Don't do anything yet */ 14291 break; 14292 case 200: /* OK: The new call is up, hangup this call */ 14293 /* Hangup the call that we are replacing */ 14294 break; 14295 case 301: /* Moved permenantly */ 14296 case 302: /* Moved temporarily */ 14297 /* Do we get the header in the packet in this case? */ 14298 success = FALSE; 14299 break; 14300 case 503: /* Service Unavailable: The new call failed */ 14301 /* Cancel transfer, continue the call */ 14302 success = FALSE; 14303 break; 14304 case 603: /* Declined: Not accepted */ 14305 /* Cancel transfer, continue the current call */ 14306 success = FALSE; 14307 break; 14308 } 14309 if (!success) { 14310 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 14311 } 14312 14313 /* Confirm that we received this packet */ 14314 transmit_response(p, "200 OK", req); 14315 }; 14316 14317 if (!p->lastinvite) 14318 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14319 14320 return res; 14321 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 14324 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
14325 { 14326 int res; 14327 14328 14329 /* XXX Should we authenticate OPTIONS? XXX */ 14330 14331 if (p->lastinvite) { 14332 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 14333 transmit_response_with_allow(p, "200 OK", req, 0); 14334 return 0; 14335 } 14336 14337 res = get_destination(p, req); 14338 build_contact(p); 14339 14340 if (ast_strlen_zero(p->context)) 14341 ast_string_field_set(p, context, default_context); 14342 14343 if (ast_shutting_down()) 14344 transmit_response_with_allow(p, "503 Unavailable", req, 0); 14345 else if (res < 0) 14346 transmit_response_with_allow(p, "404 Not Found", req, 0); 14347 else 14348 transmit_response_with_allow(p, "200 OK", req, 0); 14349 14350 /* Destroy if this OPTIONS was the opening request, but not if 14351 it's in the middle of a normal call flow. */ 14352 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14353 14354 return res; 14355 }
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 15561 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_pvt::callid, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, sip_pvt::context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
15562 { 15563 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 15564 /* Chan2: Call between asterisk and transferee */ 15565 15566 int res = 0; 15567 15568 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15569 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"); 15570 15571 if (!p->owner) { 15572 /* This is a REFER outside of an existing SIP dialog */ 15573 /* We can't handle that, so decline it */ 15574 if (option_debug > 2) 15575 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 15576 transmit_response(p, "603 Declined (No dialog)", req); 15577 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15578 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 15579 sip_alreadygone(p); 15580 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15581 } 15582 return 0; 15583 } 15584 15585 15586 /* Check if transfer is allowed from this device */ 15587 if (p->allowtransfer == TRANSFER_CLOSED ) { 15588 /* Transfer not allowed, decline */ 15589 transmit_response(p, "603 Declined (policy)", req); 15590 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 15591 /* Do not destroy SIP session */ 15592 return 0; 15593 } 15594 15595 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 15596 /* Already have a pending REFER */ 15597 transmit_response(p, "491 Request pending", req); 15598 append_history(p, "Xfer", "Refer failed. Request pending."); 15599 return 0; 15600 } 15601 15602 /* Allocate memory for call transfer data */ 15603 if (!p->refer && !sip_refer_allocate(p)) { 15604 transmit_response(p, "500 Internal Server Error", req); 15605 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 15606 return -3; 15607 } 15608 15609 res = get_refer_info(p, req); /* Extract headers */ 15610 15611 p->refer->status = REFER_SENT; 15612 15613 if (res != 0) { 15614 switch (res) { 15615 case -2: /* Syntax error */ 15616 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15617 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15618 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15619 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15620 break; 15621 case -3: 15622 transmit_response(p, "603 Declined (Non sip: uri)", req); 15623 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15624 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15625 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15626 break; 15627 default: 15628 /* Refer-to extension not found, fake a failed transfer */ 15629 transmit_response(p, "202 Accepted", req); 15630 append_history(p, "Xfer", "Refer failed. Bad extension."); 15631 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15632 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15633 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15634 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15635 break; 15636 } 15637 return 0; 15638 } 15639 if (ast_strlen_zero(p->context)) 15640 ast_string_field_set(p, context, default_context); 15641 15642 /* If we do not support SIP domains, all transfers are local */ 15643 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15644 p->refer->localtransfer = 1; 15645 if (sipdebug && option_debug > 2) 15646 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15647 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15648 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15649 p->refer->localtransfer = 1; 15650 } else if (sipdebug && option_debug > 2) 15651 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15652 15653 /* Is this a repeat of a current request? Ignore it */ 15654 /* Don't know what else to do right now. */ 15655 if (ignore) 15656 return res; 15657 15658 /* If this is a blind transfer, we have the following 15659 channels to work with: 15660 - chan1, chan2: The current call between transferer and transferee (2 channels) 15661 - target_channel: A new call from the transferee to the target (1 channel) 15662 We need to stay tuned to what happens in order to be able 15663 to bring back the call to the transferer */ 15664 15665 /* If this is a attended transfer, we should have all call legs within reach: 15666 - chan1, chan2: The call between the transferer and transferee (2 channels) 15667 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15668 We want to bridge chan2 with targetcall_pvt! 15669 15670 The replaces call id in the refer message points 15671 to the call leg between Asterisk and the transferer. 15672 So we need to connect the target and the transferee channel 15673 and hangup the two other channels silently 15674 15675 If the target is non-local, the call ID could be on a remote 15676 machine and we need to send an INVITE with replaces to the 15677 target. We basically handle this as a blind transfer 15678 and let the sip_call function catch that we need replaces 15679 header in the INVITE. 15680 */ 15681 15682 15683 /* Get the transferer's channel */ 15684 current.chan1 = p->owner; 15685 15686 /* Find the other part of the bridge (2) - transferee */ 15687 current.chan2 = ast_bridged_channel(current.chan1); 15688 15689 if (sipdebug && option_debug > 2) 15690 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>"); 15691 15692 if (!current.chan2 && !p->refer->attendedtransfer) { 15693 /* No bridged channel, propably IVR or echo or similar... */ 15694 /* Guess we should masquerade or something here */ 15695 /* Until we figure it out, refuse transfer of such calls */ 15696 if (sipdebug && option_debug > 2) 15697 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15698 p->refer->status = REFER_FAILED; 15699 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15700 transmit_response(p, "603 Declined", req); 15701 return -1; 15702 } 15703 15704 if (current.chan2) { 15705 if (sipdebug && option_debug > 3) 15706 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15707 15708 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15709 } 15710 15711 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15712 15713 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15714 if (p->refer->attendedtransfer) { 15715 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15716 return res; /* We're done with the transfer */ 15717 /* Fall through for remote transfers that we did not find locally */ 15718 if (sipdebug && option_debug > 3) 15719 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15720 /* Fallthrough if we can't find the call leg internally */ 15721 } 15722 15723 15724 /* Parking a call */ 15725 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15726 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15727 *nounlock = 1; 15728 ast_channel_unlock(current.chan1); 15729 copy_request(¤t.req, req); 15730 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15731 p->refer->status = REFER_200OK; 15732 append_history(p, "Xfer", "REFER to call parking."); 15733 if (sipdebug && option_debug > 3) 15734 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15735 sip_park(current.chan2, current.chan1, req, seqno); 15736 return res; 15737 } 15738 15739 /* Blind transfers and remote attended xfers */ 15740 transmit_response(p, "202 Accepted", req); 15741 15742 if (current.chan1 && current.chan2) { 15743 if (option_debug > 2) 15744 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15745 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15746 } 15747 if (current.chan2) { 15748 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15749 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15750 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15751 /* One for the new channel */ 15752 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15753 /* Attended transfer to remote host, prepare headers for the INVITE */ 15754 if (p->refer->referred_by) 15755 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15756 } 15757 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15758 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15759 char tempheader[SIPBUFSIZE]; 15760 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15761 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15762 p->refer->replaces_callid_totag, 15763 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15764 p->refer->replaces_callid_fromtag); 15765 if (current.chan2) 15766 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15767 } 15768 /* Must release lock now, because it will not longer 15769 be accessible after the transfer! */ 15770 *nounlock = 1; 15771 ast_channel_unlock(current.chan1); 15772 15773 /* Connect the call */ 15774 15775 /* FAKE ringing if not attended transfer */ 15776 if (!p->refer->attendedtransfer) 15777 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15778 15779 /* For blind transfer, this will lead to a new call */ 15780 /* For attended transfer to remote host, this will lead to 15781 a new SIP call with a replaces header, if the dial plan allows it 15782 */ 15783 if (!current.chan2) { 15784 /* We have no bridge, so we're talking with Asterisk somehow */ 15785 /* We need to masquerade this call */ 15786 /* What to do to fix this situation: 15787 * Set up the new call in a new channel 15788 * Let the new channel masq into this channel 15789 Please add that code here :-) 15790 */ 15791 p->refer->status = REFER_FAILED; 15792 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15793 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15794 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15795 return -1; 15796 } 15797 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15798 15799 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15800 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15801 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15802 15803 if (!res) { 15804 /* Success - we have a new channel */ 15805 if (option_debug > 2) 15806 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15807 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15808 if (p->refer->localtransfer) 15809 p->refer->status = REFER_200OK; 15810 if (p->owner) 15811 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15812 append_history(p, "Xfer", "Refer succeeded."); 15813 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15814 /* Do not hangup call, the other side do that when we say 200 OK */ 15815 /* We could possibly implement a timer here, auto congestion */ 15816 res = 0; 15817 } else { 15818 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15819 if (option_debug > 2) 15820 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15821 append_history(p, "Xfer", "Refer failed."); 15822 /* Failure of some kind */ 15823 p->refer->status = REFER_FAILED; 15824 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15825 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15826 res = -1; 15827 } 15828 return res; 15829 }
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 16355 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().
16356 { 16357 enum check_auth_result res; 16358 16359 /* Use this as the basis */ 16360 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16361 ast_verbose("Using latest REGISTER request as basis request\n"); 16362 copy_request(&p->initreq, req); 16363 check_via(p, req); 16364 if ((res = register_verify(p, sin, req, e)) < 0) { 16365 const char *reason; 16366 16367 switch (res) { 16368 case AUTH_SECRET_FAILED: 16369 reason = "Wrong password"; 16370 break; 16371 case AUTH_USERNAME_MISMATCH: 16372 reason = "Username/auth name mismatch"; 16373 break; 16374 case AUTH_NOT_FOUND: 16375 reason = "No matching peer found"; 16376 break; 16377 case AUTH_UNKNOWN_DOMAIN: 16378 reason = "Not a local domain"; 16379 break; 16380 case AUTH_PEER_NOT_DYNAMIC: 16381 reason = "Peer is not supposed to register"; 16382 break; 16383 case AUTH_ACL_FAILED: 16384 reason = "Device does not match ACL"; 16385 break; 16386 default: 16387 reason = "Unknown failure"; 16388 break; 16389 } 16390 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 16391 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 16392 reason); 16393 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 16394 } else 16395 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 16396 16397 if (res < 1) { 16398 /* Destroy the session, but keep us around for just a bit in case they don't 16399 get our 200 OK */ 16400 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16401 } 16402 return res; 16403 }
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 16051 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, 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_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
16052 { 16053 int gotdest = 0; 16054 int res = 0; 16055 int firststate = AST_EXTENSION_REMOVED; 16056 struct sip_peer *authpeer = NULL; 16057 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 16058 const char *accept = get_header(req, "Accept"); 16059 int resubscribe = (p->subscribed != NONE); 16060 char *temp, *event; 16061 16062 if (p->initreq.headers) { 16063 /* We already have a dialog */ 16064 if (p->initreq.method != SIP_SUBSCRIBE) { 16065 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 16066 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 16067 transmit_response(p, "403 Forbidden (within dialog)", req); 16068 /* Do not destroy session, since we will break the call if we do */ 16069 if (option_debug) 16070 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); 16071 return 0; 16072 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 16073 if (option_debug) { 16074 if (resubscribe) 16075 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 16076 else 16077 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 16078 } 16079 } 16080 } 16081 16082 /* Check if we have a global disallow setting on subscriptions. 16083 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 16084 */ 16085 if (!global_allowsubscribe) { 16086 transmit_response(p, "403 Forbidden (policy)", req); 16087 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16088 return 0; 16089 } 16090 16091 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 16092 const char *to = get_header(req, "To"); 16093 char totag[128]; 16094 16095 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 16096 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 16097 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16098 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 16099 transmit_response(p, "481 Subscription does not exist", req); 16100 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16101 return 0; 16102 } 16103 16104 /* Use this as the basis */ 16105 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16106 ast_verbose("Creating new subscription\n"); 16107 16108 copy_request(&p->initreq, req); 16109 check_via(p, req); 16110 build_route(p, req, 0); 16111 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 16112 ast_verbose("Ignoring this SUBSCRIBE request\n"); 16113 16114 /* Find parameters to Event: header value and remove them for now */ 16115 if (ast_strlen_zero(eventheader)) { 16116 transmit_response(p, "489 Bad Event", req); 16117 if (option_debug > 1) 16118 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 16119 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16120 return 0; 16121 } 16122 16123 if ( (strchr(eventheader, ';'))) { 16124 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 16125 temp = strchr(event, ';'); 16126 *temp = '\0'; /* Remove any options for now */ 16127 /* We might need to use them later :-) */ 16128 } else 16129 event = (char *) eventheader; /* XXX is this legal ? */ 16130 16131 /* Handle authentication */ 16132 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 16133 /* if an authentication response was sent, we are done here */ 16134 if (res == AUTH_CHALLENGE_SENT) { 16135 if (authpeer) 16136 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16137 return 0; 16138 } 16139 if (res < 0) { 16140 if (res == AUTH_FAKE_AUTH) { 16141 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 16142 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 16143 } else { 16144 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 16145 transmit_response_reliable(p, "403 Forbidden", req); 16146 } 16147 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16148 if (authpeer) 16149 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16150 return 0; 16151 } 16152 16153 /* Check if this user/peer is allowed to subscribe at all */ 16154 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 16155 transmit_response(p, "403 Forbidden (policy)", req); 16156 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16157 if (authpeer) 16158 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16159 return 0; 16160 } 16161 16162 if (strcmp(event, "message-summary")) { 16163 /* Get destination right away */ 16164 gotdest = get_destination(p, NULL); 16165 } 16166 16167 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 16168 parse_ok_contact(p, req); 16169 16170 build_contact(p); 16171 if (gotdest) { 16172 transmit_response(p, "404 Not Found", req); 16173 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16174 if (authpeer) 16175 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16176 return 0; 16177 } 16178 16179 /* Initialize tag for new subscriptions */ 16180 if (ast_strlen_zero(p->tag)) 16181 make_our_tag(p->tag, sizeof(p->tag)); 16182 16183 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 16184 unsigned int pidf_xml; 16185 16186 if (authpeer) /* No need for authpeer here */ 16187 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16188 16189 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 16190 16191 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 16192 16193 /* Older versions of Polycom firmware will claim pidf+xml, but really 16194 * they only support xpidf+xml. */ 16195 if (pidf_xml && strstr(p->useragent, "Polycom")) { 16196 p->subscribed = XPIDF_XML; 16197 } else if (pidf_xml) { 16198 p->subscribed = PIDF_XML; /* RFC 3863 format */ 16199 } else if (strstr(accept, "application/dialog-info+xml")) { 16200 p->subscribed = DIALOG_INFO_XML; 16201 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 16202 } else if (strstr(accept, "application/cpim-pidf+xml")) { 16203 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 16204 } else if (strstr(accept, "application/xpidf+xml")) { 16205 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 16206 } else if (ast_strlen_zero(accept)) { 16207 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 16208 transmit_response(p, "489 Bad Event", req); 16209 16210 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16211 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 16212 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16213 return 0; 16214 } 16215 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 16216 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 16217 } else { 16218 /* Can't find a format for events that we know about */ 16219 char mybuf[200]; 16220 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 16221 transmit_response(p, mybuf, req); 16222 16223 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16224 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 16225 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16226 return 0; 16227 } 16228 } else if (!strcmp(event, "message-summary")) { 16229 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 16230 /* Format requested that we do not support */ 16231 transmit_response(p, "406 Not Acceptable", req); 16232 if (option_debug > 1) 16233 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 16234 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16235 if (authpeer) /* No need for authpeer here */ 16236 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16237 return 0; 16238 } 16239 /* Looks like they actually want a mailbox status 16240 This version of Asterisk supports mailbox subscriptions 16241 The subscribed URI needs to exist in the dial plan 16242 In most devices, this is configurable to the voicemailmain extension you use 16243 */ 16244 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 16245 transmit_response(p, "404 Not found (no mailbox)", req); 16246 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16247 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 16248 if (authpeer) /* No need for authpeer here */ 16249 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16250 return 0; 16251 } 16252 16253 p->subscribed = MWI_NOTIFICATION; 16254 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 16255 /* We only allow one subscription per peer */ 16256 sip_destroy(authpeer->mwipvt); 16257 authpeer->mwipvt = p; /* Link from peer to pvt */ 16258 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 16259 } else { /* At this point, Asterisk does not understand the specified event */ 16260 transmit_response(p, "489 Bad Event", req); 16261 if (option_debug > 1) 16262 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 16263 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16264 if (authpeer) /* No need for authpeer here */ 16265 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16266 return 0; 16267 } 16268 16269 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 16270 if (p->stateid > -1) 16271 ast_extension_state_del(p->stateid, cb_extensionstate); 16272 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 16273 } 16274 16275 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 16276 p->lastinvite = seqno; 16277 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 16278 p->expiry = atoi(get_header(req, "Expires")); 16279 16280 /* check if the requested expiry-time is within the approved limits from sip.conf */ 16281 if (p->expiry > max_expiry) 16282 p->expiry = max_expiry; 16283 if (p->expiry < min_expiry && p->expiry > 0) 16284 p->expiry = min_expiry; 16285 16286 if (sipdebug || option_debug > 1) { 16287 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 16288 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 16289 else 16290 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 16291 } 16292 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 16293 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16294 if (p->expiry > 0) 16295 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 16296 16297 if (p->subscribed == MWI_NOTIFICATION) { 16298 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16299 transmit_response(p, "200 OK", req); 16300 if (p->relatedpeer) { /* Send first notification */ 16301 ASTOBJ_WRLOCK(p->relatedpeer); 16302 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 16303 ASTOBJ_UNLOCK(p->relatedpeer); 16304 } 16305 } else { 16306 struct sip_pvt *p_old; 16307 16308 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 16309 16310 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)); 16311 transmit_response(p, "404 Not found", req); 16312 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16313 return 0; 16314 } 16315 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16316 transmit_response(p, "200 OK", req); 16317 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 16318 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 16319 /* hide the 'complete' exten/context in the refer_to field for later display */ 16320 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 16321 16322 /* remove any old subscription from this peer for the same exten/context, 16323 as the peer has obviously forgotten about it and it's wasteful to wait 16324 for it to expire and send NOTIFY messages to the peer only to have them 16325 ignored (or generate errors) 16326 */ 16327 ast_mutex_lock(&iflock); 16328 for (p_old = iflist; p_old; p_old = p_old->next) { 16329 if (p_old == p) 16330 continue; 16331 if (p_old->initreq.method != SIP_SUBSCRIBE) 16332 continue; 16333 if (p_old->subscribed == NONE) 16334 continue; 16335 ast_mutex_lock(&p_old->lock); 16336 if (!strcmp(p_old->username, p->username)) { 16337 if (!strcmp(p_old->exten, p->exten) && 16338 !strcmp(p_old->context, p->context)) { 16339 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 16340 ast_mutex_unlock(&p_old->lock); 16341 break; 16342 } 16343 } 16344 ast_mutex_unlock(&p_old->lock); 16345 } 16346 ast_mutex_unlock(&iflock); 16347 } 16348 if (!p->expiry) 16349 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16350 } 16351 return 1; 16352 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 13465 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::call_forward, cb_extensionstate(), sip_pvt::context, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
13466 { 13467 struct ast_channel *owner; 13468 int sipmethod; 13469 int res = 1; 13470 int ack_res; 13471 const char *c = get_header(req, "Cseq"); 13472 /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */ 13473 char *c_copy = ast_strdupa(c); 13474 /* Skip the Cseq and its subsequent spaces */ 13475 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 13476 13477 if (!msg) 13478 msg = ""; 13479 13480 sipmethod = find_sip_method(msg); 13481 13482 owner = p->owner; 13483 if (owner) 13484 owner->hangupcause = hangup_sip2cause(resp); 13485 13486 /* Acknowledge whatever it is destined for */ 13487 if ((resp >= 100) && (resp <= 199)) { 13488 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 13489 } else { 13490 ack_res = __sip_ack(p, seqno, 0, sipmethod); 13491 } 13492 13493 if (ack_res == FALSE) { 13494 append_history(p, "Ignore", "Ignoring this retransmit\n"); 13495 return; 13496 } 13497 13498 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 13499 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 13500 p->pendinginvite = 0; 13501 13502 /* Get their tag if we haven't already */ 13503 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 13504 char tag[128]; 13505 13506 gettag(req, "To", tag, sizeof(tag)); 13507 ast_string_field_set(p, theirtag, tag); 13508 } 13509 13510 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 13511 * in response to a BYE, then we should end the current dialog 13512 * and session. It is known that at least one phone manufacturer 13513 * potentially will send a 404 in response to a BYE, so we'll be 13514 * liberal in what we accept and end the dialog and session if we 13515 * receive any of those responses to a BYE. 13516 */ 13517 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 13518 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13519 return; 13520 } 13521 13522 if (p->relatedpeer && p->method == SIP_OPTIONS) { 13523 /* We don't really care what the response is, just that it replied back. 13524 Well, as long as it's not a 100 response... since we might 13525 need to hang around for something more "definitive" */ 13526 if (resp != 100) 13527 handle_response_peerpoke(p, resp, req); 13528 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13529 switch(resp) { 13530 case 100: /* 100 Trying */ 13531 case 101: /* 101 Dialog establishment */ 13532 if (sipmethod == SIP_INVITE) 13533 handle_response_invite(p, resp, rest, req, seqno); 13534 break; 13535 case 183: /* 183 Session Progress */ 13536 if (sipmethod == SIP_INVITE) 13537 handle_response_invite(p, resp, rest, req, seqno); 13538 break; 13539 case 180: /* 180 Ringing */ 13540 if (sipmethod == SIP_INVITE) 13541 handle_response_invite(p, resp, rest, req, seqno); 13542 break; 13543 case 182: /* 182 Queued */ 13544 if (sipmethod == SIP_INVITE) 13545 handle_response_invite(p, resp, rest, req, seqno); 13546 break; 13547 case 200: /* 200 OK */ 13548 p->authtries = 0; /* Reset authentication counter */ 13549 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 13550 /* We successfully transmitted a message 13551 or a video update request in INFO */ 13552 /* Nothing happens here - the message is inside a dialog */ 13553 } else if (sipmethod == SIP_INVITE) { 13554 handle_response_invite(p, resp, rest, req, seqno); 13555 } else if (sipmethod == SIP_NOTIFY) { 13556 /* They got the notify, this is the end */ 13557 if (p->owner) { 13558 if (!p->refer) { 13559 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 13560 ast_queue_hangup(p->owner); 13561 } else if (option_debug > 3) 13562 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 13563 } else { 13564 if (p->subscribed == NONE) 13565 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13566 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13567 /* Ready to send the next state we have on queue */ 13568 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13569 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13570 } 13571 } 13572 } else if (sipmethod == SIP_REGISTER) 13573 res = handle_response_register(p, resp, rest, req, seqno); 13574 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13575 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13576 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13577 } else if (sipmethod == SIP_SUBSCRIBE) 13578 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13579 break; 13580 case 202: /* Transfer accepted */ 13581 if (sipmethod == SIP_REFER) 13582 handle_response_refer(p, resp, rest, req, seqno); 13583 break; 13584 case 401: /* Not www-authorized on SIP method */ 13585 if (sipmethod == SIP_INVITE) 13586 handle_response_invite(p, resp, rest, req, seqno); 13587 else if (sipmethod == SIP_REFER) 13588 handle_response_refer(p, resp, rest, req, seqno); 13589 else if (p->registry && sipmethod == SIP_REGISTER) 13590 res = handle_response_register(p, resp, rest, req, seqno); 13591 else if (sipmethod == SIP_BYE) { 13592 if (ast_strlen_zero(p->authname)) { 13593 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13594 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13595 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13596 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13597 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13598 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13599 /* We fail to auth bye on our own call, but still needs to tear down the call. 13600 Life, they call it. */ 13601 } 13602 } else { 13603 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13604 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13605 } 13606 break; 13607 case 403: /* Forbidden - we failed authentication */ 13608 if (sipmethod == SIP_INVITE) 13609 handle_response_invite(p, resp, rest, req, seqno); 13610 else if (p->registry && sipmethod == SIP_REGISTER) 13611 res = handle_response_register(p, resp, rest, req, seqno); 13612 else { 13613 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13614 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13615 } 13616 break; 13617 case 404: /* Not found */ 13618 if (p->registry && sipmethod == SIP_REGISTER) 13619 res = handle_response_register(p, resp, rest, req, seqno); 13620 else if (sipmethod == SIP_INVITE) 13621 handle_response_invite(p, resp, rest, req, seqno); 13622 else if (owner) 13623 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13624 break; 13625 case 407: /* Proxy auth required */ 13626 if (sipmethod == SIP_INVITE) 13627 handle_response_invite(p, resp, rest, req, seqno); 13628 else if (sipmethod == SIP_REFER) 13629 handle_response_refer(p, resp, rest, req, seqno); 13630 else if (p->registry && sipmethod == SIP_REGISTER) 13631 res = handle_response_register(p, resp, rest, req, seqno); 13632 else if (sipmethod == SIP_BYE) { 13633 if (ast_strlen_zero(p->authname)) { 13634 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13635 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13636 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13637 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13638 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13639 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13640 } 13641 } else /* We can't handle this, giving up in a bad way */ 13642 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13643 13644 break; 13645 case 408: /* Request timeout - terminate dialog */ 13646 if (sipmethod == SIP_INVITE) 13647 handle_response_invite(p, resp, rest, req, seqno); 13648 else if (sipmethod == SIP_REGISTER) 13649 res = handle_response_register(p, resp, rest, req, seqno); 13650 else if (sipmethod == SIP_BYE) { 13651 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13652 if (option_debug) 13653 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13654 } else { 13655 if (owner) 13656 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13657 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13658 } 13659 break; 13660 case 481: /* Call leg does not exist */ 13661 if (sipmethod == SIP_INVITE) { 13662 handle_response_invite(p, resp, rest, req, seqno); 13663 } else if (sipmethod == SIP_REFER) { 13664 handle_response_refer(p, resp, rest, req, seqno); 13665 } else if (sipmethod == SIP_BYE) { 13666 /* The other side has no transaction to bye, 13667 just assume it's all right then */ 13668 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13669 } else if (sipmethod == SIP_CANCEL) { 13670 /* The other side has no transaction to cancel, 13671 just assume it's all right then */ 13672 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13673 } else { 13674 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13675 /* Guessing that this is not an important request */ 13676 } 13677 break; 13678 case 487: 13679 if (sipmethod == SIP_INVITE) 13680 handle_response_invite(p, resp, rest, req, seqno); 13681 break; 13682 case 488: /* Not acceptable here - codec error */ 13683 if (sipmethod == SIP_INVITE) 13684 handle_response_invite(p, resp, rest, req, seqno); 13685 break; 13686 case 491: /* Pending */ 13687 if (sipmethod == SIP_INVITE) 13688 handle_response_invite(p, resp, rest, req, seqno); 13689 else { 13690 if (option_debug) 13691 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13692 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13693 } 13694 break; 13695 case 501: /* Not Implemented */ 13696 if (sipmethod == SIP_INVITE) 13697 handle_response_invite(p, resp, rest, req, seqno); 13698 else if (sipmethod == SIP_REFER) 13699 handle_response_refer(p, resp, rest, req, seqno); 13700 else 13701 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13702 break; 13703 case 603: /* Declined transfer */ 13704 if (sipmethod == SIP_REFER) { 13705 handle_response_refer(p, resp, rest, req, seqno); 13706 break; 13707 } 13708 /* Fallthrough */ 13709 default: 13710 if ((resp >= 300) && (resp < 700)) { 13711 /* Fatal response */ 13712 if ((option_verbose > 2) && (resp != 487)) 13713 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13714 13715 if (sipmethod == SIP_INVITE) 13716 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13717 13718 /* XXX Locking issues?? XXX */ 13719 switch(resp) { 13720 case 300: /* Multiple Choices */ 13721 case 301: /* Moved permenantly */ 13722 case 302: /* Moved temporarily */ 13723 case 305: /* Use Proxy */ 13724 parse_moved_contact(p, req); 13725 /* Fall through */ 13726 case 486: /* Busy here */ 13727 case 600: /* Busy everywhere */ 13728 case 603: /* Decline */ 13729 if (p->owner) 13730 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13731 break; 13732 case 482: /* 13733 \note SIP is incapable of performing a hairpin call, which 13734 is yet another failure of not having a layer 2 (again, YAY 13735 IETF for thinking ahead). So we treat this as a call 13736 forward and hope we end up at the right place... */ 13737 if (option_debug) 13738 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13739 if (p->owner) 13740 ast_string_field_build(p->owner, call_forward, 13741 "Local/%s@%s", p->username, p->context); 13742 /* Fall through */ 13743 case 480: /* Temporarily Unavailable */ 13744 case 404: /* Not Found */ 13745 case 410: /* Gone */ 13746 case 400: /* Bad Request */ 13747 case 500: /* Server error */ 13748 if (sipmethod == SIP_REFER) { 13749 handle_response_refer(p, resp, rest, req, seqno); 13750 break; 13751 } 13752 /* Fall through */ 13753 case 502: /* Bad gateway */ 13754 case 503: /* Service Unavailable */ 13755 case 504: /* Server Timeout */ 13756 if (owner) 13757 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13758 break; 13759 default: 13760 /* Send hangup */ 13761 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13762 ast_queue_hangup(p->owner); 13763 break; 13764 } 13765 /* ACK on invite */ 13766 if (sipmethod == SIP_INVITE) 13767 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13768 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13769 sip_alreadygone(p); 13770 if (!p->owner) 13771 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13772 } else if ((resp >= 100) && (resp < 200)) { 13773 if (sipmethod == SIP_INVITE) { 13774 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13775 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13776 if (find_sdp(req)) 13777 process_sdp(p, req); 13778 if (p->owner) { 13779 /* Queue a progress frame */ 13780 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13781 } 13782 } 13783 } else 13784 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)); 13785 } 13786 } else { 13787 /* Responses to OUTGOING SIP requests on INCOMING calls 13788 get handled here. As well as out-of-call message responses */ 13789 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13790 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13791 13792 if (sipmethod == SIP_INVITE && resp == 200) { 13793 /* Tags in early session is replaced by the tag in 200 OK, which is 13794 the final reply to our INVITE */ 13795 char tag[128]; 13796 13797 gettag(req, "To", tag, sizeof(tag)); 13798 ast_string_field_set(p, theirtag, tag); 13799 } 13800 13801 switch(resp) { 13802 case 200: 13803 if (sipmethod == SIP_INVITE) { 13804 handle_response_invite(p, resp, rest, req, seqno); 13805 } else if (sipmethod == SIP_CANCEL) { 13806 if (option_debug) 13807 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13808 13809 /* Wait for 487, then destroy */ 13810 } else if (sipmethod == SIP_NOTIFY) { 13811 /* They got the notify, this is the end */ 13812 if (p->owner) { 13813 if (p->refer) { 13814 if (option_debug) 13815 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13816 } else 13817 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13818 /* ast_queue_hangup(p->owner); Disabled */ 13819 } else { 13820 if (!p->subscribed && !p->refer) 13821 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13822 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13823 /* Ready to send the next state we have on queue */ 13824 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13825 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13826 } 13827 } 13828 } else if (sipmethod == SIP_BYE) 13829 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13830 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13831 /* We successfully transmitted a message or 13832 a video update request in INFO */ 13833 ; 13834 else if (sipmethod == SIP_BYE) 13835 /* Ok, we're ready to go */ 13836 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13837 break; 13838 case 202: /* Transfer accepted */ 13839 if (sipmethod == SIP_REFER) 13840 handle_response_refer(p, resp, rest, req, seqno); 13841 break; 13842 case 401: /* www-auth */ 13843 case 407: 13844 if (sipmethod == SIP_REFER) 13845 handle_response_refer(p, resp, rest, req, seqno); 13846 else if (sipmethod == SIP_INVITE) 13847 handle_response_invite(p, resp, rest, req, seqno); 13848 else if (sipmethod == SIP_BYE) { 13849 char *auth, *auth2; 13850 13851 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13852 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13853 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13854 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13855 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13856 } 13857 } 13858 break; 13859 case 481: /* Call leg does not exist */ 13860 if (sipmethod == SIP_INVITE) { 13861 /* Re-invite failed */ 13862 handle_response_invite(p, resp, rest, req, seqno); 13863 } else if (sipmethod == SIP_BYE) { 13864 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13865 } else if (sipdebug) { 13866 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13867 } 13868 break; 13869 case 501: /* Not Implemented */ 13870 if (sipmethod == SIP_INVITE) 13871 handle_response_invite(p, resp, rest, req, seqno); 13872 else if (sipmethod == SIP_REFER) 13873 handle_response_refer(p, resp, rest, req, seqno); 13874 break; 13875 case 603: /* Declined transfer */ 13876 if (sipmethod == SIP_REFER) { 13877 handle_response_refer(p, resp, rest, req, seqno); 13878 break; 13879 } 13880 /* Fallthrough */ 13881 default: /* Errors without handlers */ 13882 if ((resp >= 100) && (resp < 200)) { 13883 if (sipmethod == SIP_INVITE) { /* re-invite */ 13884 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13885 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13886 } 13887 } 13888 if ((resp >= 300) && (resp < 700)) { 13889 if ((option_verbose > 2) && (resp != 487)) 13890 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)); 13891 switch(resp) { 13892 case 488: /* Not acceptable here - codec error */ 13893 case 603: /* Decline */ 13894 case 500: /* Server error */ 13895 case 502: /* Bad gateway */ 13896 case 503: /* Service Unavailable */ 13897 case 504: /* Server timeout */ 13898 13899 /* re-invite failed */ 13900 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13901 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13902 break; 13903 } 13904 } 13905 break; 13906 } 13907 } 13908 }
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 12876 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(), sip_pvt::callid, check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_AUTHTRIES, ast_channel::name, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_OUTGOING_CALL, 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_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, 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().
12877 { 12878 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12879 int res = 0; 12880 int xmitres = 0; 12881 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12882 struct ast_channel *bridgepeer = NULL; 12883 12884 if (option_debug > 3) { 12885 if (reinvite) 12886 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12887 else 12888 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12889 } 12890 12891 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12892 if (option_debug) 12893 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12894 return; 12895 } 12896 12897 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12898 /* Don't auto congest anymore since we've gotten something useful back */ 12899 AST_SCHED_DEL(sched, p->initid); 12900 12901 /* RFC3261 says we must treat every 1xx response (but not 100) 12902 that we don't recognize as if it was 183. 12903 */ 12904 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12905 resp = 183; 12906 12907 /* Any response between 100 and 199 is PROCEEDING */ 12908 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12909 p->invitestate = INV_PROCEEDING; 12910 12911 /* Final response, not 200 ? */ 12912 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12913 p->invitestate = INV_COMPLETED; 12914 12915 12916 switch (resp) { 12917 case 100: /* Trying */ 12918 case 101: /* Dialog establishment */ 12919 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12920 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12921 check_pendings(p); 12922 break; 12923 12924 case 180: /* 180 Ringing */ 12925 case 182: /* 182 Queued */ 12926 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12927 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12928 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12929 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12930 if (p->owner->_state != AST_STATE_UP) { 12931 ast_setstate(p->owner, AST_STATE_RINGING); 12932 } 12933 } 12934 if (find_sdp(req)) { 12935 if (p->invitestate != INV_CANCELLED) 12936 p->invitestate = INV_EARLY_MEDIA; 12937 res = process_sdp(p, req); 12938 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12939 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12940 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12941 } 12942 } 12943 check_pendings(p); 12944 break; 12945 12946 case 183: /* Session progress */ 12947 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12948 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12949 if (find_sdp(req)) { 12950 if (p->invitestate != INV_CANCELLED) 12951 p->invitestate = INV_EARLY_MEDIA; 12952 res = process_sdp(p, req); 12953 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12954 /* Queue a progress frame */ 12955 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12956 } 12957 } else { 12958 /* Alcatel PBXs are known to send 183s with no SDP after sending 12959 * a 100 Trying response. We're just going to treat this sort of thing 12960 * the same as we would treat a 180 Ringing 12961 */ 12962 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12963 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12964 } 12965 } 12966 check_pendings(p); 12967 break; 12968 12969 case 200: /* 200 OK on invite - someone's answering our call */ 12970 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12971 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12972 p->authtries = 0; 12973 if (find_sdp(req)) { 12974 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12975 if (!reinvite) 12976 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12977 /* For re-invites, we try to recover */ 12978 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12979 } 12980 12981 /* Parse contact header for continued conversation */ 12982 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12983 /* This is important when we have a SIP proxy between us and the phone */ 12984 if (outgoing) { 12985 update_call_counter(p, DEC_CALL_RINGING); 12986 parse_ok_contact(p, req); 12987 /* Save Record-Route for any later requests we make on this dialogue */ 12988 if (!reinvite) 12989 build_route(p, req, 1); 12990 12991 if(set_address_from_contact(p)) { 12992 /* Bad contact - we don't know how to reach this device */ 12993 /* We need to ACK, but then send a bye */ 12994 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12995 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12996 } 12997 12998 } 12999 13000 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13001 struct sip_pvt *bridgepvt = NULL; 13002 13003 if (!bridgepeer->tech) { 13004 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 13005 break; 13006 } 13007 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13008 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13009 if (bridgepvt->udptl) { 13010 if (p->t38.state == T38_PEER_REINVITE) { 13011 sip_handle_t38_reinvite(bridgepeer, p, 0); 13012 ast_rtp_set_rtptimers_onhold(p->rtp); 13013 if (p->vrtp) 13014 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 13015 } 13016 } else { 13017 if (option_debug > 1) 13018 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 13019 ast_mutex_lock(&bridgepvt->lock); 13020 bridgepvt->t38.state = T38_DISABLED; 13021 ast_mutex_unlock(&bridgepvt->lock); 13022 if (option_debug) 13023 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 13024 p->t38.state = T38_DISABLED; 13025 if (option_debug > 1) 13026 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13027 } 13028 } else { 13029 /* Other side is not a SIP channel */ 13030 if (option_debug > 1) 13031 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 13032 p->t38.state = T38_DISABLED; 13033 if (option_debug > 1) 13034 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13035 } 13036 } 13037 if (p->t38.state == T38_LOCAL_REINVITE) { 13038 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 13039 p->t38.state = T38_ENABLED; 13040 if (option_debug) 13041 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13042 } 13043 13044 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13045 if (!reinvite) { 13046 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 13047 } else { /* RE-invite */ 13048 ast_queue_frame(p->owner, &ast_null_frame); 13049 } 13050 } else { 13051 /* It's possible we're getting an 200 OK after we've tried to disconnect 13052 by sending CANCEL */ 13053 /* First send ACK, then send bye */ 13054 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13055 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13056 } 13057 /* If I understand this right, the branch is different for a non-200 ACK only */ 13058 p->invitestate = INV_TERMINATED; 13059 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13060 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 13061 check_pendings(p); 13062 break; 13063 case 407: /* Proxy authentication */ 13064 case 401: /* Www auth */ 13065 /* First we ACK */ 13066 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13067 if (p->options) 13068 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 13069 13070 /* Then we AUTH */ 13071 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 13072 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13073 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 13074 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 13075 if (p->authtries < MAX_AUTHTRIES) 13076 p->invitestate = INV_CALLING; 13077 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 13078 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 13079 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13080 sip_alreadygone(p); 13081 if (p->owner) 13082 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13083 } 13084 } 13085 break; 13086 13087 case 403: /* Forbidden */ 13088 /* First we ACK */ 13089 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13090 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 13091 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 13092 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13093 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13094 sip_alreadygone(p); 13095 break; 13096 13097 case 404: /* Not found */ 13098 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13099 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13100 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13101 sip_alreadygone(p); 13102 break; 13103 13104 case 408: /* Request timeout */ 13105 case 481: /* Call leg does not exist */ 13106 /* Could be REFER caused INVITE with replaces */ 13107 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 13108 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13109 if (p->owner) 13110 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13111 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13112 break; 13113 case 487: /* Cancelled transaction */ 13114 /* We have sent CANCEL on an outbound INVITE 13115 This transaction is already scheduled to be killed by sip_hangup(). 13116 */ 13117 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13118 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13119 ast_queue_hangup(p->owner); 13120 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 13121 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13122 update_call_counter(p, DEC_CALL_LIMIT); 13123 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 13124 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13125 sip_alreadygone(p); 13126 } 13127 break; 13128 case 488: /* Not acceptable here */ 13129 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13130 if (reinvite && p->udptl) { 13131 /* If this is a T.38 call, we should go back to 13132 audio. If this is an audio call - something went 13133 terribly wrong since we don't renegotiate codecs, 13134 only IP/port . 13135 */ 13136 p->t38.state = T38_DISABLED; 13137 /* Try to reset RTP timers */ 13138 ast_rtp_set_rtptimers_onhold(p->rtp); 13139 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 13140 13141 /*! \bug Is there any way we can go back to the audio call on both 13142 sides here? 13143 */ 13144 /* While figuring that out, hangup the call */ 13145 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13146 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13147 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13148 } else { 13149 /* We can't set up this call, so give up */ 13150 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13151 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13152 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13153 /* If there's no dialog to end, then mark p as already gone */ 13154 if (!reinvite) 13155 sip_alreadygone(p); 13156 } 13157 break; 13158 case 491: /* Pending */ 13159 /* we really should have to wait a while, then retransmit 13160 * We should support the retry-after at some point 13161 * At this point, we treat this as a congestion if the call is not in UP state 13162 */ 13163 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13164 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13165 if (p->owner->_state != AST_STATE_UP) { 13166 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13167 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13168 } else { 13169 /* This is a re-invite that failed. 13170 * Reset the flag after a while 13171 */ 13172 int wait; 13173 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 13174 * if not owner of call, wait 0 to 2 seconds */ 13175 if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 13176 wait = 2100 + ast_random() % 2000; 13177 } else { 13178 wait = ast_random() % 2000; 13179 } 13180 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 13181 if (option_debug > 2) 13182 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 13183 } 13184 } 13185 break; 13186 13187 case 501: /* Not implemented */ 13188 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13189 if (p->owner) 13190 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13191 break; 13192 } 13193 if (xmitres == XMIT_ERROR) 13194 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 13195 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 13393 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by handle_response().
13394 { 13395 struct sip_peer *peer = p->relatedpeer; 13396 int statechanged, is_reachable, was_reachable; 13397 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 13398 13399 /* 13400 * Compute the response time to a ping (goes in peer->lastms.) 13401 * -1 means did not respond, 0 means unknown, 13402 * 1..maxms is a valid response, >maxms means late response. 13403 */ 13404 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 13405 pingtime = 1; 13406 13407 /* Now determine new state and whether it has changed. 13408 * Use some helper variables to simplify the writing 13409 * of the expressions. 13410 */ 13411 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 13412 is_reachable = pingtime <= peer->maxms; 13413 statechanged = peer->lastms == 0 /* yes, unknown before */ 13414 || was_reachable != is_reachable; 13415 13416 peer->lastms = pingtime; 13417 peer->call = NULL; 13418 if (statechanged) { 13419 const char *s = is_reachable ? "Reachable" : "Lagged"; 13420 char str_lastms[20]; 13421 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 13422 13423 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 13424 peer->name, s, pingtime, peer->maxms); 13425 ast_device_state_changed("SIP/%s", peer->name); 13426 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 13427 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 13428 } 13429 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 13430 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 13431 peer->name, s, pingtime); 13432 } 13433 13434 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 13435 struct sip_peer *peer_ptr = peer; 13436 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 13437 } 13438 13439 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13440 13441 /* Try again eventually */ 13442 peer->pokeexpire = ast_sched_add(sched, 13443 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 13444 sip_poke_peer_s, ASTOBJ_REF(peer)); 13445 13446 if (peer->pokeexpire == -1) { 13447 ASTOBJ_UNREF(peer, sip_destroy_peer); 13448 } 13449 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 13200 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::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
13201 { 13202 char *auth = "Proxy-Authenticate"; 13203 char *auth2 = "Proxy-Authorization"; 13204 13205 /* If no refer structure exists, then do nothing */ 13206 if (!p->refer) 13207 return; 13208 13209 switch (resp) { 13210 case 202: /* Transfer accepted */ 13211 /* We need to do something here */ 13212 /* The transferee is now sending INVITE to target */ 13213 p->refer->status = REFER_ACCEPTED; 13214 /* Now wait for next message */ 13215 if (option_debug > 2) 13216 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 13217 /* We should hang along, waiting for NOTIFY's here */ 13218 break; 13219 13220 case 401: /* Not www-authorized on SIP method */ 13221 case 407: /* Proxy auth */ 13222 if (ast_strlen_zero(p->authname)) { 13223 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 13224 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13225 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13226 } 13227 if (resp == 401) { 13228 auth = "WWW-Authenticate"; 13229 auth2 = "Authorization"; 13230 } 13231 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 13232 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 13233 p->refer->status = REFER_NOAUTH; 13234 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13235 } 13236 break; 13237 case 481: /* Call leg does not exist */ 13238 13239 /* A transfer with Replaces did not work */ 13240 /* OEJ: We should Set flag, cancel the REFER, go back 13241 to original call - but right now we can't */ 13242 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 13243 if (p->owner) 13244 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13245 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13246 break; 13247 13248 case 500: /* Server error */ 13249 case 501: /* Method not implemented */ 13250 /* Return to the current call onhold */ 13251 /* Status flag needed to be reset */ 13252 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 13253 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13254 p->refer->status = REFER_FAILED; 13255 break; 13256 case 603: /* Transfer declined */ 13257 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 13258 p->refer->status = REFER_FAILED; 13259 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13260 break; 13261 } 13262 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 13265 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, sip_pvt::callid, sip_registry::contact, 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_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, sip_registry::timeout, sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
13266 { 13267 int expires, expires_ms; 13268 struct sip_registry *r; 13269 r=p->registry; 13270 13271 switch (resp) { 13272 case 401: /* Unauthorized */ 13273 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 13274 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 13275 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13276 } 13277 break; 13278 case 403: /* Forbidden */ 13279 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 13280 if (global_regattempts_max) 13281 p->registry->regattempts = global_regattempts_max+1; 13282 AST_SCHED_DEL(sched, r->timeout); 13283 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13284 break; 13285 case 404: /* Not found */ 13286 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 13287 if (global_regattempts_max) 13288 p->registry->regattempts = global_regattempts_max+1; 13289 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13290 r->call = NULL; 13291 AST_SCHED_DEL(sched, r->timeout); 13292 break; 13293 case 407: /* Proxy auth */ 13294 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 13295 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 13296 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13297 } 13298 break; 13299 case 408: /* Request timeout */ 13300 /* Got a timeout response, so reset the counter of failed responses */ 13301 if (r) { 13302 r->regattempts = 0; 13303 } else { 13304 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 13305 } 13306 break; 13307 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 13308 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 13309 if (global_regattempts_max) 13310 p->registry->regattempts = global_regattempts_max+1; 13311 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13312 r->call = NULL; 13313 AST_SCHED_DEL(sched, r->timeout); 13314 break; 13315 case 200: /* 200 OK */ 13316 if (!r) { 13317 ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username)); 13318 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13319 return 0; 13320 } 13321 13322 r->regstate = REG_STATE_REGISTERED; 13323 r->regtime = time(NULL); /* Reset time of last succesful registration */ 13324 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 13325 r->regattempts = 0; 13326 if (option_debug) 13327 ast_log(LOG_DEBUG, "Registration successful\n"); 13328 if (r->timeout > -1) { 13329 if (option_debug) 13330 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 13331 } 13332 AST_SCHED_DEL(sched, r->timeout); 13333 r->call = NULL; 13334 p->registry = NULL; 13335 /* Let this one hang around until we have all the responses */ 13336 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13337 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 13338 13339 /* set us up for re-registering */ 13340 /* figure out how long we got registered for */ 13341 AST_SCHED_DEL(sched, r->expire); 13342 /* according to section 6.13 of RFC, contact headers override 13343 expires headers, so check those first */ 13344 expires = 0; 13345 13346 /* XXX todo: try to save the extra call */ 13347 if (!ast_strlen_zero(get_header(req, "Contact"))) { 13348 const char *contact = NULL; 13349 const char *tmptmp = NULL; 13350 int start = 0; 13351 for(;;) { 13352 contact = __get_header(req, "Contact", &start); 13353 /* this loop ensures we get a contact header about our register request */ 13354 if(!ast_strlen_zero(contact)) { 13355 if( (tmptmp=strstr(contact, p->our_contact))) { 13356 contact=tmptmp; 13357 break; 13358 } 13359 } else 13360 break; 13361 } 13362 tmptmp = strcasestr(contact, "expires="); 13363 if (tmptmp) { 13364 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 13365 expires = 0; 13366 } 13367 13368 } 13369 if (!expires) 13370 expires=atoi(get_header(req, "expires")); 13371 if (!expires) 13372 expires=default_expiry; 13373 13374 expires_ms = expires * 1000; 13375 if (expires <= EXPIRY_GUARD_LIMIT) 13376 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 13377 else 13378 expires_ms -= EXPIRY_GUARD_SECS * 1000; 13379 if (sipdebug) 13380 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 13381 13382 r->refresh= (int) expires_ms / 1000; 13383 13384 /* Schedule re-registration before we expire */ 13385 AST_SCHED_DEL(sched, r->expire); 13386 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 13387 ASTOBJ_UNREF(r, sip_registry_destroy); 13388 } 13389 return 1; 13390 }
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 3617 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_UNREGISTERED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03618 { 03619 switch (cause) { 03620 case AST_CAUSE_UNALLOCATED: /* 1 */ 03621 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03622 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03623 return "404 Not Found"; 03624 case AST_CAUSE_CONGESTION: /* 34 */ 03625 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03626 return "503 Service Unavailable"; 03627 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03628 return "408 Request Timeout"; 03629 case AST_CAUSE_NO_ANSWER: /* 19 */ 03630 case AST_CAUSE_UNREGISTERED: /* 20 */ 03631 return "480 Temporarily unavailable"; 03632 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03633 return "403 Forbidden"; 03634 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03635 return "410 Gone"; 03636 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03637 return "480 Temporarily unavailable"; 03638 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03639 return "484 Address incomplete"; 03640 case AST_CAUSE_USER_BUSY: 03641 return "486 Busy here"; 03642 case AST_CAUSE_FAILURE: 03643 return "500 Server internal failure"; 03644 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03645 return "501 Not Implemented"; 03646 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03647 return "503 Service Unavailable"; 03648 /* Used in chan_iax2 */ 03649 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03650 return "502 Bad Gateway"; 03651 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03652 return "488 Not Acceptable Here"; 03653 03654 case AST_CAUSE_NOTDEFINED: 03655 default: 03656 if (option_debug) 03657 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03658 return NULL; 03659 } 03660 03661 /* Never reached */ 03662 return 0; 03663 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3505 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_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by handle_response().
03506 { 03507 /* Possible values taken from causes.h */ 03508 03509 switch(cause) { 03510 case 401: /* Unauthorized */ 03511 return AST_CAUSE_CALL_REJECTED; 03512 case 403: /* Not found */ 03513 return AST_CAUSE_CALL_REJECTED; 03514 case 404: /* Not found */ 03515 return AST_CAUSE_UNALLOCATED; 03516 case 405: /* Method not allowed */ 03517 return AST_CAUSE_INTERWORKING; 03518 case 407: /* Proxy authentication required */ 03519 return AST_CAUSE_CALL_REJECTED; 03520 case 408: /* No reaction */ 03521 return AST_CAUSE_NO_USER_RESPONSE; 03522 case 409: /* Conflict */ 03523 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03524 case 410: /* Gone */ 03525 return AST_CAUSE_NUMBER_CHANGED; 03526 case 411: /* Length required */ 03527 return AST_CAUSE_INTERWORKING; 03528 case 413: /* Request entity too large */ 03529 return AST_CAUSE_INTERWORKING; 03530 case 414: /* Request URI too large */ 03531 return AST_CAUSE_INTERWORKING; 03532 case 415: /* Unsupported media type */ 03533 return AST_CAUSE_INTERWORKING; 03534 case 420: /* Bad extension */ 03535 return AST_CAUSE_NO_ROUTE_DESTINATION; 03536 case 480: /* No answer */ 03537 return AST_CAUSE_NO_ANSWER; 03538 case 481: /* No answer */ 03539 return AST_CAUSE_INTERWORKING; 03540 case 482: /* Loop detected */ 03541 return AST_CAUSE_INTERWORKING; 03542 case 483: /* Too many hops */ 03543 return AST_CAUSE_NO_ANSWER; 03544 case 484: /* Address incomplete */ 03545 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03546 case 485: /* Ambigous */ 03547 return AST_CAUSE_UNALLOCATED; 03548 case 486: /* Busy everywhere */ 03549 return AST_CAUSE_BUSY; 03550 case 487: /* Request terminated */ 03551 return AST_CAUSE_INTERWORKING; 03552 case 488: /* No codecs approved */ 03553 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03554 case 491: /* Request pending */ 03555 return AST_CAUSE_INTERWORKING; 03556 case 493: /* Undecipherable */ 03557 return AST_CAUSE_INTERWORKING; 03558 case 500: /* Server internal failure */ 03559 return AST_CAUSE_FAILURE; 03560 case 501: /* Call rejected */ 03561 return AST_CAUSE_FACILITY_REJECTED; 03562 case 502: 03563 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03564 case 503: /* Service unavailable */ 03565 return AST_CAUSE_CONGESTION; 03566 case 504: /* Gateway timeout */ 03567 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03568 case 505: /* SIP version not supported */ 03569 return AST_CAUSE_INTERWORKING; 03570 case 600: /* Busy everywhere */ 03571 return AST_CAUSE_USER_BUSY; 03572 case 603: /* Decline */ 03573 return AST_CAUSE_CALL_REJECTED; 03574 case 604: /* Does not exist anywhere */ 03575 return AST_CAUSE_UNALLOCATED; 03576 case 606: /* Not acceptable */ 03577 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03578 default: 03579 return AST_CAUSE_NORMAL; 03580 } 03581 /* Never reached */ 03582 return 0; 03583 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6339 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06340 { 06341 /* Initialize a request */ 06342 memset(req, 0, sizeof(*req)); 06343 req->method = sipmethod; 06344 req->header[0] = req->data; 06345 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06346 req->len = strlen(req->header[0]); 06347 req->headers++; 06348 return 0; 06349 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6326 of file chan_sip.c.
References SIP_RESPONSE.
06327 { 06328 /* Initialize a response */ 06329 memset(resp, 0, sizeof(*resp)); 06330 resp->method = SIP_RESPONSE; 06331 resp->header[0] = resp->data; 06332 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06333 resp->len = strlen(resp->header[0]); 06334 resp->headers++; 06335 return 0; 06336 }
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 1704 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), sip_pvt::callid, 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().
01705 { 01706 if (p->initreq.headers && option_debug) { 01707 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01708 } 01709 /* Use this as the basis */ 01710 copy_request(&p->initreq, req); 01711 parse_request(&p->initreq); 01712 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01713 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01714 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7485 of file chan_sip.c.
References add_header(), add_route(), 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::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, FROMDOMAIN_INVALID, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::portinuri, sip_pvt::route, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
07486 { 07487 char invite_buf[256] = ""; 07488 char *invite = invite_buf; 07489 size_t invite_max = sizeof(invite_buf); 07490 char from[256]; 07491 char to[256]; 07492 char tmp[SIPBUFSIZE/2]; 07493 char tmp2[SIPBUFSIZE/2]; 07494 const char *l = NULL, *n = NULL, *d = NULL; 07495 const char *urioptions = ""; 07496 07497 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07498 const char *s = p->username; /* being a string field, cannot be NULL */ 07499 07500 /* Test p->username against allowed characters in AST_DIGIT_ANY 07501 If it matches the allowed characters list, then sipuser = ";user=phone" 07502 If not, then sipuser = "" 07503 */ 07504 /* + is allowed in first position in a tel: uri */ 07505 if (*s == '+') 07506 s++; 07507 for (; *s; s++) { 07508 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07509 break; 07510 } 07511 /* If we have only digits, add ;user=phone to the uri */ 07512 if (!*s) 07513 urioptions = ";user=phone"; 07514 } 07515 07516 07517 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07518 07519 d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07520 if (p->owner) { 07521 l = p->owner->cid.cid_num; 07522 n = p->owner->cid.cid_name; 07523 } 07524 /* if we are not sending RPID and user wants his callerid restricted */ 07525 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07526 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07527 l = CALLERID_UNKNOWN; 07528 n = l; 07529 d = FROMDOMAIN_INVALID; 07530 } 07531 if (ast_strlen_zero(l)) 07532 l = default_callerid; 07533 if (ast_strlen_zero(n)) 07534 n = l; 07535 /* Allow user to be overridden */ 07536 if (!ast_strlen_zero(p->fromuser)) 07537 l = p->fromuser; 07538 else /* Save for any further attempts */ 07539 ast_string_field_set(p, fromuser, l); 07540 07541 /* Allow user to be overridden */ 07542 if (!ast_strlen_zero(p->fromname)) 07543 n = p->fromname; 07544 else /* Save for any further attempts */ 07545 ast_string_field_set(p, fromname, n); 07546 07547 if (pedanticsipchecking) { 07548 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07549 n = tmp; 07550 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07551 l = tmp2; 07552 } 07553 07554 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07555 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 07556 else 07557 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 07558 07559 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07560 if (!ast_strlen_zero(p->fullcontact)) { 07561 /* If we have full contact, trust it */ 07562 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07563 } else { 07564 /* Otherwise, use the username while waiting for registration */ 07565 ast_build_string(&invite, &invite_max, "sip:"); 07566 if (!ast_strlen_zero(p->username)) { 07567 n = p->username; 07568 if (pedanticsipchecking) { 07569 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07570 n = tmp; 07571 } 07572 ast_build_string(&invite, &invite_max, "%s@", n); 07573 } 07574 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07575 if (p->portinuri) 07576 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07577 ast_build_string(&invite, &invite_max, "%s", urioptions); 07578 } 07579 07580 /* If custom URI options have been provided, append them */ 07581 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07582 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07583 07584 ast_string_field_set(p, uri, invite_buf); 07585 07586 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07587 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07588 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07589 } else if (p->options && p->options->vxml_url) { 07590 /* If there is a VXML URL append it to the SIP URL */ 07591 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07592 } else 07593 snprintf(to, sizeof(to), "<%s>", p->uri); 07594 07595 init_req(req, sipmethod, p->uri); 07596 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07597 07598 add_header(req, "Via", p->via); 07599 /* This will be a no-op most of the time. However, under certain circumstances, 07600 * NOTIFY messages will use this function for preparing the request and should 07601 * have Route headers present. 07602 */ 07603 add_route(req, p->route); 07604 /* Build Remote Party-ID and From */ 07605 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07606 build_rpid(p); 07607 add_header(req, "From", p->rpid_from); 07608 } else 07609 add_header(req, "From", from); 07610 add_header(req, "To", to); 07611 ast_string_field_set(p, exten, l); 07612 build_contact(p); 07613 add_header(req, "Contact", p->our_contact); 07614 add_header(req, "Call-ID", p->callid); 07615 add_header(req, "CSeq", tmp); 07616 if (!ast_strlen_zero(global_useragent)) 07617 add_header(req, "User-Agent", global_useragent); 07618 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07619 if (!ast_strlen_zero(p->rpid)) 07620 add_header(req, "Remote-Party-ID", p->rpid); 07621 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10867 of file chan_sip.c.
Referenced by _sip_show_peer().
10868 { 10869 if (port && invite) 10870 return "port,invite"; 10871 else if (port) 10872 return "port"; 10873 else if (invite) 10874 return "invite"; 10875 else 10876 return "no"; 10877 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8868 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08869 { 08870 if (!route) 08871 ast_verbose("list_route: no route\n"); 08872 else { 08873 for (;route; route = route->next) 08874 ast_verbose("list_route: hop: <%s>\n", route->hop); 08875 } 08876 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 19501 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
19502 { 19503 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 19504 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 19505 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 19506 19507 if (!(sched = sched_context_create())) { 19508 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 19509 return AST_MODULE_LOAD_FAILURE; 19510 } 19511 19512 if (!(io = io_context_create())) { 19513 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 19514 sched_context_destroy(sched); 19515 return AST_MODULE_LOAD_FAILURE; 19516 } 19517 19518 sip_reloadreason = CHANNEL_MODULE_LOAD; 19519 19520 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 19521 return AST_MODULE_LOAD_DECLINE; 19522 19523 /* Make sure we can register our sip channel type */ 19524 if (ast_channel_register(&sip_tech)) { 19525 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 19526 io_context_destroy(io); 19527 sched_context_destroy(sched); 19528 return AST_MODULE_LOAD_FAILURE; 19529 } 19530 19531 /* Register all CLI functions for SIP */ 19532 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 19533 19534 /* Tell the RTP subdriver that we're here */ 19535 ast_rtp_proto_register(&sip_rtp); 19536 19537 /* Tell the UDPTL subdriver that we're here */ 19538 ast_udptl_proto_register(&sip_udptl); 19539 19540 /* Register dialplan applications */ 19541 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 19542 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 19543 19544 /* Register dialplan functions */ 19545 ast_custom_function_register(&sip_header_function); 19546 ast_custom_function_register(&sippeer_function); 19547 ast_custom_function_register(&sipchaninfo_function); 19548 ast_custom_function_register(&checksipdomain_function); 19549 19550 /* Register manager commands */ 19551 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 19552 "List SIP peers (text format)", mandescr_show_peers); 19553 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 19554 "Show SIP peer (text format)", mandescr_show_peer); 19555 19556 sip_poke_all_peers(); 19557 sip_send_all_registers(); 19558 19559 /* And start the monitor for the first time */ 19560 restart_monitor(); 19561 19562 return AST_MODULE_LOAD_SUCCESS; 19563 }
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 15398 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, ast_channel::name, 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().
15399 { 15400 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 15401 /* Chan 2: Call from Asterisk to target */ 15402 int res = 0; 15403 struct sip_pvt *targetcall_pvt; 15404 15405 /* Check if the call ID of the replaces header does exist locally */ 15406 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 15407 transferer->refer->replaces_callid_fromtag))) { 15408 if (transferer->refer->localtransfer) { 15409 /* We did not find the refered call. Sorry, can't accept then */ 15410 transmit_response(transferer, "202 Accepted", req); 15411 /* Let's fake a response from someone else in order 15412 to follow the standard */ 15413 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 15414 append_history(transferer, "Xfer", "Refer failed"); 15415 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15416 transferer->refer->status = REFER_FAILED; 15417 return -1; 15418 } 15419 /* Fall through for remote transfers that we did not find locally */ 15420 if (option_debug > 2) 15421 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 15422 return 0; 15423 } 15424 15425 /* Ok, we can accept this transfer */ 15426 transmit_response(transferer, "202 Accepted", req); 15427 append_history(transferer, "Xfer", "Refer accepted"); 15428 if (!targetcall_pvt->owner) { /* No active channel */ 15429 if (option_debug > 3) 15430 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 15431 /* Cancel transfer */ 15432 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 15433 append_history(transferer, "Xfer", "Refer failed"); 15434 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15435 transferer->refer->status = REFER_FAILED; 15436 ast_mutex_unlock(&targetcall_pvt->lock); 15437 return -1; 15438 } 15439 15440 /* We have a channel, find the bridge */ 15441 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 15442 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 15443 15444 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 15445 /* Wrong state of new channel */ 15446 if (option_debug > 3) { 15447 if (target.chan2) 15448 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 15449 else if (target.chan1->_state != AST_STATE_RING) 15450 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 15451 else 15452 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 15453 } 15454 } 15455 15456 /* Transfer */ 15457 if (option_debug > 3 && sipdebug) { 15458 if (current->chan2) /* We have two bridges */ 15459 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 15460 else /* One bridge, propably transfer of IVR/voicemail etc */ 15461 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 15462 } 15463 15464 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15465 15466 /* Perform the transfer */ 15467 res = attempt_transfer(current, &target); 15468 ast_mutex_unlock(&targetcall_pvt->lock); 15469 if (res) { 15470 /* Failed transfer */ 15471 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 15472 append_history(transferer, "Xfer", "Refer failed"); 15473 transferer->refer->status = REFER_FAILED; 15474 if (targetcall_pvt->owner) 15475 ast_channel_unlock(targetcall_pvt->owner); 15476 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 15477 if (res != -2) 15478 ast_hangup(transferer->owner); 15479 else 15480 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 15481 } else { 15482 /* Transfer succeeded! */ 15483 15484 /* Tell transferer that we're done. */ 15485 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 15486 append_history(transferer, "Xfer", "Refer succeeded"); 15487 transferer->refer->status = REFER_200OK; 15488 if (targetcall_pvt->owner) { 15489 if (option_debug) 15490 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 15491 ast_channel_unlock(targetcall_pvt->owner); 15492 } 15493 } 15494 return 1; 15495 }
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 5033 of file chan_sip.c.
References t.
Referenced by sipsock_read().
05034 { 05035 int h = 0, t = 0; 05036 int lws = 0; 05037 05038 for (; h < len;) { 05039 /* Eliminate all CRs */ 05040 if (msgbuf[h] == '\r') { 05041 h++; 05042 continue; 05043 } 05044 /* Check for end-of-line */ 05045 if (msgbuf[h] == '\n') { 05046 /* Check for end-of-message */ 05047 if (h + 1 == len) 05048 break; 05049 /* Check for a continuation line */ 05050 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 05051 /* Merge continuation line */ 05052 h++; 05053 continue; 05054 } 05055 /* Propagate LF and start new line */ 05056 msgbuf[t++] = msgbuf[h++]; 05057 lws = 0; 05058 continue; 05059 } 05060 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 05061 if (lws) { 05062 h++; 05063 continue; 05064 } 05065 msgbuf[t++] = msgbuf[h++]; 05066 lws = 1; 05067 continue; 05068 } 05069 msgbuf[t++] = msgbuf[h++]; 05070 if (lws) 05071 lws = 0; 05072 } 05073 msgbuf[t] = '\0'; 05074 return t; 05075 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4688 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().
04689 { 04690 snprintf(tagbuf, len, "as%08lx", ast_random()); 04691 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11112 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.
Referenced by load_module().
11113 { 11114 const char *a[4]; 11115 const char *peer; 11116 int ret; 11117 11118 peer = astman_get_header(m,"Peer"); 11119 if (ast_strlen_zero(peer)) { 11120 astman_send_error(s, m, "Peer: <name> missing."); 11121 return 0; 11122 } 11123 a[0] = "sip"; 11124 a[1] = "show"; 11125 a[2] = "peer"; 11126 a[3] = peer; 11127 11128 ret = _sip_show_peer(1, -1, s, m, 4, a); 11129 astman_append(s, "\r\n\r\n" ); 11130 return ret; 11131 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10663 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), s, and total.
Referenced by load_module().
10664 { 10665 const char *id = astman_get_header(m,"ActionID"); 10666 const char *a[] = {"sip", "show", "peers"}; 10667 char idtext[256] = ""; 10668 int total = 0; 10669 10670 if (!ast_strlen_zero(id)) 10671 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10672 10673 astman_send_ack(s, m, "Peer status list will follow"); 10674 /* List the peers in separate manager events */ 10675 _sip_show_peers(-1, &total, s, m, 3, a); 10676 /* Send final confirmation */ 10677 astman_append(s, 10678 "Event: PeerlistComplete\r\n" 10679 "ListItems: %d\r\n" 10680 "%s" 10681 "\r\n", total, idtext); 10682 return 0; 10683 }
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 1730 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
01731 { 01732 int len = strlen(sip_methods[id].text); 01733 int l_name = name ? strlen(name) : 0; 01734 /* true if the string is long enough, and ends with whitespace, and matches */ 01735 return (l_name >= len && name[len] < 33 && 01736 !strncasecmp(sip_methods[id].text, name, len)); 01737 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10566 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().
10567 { 10568 switch(nat) { 10569 case SIP_NAT_NEVER: 10570 return "No"; 10571 case SIP_NAT_ROUTE: 10572 return "Route"; 10573 case SIP_NAT_ALWAYS: 10574 return "Always"; 10575 case SIP_NAT_RFC3581: 10576 return "RFC3581"; 10577 default: 10578 return "Unknown"; 10579 } 10580 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2319 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02320 { 02321 memset(dst, 0, sizeof(*dst)); 02322 memcpy(dst->data, src->data, sizeof(dst->data)); 02323 dst->len = src->len; 02324 parse_request(dst); 02325 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12774 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, SIPBUFSIZE, and t.
Referenced by handle_response().
12775 { 12776 char tmp[SIPBUFSIZE]; 12777 char *s, *e, *uri, *t; 12778 char *domain; 12779 12780 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12781 if ((t = strchr(tmp, ','))) 12782 *t = '\0'; 12783 s = get_in_brackets(tmp); 12784 uri = ast_strdupa(s); 12785 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12786 if (!strncasecmp(s, "sip:", 4)) 12787 s += 4; 12788 e = strchr(s, ';'); 12789 if (e) 12790 *e = '\0'; 12791 if (option_debug) 12792 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12793 if (p->owner) 12794 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12795 } else { 12796 e = strchr(tmp, '@'); 12797 if (e) { 12798 *e++ = '\0'; 12799 domain = e; 12800 } else { 12801 /* No username part */ 12802 domain = tmp; 12803 } 12804 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12805 if (e) 12806 *e = '\0'; 12807 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12808 if (e) 12809 *e = '\0'; 12810 12811 if (!strncasecmp(s, "sip:", 4)) 12812 s += 4; 12813 if (option_debug > 1) 12814 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12815 if (p->owner) { 12816 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12817 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12818 ast_string_field_set(p->owner, call_forward, s); 12819 } 12820 } 12821 }
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 8593 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
08594 { 08595 char contact[SIPBUFSIZE]; 08596 char *c; 08597 08598 /* Look for brackets */ 08599 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08600 c = get_in_brackets(contact); 08601 08602 /* Save full contact to call pvt for later bye or re-invite */ 08603 ast_string_field_set(pvt, fullcontact, c); 08604 08605 /* Save URI for later ACKs, BYE or RE-invites */ 08606 ast_string_field_set(pvt, okcontacturi, c); 08607 08608 /* We should return false for URI:s we can't handle, 08609 like sips:, tel:, mailto:,ldap: etc */ 08610 return TRUE; 08611 }
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 8682 of file chan_sip.c.
References sip_peer::addr, ahp, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), AST_SENSE_ALLOW, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), global_contact_ha, hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, option_verbose, PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_peer::portinuri, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08683 { 08684 char contact[SIPBUFSIZE]; 08685 char data[SIPBUFSIZE]; 08686 const char *expires = get_header(req, "Expires"); 08687 int expiry = atoi(expires); 08688 char *curi, *n, *pt; 08689 int port; 08690 const char *useragent; 08691 struct hostent *hp; 08692 struct ast_hostent ahp; 08693 struct sockaddr_in oldsin, testsin; 08694 08695 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08696 08697 if (ast_strlen_zero(expires)) { /* No expires header */ 08698 expires = strcasestr(contact, ";expires="); 08699 if (expires) { 08700 /* XXX bug here, we overwrite the string */ 08701 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08702 if (sscanf(expires + 9, "%30d", &expiry) != 1) 08703 expiry = default_expiry; 08704 } else { 08705 /* Nothing has been specified */ 08706 expiry = default_expiry; 08707 } 08708 } 08709 08710 /* Look for brackets */ 08711 curi = contact; 08712 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08713 strsep(&curi, ";"); /* This is Header options, not URI options */ 08714 curi = get_in_brackets(contact); 08715 08716 /* if they did not specify Contact: or Expires:, they are querying 08717 what we currently have stored as their contact address, so return 08718 it 08719 */ 08720 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08721 /* If we have an active registration, tell them when the registration is going to expire */ 08722 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08723 pvt->expiry = ast_sched_when(sched, peer->expire); 08724 return PARSE_REGISTER_QUERY; 08725 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08726 /* This means remove all registrations and return OK */ 08727 memset(&peer->addr, 0, sizeof(peer->addr)); 08728 if (!AST_SCHED_DEL(sched, peer->expire)) { 08729 struct sip_peer *peer_ptr = peer; 08730 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08731 } 08732 08733 destroy_association(peer); 08734 08735 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08736 peer->fullcontact[0] = '\0'; 08737 peer->useragent[0] = '\0'; 08738 peer->sipoptions = 0; 08739 peer->lastms = 0; 08740 peer->portinuri = 0; 08741 pvt->expiry = 0; 08742 08743 if (option_verbose > 2) 08744 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08745 08746 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08747 return PARSE_REGISTER_UPDATE; 08748 } 08749 08750 /* Store whatever we got as a contact from the client */ 08751 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08752 08753 /* For the 200 OK, we should use the received contact */ 08754 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08755 08756 /* Make sure it's a SIP URL */ 08757 if (strncasecmp(curi, "sip:", 4)) { 08758 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08759 } else 08760 curi += 4; 08761 /* Ditch q */ 08762 curi = strsep(&curi, ";"); 08763 /* Grab host */ 08764 n = strchr(curi, '@'); 08765 if (!n) { 08766 n = curi; 08767 curi = NULL; 08768 } else 08769 *n++ = '\0'; 08770 pt = strchr(n, ':'); 08771 if (pt) { 08772 *pt++ = '\0'; 08773 port = atoi(pt); 08774 peer->portinuri = 1; 08775 } else { 08776 port = STANDARD_SIP_PORT; 08777 peer->portinuri = 0; 08778 } 08779 oldsin = peer->addr; 08780 08781 /* Check that they're allowed to register at this IP */ 08782 /* XXX This could block for a long time XXX */ 08783 hp = ast_gethostbyname(n, &ahp); 08784 if (!hp) { 08785 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08786 *peer->fullcontact = '\0'; 08787 ast_string_field_set(pvt, our_contact, ""); 08788 return PARSE_REGISTER_FAILED; 08789 } 08790 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08791 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08792 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08793 ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", n, ast_inet_ntoa(testsin.sin_addr)); 08794 *peer->fullcontact = '\0'; 08795 ast_string_field_set(pvt, our_contact, ""); 08796 return PARSE_REGISTER_DENIED; 08797 } 08798 08799 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08800 peer->addr.sin_family = AF_INET; 08801 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08802 peer->addr.sin_port = htons(port); 08803 } else { 08804 /* Don't trust the contact field. Just use what they came to us 08805 with */ 08806 peer->addr = pvt->recv; 08807 } 08808 08809 /* Save SIP options profile */ 08810 peer->sipoptions = pvt->sipoptions; 08811 08812 if (curi && ast_strlen_zero(peer->username)) 08813 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08814 08815 if (!AST_SCHED_DEL(sched, peer->expire)) { 08816 struct sip_peer *peer_ptr = peer; 08817 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08818 } 08819 if (expiry > max_expiry) 08820 expiry = max_expiry; 08821 if (expiry < min_expiry) 08822 expiry = min_expiry; 08823 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08824 peer->expire = -1; 08825 } else { 08826 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08827 if (peer->expire == -1) { 08828 struct sip_peer *peer_ptr = peer; 08829 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08830 } 08831 } 08832 pvt->expiry = expiry; 08833 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); 08834 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08835 ast_db_put("SIP/Registry", peer->name, data); 08836 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08837 08838 /* Is this a new IP address for us? */ 08839 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08840 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port)); 08841 } 08842 sip_poke_peer(peer); 08843 register_peer_exten(peer, 1); 08844 08845 /* Save User agent */ 08846 useragent = get_header(req, "User-Agent"); 08847 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08848 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08849 if (option_verbose > 3) 08850 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08851 } 08852 return PARSE_REGISTER_UPDATE; 08853 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 5080 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
05081 { 05082 /* Divide fields by NULL's */ 05083 char *c; 05084 int f = 0; 05085 05086 c = req->data; 05087 05088 /* First header starts immediately */ 05089 req->header[f] = c; 05090 while(*c) { 05091 if (*c == '\n') { 05092 /* We've got a new header */ 05093 *c = 0; 05094 05095 if (sipdebug && option_debug > 3) 05096 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05097 if (ast_strlen_zero(req->header[f])) { 05098 /* Line by itself means we're now in content */ 05099 c++; 05100 break; 05101 } 05102 if (f >= SIP_MAX_HEADERS - 1) { 05103 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 05104 } else { 05105 f++; 05106 req->header[f] = c + 1; 05107 } 05108 } else if (*c == '\r') { 05109 /* Ignore but eliminate \r's */ 05110 *c = 0; 05111 } 05112 c++; 05113 } 05114 05115 req->headers = f; 05116 05117 /* Check a non-newline-terminated last header */ 05118 if (!ast_strlen_zero(req->header[f])) { 05119 if (sipdebug && option_debug > 3) 05120 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05121 req->headers++; 05122 } 05123 05124 /* Now we process any body content */ 05125 f = 0; 05126 req->line[f] = c; 05127 while (*c) { 05128 if (*c == '\n') { 05129 /* We've got a new line */ 05130 *c = 0; 05131 if (sipdebug && option_debug > 3) 05132 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05133 if (f == SIP_MAX_LINES - 1) { 05134 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 05135 break; 05136 } else { 05137 f++; 05138 req->line[f] = c + 1; 05139 } 05140 } else if (*c == '\r') { 05141 /* Ignore and eliminate \r's */ 05142 *c = 0; 05143 } 05144 c++; 05145 } 05146 05147 req->lines = f; 05148 05149 /* Check a non-newline-terminated last line */ 05150 if (!ast_strlen_zero(req->line[f])) { 05151 if (sipdebug && option_debug > 3) 05152 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05153 req->lines++; 05154 } 05155 05156 if (*c) 05157 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05158 05159 /* Split up the first line parts */ 05160 return determine_firstline_parts(req); 05161 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1754 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, sip_request::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01755 { 01756 char *next, *sep; 01757 char *temp; 01758 unsigned int profile = 0; 01759 int i, found; 01760 01761 if (ast_strlen_zero(supported) ) 01762 return 0; 01763 temp = ast_strdupa(supported); 01764 01765 if (option_debug > 2 && sipdebug) 01766 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01767 01768 for (next = temp; next; next = sep) { 01769 found = FALSE; 01770 if ( (sep = strchr(next, ',')) != NULL) 01771 *sep++ = '\0'; 01772 next = ast_skip_blanks(next); 01773 if (option_debug > 2 && sipdebug) 01774 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01775 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01776 if (!strcasecmp(next, sip_options[i].text)) { 01777 profile |= sip_options[i].id; 01778 found = TRUE; 01779 if (option_debug > 2 && sipdebug) 01780 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01781 break; 01782 } 01783 } 01784 if (!found && option_debug > 2 && sipdebug) { 01785 if (!strncasecmp(next, "x-", 2)) 01786 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01787 else 01788 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01789 } 01790 } 01791 01792 if (pvt) 01793 pvt->sipoptions = profile; 01794 return profile; 01795 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10585 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10586 { 10587 int res = 0; 10588 if (peer->maxms) { 10589 if (peer->lastms < 0) { 10590 ast_copy_string(status, "UNREACHABLE", statuslen); 10591 } else if (peer->lastms > peer->maxms) { 10592 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10593 res = 1; 10594 } else if (peer->lastms) { 10595 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10596 res = 1; 10597 } else { 10598 ast_copy_string(status, "UNKNOWN", statuslen); 10599 } 10600 } else { 10601 ast_copy_string(status, "Unmonitored", statuslen); 10602 /* Checking if port is 0 */ 10603 res = -1; 10604 } 10605 return res; 10606 }
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 11053 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().
11054 { 11055 int x, codec; 11056 11057 for(x = 0; x < 32 ; x++) { 11058 codec = ast_codec_pref_index(pref, x); 11059 if (!codec) 11060 break; 11061 ast_cli(fd, "%s", ast_getformatname(codec)); 11062 ast_cli(fd, ":%d", pref->framing[x]); 11063 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 11064 ast_cli(fd, ","); 11065 } 11066 if (!x) 11067 ast_cli(fd, "none"); 11068 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10844 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10845 { 10846 char buf[256]; 10847 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10848 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16626 of file chan_sip.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_request(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.
Referenced by sipsock_read().
16627 { 16628 struct sip_request *req; 16629 16630 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 16631 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 16632 /* Request failed */ 16633 if (option_debug) { 16634 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16635 } 16636 } 16637 ast_free(req); 16638 } 16639 }
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 host IP
< RTP video host IP
< RTP Audio port number
< RTP Video port number
< UDPTL Image port number
< media socket address
< video socket address
< image socket address
< Buffers for codec handling
< Negotiated capability
Definition at line 5352 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::callid, sip_pvt::capability, change_hold_state(), debug, t38properties::direct, FALSE, sip_pvt::flags, get_sdp_iterate(), get_sdp_line(), ast_hostent::hp, 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, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_pvt::noncodeccapability, offered_media::offered, sip_pvt::offered_media, option_debug, sip_pvt::owner, sip_pvt::peercapability, portno, sip_pvt::prefs, process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_video(), process_sdp_c(), ast_channel::readformat, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_IMAGE, sip_request::sdp_start, SDP_VIDEO, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, TRUE, type, sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.
05353 { 05354 /* Iterators for SDP parsing */ 05355 int start = req->sdp_start; 05356 int next = start; 05357 int iterator = start; 05358 05359 /* Temporary vars for SDP parsing */ 05360 char type = '\0'; 05361 const char *value = NULL; 05362 const char *m = NULL; /* SDP media offer */ 05363 const char *nextm = NULL; 05364 int len = -1; 05365 05366 /* Host information */ 05367 struct ast_hostent audiohp; 05368 struct ast_hostent videohp; 05369 struct ast_hostent sessionhp; 05370 struct hostent *hp = NULL; /*!< RTP Audio host IP */ 05371 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05372 int portno = -1; /*!< RTP Audio port number */ 05373 int vportno = -1; /*!< RTP Video port number */ 05374 int udptlportno = -1; /*!< UDPTL Image port number */ 05375 struct sockaddr_in sin; /*!< media socket address */ 05376 struct sockaddr_in vsin; /*!< video socket address */ 05377 struct sockaddr_in isin; /*!< image socket address */ 05378 05379 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05380 int peercapability = 0, peernoncodeccapability = 0; 05381 int vpeercapability = 0, vpeernoncodeccapability = 0; 05382 struct ast_rtp *newaudiortp, *newvideortp; /*!< Buffers for codec handling */ 05383 int newjointcapability; /*!< Negotiated capability */ 05384 int newpeercapability; 05385 int newnoncodeccapability; 05386 const char *codecs; 05387 int codec; 05388 05389 /* Others */ 05390 int sendonly = -1; 05391 int vsendonly = -1; 05392 int numberofports; 05393 int numberofmediastreams = 0; 05394 int last_rtpmap_codec = 0; 05395 int debug = sip_debug_test_pvt(p); 05396 05397 /* Initial check */ 05398 if (!p->rtp) { 05399 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05400 return -1; 05401 } 05402 05403 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05404 #ifdef LOW_MEMORY 05405 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05406 #else 05407 newaudiortp = alloca(ast_rtp_alloc_size()); 05408 #endif 05409 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05410 ast_rtp_new_init(newaudiortp); 05411 ast_rtp_pt_clear(newaudiortp); 05412 05413 #ifdef LOW_MEMORY 05414 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05415 #else 05416 newvideortp = alloca(ast_rtp_alloc_size()); 05417 #endif 05418 memset(newvideortp, 0, ast_rtp_alloc_size()); 05419 ast_rtp_new_init(newvideortp); 05420 ast_rtp_pt_clear(newvideortp); 05421 05422 05423 /* Update our last rtprx when we receive an SDP, too */ 05424 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05425 05426 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05427 05428 memset(p->offered_media, 0, sizeof(p->offered_media)); 05429 05430 05431 /* Scan for the first media stream (m=) line to limit scanning of globals */ 05432 nextm = get_sdp_iterate(&next, req, "m"); 05433 if (ast_strlen_zero(nextm)) { 05434 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 05435 return -1; 05436 } 05437 05438 /* Scan session level SDP parameters (lines before first media stream) */ 05439 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05440 int processed = FALSE; 05441 switch (type) { 05442 case 'c': 05443 if (process_sdp_c(value, &sessionhp)) { 05444 processed = TRUE; 05445 hp = &sessionhp.hp; 05446 vhp = hp; 05447 } 05448 break; 05449 case 'a': 05450 if (process_sdp_a_sendonly(value, &sendonly)) { 05451 processed = TRUE; 05452 vsendonly = sendonly; 05453 } 05454 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05455 processed = TRUE; 05456 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05457 processed = TRUE; 05458 else if (process_sdp_a_image(value, p)) 05459 processed = TRUE; 05460 break; 05461 } 05462 05463 if (option_debug > 2) 05464 ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 05465 } 05466 05467 05468 /* Scan media stream (m=) specific parameters loop */ 05469 while (!ast_strlen_zero(nextm)) { 05470 int audio = FALSE; 05471 int video = FALSE; 05472 int image = FALSE; 05473 int x; 05474 05475 numberofports = 1; 05476 len = -1; 05477 start = next; 05478 m = nextm; 05479 iterator = next; 05480 nextm = get_sdp_iterate(&next, req, "m"); 05481 05482 /* Search for audio media definition */ 05483 if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05484 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05485 /* Found audio stream in this media definition */ 05486 audio = TRUE; 05487 p->offered_media[SDP_AUDIO].offered = TRUE; 05488 numberofmediastreams++; 05489 portno = x; 05490 05491 /* Scan through the RTP payload types specified in a "m=" line: */ 05492 codecs = m + len; 05493 ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text)); 05494 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05495 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05496 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05497 return -1; 05498 } 05499 if (debug) 05500 ast_verbose("Found RTP audio format %d\n", codec); 05501 ast_rtp_set_m_type(newaudiortp, codec); 05502 } 05503 /* Search for video media definition */ 05504 } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05505 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05506 /* Found video stream in this media definition */ 05507 video = TRUE; 05508 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05509 p->offered_media[SDP_VIDEO].offered = TRUE; 05510 numberofmediastreams++; 05511 vportno = x; 05512 05513 /* Scan through the RTP payload types specified in a "m=" line: */ 05514 codecs = m + len; 05515 ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text)); 05516 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05517 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05518 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05519 return -1; 05520 } 05521 if (debug) 05522 ast_verbose("Found RTP video format %d\n", codec); 05523 ast_rtp_set_m_type(newvideortp, codec); 05524 } 05525 /* Search for image media definition */ 05526 } else if (p->udptl && ((sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 05527 (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0))) { 05528 /* Found image stream in this media definition */ 05529 image = TRUE; 05530 if (debug) 05531 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05532 p->offered_media[SDP_IMAGE].offered = TRUE; 05533 udptlportno = x; 05534 numberofmediastreams++; 05535 05536 if (p->owner && p->lastinvite) { 05537 if (p->t38.state != T38_LOCAL_REINVITE) { 05538 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05539 if (option_debug > 1) 05540 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05541 } 05542 } else { 05543 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05544 p->t38.direct = 1; 05545 if (option_debug > 1) 05546 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05547 } 05548 } else { 05549 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05550 continue; 05551 } 05552 05553 /* Check for number of ports */ 05554 if (numberofports > 1) 05555 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05556 05557 05558 05559 /* Media stream specific parameters */ 05560 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05561 int processed = FALSE; 05562 05563 switch (type) { 05564 case 'c': 05565 if (audio) { 05566 if (process_sdp_c(value, &audiohp)) { 05567 processed = TRUE; 05568 hp = &audiohp.hp; 05569 } 05570 } 05571 else if (video) { 05572 if (process_sdp_c(value, &videohp)) { 05573 processed = TRUE; 05574 vhp = &videohp.hp; 05575 } 05576 } 05577 break; 05578 case 'a': 05579 /* Audio specific scanning */ 05580 if (audio) { 05581 if (process_sdp_a_sendonly(value, &sendonly)) 05582 processed = TRUE; 05583 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05584 processed = TRUE; 05585 } 05586 /* Video specific scanning */ 05587 else if (video) { 05588 if (process_sdp_a_sendonly(value, &vsendonly)) 05589 processed = TRUE; 05590 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05591 processed = TRUE; 05592 } 05593 /* Image (T.38 FAX) specific scanning */ 05594 else if (image) { 05595 if (process_sdp_a_image(value, p)) 05596 processed = TRUE; 05597 } 05598 break; 05599 } 05600 05601 if (option_debug > 2) 05602 ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n", 05603 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 05604 type, value, 05605 (processed == TRUE)? "OK." : "UNSUPPORTED."); 05606 } 05607 } 05608 05609 /* Sanity checks */ 05610 if (!hp) { 05611 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 05612 return -1; 05613 } 05614 05615 if (portno == -1 && vportno == -1 && udptlportno == -1) 05616 /* No acceptable offer found in SDP - we have no ports */ 05617 /* Do not change RTP or VRTP if this is a re-invite */ 05618 return -2; 05619 05620 if (numberofmediastreams > 2) 05621 /* We have too many fax, audio and/or video media streams, fail this offer */ 05622 return -3; 05623 05624 if (udptlportno == -1) { 05625 p->t38.state = T38_DISABLED; 05626 if (option_debug > 2) 05627 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05628 } 05629 05630 05631 /* Now gather all of the codecs that we are asked for: */ 05632 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05633 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05634 05635 newjointcapability = p->capability & (peercapability | vpeercapability); 05636 newpeercapability = (peercapability | vpeercapability); 05637 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05638 05639 05640 if (debug) { 05641 /* shame on whoever coded this.... */ 05642 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05643 05644 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05645 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05646 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05647 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05648 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05649 05650 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05651 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05652 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05653 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05654 } 05655 if (!newjointcapability) { 05656 /* If T.38 was not negotiated either, totally bail out... */ 05657 if (!p->t38.jointcapability || !udptlportno) { 05658 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05659 /* Do NOT Change current setting */ 05660 return -1; 05661 } else { 05662 if (option_debug > 2) 05663 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05664 return 0; 05665 } 05666 } 05667 05668 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05669 they are acceptable */ 05670 p->jointcapability = newjointcapability; /* Our joint codec profile */ 05671 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05672 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05673 05674 ast_rtp_pt_copy(p->rtp, newaudiortp); 05675 if (p->vrtp) 05676 ast_rtp_pt_copy(p->vrtp, newvideortp); 05677 05678 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05679 ast_clear_flag(&p->flags[0], SIP_DTMF); 05680 if (newnoncodeccapability & AST_RTP_DTMF) { 05681 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05682 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05683 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05684 ast_rtp_setdtmf(p->rtp, 1); 05685 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05686 } else { 05687 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05688 } 05689 } 05690 05691 /* Setup audio port number */ 05692 if (p->rtp) { 05693 if (portno > 0) { 05694 sin.sin_family = AF_INET; 05695 sin.sin_port = htons(portno); 05696 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05697 ast_rtp_set_peer(p->rtp, &sin); 05698 if (debug) 05699 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05700 } else if (udptlportno > 0) { 05701 if (debug) 05702 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 05703 } else { 05704 ast_rtp_stop(p->rtp); 05705 if (debug) 05706 ast_verbose("Peer doesn't provide audio\n"); 05707 } 05708 } 05709 05710 /* Setup video port number */ 05711 if (p->vrtp) { 05712 if (vportno > 0) { 05713 vsin.sin_family = AF_INET; 05714 vsin.sin_port = htons(vportno); 05715 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05716 ast_rtp_set_peer(p->vrtp, &vsin); 05717 if (debug) 05718 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05719 } else { 05720 ast_rtp_stop(p->vrtp); 05721 if (debug) 05722 ast_verbose("Peer doesn't provide video\n"); 05723 } 05724 } 05725 05726 /* Setup image port number */ 05727 if (p->udptl) { 05728 if (udptlportno > 0) { 05729 isin.sin_family = AF_INET; 05730 isin.sin_port = htons(udptlportno); 05731 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05732 struct sockaddr_in peer; 05733 ast_rtp_get_peer(p->rtp, &peer); 05734 if (peer.sin_addr.s_addr) { 05735 memcpy(&isin.sin_addr, &peer.sin_addr, sizeof(isin.sin_addr)); 05736 if (debug) 05737 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr)); 05738 } 05739 } else 05740 memcpy(&isin.sin_addr, hp->h_addr, sizeof(isin.sin_addr)); 05741 ast_udptl_set_peer(p->udptl, &isin); 05742 if (debug) 05743 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port)); 05744 } else { 05745 ast_udptl_stop(p->udptl); 05746 if (debug) 05747 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05748 } 05749 } 05750 05751 05752 /* Ok, we're going with this offer */ 05753 if (option_debug > 1) { 05754 char buf[SIPBUFSIZE]; 05755 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05756 } 05757 05758 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05759 return 0; 05760 05761 if (option_debug > 3) 05762 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05763 05764 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05765 if (debug) { 05766 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05767 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05768 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05769 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05770 } 05771 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05772 ast_set_read_format(p->owner, p->owner->readformat); 05773 ast_set_write_format(p->owner, p->owner->writeformat); 05774 } 05775 05776 /* sendonly processing */ 05777 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05778 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05779 /* Activate a re-invite */ 05780 ast_queue_frame(p->owner, &ast_null_frame); 05781 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05782 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05783 S_OR(p->mohsuggest, NULL), 05784 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05785 if (sendonly) 05786 ast_rtp_stop(p->rtp); 05787 /* RTCP needs to go ahead, even if we're on hold!!! */ 05788 /* Activate a re-invite */ 05789 ast_queue_frame(p->owner, &ast_null_frame); 05790 } 05791 05792 /* Manager Hold and Unhold events must be generated, if necessary */ 05793 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05794 change_hold_state(p, req, FALSE, sendonly); 05795 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05796 change_hold_state(p, req, TRUE, sendonly); 05797 05798 return 0; 05799 }
static int process_sdp_a_audio | ( | const char * | a, | |
struct sip_pvt * | p, | |||
struct ast_rtp * | newaudiortp, | |||
int * | last_rtpmap_codec | |||
) | [static] |
Definition at line 5841 of file chan_sip.c.
References ast_codec_pref_setsize(), ast_log(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_test_flag, ast_verbose(), sip_pvt::autoframing, debug, FALSE, sip_pvt::flags, format, LOG_DEBUG, MAX_RTP_PT, option_debug, sip_pvt::rtp, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), SIP_G726_NONSTANDARD, and TRUE.
Referenced by process_sdp().
05842 { 05843 int found = FALSE; 05844 int codec; 05845 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05846 int debug = sip_debug_test_pvt(p); 05847 05848 if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05849 char *tmp = strrchr(a, ':'); 05850 long int framing = 0; 05851 if (tmp) { 05852 tmp++; 05853 framing = strtol(tmp, NULL, 10); 05854 if (framing == LONG_MIN || framing == LONG_MAX) { 05855 framing = 0; 05856 if (option_debug) 05857 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05858 } 05859 } 05860 if (framing && p->autoframing) { 05861 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05862 int codec_n; 05863 int format = 0; 05864 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05865 format = ast_rtp_codec_getformat(codec_n); 05866 if (!format) /* non-codec or not found */ 05867 continue; 05868 if (option_debug) 05869 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05870 ast_codec_pref_setsize(pref, format, framing); 05871 } 05872 ast_rtp_codec_setpref(p->rtp, pref); 05873 } 05874 found = TRUE; 05875 } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 05876 /* We have a rtpmap to handle */ 05877 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05878 /* Note: should really look at the 'freq' and '#chans' params too */ 05879 if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05880 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05881 if (debug) 05882 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05883 (*last_rtpmap_codec)++; 05884 found = TRUE; 05885 } 05886 } else { 05887 if (debug) 05888 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05889 } 05890 05891 if (!found) { 05892 /* Remove this codec since it's an unknown media type for us */ 05893 ast_rtp_unset_m_type(newaudiortp, codec); 05894 if (debug) 05895 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05896 } 05897 } 05898 05899 return found; 05900 }
static int process_sdp_a_image | ( | const char * | a, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 5935 of file chan_sip.c.
References ast_log(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), t38properties::capability, debug, FALSE, t38properties::jointcapability, LOG_DEBUG, option_debug, t38properties::peercapability, s, sip_debug_test_pvt(), sip_pvt::t38, 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, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp().
05936 { 05937 int found = FALSE; 05938 int peert38capability = 0; 05939 char s[256]; 05940 int x; 05941 int debug = sip_debug_test_pvt(p); 05942 05943 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05944 if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) { 05945 found = TRUE; 05946 if (option_debug > 2) 05947 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05948 } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) { 05949 found = TRUE; 05950 if (option_debug > 2) 05951 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05952 switch (x) { 05953 case 14400: 05954 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05955 break; 05956 case 12000: 05957 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05958 break; 05959 case 9600: 05960 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05961 break; 05962 case 7200: 05963 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05964 break; 05965 case 4800: 05966 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05967 break; 05968 case 2400: 05969 peert38capability |= T38FAX_RATE_2400; 05970 break; 05971 } 05972 } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) { 05973 found = TRUE; 05974 if (option_debug > 2) 05975 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05976 if (x == 0) 05977 peert38capability |= T38FAX_VERSION_0; 05978 else if (x == 1) 05979 peert38capability |= T38FAX_VERSION_1; 05980 } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) { 05981 found = TRUE; 05982 if (option_debug > 2) 05983 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05984 ast_udptl_set_far_max_datagram(p->udptl, x); 05985 ast_udptl_set_local_max_datagram(p->udptl, x); 05986 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05987 found = TRUE; 05988 if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) { 05989 if (option_debug > 2) 05990 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05991 if (x == 1) 05992 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05993 } else { 05994 if (option_debug > 2) 05995 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 05996 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05997 } 05998 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 05999 found = TRUE; 06000 if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) { 06001 if (option_debug > 2) 06002 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 06003 if (x == 1) 06004 peert38capability |= T38FAX_TRANSCODING_MMR; 06005 } else { 06006 if (option_debug > 2) 06007 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 06008 peert38capability |= T38FAX_TRANSCODING_MMR; 06009 } 06010 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 06011 found = TRUE; 06012 if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) { 06013 if (option_debug > 2) 06014 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 06015 if (x == 1) 06016 peert38capability |= T38FAX_TRANSCODING_JBIG; 06017 } else { 06018 if (option_debug > 2) 06019 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 06020 peert38capability |= T38FAX_TRANSCODING_JBIG; 06021 } 06022 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 06023 found = TRUE; 06024 if (option_debug > 2) 06025 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 06026 if (!strcasecmp(s, "localTCF")) 06027 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 06028 else if (!strcasecmp(s, "transferredTCF")) 06029 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 06030 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 06031 found = TRUE; 06032 if (option_debug > 2) 06033 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 06034 if (!strcasecmp(s, "t38UDPRedundancy")) { 06035 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 06036 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 06037 } else if (!strcasecmp(s, "t38UDPFEC")) { 06038 peert38capability |= T38FAX_UDP_EC_FEC; 06039 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 06040 } else { 06041 peert38capability |= T38FAX_UDP_EC_NONE; 06042 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 06043 } 06044 } 06045 06046 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 06047 p->t38.peercapability = peert38capability; 06048 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 06049 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 06050 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 06051 } 06052 if (debug) 06053 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 06054 p->t38.capability, 06055 p->t38.peercapability, 06056 p->t38.jointcapability); 06057 06058 return found; 06059 }
static int process_sdp_a_sendonly | ( | const char * | a, | |
int * | sendonly | |||
) | [static] |
Definition at line 5821 of file chan_sip.c.
Referenced by process_sdp().
05822 { 05823 int found = FALSE; 05824 05825 if (!strcasecmp(a, "sendonly")) { 05826 if (*sendonly == -1) 05827 *sendonly = 1; 05828 found = TRUE; 05829 } else if (!strcasecmp(a, "inactive")) { 05830 if (*sendonly == -1) 05831 *sendonly = 2; 05832 found = TRUE; 05833 } else if (!strcasecmp(a, "sendrecv")) { 05834 if (*sendonly == -1) 05835 *sendonly = 0; 05836 found = TRUE; 05837 } 05838 return found; 05839 }
static int process_sdp_a_video | ( | const char * | a, | |
struct sip_pvt * | p, | |||
struct ast_rtp * | newvideortp, | |||
int * | last_rtpmap_codec | |||
) | [static] |
Definition at line 5902 of file chan_sip.c.
References ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_strdupa, ast_verbose(), debug, FALSE, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), TRUE, and sip_pvt::vrtp.
Referenced by process_sdp().
05903 { 05904 int found = FALSE; 05905 int codec; 05906 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05907 int debug = sip_debug_test_pvt(p); 05908 05909 if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 05910 /* We have a rtpmap to handle */ 05911 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05912 /* Note: should really look at the 'freq' and '#chans' params too */ 05913 if (p->vrtp && ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05914 if (debug) 05915 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05916 (*last_rtpmap_codec)++; 05917 found = TRUE; 05918 } 05919 } else { 05920 if (debug) 05921 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05922 } 05923 05924 if (!found) { 05925 /* Remove this codec since it's an unknown media type for us */ 05926 ast_rtp_unset_m_type(newvideortp, codec); 05927 if (debug) 05928 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05929 } 05930 } 05931 05932 return found; 05933 }
static int process_sdp_c | ( | const char * | c, | |
struct ast_hostent * | hp | |||
) | [static] |
Definition at line 5802 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), FALSE, hp, and TRUE.
Referenced by process_sdp().
05803 { 05804 char host[258]; 05805 struct hostent *hp; 05806 05807 /* Check for Media-description-level-address */ 05808 if (sscanf(c, "IN IP4 %255s", host) != 1) { 05809 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05810 return FALSE; 05811 } else { 05812 if (!(hp = ast_gethostbyname(host, ast_hp))) { 05813 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 05814 return FALSE; 05815 } 05816 return TRUE; 05817 } 05818 return FALSE; 05819 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16691 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().
Referenced by sipsock_read().
16692 { 16693 struct sip_request *newreq; 16694 16695 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16696 return -1; 16697 } 16698 16699 copy_request(newreq, req); 16700 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16701 if (p->request_queue_sched_id == -1) { 16702 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16703 } 16704 16705 return 0; 16706 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin, | |||
int | devstate_only | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2642 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), sip_request::flags, hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02643 { 02644 struct sip_peer *peer=NULL; 02645 struct ast_variable *var = NULL; 02646 struct ast_config *peerlist = NULL; 02647 struct ast_variable *tmp; 02648 struct ast_flags flags = {0}; 02649 const char *iabuf = NULL; 02650 char portstring[6]; /*up to five digits plus null terminator*/ 02651 const char *insecure; 02652 char *cat = NULL; 02653 unsigned short portnum; 02654 02655 /* First check on peer name */ 02656 if (newpeername) { 02657 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02658 if (!var && sin) 02659 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02660 if (!var) { 02661 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02662 /*!\note 02663 * If this one loaded something, then we need to ensure that the host 02664 * field matched. The only reason why we can't have this as a criteria 02665 * is because we only have the IP address and the host field might be 02666 * set as a name (and the reverse PTR might not match). 02667 */ 02668 if (var && sin) { 02669 for (tmp = var; tmp; tmp = tmp->next) { 02670 if (!strcasecmp(tmp->name, "host")) { 02671 struct hostent *hp; 02672 struct ast_hostent ahp; 02673 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02674 /* No match */ 02675 ast_variables_destroy(var); 02676 var = NULL; 02677 } 02678 break; 02679 } 02680 } 02681 } 02682 } 02683 } 02684 02685 if (!var && sin) { /* Then check on IP address */ 02686 iabuf = ast_inet_ntoa(sin->sin_addr); 02687 portnum = ntohs(sin->sin_port); 02688 sprintf(portstring, "%d", portnum); 02689 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02690 if (!var) 02691 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02692 if (!var) { 02693 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02694 if(peerlist){ 02695 while((cat = ast_category_browse(peerlist, cat))) 02696 { 02697 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02698 set_insecure_flags(&flags, insecure, -1); 02699 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02700 var = ast_category_root(peerlist, cat); 02701 break; 02702 } 02703 } 02704 } 02705 if(!var) { 02706 ast_config_destroy(peerlist); 02707 peerlist = NULL; /*for safety's sake*/ 02708 cat = NULL; 02709 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02710 if(peerlist) { 02711 while((cat = ast_category_browse(peerlist, cat))) 02712 { 02713 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02714 set_insecure_flags(&flags, insecure, -1); 02715 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02716 var = ast_category_root(peerlist, cat); 02717 break; 02718 } 02719 } 02720 } 02721 } 02722 } 02723 } 02724 02725 if (!var) { 02726 if(peerlist) 02727 ast_config_destroy(peerlist); 02728 return NULL; 02729 } 02730 02731 for (tmp = var; tmp; tmp = tmp->next) { 02732 /* If this is type=user, then skip this object. */ 02733 if (!strcasecmp(tmp->name, "type") && 02734 !strcasecmp(tmp->value, "user")) { 02735 ast_variables_destroy(var); 02736 return NULL; 02737 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02738 newpeername = tmp->value; 02739 } else if (!strcasecmp(tmp->name, "lastms")) { 02740 seen_lastms = 1; 02741 } 02742 } 02743 02744 if (!newpeername) { /* Did not find peer in realtime */ 02745 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02746 if(peerlist) 02747 ast_config_destroy(peerlist); 02748 else 02749 ast_variables_destroy(var); 02750 return NULL; 02751 } 02752 02753 /* Peer found in realtime, now build it in memory */ 02754 peer = build_peer(newpeername, var, NULL, 1, devstate_only); 02755 if (!peer) { 02756 if(peerlist) 02757 ast_config_destroy(peerlist); 02758 else 02759 ast_variables_destroy(var); 02760 return NULL; 02761 } 02762 02763 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02764 /* Cache peer */ 02765 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02766 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02767 if (!AST_SCHED_DEL(sched, peer->expire)) { 02768 struct sip_peer *peer_ptr = peer; 02769 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02770 } 02771 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02772 if (peer->expire == -1) { 02773 struct sip_peer *peer_ptr = peer; 02774 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02775 } 02776 } 02777 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02778 } 02779 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02780 if(peerlist) 02781 ast_config_destroy(peerlist); 02782 else 02783 ast_variables_destroy(var); 02784 return peer; 02785 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey, | |||
int | lastms | |||
) | [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 2521 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02522 { 02523 char port[10]; 02524 char ipaddr[INET_ADDRSTRLEN]; 02525 char regseconds[20]; 02526 char str_lastms[20]; 02527 02528 char *sysname = ast_config_AST_SYSTEM_NAME; 02529 char *syslabel = NULL; 02530 02531 time_t nowtime = time(NULL) + expirey; 02532 const char *fc = fullcontact ? "fullcontact" : NULL; 02533 02534 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02535 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02536 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02537 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02538 02539 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02540 sysname = NULL; 02541 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02542 syslabel = "regserver"; 02543 02544 if (fc) 02545 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02546 "port", port, "regseconds", regseconds, 02547 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02548 else 02549 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02550 "port", port, "regseconds", regseconds, 02551 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02552 if (seen_lastms) { 02553 /* We cannot do this in the same statement as above, because the lack of 02554 * this field could cause the whole statement to fail. */ 02555 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02556 } 02557 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2835 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02836 { 02837 struct ast_variable *var; 02838 struct ast_variable *tmp; 02839 struct sip_user *user = NULL; 02840 02841 var = ast_load_realtime("sipusers", "name", username, NULL); 02842 02843 if (!var) 02844 return NULL; 02845 02846 for (tmp = var; tmp; tmp = tmp->next) { 02847 if (!strcasecmp(tmp->name, "type") && 02848 !strcasecmp(tmp->value, "peer")) { 02849 ast_variables_destroy(var); 02850 return NULL; 02851 } 02852 } 02853 02854 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02855 02856 if (!user) { /* No user found */ 02857 ast_variables_destroy(var); 02858 return NULL; 02859 } 02860 02861 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02862 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02863 suserobjs++; 02864 ASTOBJ_CONTAINER_LINK(&userl,user); 02865 } else { 02866 /* Move counter from s to r... */ 02867 suserobjs--; 02868 ruserobjs++; 02869 } 02870 ast_set_flag(&user->flags[0], SIP_REALTIME); 02871 ast_variables_destroy(var); 02872 return user; 02873 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 10468 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
10469 { 10470 char buf[1024]; 10471 struct ast_frame f; 10472 const char *content_type = get_header(req, "Content-Type"); 10473 10474 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 10475 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 10476 if (!p->owner) 10477 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10478 return; 10479 } 10480 10481 if (get_msg_text(buf, sizeof(buf), req)) { 10482 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 10483 transmit_response(p, "202 Accepted", req); 10484 if (!p->owner) 10485 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10486 return; 10487 } 10488 10489 if (p->owner) { 10490 if (sip_debug_test_pvt(p)) 10491 ast_verbose("Message received: '%s'\n", buf); 10492 memset(&f, 0, sizeof(f)); 10493 f.frametype = AST_FRAME_TEXT; 10494 f.subclass = 0; 10495 f.offset = 0; 10496 f.data = buf; 10497 f.datalen = strlen(buf); 10498 ast_queue_frame(p->owner, &f); 10499 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 10500 } else { /* Message outside of a call, we do not support that */ 10501 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); 10502 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 10503 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10504 } 10505 return; 10506 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1689 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01690 { 01691 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01692 int x; 01693 01694 for (x = 0; x < i; x++) { 01695 if (referstatusstrings[x].status == rstatus) 01696 return (char *) referstatusstrings[x].text; 01697 } 01698 return ""; 01699 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8521 of file chan_sip.c.
References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, sip_peer::name, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, TRUE, sip_peer::username, and username.
08522 { 08523 char data[256]; 08524 struct in_addr in; 08525 int expiry; 08526 int port; 08527 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08528 08529 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08530 return; 08531 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08532 return; 08533 08534 scan = data; 08535 addr = strsep(&scan, ":"); 08536 port_str = strsep(&scan, ":"); 08537 expiry_str = strsep(&scan, ":"); 08538 username = strsep(&scan, ":"); 08539 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08540 08541 if (!inet_aton(addr, &in)) 08542 return; 08543 08544 if (port_str) 08545 port = atoi(port_str); 08546 else 08547 return; 08548 08549 if (expiry_str) 08550 expiry = atoi(expiry_str); 08551 else 08552 return; 08553 08554 if (username) 08555 ast_copy_string(peer->username, username, sizeof(peer->username)); 08556 if (contact) 08557 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08558 08559 if (option_debug > 1) 08560 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08561 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08562 08563 memset(&peer->addr, 0, sizeof(peer->addr)); 08564 peer->addr.sin_family = AF_INET; 08565 peer->addr.sin_addr = in; 08566 peer->addr.sin_port = htons(port); 08567 if (sipsock < 0) { 08568 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08569 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08570 struct sip_peer *peer_ptr = peer; 08571 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08572 } 08573 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08574 if (peer->pokeexpire == -1) { 08575 struct sip_peer *peer_ptr = peer; 08576 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08577 } 08578 } else 08579 sip_poke_peer(peer); 08580 if (!AST_SCHED_DEL(sched, peer->expire)) { 08581 struct sip_peer *peer_ptr = peer; 08582 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08583 } 08584 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08585 if (peer->expire == -1) { 08586 struct sip_peer *peer_ptr = peer; 08587 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08588 } 08589 register_peer_exten(peer, TRUE); 08590 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2560 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, and S_OR.
02561 { 02562 char multi[256]; 02563 char *stringp, *ext, *context; 02564 02565 /* XXX note that global_regcontext is both a global 'enable' flag and 02566 * the name of the global regexten context, if not specified 02567 * individually. 02568 */ 02569 if (ast_strlen_zero(global_regcontext)) 02570 return; 02571 02572 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02573 stringp = multi; 02574 while ((ext = strsep(&stringp, "&"))) { 02575 if ((context = strchr(ext, '@'))) { 02576 *context++ = '\0'; /* split ext@context */ 02577 if (!ast_context_find(context)) { 02578 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02579 continue; 02580 } 02581 } else { 02582 context = global_regcontext; 02583 } 02584 if (onoff) { 02585 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02586 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02587 ast_strdup(peer->name), ast_free_ptr, "SIP"); 02588 } 02589 } else { 02590 ast_context_remove_extension(context, ext, 1, NULL); 02591 } 02592 } 02593 }
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 9344 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_copy_string(), ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, manager_event(), sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_DENIED, 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, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
09346 { 09347 enum check_auth_result res = AUTH_NOT_FOUND; 09348 struct sip_peer *peer; 09349 char tmp[256]; 09350 char *name, *c; 09351 char *t; 09352 char *domain; 09353 09354 /* Terminate URI */ 09355 t = uri; 09356 while(*t && (*t > 32) && (*t != ';')) 09357 t++; 09358 *t = '\0'; 09359 09360 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09361 if (pedanticsipchecking) 09362 ast_uri_decode(tmp); 09363 09364 c = get_in_brackets(tmp); 09365 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09366 09367 if (!strncasecmp(c, "sip:", 4)) { 09368 name = c + 4; 09369 } else { 09370 name = c; 09371 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09372 } 09373 09374 /* Strip off the domain name */ 09375 if ((c = strchr(name, '@'))) { 09376 *c++ = '\0'; 09377 domain = c; 09378 if ((c = strchr(domain, ':'))) /* Remove :port */ 09379 *c = '\0'; 09380 if (!AST_LIST_EMPTY(&domain_list)) { 09381 if (!check_sip_domain(domain, NULL, 0)) { 09382 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09383 return AUTH_UNKNOWN_DOMAIN; 09384 } 09385 } 09386 } 09387 09388 ast_string_field_set(p, exten, name); 09389 build_contact(p); 09390 peer = find_peer(name, NULL, 1, 0); 09391 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09392 /* Peer fails ACL check */ 09393 if (peer) { 09394 ASTOBJ_UNREF(peer, sip_destroy_peer); 09395 res = AUTH_ACL_FAILED; 09396 } else 09397 res = AUTH_NOT_FOUND; 09398 } 09399 if (peer) { 09400 /* Set Frame packetization */ 09401 if (p->rtp) { 09402 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09403 p->autoframing = peer->autoframing; 09404 } 09405 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09406 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09407 res = AUTH_PEER_NOT_DYNAMIC; 09408 } else { 09409 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09410 transmit_response(p, "100 Trying", req); 09411 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09412 if (sip_cancel_destroy(p)) 09413 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09414 09415 /* We have a succesful registration attemp with proper authentication, 09416 now, update the peer */ 09417 switch (parse_register_contact(p, peer, req)) { 09418 case PARSE_REGISTER_DENIED: 09419 transmit_response_with_date(p, "603 Denied", req); 09420 peer->lastmsgssent = -1; 09421 res = 0; 09422 break; 09423 case PARSE_REGISTER_FAILED: 09424 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09425 transmit_response_with_date(p, "400 Bad Request", req); 09426 peer->lastmsgssent = -1; 09427 res = 0; 09428 break; 09429 case PARSE_REGISTER_QUERY: 09430 ast_string_field_set(p, fullcontact, peer->fullcontact); 09431 transmit_response_with_date(p, "200 OK", req); 09432 peer->lastmsgssent = -1; 09433 res = 0; 09434 break; 09435 case PARSE_REGISTER_UPDATE: 09436 ast_string_field_set(p, fullcontact, peer->fullcontact); 09437 update_peer(peer, p->expiry); 09438 /* Say OK and ask subsystem to retransmit msg counter */ 09439 transmit_response_with_date(p, "200 OK", req); 09440 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 09441 peer->lastmsgssent = -1; 09442 res = 0; 09443 break; 09444 } 09445 } 09446 } 09447 } 09448 if (!peer && autocreatepeer) { 09449 /* Create peer if we have autocreate mode enabled */ 09450 peer = temp_peer(name); 09451 if (peer) { 09452 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09453 if (sip_cancel_destroy(p)) 09454 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09455 switch (parse_register_contact(p, peer, req)) { 09456 case PARSE_REGISTER_DENIED: 09457 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 09458 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 09459 peer->lastmsgssent = -1; 09460 res = 0; 09461 break; 09462 case PARSE_REGISTER_FAILED: 09463 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09464 transmit_response_with_date(p, "400 Bad Request", req); 09465 peer->lastmsgssent = -1; 09466 res = 0; 09467 break; 09468 case PARSE_REGISTER_QUERY: 09469 ast_string_field_set(p, fullcontact, peer->fullcontact); 09470 transmit_response_with_date(p, "200 OK", req); 09471 peer->lastmsgssent = -1; 09472 res = 0; 09473 break; 09474 case PARSE_REGISTER_UPDATE: 09475 ast_string_field_set(p, fullcontact, peer->fullcontact); 09476 /* Say OK and ask subsystem to retransmit msg counter */ 09477 transmit_response_with_date(p, "200 OK", req); 09478 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09479 peer->lastmsgssent = -1; 09480 res = 0; 09481 break; 09482 } 09483 } 09484 } 09485 if (!peer && global_alwaysauthreject) { 09486 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 09487 * trying to avoid leaking information, we MUST also transmit the same 09488 * response when we DON'T find a peer. */ 09489 transmit_response(p, "100 Trying", req); 09490 /* Insert a fake delay between the 100 and the subsequent failure. */ 09491 sched_yield(); 09492 } 09493 if (!res) { 09494 ast_device_state_changed("SIP/%s", peer->name); 09495 } 09496 if (res < 0) { 09497 switch (res) { 09498 case AUTH_SECRET_FAILED: 09499 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 09500 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09501 break; 09502 case AUTH_USERNAME_MISMATCH: 09503 /* Username and digest username does not match. 09504 Asterisk uses the From: username for authentication. We need the 09505 users to use the same authentication user name until we support 09506 proper authentication by digest auth name */ 09507 case AUTH_NOT_FOUND: 09508 case AUTH_PEER_NOT_DYNAMIC: 09509 case AUTH_ACL_FAILED: 09510 if (global_alwaysauthreject) { 09511 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 09512 } else { 09513 /* URI not found */ 09514 if (res == AUTH_PEER_NOT_DYNAMIC) 09515 transmit_response(p, "403 Forbidden", &p->initreq); 09516 else 09517 transmit_response(p, "404 Not found", &p->initreq); 09518 } 09519 break; 09520 default: 09521 break; 09522 } 09523 } 09524 if (peer) 09525 ASTOBJ_UNREF(peer, sip_destroy_peer); 09526 09527 return res; 09528 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7990 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.
07991 { 07992 switch(regstate) { 07993 case REG_STATE_FAILED: 07994 return "Failed"; 07995 case REG_STATE_UNREGISTERED: 07996 return "Unregistered"; 07997 case REG_STATE_REGSENT: 07998 return "Request Sent"; 07999 case REG_STATE_AUTHSENT: 08000 return "Auth. Sent"; 08001 case REG_STATE_REGISTERED: 08002 return "Registered"; 08003 case REG_STATE_REJECTED: 08004 return "Rejected"; 08005 case REG_STATE_TIMEOUT: 08006 return "Timeout"; 08007 case REG_STATE_NOAUTH: 08008 return "No Authentication"; 08009 default: 08010 return "Unknown"; 08011 } 08012 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 19387 of file chan_sip.c.
References sip_reload().
19388 { 19389 return sip_reload(0, 0, NULL); 19390 }
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 18247 of file chan_sip.c.
References ahp, ast_config_load(), ast_free_ha(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, global_contact_ha, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().
18248 { 18249 struct ast_config *cfg, *ucfg; 18250 struct ast_variable *v; 18251 struct sip_peer *peer; 18252 struct sip_user *user; 18253 struct ast_hostent ahp; 18254 char *cat, *stringp, *context, *oldregcontext; 18255 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 18256 struct hostent *hp; 18257 int format; 18258 struct ast_flags dummy[2]; 18259 int auto_sip_domains = FALSE; 18260 struct sockaddr_in old_bindaddr = bindaddr; 18261 int registry_count = 0, peer_count = 0, user_count = 0; 18262 unsigned int temp_tos = 0; 18263 struct ast_flags debugflag = {0}; 18264 18265 cfg = ast_config_load(config); 18266 18267 /* We *must* have a config file otherwise stop immediately */ 18268 if (!cfg) { 18269 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 18270 return -1; 18271 } 18272 18273 if (option_debug > 3) 18274 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 18275 18276 clear_realm_authentication(authl); 18277 clear_sip_domains(); 18278 authl = NULL; 18279 18280 ast_free_ha(global_contact_ha); 18281 global_contact_ha = NULL; 18282 18283 /* First, destroy all outstanding registry calls */ 18284 /* This is needed, since otherwise active registry entries will not be destroyed */ 18285 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18286 ASTOBJ_RDLOCK(iterator); 18287 if (iterator->call) { 18288 if (option_debug > 2) 18289 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 18290 /* This will also remove references to the registry */ 18291 sip_destroy(iterator->call); 18292 } 18293 ASTOBJ_UNLOCK(iterator); 18294 18295 } while(0)); 18296 18297 /* Then, actually destroy users and registry */ 18298 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18299 if (option_debug > 3) 18300 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 18301 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18302 if (option_debug > 3) 18303 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 18304 ASTOBJ_CONTAINER_MARKALL(&peerl); 18305 18306 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 18307 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 18308 oldregcontext = oldcontexts; 18309 18310 /* Clear all flags before setting default values */ 18311 /* Preserve debugging settings for console */ 18312 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 18313 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 18314 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 18315 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 18316 18317 /* Reset IP addresses */ 18318 memset(&bindaddr, 0, sizeof(bindaddr)); 18319 ast_free_ha(localaddr); 18320 memset(&localaddr, 0, sizeof(localaddr)); 18321 memset(&externip, 0, sizeof(externip)); 18322 memset(&default_prefs, 0 , sizeof(default_prefs)); 18323 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 18324 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 18325 ourport = STANDARD_SIP_PORT; 18326 srvlookup = DEFAULT_SRVLOOKUP; 18327 global_tos_sip = DEFAULT_TOS_SIP; 18328 global_tos_audio = DEFAULT_TOS_AUDIO; 18329 global_tos_video = DEFAULT_TOS_VIDEO; 18330 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 18331 externexpire = 0; /* Expiration for DNS re-issuing */ 18332 externrefresh = 10; 18333 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 18334 18335 /* Reset channel settings to default before re-configuring */ 18336 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 18337 global_regcontext[0] = '\0'; 18338 expiry = DEFAULT_EXPIRY; 18339 global_notifyringing = DEFAULT_NOTIFYRINGING; 18340 global_limitonpeers = FALSE; 18341 global_prematuremediafilter = FALSE; 18342 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 18343 global_notifyhold = FALSE; 18344 global_alwaysauthreject = 0; 18345 global_allowsubscribe = FALSE; 18346 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 18347 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 18348 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 18349 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 18350 else 18351 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 18352 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 18353 compactheaders = DEFAULT_COMPACTHEADERS; 18354 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18355 global_regattempts_max = 0; 18356 pedanticsipchecking = DEFAULT_PEDANTIC; 18357 global_mwitime = DEFAULT_MWITIME; 18358 autocreatepeer = DEFAULT_AUTOCREATEPEER; 18359 global_autoframing = 0; 18360 global_allowguest = DEFAULT_ALLOWGUEST; 18361 global_rtptimeout = 0; 18362 global_rtpholdtimeout = 0; 18363 global_rtpkeepalive = 0; 18364 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 18365 global_rtautoclear = 120; 18366 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 18367 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 18368 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 18369 18370 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 18371 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 18372 default_subscribecontext[0] = '\0'; 18373 default_language[0] = '\0'; 18374 default_fromdomain[0] = '\0'; 18375 default_qualify = DEFAULT_QUALIFY; 18376 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18377 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 18378 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 18379 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 18380 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 18381 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 18382 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 18383 18384 /* Debugging settings, always default to off */ 18385 dumphistory = FALSE; 18386 recordhistory = FALSE; 18387 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18388 18389 /* Misc settings for the channel */ 18390 global_relaxdtmf = FALSE; 18391 global_callevents = FALSE; 18392 global_t1min = DEFAULT_T1MIN; 18393 global_shrinkcallerid = 1; 18394 18395 global_matchexterniplocally = FALSE; 18396 18397 /* Copy the default jb config over global_jbconf */ 18398 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 18399 18400 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 18401 18402 /* Read the [general] config section of sip.conf (or from realtime config) */ 18403 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 18404 if (handle_common_options(&global_flags[0], &dummy[0], v)) 18405 continue; 18406 /* handle jb conf */ 18407 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 18408 continue; 18409 18410 /* Create the interface list */ 18411 if (!strcasecmp(v->name, "context")) { 18412 ast_copy_string(default_context, v->value, sizeof(default_context)); 18413 } else if (!strcasecmp(v->name, "subscribecontext")) { 18414 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 18415 } else if (!strcasecmp(v->name, "allowguest")) { 18416 global_allowguest = ast_true(v->value) ? 1 : 0; 18417 } else if (!strcasecmp(v->name, "realm")) { 18418 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 18419 } else if (!strcasecmp(v->name, "useragent")) { 18420 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 18421 if (option_debug) 18422 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 18423 } else if (!strcasecmp(v->name, "allowtransfer")) { 18424 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18425 } else if (!strcasecmp(v->name, "rtcachefriends")) { 18426 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 18427 } else if (!strcasecmp(v->name, "rtsavesysname")) { 18428 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 18429 } else if (!strcasecmp(v->name, "rtupdate")) { 18430 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 18431 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 18432 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 18433 } else if (!strcasecmp(v->name, "t1min")) { 18434 global_t1min = atoi(v->value); 18435 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 18436 global_dynamic_exclude_static = ast_true(v->value); 18437 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18438 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 18439 } else if (!strcasecmp(v->name, "rtautoclear")) { 18440 int i = atoi(v->value); 18441 if (i > 0) 18442 global_rtautoclear = i; 18443 else 18444 i = 0; 18445 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 18446 } else if (!strcasecmp(v->name, "usereqphone")) { 18447 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 18448 } else if (!strcasecmp(v->name, "prematuremedia")) { 18449 global_prematuremediafilter = ast_true(v->value); 18450 } else if (!strcasecmp(v->name, "relaxdtmf")) { 18451 global_relaxdtmf = ast_true(v->value); 18452 } else if (!strcasecmp(v->name, "checkmwi")) { 18453 if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) { 18454 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 18455 global_mwitime = DEFAULT_MWITIME; 18456 } 18457 } else if (!strcasecmp(v->name, "vmexten")) { 18458 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 18459 } else if (!strcasecmp(v->name, "rtptimeout")) { 18460 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 18461 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18462 global_rtptimeout = 0; 18463 } 18464 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18465 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 18466 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18467 global_rtpholdtimeout = 0; 18468 } 18469 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18470 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 18471 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18472 global_rtpkeepalive = 0; 18473 } 18474 } else if (!strcasecmp(v->name, "compactheaders")) { 18475 compactheaders = ast_true(v->value); 18476 } else if (!strcasecmp(v->name, "notifymimetype")) { 18477 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 18478 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 18479 global_limitonpeers = ast_true(v->value); 18480 } else if (!strcasecmp(v->name, "directrtpsetup")) { 18481 global_directrtpsetup = ast_true(v->value); 18482 } else if (!strcasecmp(v->name, "notifyringing")) { 18483 global_notifyringing = ast_true(v->value); 18484 } else if (!strcasecmp(v->name, "notifyhold")) { 18485 global_notifyhold = ast_true(v->value); 18486 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 18487 global_alwaysauthreject = ast_true(v->value); 18488 } else if (!strcasecmp(v->name, "mohinterpret") 18489 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18490 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 18491 } else if (!strcasecmp(v->name, "mohsuggest")) { 18492 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 18493 } else if (!strcasecmp(v->name, "language")) { 18494 ast_copy_string(default_language, v->value, sizeof(default_language)); 18495 } else if (!strcasecmp(v->name, "regcontext")) { 18496 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 18497 stringp = newcontexts; 18498 /* Let's remove any contexts that are no longer defined in regcontext */ 18499 cleanup_stale_contexts(stringp, oldregcontext); 18500 /* Create contexts if they don't exist already */ 18501 while ((context = strsep(&stringp, "&"))) { 18502 if (!ast_context_find(context)) 18503 ast_context_create(NULL, context,"SIP"); 18504 } 18505 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 18506 } else if (!strcasecmp(v->name, "callerid")) { 18507 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 18508 } else if (!strcasecmp(v->name, "fromdomain")) { 18509 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 18510 } else if (!strcasecmp(v->name, "outboundproxy")) { 18511 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 18512 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 18513 } else if (!strcasecmp(v->name, "outboundproxyport")) { 18514 /* Port needs to be after IP */ 18515 sscanf(v->value, "%30d", &format); 18516 outboundproxyip.sin_port = htons(format); 18517 } else if (!strcasecmp(v->name, "autocreatepeer")) { 18518 autocreatepeer = ast_true(v->value); 18519 } else if (!strcasecmp(v->name, "srvlookup")) { 18520 srvlookup = ast_true(v->value); 18521 } else if (!strcasecmp(v->name, "pedantic")) { 18522 pedanticsipchecking = ast_true(v->value); 18523 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 18524 max_expiry = atoi(v->value); 18525 if (max_expiry < 1) 18526 max_expiry = DEFAULT_MAX_EXPIRY; 18527 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 18528 min_expiry = atoi(v->value); 18529 if (min_expiry < 1) 18530 min_expiry = DEFAULT_MIN_EXPIRY; 18531 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 18532 default_expiry = atoi(v->value); 18533 if (default_expiry < 1) 18534 default_expiry = DEFAULT_DEFAULT_EXPIRY; 18535 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 18536 if (ast_true(v->value)) 18537 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18538 } else if (!strcasecmp(v->name, "dumphistory")) { 18539 dumphistory = ast_true(v->value); 18540 } else if (!strcasecmp(v->name, "recordhistory")) { 18541 recordhistory = ast_true(v->value); 18542 } else if (!strcasecmp(v->name, "registertimeout")) { 18543 global_reg_timeout = atoi(v->value); 18544 if (global_reg_timeout < 1) 18545 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18546 } else if (!strcasecmp(v->name, "registerattempts")) { 18547 global_regattempts_max = atoi(v->value); 18548 } else if (!strcasecmp(v->name, "bindaddr")) { 18549 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 18550 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 18551 } else { 18552 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 18553 } 18554 } else if (!strcasecmp(v->name, "localnet")) { 18555 struct ast_ha *na; 18556 if (!(na = ast_append_ha("d", v->value, localaddr))) 18557 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 18558 else 18559 localaddr = na; 18560 } else if (!strcasecmp(v->name, "localmask")) { 18561 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 18562 } else if (!strcasecmp(v->name, "externip")) { 18563 if (!(hp = ast_gethostbyname(v->value, &ahp))) 18564 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 18565 else 18566 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18567 externexpire = 0; 18568 } else if (!strcasecmp(v->name, "externhost")) { 18569 ast_copy_string(externhost, v->value, sizeof(externhost)); 18570 if (!(hp = ast_gethostbyname(externhost, &ahp))) 18571 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 18572 else 18573 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18574 externexpire = time(NULL); 18575 } else if (!strcasecmp(v->name, "externrefresh")) { 18576 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 18577 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 18578 externrefresh = 10; 18579 } 18580 } else if (!strcasecmp(v->name, "allow")) { 18581 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 18582 } else if (!strcasecmp(v->name, "disallow")) { 18583 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 18584 } else if (!strcasecmp(v->name, "autoframing")) { 18585 global_autoframing = ast_true(v->value); 18586 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 18587 allow_external_domains = ast_true(v->value); 18588 } else if (!strcasecmp(v->name, "autodomain")) { 18589 auto_sip_domains = ast_true(v->value); 18590 } else if (!strcasecmp(v->name, "domain")) { 18591 char *domain = ast_strdupa(v->value); 18592 char *context = strchr(domain, ','); 18593 18594 if (context) 18595 *context++ = '\0'; 18596 18597 if (option_debug && ast_strlen_zero(context)) 18598 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 18599 if (ast_strlen_zero(domain)) 18600 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 18601 else 18602 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 18603 } else if (!strcasecmp(v->name, "register")) { 18604 if (sip_register(v->value, v->lineno) == 0) 18605 registry_count++; 18606 } else if (!strcasecmp(v->name, "tos")) { 18607 if (!ast_str2tos(v->value, &temp_tos)) { 18608 global_tos_sip = temp_tos; 18609 global_tos_audio = temp_tos; 18610 global_tos_video = temp_tos; 18611 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 18612 } else 18613 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 18614 } else if (!strcasecmp(v->name, "tos_sip")) { 18615 if (ast_str2tos(v->value, &global_tos_sip)) 18616 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 18617 } else if (!strcasecmp(v->name, "tos_audio")) { 18618 if (ast_str2tos(v->value, &global_tos_audio)) 18619 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 18620 } else if (!strcasecmp(v->name, "tos_video")) { 18621 if (ast_str2tos(v->value, &global_tos_video)) 18622 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 18623 } else if (!strcasecmp(v->name, "bindport")) { 18624 if (sscanf(v->value, "%5d", &ourport) == 1) { 18625 bindaddr.sin_port = htons(ourport); 18626 } else { 18627 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 18628 } 18629 } else if (!strcasecmp(v->name, "qualify")) { 18630 if (!strcasecmp(v->value, "no")) { 18631 default_qualify = 0; 18632 } else if (!strcasecmp(v->value, "yes")) { 18633 default_qualify = DEFAULT_MAXMS; 18634 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 18635 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 18636 default_qualify = 0; 18637 } 18638 } else if (!strcasecmp(v->name, "callevents")) { 18639 global_callevents = ast_true(v->value); 18640 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18641 default_maxcallbitrate = atoi(v->value); 18642 if (default_maxcallbitrate < 0) 18643 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18644 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 18645 global_matchexterniplocally = ast_true(v->value); 18646 } else if (!strcasecmp(v->name, "constantssrc")) { 18647 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); 18648 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 18649 if (ast_true(v->value)) { 18650 global_shrinkcallerid = 1; 18651 } else if (ast_false(v->value)) { 18652 global_shrinkcallerid = 0; 18653 } else { 18654 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 18655 } 18656 } 18657 } 18658 18659 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 18660 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 18661 allow_external_domains = 1; 18662 } 18663 18664 /* Build list of authentication to various SIP realms, i.e. service providers */ 18665 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 18666 /* Format for authentication is auth = username:password@realm */ 18667 if (!strcasecmp(v->name, "auth")) 18668 authl = add_realm_authentication(authl, v->value, v->lineno); 18669 } 18670 18671 ucfg = ast_config_load("users.conf"); 18672 if (ucfg) { 18673 struct ast_variable *gen; 18674 int genhassip, genregistersip; 18675 const char *hassip, *registersip; 18676 18677 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 18678 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 18679 gen = ast_variable_browse(ucfg, "general"); 18680 cat = ast_category_browse(ucfg, NULL); 18681 while (cat) { 18682 if (strcasecmp(cat, "general")) { 18683 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 18684 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 18685 if (ast_true(hassip) || (!hassip && genhassip)) { 18686 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 18687 if (user) { 18688 ASTOBJ_CONTAINER_LINK(&userl,user); 18689 ASTOBJ_UNREF(user, sip_destroy_user); 18690 user_count++; 18691 } 18692 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 18693 if (peer) { 18694 ast_device_state_changed("SIP/%s", peer->name); 18695 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18696 ASTOBJ_UNREF(peer, sip_destroy_peer); 18697 peer_count++; 18698 } 18699 } 18700 if (ast_true(registersip) || (!registersip && genregistersip)) { 18701 char tmp[256]; 18702 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 18703 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 18704 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 18705 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 18706 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 18707 if (!host) 18708 host = ast_variable_retrieve(ucfg, "general", "host"); 18709 if (!username) 18710 username = ast_variable_retrieve(ucfg, "general", "username"); 18711 if (!secret) 18712 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18713 if (!contact) 18714 contact = "s"; 18715 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18716 if (!ast_strlen_zero(secret)) { 18717 if (!ast_strlen_zero(authuser)) { 18718 snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact); 18719 } else { 18720 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18721 } 18722 } else if (!ast_strlen_zero(authuser)) { 18723 snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact); 18724 } else { 18725 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18726 } 18727 if (sip_register(tmp, 0) == 0) 18728 registry_count++; 18729 } 18730 } 18731 } 18732 cat = ast_category_browse(ucfg, cat); 18733 } 18734 ast_config_destroy(ucfg); 18735 } 18736 18737 18738 /* Load peers, users and friends */ 18739 cat = NULL; 18740 while ( (cat = ast_category_browse(cfg, cat)) ) { 18741 const char *utype; 18742 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18743 continue; 18744 utype = ast_variable_retrieve(cfg, cat, "type"); 18745 if (!utype) { 18746 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18747 continue; 18748 } else { 18749 int is_user = 0, is_peer = 0; 18750 if (!strcasecmp(utype, "user")) 18751 is_user = 1; 18752 else if (!strcasecmp(utype, "friend")) 18753 is_user = is_peer = 1; 18754 else if (!strcasecmp(utype, "peer")) 18755 is_peer = 1; 18756 else { 18757 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18758 continue; 18759 } 18760 if (is_user) { 18761 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18762 if (user) { 18763 ASTOBJ_CONTAINER_LINK(&userl,user); 18764 ASTOBJ_UNREF(user, sip_destroy_user); 18765 user_count++; 18766 } 18767 } 18768 if (is_peer) { 18769 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 18770 if (peer) { 18771 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18772 ASTOBJ_UNREF(peer, sip_destroy_peer); 18773 peer_count++; 18774 } 18775 } 18776 } 18777 } 18778 if (ast_find_ourip(&__ourip, bindaddr)) { 18779 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18780 ast_config_destroy(cfg); 18781 return 0; 18782 } 18783 if (!ntohs(bindaddr.sin_port)) 18784 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18785 bindaddr.sin_family = AF_INET; 18786 ast_mutex_lock(&netlock); 18787 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 18788 close(sipsock); 18789 sipsock = -1; 18790 } 18791 if (sipsock < 0) { 18792 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18793 if (sipsock < 0) { 18794 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18795 ast_config_destroy(cfg); 18796 return -1; 18797 } else { 18798 /* Allow SIP clients on the same host to access us: */ 18799 const int reuseFlag = 1; 18800 18801 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18802 (const char*)&reuseFlag, 18803 sizeof reuseFlag); 18804 18805 ast_enable_packet_fragmentation(sipsock); 18806 18807 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18808 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 18809 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18810 strerror(errno)); 18811 close(sipsock); 18812 sipsock = -1; 18813 } else { 18814 if (option_verbose > 1) { 18815 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 18816 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18817 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 18818 } 18819 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18820 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 18821 } 18822 } 18823 } 18824 ast_mutex_unlock(&netlock); 18825 18826 /* Add default domains - host name, IP address and IP:port */ 18827 /* Only do this if user added any sip domain with "localdomains" */ 18828 /* In order to *not* break backwards compatibility */ 18829 /* Some phones address us at IP only, some with additional port number */ 18830 if (auto_sip_domains) { 18831 char temp[MAXHOSTNAMELEN]; 18832 18833 /* First our default IP address */ 18834 if (bindaddr.sin_addr.s_addr) 18835 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18836 else 18837 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18838 18839 /* Our extern IP address, if configured */ 18840 if (externip.sin_addr.s_addr) 18841 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18842 18843 /* Extern host name (NAT traversal support) */ 18844 if (!ast_strlen_zero(externhost)) 18845 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18846 18847 /* Our host name */ 18848 if (!gethostname(temp, sizeof(temp))) 18849 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18850 } 18851 18852 /* Release configuration from memory */ 18853 ast_config_destroy(cfg); 18854 18855 /* Load the list of manual NOTIFY types to support */ 18856 if (notify_types) 18857 ast_config_destroy(notify_types); 18858 notify_types = ast_config_load(notify_config); 18859 18860 /* Done, tell the manager */ 18861 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); 18862 18863 return 0; 18864 }
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 12275 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), sip_pvt::domain, get_header(), keys, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::qop, sip_registry::qop, sip_pvt::realm, sip_registry::realm, and sip_pvt::registry.
Referenced by do_proxy_auth(), and do_register_auth().
12276 { 12277 char tmp[512]; 12278 char *c; 12279 char oldnonce[256]; 12280 12281 /* table of recognised keywords, and places where they should be copied */ 12282 const struct x { 12283 const char *key; 12284 int field_index; 12285 } *i, keys[] = { 12286 { "realm=", ast_string_field_index(p, realm) }, 12287 { "nonce=", ast_string_field_index(p, nonce) }, 12288 { "opaque=", ast_string_field_index(p, opaque) }, 12289 { "qop=", ast_string_field_index(p, qop) }, 12290 { "domain=", ast_string_field_index(p, domain) }, 12291 { NULL, 0 }, 12292 }; 12293 12294 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 12295 if (ast_strlen_zero(tmp)) 12296 return -1; 12297 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 12298 ast_log(LOG_WARNING, "missing Digest.\n"); 12299 return -1; 12300 } 12301 c = tmp + strlen("Digest "); 12302 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 12303 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 12304 for (i = keys; i->key != NULL; i++) { 12305 char *src, *separator; 12306 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 12307 continue; 12308 /* Found. Skip keyword, take text in quotes or up to the separator. */ 12309 c += strlen(i->key); 12310 if (*c == '"') { 12311 src = ++c; 12312 separator = "\""; 12313 } else { 12314 src = c; 12315 separator = ","; 12316 } 12317 strsep(&c, separator); /* clear separator and move ptr */ 12318 ast_string_field_index_set(p, i->field_index, src); 12319 break; 12320 } 12321 if (i->key == NULL) /* not found, try ',' */ 12322 strsep(&c, ","); 12323 } 12324 /* Reset nonce count */ 12325 if (strcmp(p->nonce, oldnonce)) 12326 p->noncecount = 0; 12327 12328 /* Save auth data for following registrations */ 12329 if (p->registry) { 12330 struct sip_registry *r = p->registry; 12331 12332 if (strcmp(r->nonce, p->nonce)) { 12333 ast_string_field_set(r, realm, p->realm); 12334 ast_string_field_set(r, nonce, p->nonce); 12335 ast_string_field_set(r, domain, p->domain); 12336 ast_string_field_set(r, opaque, p->opaque); 12337 ast_string_field_set(r, qop, p->qop); 12338 r->noncecount = 0; 12339 } 12340 } 12341 return build_reply_digest(p, sipmethod, digest, digest_len); 12342 }
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 6461 of file chan_sip.c.
References add_header(), add_route(), ast_copy_string(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), sip_pvt::callid, copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::invite_branch, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.
06462 { 06463 struct sip_request *orig = &p->initreq; 06464 char stripped[80]; 06465 char tmp[80]; 06466 char newto[256]; 06467 const char *c; 06468 const char *ot, *of; 06469 int is_strict = FALSE; /*!< Strict routing flag */ 06470 06471 memset(req, 0, sizeof(struct sip_request)); 06472 06473 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06474 06475 if (!seqno) { 06476 p->ocseq++; 06477 seqno = p->ocseq; 06478 } 06479 06480 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 06481 if (sipmethod == SIP_CANCEL) { 06482 p->branch = p->invite_branch; 06483 build_via(p); 06484 } else if (newbranch && (sipmethod == SIP_INVITE)) { 06485 p->branch ^= ast_random(); 06486 p->invite_branch = p->branch; 06487 build_via(p); 06488 } else if (newbranch) { 06489 p->branch ^= ast_random(); 06490 build_via(p); 06491 } 06492 06493 /* Check for strict or loose router */ 06494 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06495 is_strict = TRUE; 06496 if (sipdebug) 06497 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06498 } 06499 06500 if (sipmethod == SIP_CANCEL) 06501 c = p->initreq.rlPart2; /* Use original URI */ 06502 else if (sipmethod == SIP_ACK) { 06503 /* Use URI from Contact: in 200 OK (if INVITE) 06504 (we only have the contacturi on INVITEs) */ 06505 if (!ast_strlen_zero(p->okcontacturi)) 06506 c = is_strict ? p->route->hop : p->okcontacturi; 06507 else 06508 c = p->initreq.rlPart2; 06509 } else if (!ast_strlen_zero(p->okcontacturi)) 06510 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06511 else if (!ast_strlen_zero(p->uri)) 06512 c = p->uri; 06513 else { 06514 char *n; 06515 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06516 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06517 sizeof(stripped)); 06518 n = get_in_brackets(stripped); 06519 c = strsep(&n, ";"); /* trim ; and beyond */ 06520 } 06521 init_req(req, sipmethod, c); 06522 06523 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06524 06525 add_header(req, "Via", p->via); 06526 if (p->route) { 06527 set_destination(p, p->route->hop); 06528 add_route(req, is_strict ? p->route->next : p->route); 06529 } 06530 06531 ot = get_header(orig, "To"); 06532 of = get_header(orig, "From"); 06533 06534 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06535 as our original request, including tag (or presumably lack thereof) */ 06536 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06537 /* Add the proper tag if we don't have it already. If they have specified 06538 their tag, use it. Otherwise, use our own tag */ 06539 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06540 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06541 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06542 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06543 else 06544 snprintf(newto, sizeof(newto), "%s", ot); 06545 ot = newto; 06546 } 06547 06548 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06549 add_header(req, "From", of); 06550 add_header(req, "To", ot); 06551 } else { 06552 add_header(req, "From", ot); 06553 add_header(req, "To", of); 06554 } 06555 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06556 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06557 add_header(req, "Contact", p->our_contact); 06558 06559 copy_header(req, orig, "Call-ID"); 06560 add_header(req, "CSeq", tmp); 06561 06562 if (!ast_strlen_zero(global_useragent)) 06563 add_header(req, "User-Agent", global_useragent); 06564 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06565 06566 if (!ast_strlen_zero(p->rpid)) 06567 add_header(req, "Remote-Party-ID", p->rpid); 06568 06569 return 0; 06570 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6352 of file chan_sip.c.
References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.
Referenced by respprep().
06352 { 06353 /* Requirements for Contact header inclusion in responses generated 06354 * from the header tables found in the following RFCs. Where the 06355 * Contact header was marked mandatory (m) or optional (o) this 06356 * function returns 1. 06357 * 06358 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06359 * - RFC 2976 (INFO) 06360 * - RFC 3262 (PRACK) 06361 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06362 * - RFC 3311 (UPDATE) 06363 * - RFC 3428 (MESSAGE) 06364 * - RFC 3515 (REFER) 06365 * - RFC 3903 (PUBLISH) 06366 */ 06367 06368 switch (method) { 06369 /* 1xx, 2xx, 3xx, 485 */ 06370 case SIP_INVITE: 06371 case SIP_UPDATE: 06372 case SIP_SUBSCRIBE: 06373 case SIP_NOTIFY: 06374 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06375 return 1; 06376 break; 06377 06378 /* 2xx, 3xx, 485 */ 06379 case SIP_REGISTER: 06380 case SIP_OPTIONS: 06381 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06382 return 1; 06383 break; 06384 06385 /* 3xx, 485 */ 06386 case SIP_BYE: 06387 case SIP_PRACK: 06388 case SIP_MESSAGE: 06389 case SIP_PUBLISH: 06390 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06391 return 1; 06392 break; 06393 06394 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06395 case SIP_REFER: 06396 if (msg[0] >= '2' && msg[0] <= '6') 06397 return 1; 06398 break; 06399 06400 /* contact will not be included for everything else */ 06401 case SIP_ACK: 06402 case SIP_CANCEL: 06403 case SIP_INFO: 06404 case SIP_PING: 06405 default: 06406 return 0; 06407 } 06408 return 0; 06409 }
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 6413 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, sip_pvt::fullcontact, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, resp_needs_contact(), SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06414 { 06415 char newto[256]; 06416 const char *ot; 06417 06418 init_resp(resp, msg); 06419 copy_via_headers(p, resp, req, "Via"); 06420 if (msg[0] == '1' || msg[0] == '2') 06421 copy_all_header(resp, req, "Record-Route"); 06422 copy_header(resp, req, "From"); 06423 ot = get_header(req, "To"); 06424 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06425 /* Add the proper tag if we don't have it already. If they have specified 06426 their tag, use it. Otherwise, use our own tag */ 06427 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06428 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06429 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06430 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06431 else 06432 ast_copy_string(newto, ot, sizeof(newto)); 06433 ot = newto; 06434 } 06435 add_header(resp, "To", ot); 06436 copy_header(resp, req, "Call-ID"); 06437 copy_header(resp, req, "CSeq"); 06438 if (!ast_strlen_zero(global_useragent)) 06439 add_header(resp, "User-Agent", global_useragent); 06440 add_header(resp, "Allow", ALLOWED_METHODS); 06441 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06442 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06443 /* For registration responses, we also need expiry and 06444 contact info */ 06445 char tmp[256]; 06446 06447 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06448 add_header(resp, "Expires", tmp); 06449 if (p->expiry) { /* Only add contact if we have an expiry time */ 06450 char contact[SIPBUFSIZE]; 06451 snprintf(contact, sizeof(contact), "%s;expires=%d", (p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact), p->expiry); 06452 add_header(resp, "Contact", contact); /* Not when we unregister */ 06453 } 06454 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06455 add_header(resp, "Contact", p->our_contact); 06456 } 06457 return 0; 06458 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 17076 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 monlock.
17077 { 17078 /* If we're supposed to be stopped -- stay stopped */ 17079 if (monitor_thread == AST_PTHREADT_STOP) 17080 return 0; 17081 ast_mutex_lock(&monlock); 17082 if (monitor_thread == pthread_self()) { 17083 ast_mutex_unlock(&monlock); 17084 ast_log(LOG_WARNING, "Cannot kill myself\n"); 17085 return -1; 17086 } 17087 if (monitor_thread != AST_PTHREADT_NULL) { 17088 /* Wake up the thread */ 17089 pthread_kill(monitor_thread, SIGURG); 17090 } else { 17091 /* Start a new monitor */ 17092 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 17093 ast_mutex_unlock(&monlock); 17094 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 17095 return -1; 17096 } 17097 } 17098 ast_mutex_unlock(&monlock); 17099 return 0; 17100 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1960 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_pvt::callid, sip_pkt::data, DEADLOCK_AVOIDANCE, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, sip_pvt::from, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, ast_channel::name, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01961 { 01962 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01963 int reschedule = DEFAULT_RETRANS; 01964 int xmitres = 0; 01965 01966 /* Lock channel PVT */ 01967 ast_mutex_lock(&pkt->owner->lock); 01968 01969 if (pkt->retrans < MAX_RETRANS) { 01970 pkt->retrans++; 01971 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01972 if (sipdebug && option_debug > 3) 01973 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); 01974 } else { 01975 int siptimer_a; 01976 01977 if (sipdebug && option_debug > 3) 01978 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01979 if (!pkt->timer_a) 01980 pkt->timer_a = 2 ; 01981 else 01982 pkt->timer_a = 2 * pkt->timer_a; 01983 01984 /* For non-invites, a maximum of 4 secs */ 01985 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01986 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01987 siptimer_a = 4000; 01988 01989 /* Reschedule re-transmit */ 01990 reschedule = siptimer_a; 01991 if (option_debug > 3) 01992 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); 01993 } 01994 01995 if (sip_debug_test_pvt(pkt->owner)) { 01996 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01997 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01998 pkt->retrans, sip_nat_mode(pkt->owner), 01999 ast_inet_ntoa(dst->sin_addr), 02000 ntohs(dst->sin_port), pkt->data); 02001 } 02002 02003 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 02004 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 02005 ast_mutex_unlock(&pkt->owner->lock); 02006 if (xmitres == XMIT_ERROR) 02007 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 02008 else 02009 return reschedule; 02010 } 02011 /* Too many retries */ 02012 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 02013 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 02014 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s from %s for packet seqno %d (%s %s %s)\n", pkt->owner->callid, pkt->owner->from, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response: " : "Request: ", sip_methods[pkt->method].text); 02015 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 02016 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 02017 } 02018 if (xmitres == XMIT_ERROR) { 02019 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 02020 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02021 } else 02022 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02023 02024 pkt->retransid = -1; 02025 02026 if (ast_test_flag(pkt, FLAG_FATAL)) { 02027 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02028 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 02029 } 02030 02031 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02032 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02033 02034 if (pkt->owner->owner) { 02035 sip_alreadygone(pkt->owner); 02036 ast_log(LOG_WARNING, "Hanging up call %s from channel %s . No reply to our critical packet after %d retries (see doc/sip-retransmit.txt).\n", pkt->owner->callid, pkt->owner->owner->name, pkt->retrans); 02037 ast_queue_hangup(pkt->owner->owner); 02038 ast_channel_unlock(pkt->owner->owner); 02039 } else { 02040 /* If no channel owner, destroy now */ 02041 02042 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02043 if (pkt->method != SIP_OPTIONS) { 02044 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02045 sip_alreadygone(pkt->owner); 02046 if (option_debug) 02047 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02048 } 02049 } 02050 } 02051 02052 if (pkt->method == SIP_BYE) { 02053 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02054 if (pkt->owner->owner) 02055 ast_channel_unlock(pkt->owner->owner); 02056 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02057 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02058 } 02059 02060 /* In any case, go ahead and remove the packet */ 02061 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02062 if (cur == pkt) 02063 break; 02064 } 02065 if (cur) { 02066 if (prev) 02067 prev->next = cur->next; 02068 else 02069 pkt->owner->packets = cur->next; 02070 ast_mutex_unlock(&pkt->owner->lock); 02071 free(cur); 02072 pkt = NULL; 02073 } else 02074 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02075 if (pkt) 02076 ast_mutex_unlock(&pkt->owner->lock); 02077 return 0; 02078 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 16641 of file chan_sip.c.
References ast_channel_trylock, ast_mutex_lock, ast_mutex_unlock, sip_pvt::lock, and sip_pvt::owner.
Referenced by queue_request().
16642 { 16643 struct sip_pvt *p = (struct sip_pvt *) data; 16644 int recount = 0; 16645 int nounlock = 0; 16646 int lockretry; 16647 16648 for (lockretry = 10; lockretry > 0; lockretry--) { 16649 ast_mutex_lock(&p->lock); 16650 16651 /* lock the owner if it has one -- we may need it */ 16652 /* because this is deadlock-prone, we need to try and unlock if failed */ 16653 if (!p->owner || !ast_channel_trylock(p->owner)) { 16654 break; /* locking succeeded */ 16655 } 16656 16657 if (lockretry != 1) { 16658 ast_mutex_unlock(&p->lock); 16659 /* Sleep for a very short amount of time */ 16660 usleep(1); 16661 } 16662 } 16663 16664 if (!lockretry) { 16665 int retry = !AST_LIST_EMPTY(&p->request_queue); 16666 16667 /* we couldn't get the owner lock, which is needed to process 16668 the queued requests, so return a non-zero value, which will 16669 cause the scheduler to run this request again later if there 16670 still requests to be processed 16671 */ 16672 ast_mutex_unlock(&p->lock); 16673 return retry; 16674 }; 16675 16676 process_request_queue(p, &recount, &nounlock); 16677 p->request_queue_sched_id = -1; 16678 16679 if (p->owner && !nounlock) { 16680 ast_channel_unlock(p->owner); 16681 } 16682 ast_mutex_unlock(&p->lock); 16683 16684 if (recount) { 16685 ast_update_use_count(); 16686 } 16687 16688 return 0; 16689 }
static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 2357 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02357 { 02358 struct sip_pvt *pvt = (struct sip_pvt *) data; 02359 02360 return send_provisional_keepalive_full(pvt, 0); 02361 }
static int send_provisional_keepalive_full | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2337 of file chan_sip.c.
References sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, PROVIS_KEEPALIVE_TIMEOUT, S_OR, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.
Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
02338 { 02339 const char *msg = NULL; 02340 02341 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 02342 msg = "183 Session Progress"; 02343 } 02344 02345 if (pvt->invitestate < INV_COMPLETED) { 02346 if (with_sdp) { 02347 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE); 02348 } else { 02349 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 02350 } 02351 return PROVIS_KEEPALIVE_TIMEOUT; 02352 } 02353 02354 return 0; 02355 }
static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 2363 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02363 { 02364 struct sip_pvt *pvt = (void *)data; 02365 02366 return send_provisional_keepalive_full(pvt, 1); 02367 }
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 2412 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.
02413 { 02414 int res; 02415 02416 add_blank(req); 02417 if (sip_debug_test_pvt(p)) { 02418 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02419 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); 02420 else 02421 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); 02422 } 02423 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02424 struct sip_request tmp; 02425 parse_copy(&tmp, req); 02426 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02427 } 02428 res = (reliable) ? 02429 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02430 __sip_xmit(p, req->data, req->len); 02431 return res; 02432 }
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 2378 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), sip_pvt::provisional_keepalive_sched_id, sched, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02379 { 02380 int res; 02381 02382 add_blank(req); 02383 if (sip_debug_test_pvt(p)) { 02384 const struct sockaddr_in *dst = sip_real_dst(p); 02385 02386 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02387 reliable ? "Reliably " : "", sip_nat_mode(p), 02388 ast_inet_ntoa(dst->sin_addr), 02389 ntohs(dst->sin_port), req->data); 02390 } 02391 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02392 struct sip_request tmp; 02393 parse_copy(&tmp, req); 02394 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02395 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02396 } 02397 02398 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 02399 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 02400 AST_SCHED_DEL(sched, p->provisional_keepalive_sched_id); 02401 } 02402 02403 res = (reliable) ? 02404 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02405 __sip_xmit(p, req->data, req->len); 02406 if (res > 0) 02407 return 0; 02408 return res; 02409 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8668 of file chan_sip.c.
References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::recv, sip_pvt::sa, and SIP_NAT_ROUTE.
Referenced by handle_response_invite().
08669 { 08670 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08671 /* NAT: Don't trust the contact field. Just use what they came to us 08672 with. */ 08673 pvt->sa = pvt->recv; 08674 return 0; 08675 } 08676 08677 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08678 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 6262 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
06263 { 06264 char *h, *maddr, hostname[256]; 06265 int port, hn; 06266 struct hostent *hp; 06267 struct ast_hostent ahp; 06268 int debug=sip_debug_test_pvt(p); 06269 06270 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 06271 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 06272 06273 if (debug) 06274 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 06275 06276 /* Find and parse hostname */ 06277 h = strchr(uri, '@'); 06278 if (h) 06279 ++h; 06280 else { 06281 h = uri; 06282 if (strncasecmp(h, "sip:", 4) == 0) 06283 h += 4; 06284 else if (strncasecmp(h, "sips:", 5) == 0) 06285 h += 5; 06286 } 06287 hn = strcspn(h, ":;>") + 1; 06288 if (hn > sizeof(hostname)) 06289 hn = sizeof(hostname); 06290 ast_copy_string(hostname, h, hn); 06291 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 06292 h += hn - 1; 06293 06294 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 06295 if (*h == ':') { 06296 /* Parse port */ 06297 ++h; 06298 port = strtol(h, &h, 10); 06299 } 06300 else 06301 port = STANDARD_SIP_PORT; 06302 06303 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06304 maddr = strstr(h, "maddr="); 06305 if (maddr) { 06306 maddr += 6; 06307 hn = strspn(maddr, "0123456789.") + 1; 06308 if (hn > sizeof(hostname)) 06309 hn = sizeof(hostname); 06310 ast_copy_string(hostname, maddr, hn); 06311 } 06312 06313 hp = ast_gethostbyname(hostname, &ahp); 06314 if (hp == NULL) { 06315 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06316 return; 06317 } 06318 p->sa.sin_family = AF_INET; 06319 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06320 p->sa.sin_port = htons(port); 06321 if (debug) 06322 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06323 }
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 17413 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, ast_channel::next, SIP_INSECURE_INVITE, and SIP_INSECURE_PORT.
Referenced by handle_common_options().
17414 { 17415 static int dep_insecure_very = 0; 17416 static int dep_insecure_yes = 0; 17417 17418 if (ast_strlen_zero(value)) 17419 return; 17420 17421 if (!strcasecmp(value, "very")) { 17422 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17423 if(!dep_insecure_very) { 17424 if(lineno != -1) 17425 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 17426 else 17427 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 17428 dep_insecure_very = 1; 17429 } 17430 } 17431 else if (ast_true(value)) { 17432 ast_set_flag(flags, SIP_INSECURE_PORT); 17433 if(!dep_insecure_yes) { 17434 if(lineno != -1) 17435 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 17436 else 17437 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 17438 dep_insecure_yes = 1; 17439 } 17440 } 17441 else if (!ast_false(value)) { 17442 char buf[64]; 17443 char *word, *next; 17444 ast_copy_string(buf, value, sizeof(buf)); 17445 next = buf; 17446 while ((word = strsep(&next, ","))) { 17447 if (!strcasecmp(word, "port")) 17448 ast_set_flag(flags, SIP_INSECURE_PORT); 17449 else if (!strcasecmp(word, "invite")) 17450 ast_set_flag(flags, SIP_INSECURE_INVITE); 17451 else 17452 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 17453 } 17454 } 17455 }
static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
int | forceupdate | |||
) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 8990 of file chan_sip.c.
References ast_random(), ast_string_field_build, ast_strlen_zero(), sip_pvt::randdata, and sip_pvt::stalenonce.
Referenced by check_auth(), and transmit_fake_auth_response().
08991 { 08992 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 08993 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08994 p->stalenonce = 0; 08995 } 08996 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17848 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, global_flags, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
17849 { 17850 if (peer->expire == 0) { 17851 /* Don't reset expire or port time during reload 17852 if we have an active registration 17853 */ 17854 peer->expire = -1; 17855 peer->pokeexpire = -1; 17856 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17857 } 17858 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17859 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17860 strcpy(peer->context, default_context); 17861 strcpy(peer->subscribecontext, default_subscribecontext); 17862 strcpy(peer->language, default_language); 17863 strcpy(peer->mohinterpret, default_mohinterpret); 17864 strcpy(peer->mohsuggest, default_mohsuggest); 17865 peer->addr.sin_family = AF_INET; 17866 peer->defaddr.sin_family = AF_INET; 17867 peer->capability = global_capability; 17868 peer->maxcallbitrate = default_maxcallbitrate; 17869 peer->rtptimeout = global_rtptimeout; 17870 peer->rtpholdtimeout = global_rtpholdtimeout; 17871 peer->rtpkeepalive = global_rtpkeepalive; 17872 peer->allowtransfer = global_allowtransfer; 17873 peer->autoframing = global_autoframing; 17874 strcpy(peer->vmexten, default_vmexten); 17875 peer->secret[0] = '\0'; 17876 peer->md5secret[0] = '\0'; 17877 peer->cid_num[0] = '\0'; 17878 peer->cid_name[0] = '\0'; 17879 peer->fromdomain[0] = '\0'; 17880 peer->fromuser[0] = '\0'; 17881 peer->regexten[0] = '\0'; 17882 peer->mailbox[0] = '\0'; 17883 peer->callgroup = 0; 17884 peer->pickupgroup = 0; 17885 peer->maxms = default_qualify; 17886 peer->prefs = default_prefs; 17887 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 19200 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
19201 { 19202 int no = 0; 19203 int ok = FALSE; 19204 char varbuf[30]; 19205 char *inbuf = (char *) data; 19206 19207 if (ast_strlen_zero(inbuf)) { 19208 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 19209 return 0; 19210 } 19211 ast_channel_lock(chan); 19212 19213 /* Check for headers */ 19214 while (!ok && no <= 50) { 19215 no++; 19216 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 19217 19218 /* Compare without the leading underscores */ 19219 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 19220 ok = TRUE; 19221 } 19222 if (ok) { 19223 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 19224 if (sipdebug) 19225 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 19226 } else { 19227 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 19228 } 19229 ast_channel_unlock(chan); 19230 return 0; 19231 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2788 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02789 { 02790 /* We know name is the first field, so we can cast */ 02791 struct sip_peer *p = (struct sip_peer *) name; 02792 return !(!inaddrcmp(&p->addr, sin) || 02793 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02794 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02795 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4694 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_rtp_codec_setpref(), ast_rtp_destroy(), 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_free_memory, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, sip_pvt::fromdomain, global_flags, iflist, iflock, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04696 { 04697 struct sip_pvt *p; 04698 04699 if (!(p = ast_calloc(1, sizeof(*p)))) 04700 return NULL; 04701 04702 if (ast_string_field_init(p, 512)) { 04703 free(p); 04704 return NULL; 04705 } 04706 04707 ast_mutex_init(&p->lock); 04708 04709 p->method = intended_method; 04710 p->initid = -1; 04711 p->waitid = -1; 04712 p->autokillid = -1; 04713 p->request_queue_sched_id = -1; 04714 p->provisional_keepalive_sched_id = -1; 04715 p->subscribed = NONE; 04716 p->stateid = -1; 04717 p->prefs = default_prefs; /* Set default codecs for this call */ 04718 04719 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04720 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04721 04722 if (sin) { 04723 p->sa = *sin; 04724 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04725 p->ourip = __ourip; 04726 } else 04727 p->ourip = __ourip; 04728 04729 /* Copy global flags to this PVT at setup. */ 04730 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04731 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04732 04733 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04734 04735 p->branch = ast_random(); 04736 make_our_tag(p->tag, sizeof(p->tag)); 04737 p->ocseq = INITIAL_CSEQ; 04738 04739 if (sip_methods[intended_method].need_rtp) { 04740 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04741 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04742 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04743 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04744 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04745 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04746 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04747 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04748 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04749 /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */ 04750 if (p->rtp) { 04751 ast_rtp_destroy(p->rtp); 04752 } 04753 if (p->udptl) { 04754 ast_udptl_destroy(p->udptl); 04755 } 04756 ast_mutex_destroy(&p->lock); 04757 if (p->chanvars) { 04758 ast_variables_destroy(p->chanvars); 04759 p->chanvars = NULL; 04760 } 04761 ast_string_field_free_memory(p); 04762 free(p); 04763 return NULL; 04764 } 04765 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04766 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04767 ast_rtp_settos(p->rtp, global_tos_audio); 04768 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04769 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04770 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04771 if (p->vrtp) { 04772 ast_rtp_settos(p->vrtp, global_tos_video); 04773 ast_rtp_setdtmf(p->vrtp, 0); 04774 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04775 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04776 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04777 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04778 } 04779 if (p->udptl) 04780 ast_udptl_settos(p->udptl, global_tos_audio); 04781 p->maxcallbitrate = default_maxcallbitrate; 04782 p->autoframing = global_autoframing; 04783 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04784 } 04785 04786 if (useglobal_nat && sin) { 04787 /* Setup NAT structure according to global settings if we have an address */ 04788 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04789 p->recv = *sin; 04790 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04791 } 04792 04793 if (p->method != SIP_REGISTER) 04794 ast_string_field_set(p, fromdomain, default_fromdomain); 04795 build_via(p); 04796 if (!callid) 04797 build_callid_pvt(p); 04798 else 04799 ast_string_field_set(p, callid, callid); 04800 /* Assign default music on hold class */ 04801 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04802 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04803 p->capability = global_capability; 04804 p->allowtransfer = global_allowtransfer; 04805 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04806 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04807 p->noncodeccapability |= AST_RTP_DTMF; 04808 if (p->udptl) { 04809 p->t38.capability = global_t38_capability; 04810 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04811 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04812 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04813 p->t38.capability |= T38FAX_UDP_EC_FEC; 04814 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04815 p->t38.capability |= T38FAX_UDP_EC_NONE; 04816 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04817 p->t38.jointcapability = p->t38.capability; 04818 } 04819 ast_string_field_set(p, context, default_context); 04820 04821 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04822 04823 /* Add to active dialog list */ 04824 ast_mutex_lock(&iflock); 04825 p->next = iflist; 04826 iflist = p; 04827 ast_mutex_unlock(&iflock); 04828 if (option_debug) 04829 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"); 04830 return p; 04831 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1716 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::callid, 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().
01717 { 01718 if (option_debug > 2) 01719 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01720 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01721 }
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 3857 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03858 { 03859 int res = 0; 03860 struct sip_pvt *p = ast->tech_pvt; 03861 03862 ast_mutex_lock(&p->lock); 03863 if (ast->_state != AST_STATE_UP) { 03864 try_suggested_sip_codec(p); 03865 03866 ast_setstate(ast, AST_STATE_UP); 03867 if (option_debug) 03868 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03869 03870 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03871 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03872 } 03873 ast_mutex_unlock(&p->lock); 03874 return res; 03875 }
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 3127 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, 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, sip_pvt::cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, ast_channel::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, sip_pvt::t38, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
03128 { 03129 int res, xmitres = 0; 03130 struct sip_pvt *p; 03131 struct varshead *headp; 03132 struct ast_var_t *current; 03133 const char *referer = NULL; /* SIP refererer */ 03134 03135 p = ast->tech_pvt; 03136 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03137 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03138 return -1; 03139 } 03140 03141 /* Check whether there is vxml_url, distinctive ring variables */ 03142 headp=&ast->varshead; 03143 AST_LIST_TRAVERSE(headp,current,entries) { 03144 /* Check whether there is a VXML_URL variable */ 03145 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03146 p->options->vxml_url = ast_var_value(current); 03147 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03148 p->options->uri_options = ast_var_value(current); 03149 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03150 /* Check whether there is a ALERT_INFO variable */ 03151 p->options->distinctive_ring = ast_var_value(current); 03152 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03153 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03154 p->options->addsipheaders = 1; 03155 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03156 /* This is a transfered call */ 03157 p->options->transfer = 1; 03158 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03159 /* This is the referer */ 03160 referer = ast_var_value(current); 03161 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03162 /* We're replacing a call. */ 03163 p->options->replaces = ast_var_value(current); 03164 } 03165 } 03166 03167 res = 0; 03168 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03169 03170 if (p->options->transfer) { 03171 char buf[SIPBUFSIZE/2]; 03172 03173 if (referer) { 03174 if (sipdebug && option_debug > 2) 03175 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03176 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03177 } else 03178 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03179 ast_string_field_set(p, cid_name, buf); 03180 } 03181 if (option_debug) 03182 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03183 03184 res = update_call_counter(p, INC_CALL_RINGING); 03185 if ( res != -1 ) { 03186 p->callingpres = ast->cid.cid_pres; 03187 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03188 p->jointnoncodeccapability = p->noncodeccapability; 03189 03190 /* If there are no audio formats left to offer, punt */ 03191 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03192 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03193 res = -1; 03194 } else { 03195 p->t38.jointcapability = p->t38.capability; 03196 if (option_debug > 1) 03197 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03198 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03199 if (xmitres == XMIT_ERROR) 03200 return -1; /* Transmission error */ 03201 03202 p->invitestate = INV_CALLING; 03203 03204 /* Initialize auto-congest time */ 03205 AST_SCHED_DEL(sched, p->initid); 03206 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03207 } 03208 } else { 03209 ast->hangupcause = AST_CAUSE_USER_BUSY; 03210 } 03211 return res; 03212 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2209 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02210 { 02211 int res = 0; 02212 if (p->autokillid > -1) { 02213 if (!(res = ast_sched_del(sched, p->autokillid))) { 02214 append_history(p, "CancelDestroy", ""); 02215 p->autokillid = -1; 02216 } 02217 } 02218 return res; 02219 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1798 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01799 { 01800 if (!sipdebug) 01801 return 0; 01802 if (debugaddr.sin_addr.s_addr) { 01803 if (((ntohs(debugaddr.sin_port) != 0) 01804 && (debugaddr.sin_port != addr->sin_port)) 01805 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01806 return 0; 01807 } 01808 return 1; 01809 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1824 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01825 { 01826 if (!sipdebug) 01827 return 0; 01828 return sip_debug_test_addr(sip_real_dst(p)); 01829 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3495 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock, ast_mutex_unlock, sip_pvt::callid, iflock, 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().
03496 { 03497 ast_mutex_lock(&iflock); 03498 if (option_debug > 2) 03499 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03500 __sip_destroy(p, 1); 03501 ast_mutex_unlock(&iflock); 03502 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2596 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, sip_peer::name, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().
02597 { 02598 if (option_debug > 2) 02599 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02600 02601 /* Delete it, it needs to disappear */ 02602 if (peer->call) 02603 sip_destroy(peer->call); 02604 02605 if (peer->mwipvt) /* We have an active subscription, delete it */ 02606 sip_destroy(peer->mwipvt); 02607 02608 if (peer->chanvars) { 02609 ast_variables_destroy(peer->chanvars); 02610 peer->chanvars = NULL; 02611 } 02612 02613 register_peer_exten(peer, FALSE); 02614 ast_free_ha(peer->ha); 02615 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02616 apeerobjs--; 02617 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02618 rpeerobjs--; 02619 else 02620 speerobjs--; 02621 clear_realm_authentication(peer->auth); 02622 peer->auth = NULL; 02623 free(peer); 02624 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2816 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, sip_user::name, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02817 { 02818 if (option_debug > 2) 02819 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02820 ast_free_ha(user->ha); 02821 if (user->chanvars) { 02822 ast_variables_destroy(user->chanvars); 02823 user->chanvars = NULL; 02824 } 02825 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02826 ruserobjs--; 02827 else 02828 suserobjs--; 02829 free(user); 02830 }
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 17248 of file chan_sip.c.
References sip_peer::addr, ahp, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
17249 { 17250 char *host; 17251 char *tmp; 17252 17253 struct hostent *hp; 17254 struct ast_hostent ahp; 17255 struct sip_peer *p; 17256 17257 int res = AST_DEVICE_INVALID; 17258 17259 /* make sure data is not null. Maybe unnecessary, but better be safe */ 17260 host = ast_strdupa(data ? data : ""); 17261 if ((tmp = strchr(host, '@'))) 17262 host = tmp + 1; 17263 17264 if (option_debug > 2) 17265 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 17266 17267 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 17268 * is because when a peer tries to autoexpire, the last thing it does is to 17269 * queue up an event telling the system that the devicestate has changed 17270 * (presumably to unavailable). If we ask for a realtime peer here, this would 17271 * load it BACK into memory, thus defeating the point of trying to trying to 17272 * clear dead hosts out of memory. 17273 */ 17274 if ((p = find_peer(host, NULL, 0, 1))) { 17275 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 17276 /* we have an address for the peer */ 17277 17278 /* Check status in this order 17279 - Hold 17280 - Ringing 17281 - Busy (enforced only by call limit) 17282 - Inuse (we have a call) 17283 - Unreachable (qualify) 17284 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 17285 for registered devices */ 17286 17287 if (p->onHold) 17288 /* First check for hold or ring states */ 17289 res = AST_DEVICE_ONHOLD; 17290 else if (p->inRinging) { 17291 if (p->inRinging == p->inUse) 17292 res = AST_DEVICE_RINGING; 17293 else 17294 res = AST_DEVICE_RINGINUSE; 17295 } else if (p->call_limit && (p->inUse == p->call_limit)) 17296 /* check call limit */ 17297 res = AST_DEVICE_BUSY; 17298 else if (p->call_limit && p->inUse) 17299 /* Not busy, but we do have a call */ 17300 res = AST_DEVICE_INUSE; 17301 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 17302 /* We don't have a call. Are we reachable at all? Requires qualify= */ 17303 res = AST_DEVICE_UNAVAILABLE; 17304 else /* Default reply if we're registered and have no other data */ 17305 res = AST_DEVICE_NOT_INUSE; 17306 } else { 17307 /* there is no address, it's unavailable */ 17308 res = AST_DEVICE_UNAVAILABLE; 17309 } 17310 ASTOBJ_UNREF(p,sip_destroy_peer); 17311 } else { 17312 char *port = strchr(host, ':'); 17313 if (port) 17314 *port = '\0'; 17315 hp = ast_gethostbyname(host, &ahp); 17316 if (hp) 17317 res = AST_DEVICE_UNKNOWN; 17318 } 17319 17320 return res; 17321 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 12088 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12089 { 12090 int oldsipdebug = sipdebug_console; 12091 if (argc != 3) { 12092 if (argc != 5) 12093 return RESULT_SHOWUSAGE; 12094 else if (strcmp(argv[3], "ip") == 0) 12095 return sip_do_debug_ip(fd, argc, argv); 12096 else if (strcmp(argv[3], "peer") == 0) 12097 return sip_do_debug_peer(fd, argc, argv); 12098 else 12099 return RESULT_SHOWUSAGE; 12100 } 12101 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12102 memset(&debugaddr, 0, sizeof(debugaddr)); 12103 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12104 return RESULT_SUCCESS; 12105 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12107 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
12108 { 12109 int oldsipdebug = sipdebug_console; 12110 char *newargv[6] = { "sip", "set", "debug", NULL }; 12111 if (argc != 2) { 12112 if (argc != 4) 12113 return RESULT_SHOWUSAGE; 12114 else if (strcmp(argv[2], "ip") == 0) { 12115 newargv[3] = argv[2]; 12116 newargv[4] = argv[3]; 12117 return sip_do_debug_ip(fd, argc + 1, newargv); 12118 } else if (strcmp(argv[2], "peer") == 0) { 12119 newargv[3] = argv[2]; 12120 newargv[4] = argv[3]; 12121 return sip_do_debug_peer(fd, argc + 1, newargv); 12122 } else 12123 return RESULT_SHOWUSAGE; 12124 } 12125 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12126 memset(&debugaddr, 0, sizeof(debugaddr)); 12127 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12128 return RESULT_SUCCESS; 12129 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 12034 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12035 { 12036 struct hostent *hp; 12037 struct ast_hostent ahp; 12038 int port = 0; 12039 char *p, *arg; 12040 12041 /* sip set debug ip <ip> */ 12042 if (argc != 5) 12043 return RESULT_SHOWUSAGE; 12044 p = arg = argv[4]; 12045 strsep(&p, ":"); 12046 if (p) 12047 port = atoi(p); 12048 hp = ast_gethostbyname(arg, &ahp); 12049 if (hp == NULL) 12050 return RESULT_SHOWUSAGE; 12051 12052 debugaddr.sin_family = AF_INET; 12053 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 12054 debugaddr.sin_port = htons(port); 12055 if (port == 0) 12056 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 12057 else 12058 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 12059 12060 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12061 12062 return RESULT_SUCCESS; 12063 }
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 12066 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
12067 { 12068 struct sip_peer *peer; 12069 if (argc != 5) 12070 return RESULT_SHOWUSAGE; 12071 peer = find_peer(argv[4], NULL, 1, 0); 12072 if (peer) { 12073 if (peer->addr.sin_addr.s_addr) { 12074 debugaddr.sin_family = AF_INET; 12075 debugaddr.sin_addr = peer->addr.sin_addr; 12076 debugaddr.sin_port = peer->addr.sin_port; 12077 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 12078 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12079 } else 12080 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 12081 ASTOBJ_UNREF(peer,sip_destroy_peer); 12082 } else 12083 ast_cli(fd, "No such peer '%s'\n", argv[4]); 12084 return RESULT_SUCCESS; 12085 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 12207 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
12208 { 12209 if (argc != 2) { 12210 return RESULT_SHOWUSAGE; 12211 } 12212 recordhistory = TRUE; 12213 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 12214 return RESULT_SUCCESS; 12215 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 19346 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
19347 { 19348 reload_config(reason); 19349 19350 /* Prune peers who still are supposed to be deleted */ 19351 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 19352 if (option_debug > 3) 19353 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 19354 19355 /* Send qualify (OPTIONS) to all peers */ 19356 sip_poke_all_peers(); 19357 19358 /* Register with all services */ 19359 sip_send_all_registers(); 19360 19361 if (option_debug > 3) 19362 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 19363 19364 return 0; 19365 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 19145 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
19146 { 19147 struct sip_pvt *p; 19148 char *mode; 19149 if (data) 19150 mode = (char *)data; 19151 else { 19152 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 19153 return 0; 19154 } 19155 ast_channel_lock(chan); 19156 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 19157 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 19158 ast_channel_unlock(chan); 19159 return 0; 19160 } 19161 p = chan->tech_pvt; 19162 if (!p) { 19163 ast_channel_unlock(chan); 19164 return 0; 19165 } 19166 ast_mutex_lock(&p->lock); 19167 if (!strcasecmp(mode,"info")) { 19168 ast_clear_flag(&p->flags[0], SIP_DTMF); 19169 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 19170 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19171 } else if (!strcasecmp(mode,"rfc2833")) { 19172 ast_clear_flag(&p->flags[0], SIP_DTMF); 19173 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 19174 p->jointnoncodeccapability |= AST_RTP_DTMF; 19175 } else if (!strcasecmp(mode,"inband")) { 19176 ast_clear_flag(&p->flags[0], SIP_DTMF); 19177 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 19178 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19179 } else 19180 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 19181 if (p->rtp) 19182 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 19183 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 19184 if (!p->vad) { 19185 p->vad = ast_dsp_new(); 19186 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 19187 } 19188 } else { 19189 if (p->vad) { 19190 ast_dsp_free(p->vad); 19191 p->vad = NULL; 19192 } 19193 } 19194 ast_mutex_unlock(&p->lock); 19195 ast_channel_unlock(chan); 19196 return 0; 19197 }
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 11892 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
11893 { 11894 int x = 0; 11895 struct sip_history *hist; 11896 static int errmsg = 0; 11897 11898 if (!dialog) 11899 return; 11900 11901 if (!option_debug && !sipdebug) { 11902 if (!errmsg) { 11903 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11904 errmsg = 1; 11905 } 11906 return; 11907 } 11908 11909 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11910 if (dialog->subscribed) 11911 ast_log(LOG_DEBUG, " * Subscription\n"); 11912 else 11913 ast_log(LOG_DEBUG, " * SIP Call\n"); 11914 if (dialog->history) 11915 AST_LIST_TRAVERSE(dialog->history, hist, list) 11916 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11917 if (!x) 11918 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11919 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11920 }
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 3971 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag, sip_pvt::callid, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
03972 { 03973 int ret = -1; 03974 struct sip_pvt *p; 03975 03976 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03977 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03978 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03979 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03980 03981 if (!newchan || !newchan->tech_pvt) { 03982 if (!newchan) 03983 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03984 else 03985 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03986 return -1; 03987 } 03988 p = newchan->tech_pvt; 03989 03990 if (!p) { 03991 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03992 return -1; 03993 } 03994 03995 ast_mutex_lock(&p->lock); 03996 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03997 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03998 if (p->owner != oldchan) 03999 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 04000 else { 04001 p->owner = newchan; 04002 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 04003 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 04004 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 04005 redirect of both channels). Note that a channel can not be masqueraded *into* 04006 a native bridge. So there is no danger that this breaks a native bridge that 04007 should stay up. */ 04008 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 04009 ret = 0; 04010 } 04011 if (option_debug > 2) 04012 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 04013 04014 ast_mutex_unlock(&p->lock); 04015 return ret; 04016 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 19290 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
19291 { 19292 struct sip_pvt *p = chan->tech_pvt; 19293 return p->jointcapability ? p->jointcapability : p->capability; 19294 }
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 19001 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.
19002 { 19003 struct sip_pvt *p = NULL; 19004 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19005 19006 if (!(p = chan->tech_pvt)) 19007 return AST_RTP_GET_FAILED; 19008 19009 ast_mutex_lock(&p->lock); 19010 if (!(p->rtp)) { 19011 ast_mutex_unlock(&p->lock); 19012 return AST_RTP_GET_FAILED; 19013 } 19014 19015 *rtp = p->rtp; 19016 19017 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 19018 res = AST_RTP_TRY_PARTIAL; 19019 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19020 res = AST_RTP_TRY_NATIVE; 19021 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 19022 res = AST_RTP_GET_FAILED; 19023 19024 ast_mutex_unlock(&p->lock); 19025 19026 return res; 19027 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18866 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.
18867 { 18868 struct sip_pvt *p; 18869 struct ast_udptl *udptl = NULL; 18870 18871 p = chan->tech_pvt; 18872 if (!p) 18873 return NULL; 18874 18875 ast_mutex_lock(&p->lock); 18876 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18877 udptl = p->udptl; 18878 ast_mutex_unlock(&p->lock); 18879 return udptl; 18880 }
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 19030 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
19031 { 19032 struct sip_pvt *p = NULL; 19033 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19034 19035 if (!(p = chan->tech_pvt)) 19036 return AST_RTP_GET_FAILED; 19037 19038 ast_mutex_lock(&p->lock); 19039 if (!(p->vrtp)) { 19040 ast_mutex_unlock(&p->lock); 19041 return AST_RTP_GET_FAILED; 19042 } 19043 19044 *rtp = p->vrtp; 19045 19046 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19047 res = AST_RTP_TRY_NATIVE; 19048 19049 ast_mutex_unlock(&p->lock); 19050 19051 return res; 19052 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18918 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::callid, sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, ast_channel::name, 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().
18919 { 18920 struct sip_pvt *p; 18921 int flag = 0; 18922 18923 p = chan->tech_pvt; 18924 if (!p || !pvt->udptl) 18925 return -1; 18926 18927 /* Setup everything on the other side like offered/responded from first side */ 18928 ast_mutex_lock(&p->lock); 18929 18930 /*! \todo check if this is not set earlier when setting up the PVT. If not 18931 maybe it should move there. */ 18932 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18933 18934 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18935 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18936 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18937 18938 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18939 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18940 not really T38 re-invites which are different. In this 18941 case it's used properly, to see if we can reinvite over 18942 NAT 18943 */ 18944 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18945 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18946 flag =1; 18947 } else { 18948 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18949 } 18950 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18951 if (!p->pendinginvite) { 18952 if (option_debug > 2) { 18953 if (flag) 18954 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)); 18955 else 18956 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)); 18957 } 18958 transmit_reinvite_with_t38_sdp(p); 18959 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18960 if (option_debug > 2) { 18961 if (flag) 18962 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)); 18963 else 18964 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)); 18965 } 18966 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18967 } 18968 } 18969 /* Reset lastrtprx timer */ 18970 p->lastrtprx = p->lastrtptx = time(NULL); 18971 ast_mutex_unlock(&p->lock); 18972 return 0; 18973 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18974 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18975 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18976 flag = 1; 18977 } else { 18978 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18979 } 18980 if (option_debug > 2) { 18981 if (flag) 18982 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)); 18983 else 18984 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)); 18985 } 18986 pvt->t38.state = T38_ENABLED; 18987 p->t38.state = T38_ENABLED; 18988 if (option_debug > 1) { 18989 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18990 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18991 } 18992 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18993 p->lastrtprx = p->lastrtptx = time(NULL); 18994 ast_mutex_unlock(&p->lock); 18995 return 0; 18996 } 18997 }
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 3668 of file chan_sip.c.
References __sip_semi_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_pvt::callid, sip_pkt::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, find_sip_method(), FLAG_RESPONSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, sip_pkt::seqno, 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::username, sip_pvt::vad, and XMIT_RELIABLE.
03669 { 03670 struct sip_pvt *p = ast->tech_pvt; 03671 int needcancel = FALSE; 03672 int needdestroy = 0; 03673 struct ast_channel *oldowner = ast; 03674 03675 if (!p) { 03676 if (option_debug) 03677 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03678 return 0; 03679 } 03680 03681 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03682 if (p->owner) 03683 p->hangupcause = p->owner->hangupcause; 03684 03685 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03686 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03687 if (option_debug && sipdebug) 03688 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03689 update_call_counter(p, DEC_CALL_LIMIT); 03690 } 03691 if (option_debug >3) 03692 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03693 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03694 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03695 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03696 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03697 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03698 p->owner->tech_pvt = NULL; 03699 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03700 return 0; 03701 } 03702 if (option_debug) { 03703 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03704 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03705 else { 03706 if (option_debug) 03707 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03708 } 03709 } 03710 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03711 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03712 03713 ast_mutex_lock(&p->lock); 03714 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03715 if (option_debug && sipdebug) 03716 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03717 update_call_counter(p, DEC_CALL_LIMIT); 03718 } 03719 03720 /* Determine how to disconnect */ 03721 if (p->owner != ast) { 03722 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03723 ast_mutex_unlock(&p->lock); 03724 return 0; 03725 } 03726 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03727 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03728 needcancel = TRUE; 03729 if (option_debug > 3) 03730 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03731 } 03732 03733 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03734 03735 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03736 03737 /* Disconnect */ 03738 if (p->vad) 03739 ast_dsp_free(p->vad); 03740 03741 p->owner = NULL; 03742 ast->tech_pvt = NULL; 03743 03744 ast_module_unref(ast_module_info->self); 03745 03746 /* Do not destroy this pvt until we have timeout or 03747 get an answer to the BYE or INVITE/CANCEL 03748 If we get no answer during retransmit period, drop the call anyway. 03749 (Sorry, mother-in-law, you can't deny a hangup by sending 03750 603 declined to BYE...) 03751 */ 03752 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03753 needdestroy = 1; /* Set destroy flag at end of this function */ 03754 else if (p->invitestate != INV_CALLING) 03755 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03756 03757 /* Start the process if it's not already started */ 03758 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03759 if (needcancel) { /* Outgoing call, not up */ 03760 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03761 /* stop retransmitting an INVITE that has not received a response */ 03762 struct sip_pkt *cur; 03763 for (cur = p->packets; cur; cur = cur->next) { 03764 __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data)); 03765 } 03766 03767 /* if we can't send right now, mark it pending */ 03768 if (p->invitestate == INV_CALLING) { 03769 /* We can't send anything in CALLING state */ 03770 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03771 /* 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. */ 03772 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03773 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03774 } else { 03775 p->invitestate = INV_CANCELLED; 03776 /* Send a new request: CANCEL */ 03777 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03778 /* Actually don't destroy us yet, wait for the 487 on our original 03779 INVITE, but do set an autodestruct just in case we never get it. */ 03780 needdestroy = 0; 03781 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03782 } 03783 } else { /* Incoming call, not up */ 03784 const char *res; 03785 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03786 transmit_response_reliable(p, res, &p->initreq); 03787 else 03788 transmit_response_reliable(p, "603 Declined", &p->initreq); 03789 p->invitestate = INV_TERMINATED; 03790 } 03791 } else { /* Call is in UP state, send BYE */ 03792 if (!p->pendinginvite) { 03793 char *audioqos = ""; 03794 char *videoqos = ""; 03795 if (p->rtp) 03796 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03797 if (p->vrtp) 03798 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03799 /* Send a hangup */ 03800 if (oldowner->_state == AST_STATE_UP) { 03801 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03802 } 03803 03804 /* Get RTCP quality before end of call */ 03805 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03806 if (p->rtp) 03807 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03808 if (p->vrtp) 03809 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03810 } 03811 if (p->rtp && oldowner) 03812 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03813 if (p->vrtp && oldowner) 03814 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03815 } else { 03816 /* Note we will need a BYE when this all settles out 03817 but we can't send one while we have "INVITE" outstanding. */ 03818 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03819 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03820 AST_SCHED_DEL(sched, p->waitid); 03821 if (sip_cancel_destroy(p)) 03822 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03823 } 03824 } 03825 } 03826 if (needdestroy) 03827 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03828 ast_mutex_unlock(&p->lock); 03829 return 0; 03830 }
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 4087 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, sip_pvt::mohinterpret, sip_pvt::rtp, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
04088 { 04089 struct sip_pvt *p = ast->tech_pvt; 04090 int res = 0; 04091 04092 ast_mutex_lock(&p->lock); 04093 switch(condition) { 04094 case AST_CONTROL_RINGING: 04095 if (ast->_state == AST_STATE_RING) { 04096 p->invitestate = INV_EARLY_MEDIA; 04097 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 04098 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 04099 /* Send 180 ringing if out-of-band seems reasonable */ 04100 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 04101 ast_set_flag(&p->flags[0], SIP_RINGING); 04102 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 04103 break; 04104 } else { 04105 /* Well, if it's not reasonable, just send in-band */ 04106 } 04107 } 04108 res = -1; 04109 break; 04110 case AST_CONTROL_BUSY: 04111 if (ast->_state != AST_STATE_UP) { 04112 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04113 p->invitestate = INV_COMPLETED; 04114 sip_alreadygone(p); 04115 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04116 break; 04117 } 04118 res = -1; 04119 break; 04120 case AST_CONTROL_CONGESTION: 04121 if (ast->_state != AST_STATE_UP) { 04122 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04123 p->invitestate = INV_COMPLETED; 04124 sip_alreadygone(p); 04125 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04126 break; 04127 } 04128 res = -1; 04129 break; 04130 case AST_CONTROL_PROCEEDING: 04131 if ((ast->_state != AST_STATE_UP) && 04132 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04133 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04134 transmit_response(p, "100 Trying", &p->initreq); 04135 p->invitestate = INV_PROCEEDING; 04136 break; 04137 } 04138 res = -1; 04139 break; 04140 case AST_CONTROL_PROGRESS: 04141 if ((ast->_state != AST_STATE_UP) && 04142 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04143 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04144 p->invitestate = INV_EARLY_MEDIA; 04145 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04146 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04147 break; 04148 } 04149 res = -1; 04150 break; 04151 case AST_CONTROL_HOLD: 04152 ast_rtp_new_source(p->rtp); 04153 ast_moh_start(ast, data, p->mohinterpret); 04154 break; 04155 case AST_CONTROL_UNHOLD: 04156 ast_rtp_new_source(p->rtp); 04157 ast_moh_stop(ast); 04158 break; 04159 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04160 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04161 transmit_info_with_vidupdate(p); 04162 /* ast_rtcp_send_h261fur(p->vrtp); */ 04163 } else 04164 res = -1; 04165 break; 04166 case AST_CONTROL_SRCUPDATE: 04167 ast_rtp_new_source(p->rtp); 04168 break; 04169 case -1: 04170 res = -1; 04171 break; 04172 default: 04173 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04174 res = -1; 04175 break; 04176 } 04177 ast_mutex_unlock(&p->lock); 04178 return res; 04179 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1818 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().
01819 { 01820 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01821 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 4187 of file chan_sip.c.
References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_verbose(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, sip_pvt::exten, f, ast_channel::fds, sip_pvt::flags, sip_pvt::from, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peername, sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::uri, sip_pvt::useragent, sip_pvt::username, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04188 { 04189 struct ast_channel *tmp; 04190 struct ast_variable *v = NULL; 04191 int fmt; 04192 int what; 04193 int needvideo = 0, video = 0; 04194 char *decoded_exten; 04195 04196 if (option_debug != 0) { 04197 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04198 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04199 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04200 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04201 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04202 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04203 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04204 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04205 } 04206 04207 { 04208 char my_name[128]; /* pick a good name */ 04209 const char *f, *fromdomain = NULL; 04210 04211 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04212 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04213 else 04214 fromdomain = i->fromdomain; 04215 04216 if (!ast_strlen_zero(i->username)) { 04217 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04218 /* title not empty and different from username */ 04219 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04220 } else { 04221 /* username not empty, title is empty or equal to username */ 04222 snprintf(my_name, sizeof(my_name), "%s", i->username); 04223 } 04224 } else { /* username empty */ 04225 if (!ast_strlen_zero(i->peername)) { 04226 /* call from unregisted peer */ 04227 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04228 } else { /* username and peername empty */ 04229 if (!ast_strlen_zero(title)) { /* title not empty */ 04230 snprintf(my_name, sizeof(my_name), "%s", title); 04231 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04232 f = i->from; 04233 if (!strncmp(f, "sip:", 4)) 04234 f += 4; 04235 snprintf(my_name, sizeof(my_name), "%s", f); 04236 } else { /* fallback to fromdomain */ 04237 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04238 } 04239 } 04240 } 04241 ast_mutex_unlock(&i->lock); 04242 /* Don't hold a sip pvt lock while we allocate a channel */ 04243 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, ast_atomic_fetchadd_int((int *)&chan_idx, +1)); 04244 04245 } 04246 if (!tmp) { 04247 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04248 ast_mutex_lock(&i->lock); 04249 return NULL; 04250 } 04251 ast_mutex_lock(&i->lock); 04252 04253 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04254 tmp->tech = &sip_tech_info; 04255 else 04256 tmp->tech = &sip_tech; 04257 04258 /* Select our native format based on codec preference until we receive 04259 something from another device to the contrary. */ 04260 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04261 what = i->jointcapability; 04262 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04263 } else if (i->capability) { /* Our configured capability for this peer */ 04264 what = i->capability; 04265 video = i->capability & AST_FORMAT_VIDEO_MASK; 04266 } else { 04267 what = global_capability; /* Global codec support */ 04268 video = global_capability & AST_FORMAT_VIDEO_MASK; 04269 } 04270 04271 /* Set the native formats for audio and merge in video */ 04272 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04273 if (option_debug > 2) { 04274 char buf[SIPBUFSIZE]; 04275 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04276 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04277 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04278 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04279 if (i->prefcodec) 04280 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04281 } 04282 04283 /* XXX Why are we choosing a codec from the native formats?? */ 04284 fmt = ast_best_codec(tmp->nativeformats); 04285 04286 /* If we have a prefcodec setting, we have an inbound channel that set a 04287 preferred format for this call. Otherwise, we check the jointcapability 04288 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04289 */ 04290 if (i->vrtp) { 04291 if (i->prefcodec) 04292 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04293 else 04294 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04295 } 04296 04297 if (option_debug > 2) { 04298 if (needvideo) 04299 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04300 else 04301 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04302 } 04303 04304 04305 04306 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04307 i->vad = ast_dsp_new(); 04308 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04309 if (global_relaxdtmf) 04310 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04311 } 04312 if (i->rtp) { 04313 tmp->fds[0] = ast_rtp_fd(i->rtp); 04314 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04315 } 04316 if (needvideo && i->vrtp) { 04317 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04318 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04319 } 04320 if (i->udptl) { 04321 tmp->fds[5] = ast_udptl_fd(i->udptl); 04322 } 04323 if (state == AST_STATE_RING) 04324 tmp->rings = 1; 04325 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04326 tmp->writeformat = fmt; 04327 tmp->rawwriteformat = fmt; 04328 tmp->readformat = fmt; 04329 tmp->rawreadformat = fmt; 04330 tmp->tech_pvt = i; 04331 04332 tmp->callgroup = i->callgroup; 04333 tmp->pickupgroup = i->pickupgroup; 04334 tmp->cid.cid_pres = i->callingpres; 04335 if (!ast_strlen_zero(i->accountcode)) 04336 ast_string_field_set(tmp, accountcode, i->accountcode); 04337 if (i->amaflags) 04338 tmp->amaflags = i->amaflags; 04339 if (!ast_strlen_zero(i->language)) 04340 ast_string_field_set(tmp, language, i->language); 04341 i->owner = tmp; 04342 ast_module_ref(ast_module_info->self); 04343 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04344 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04345 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04346 * structure so that there aren't issues when forming URI's 04347 */ 04348 decoded_exten = ast_strdupa(i->exten); 04349 ast_uri_decode(decoded_exten); 04350 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04351 04352 /* Don't use ast_set_callerid() here because it will 04353 * generate an unnecessary NewCallerID event */ 04354 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04355 if (!ast_strlen_zero(i->rdnis)) 04356 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04357 04358 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04359 tmp->cid.cid_dnid = ast_strdup(i->exten); 04360 04361 tmp->priority = 1; 04362 if (!ast_strlen_zero(i->uri)) 04363 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04364 if (!ast_strlen_zero(i->domain)) 04365 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04366 if (!ast_strlen_zero(i->useragent)) 04367 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04368 if (!ast_strlen_zero(i->callid)) 04369 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04370 if (i->rtp) 04371 ast_jb_configure(tmp, &global_jbconf); 04372 04373 /* Set channel variables for this call from configuration */ 04374 for (v = i->chanvars ; v ; v = v->next) 04375 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04376 04377 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04378 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04379 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04380 ast_hangup(tmp); 04381 tmp = NULL; 04382 } 04383 04384 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04385 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04386 04387 return tmp; 04388 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 12188 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12189 { 12190 if (argc != 4) 12191 return RESULT_SHOWUSAGE; 12192 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12193 ast_cli(fd, "SIP Debugging Disabled\n"); 12194 return RESULT_SUCCESS; 12195 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12197 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12198 { 12199 if (argc != 3) 12200 return RESULT_SHOWUSAGE; 12201 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12202 ast_cli(fd, "SIP Debugging Disabled\n"); 12203 return RESULT_SUCCESS; 12204 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 12218 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
12219 { 12220 if (argc != 3) { 12221 return RESULT_SHOWUSAGE; 12222 } 12223 recordhistory = FALSE; 12224 ast_cli(fd, "SIP History Recording Disabled\n"); 12225 return RESULT_SUCCESS; 12226 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 12132 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
12133 { 12134 struct ast_variable *varlist; 12135 int i; 12136 12137 if (argc < 4) 12138 return RESULT_SHOWUSAGE; 12139 12140 if (!notify_types) { 12141 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 12142 return RESULT_FAILURE; 12143 } 12144 12145 varlist = ast_variable_browse(notify_types, argv[2]); 12146 12147 if (!varlist) { 12148 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 12149 return RESULT_FAILURE; 12150 } 12151 12152 for (i = 3; i < argc; i++) { 12153 struct sip_pvt *p; 12154 struct sip_request req; 12155 struct ast_variable *var; 12156 12157 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 12158 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 12159 return RESULT_FAILURE; 12160 } 12161 12162 if (create_addr(p, argv[i], NULL)) { 12163 /* Maybe they're not registered, etc. */ 12164 sip_destroy(p); 12165 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 12166 continue; 12167 } 12168 12169 initreqprep(&req, p, SIP_NOTIFY); 12170 12171 for (var = varlist; var; var = var->next) 12172 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 12173 12174 /* Recalculate our side, and recalculate Call ID */ 12175 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 12176 p->ourip = __ourip; 12177 build_via(p); 12178 build_callid_pvt(p); 12179 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 12180 transmit_sip_request(p, &req); 12181 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12182 } 12183 12184 return RESULT_SUCCESS; 12185 }
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 13983 of file chan_sip.c.
References ast_channel::accountcode, 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_copy_string(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
13984 { 13985 struct sip_dual *d; 13986 struct ast_channel *transferee, *transferer; 13987 /* Chan2m: The transferer, chan1m: The transferee */ 13988 pthread_t th; 13989 13990 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13991 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13992 if ((!transferer) || (!transferee)) { 13993 if (transferee) { 13994 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13995 ast_hangup(transferee); 13996 } 13997 if (transferer) { 13998 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13999 ast_hangup(transferer); 14000 } 14001 return -1; 14002 } 14003 14004 /* Make formats okay */ 14005 transferee->readformat = chan1->readformat; 14006 transferee->writeformat = chan1->writeformat; 14007 14008 /* Prepare for taking over the channel */ 14009 ast_channel_masquerade(transferee, chan1); 14010 14011 /* Setup the extensions and such */ 14012 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 14013 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 14014 transferee->priority = chan1->priority; 14015 14016 /* We make a clone of the peer channel too, so we can play 14017 back the announcement */ 14018 14019 /* Make formats okay */ 14020 transferer->readformat = chan2->readformat; 14021 transferer->writeformat = chan2->writeformat; 14022 14023 /* Prepare for taking over the channel. Go ahead and grab this channel 14024 * lock here to avoid a deadlock with callbacks into the channel driver 14025 * that hold the channel lock and want the pvt lock. */ 14026 while (ast_channel_trylock(chan2)) { 14027 struct sip_pvt *pvt = chan2->tech_pvt; 14028 DEADLOCK_AVOIDANCE(&pvt->lock); 14029 } 14030 ast_channel_masquerade(transferer, chan2); 14031 ast_channel_unlock(chan2); 14032 14033 /* Setup the extensions and such */ 14034 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 14035 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 14036 transferer->priority = chan2->priority; 14037 14038 ast_channel_lock(transferer); 14039 if (ast_do_masquerade(transferer)) { 14040 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 14041 ast_channel_unlock(transferer); 14042 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14043 ast_hangup(transferer); 14044 return -1; 14045 } 14046 ast_channel_unlock(transferer); 14047 if (!transferer || !transferee) { 14048 if (!transferer) { 14049 if (option_debug) 14050 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 14051 } 14052 if (!transferee) { 14053 if (option_debug) 14054 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 14055 } 14056 return -1; 14057 } 14058 if ((d = ast_calloc(1, sizeof(*d)))) { 14059 pthread_attr_t attr; 14060 14061 pthread_attr_init(&attr); 14062 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 14063 14064 /* Save original request for followup */ 14065 copy_request(&d->req, req); 14066 d->chan1 = transferee; /* Transferee */ 14067 d->chan2 = transferer; /* Transferer */ 14068 d->seqno = seqno; 14069 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 14070 /* Could not start thread */ 14071 free(d); /* We don't need it anymore. If thread is created, d will be free'd 14072 by sip_park_thread() */ 14073 pthread_attr_destroy(&attr); 14074 return 0; 14075 } 14076 pthread_attr_destroy(&attr); 14077 } 14078 return -1; 14079 }
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 13916 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, ast_channel::name, 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().
13917 { 13918 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13919 struct sip_dual *d; 13920 struct sip_request req; 13921 int ext; 13922 int res; 13923 13924 d = stuff; 13925 transferee = d->chan1; 13926 transferer = d->chan2; 13927 copy_request(&req, &d->req); 13928 13929 if (!transferee || !transferer) { 13930 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13931 return NULL; 13932 } 13933 if (option_debug > 3) 13934 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13935 13936 ast_channel_lock(transferee); 13937 if (ast_do_masquerade(transferee)) { 13938 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13939 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13940 ast_channel_unlock(transferee); 13941 return NULL; 13942 } 13943 ast_channel_unlock(transferee); 13944 13945 res = ast_park_call(transferee, transferer, 0, &ext); 13946 13947 13948 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13949 if (!res) { 13950 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13951 } else { 13952 /* Then tell the transferer what happened */ 13953 sprintf(buf, "Call parked on extension '%d'", ext); 13954 transmit_message_with_text(transferer->tech_pvt, buf); 13955 } 13956 #endif 13957 13958 /* Any way back to the current call??? */ 13959 /* Transmit response to the REFER request */ 13960 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13961 if (!res) { 13962 /* Transfer succeeded */ 13963 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13964 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13965 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13966 ast_hangup(transferer); /* This will cause a BYE */ 13967 if (option_debug) 13968 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13969 } else { 13970 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13971 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13972 if (option_debug) 13973 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13974 /* Do not hangup call */ 13975 } 13976 free(d); 13977 return NULL; 13978 }
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 9182 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), sip_peer::name, sip_peer::onHold, and sip_pvt::peername.
Referenced by change_hold_state(), and update_call_counter().
09183 { 09184 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 09185 09186 if (!peer) 09187 return; 09188 09189 /* If they put someone on hold, increment the value... otherwise decrement it */ 09190 if (hold) 09191 peer->onHold++; 09192 else 09193 peer->onHold--; 09194 09195 /* Request device state update */ 09196 ast_device_state_changed("SIP/%s", peer->name); 09197 09198 return; 09199 }
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 19300 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sched, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
19301 { 19302 int ms = 0; 19303 19304 if (!speerobjs) /* No peers, just give up */ 19305 return; 19306 19307 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 19308 ASTOBJ_WRLOCK(iterator); 19309 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 19310 struct sip_peer *peer_ptr = iterator; 19311 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19312 } 19313 ms += 100; 19314 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 19315 if (iterator->pokeexpire == -1) { 19316 struct sip_peer *peer_ptr = iterator; 19317 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19318 } 19319 ASTOBJ_UNLOCK(iterator); 19320 } while (0) 19321 ); 19322 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 17103 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_update_realtime(), ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by sip_poke_peer().
17104 { 17105 struct sip_peer *peer = (struct sip_peer *)data; 17106 17107 peer->pokeexpire = -1; 17108 if (peer->lastms > -1) { 17109 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 17110 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 17111 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 17112 } 17113 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 17114 } 17115 if (peer->call) 17116 sip_destroy(peer->call); 17117 peer->call = NULL; 17118 peer->lastms = -1; 17119 ast_device_state_changed("SIP/%s", peer->name); 17120 17121 /* This function gets called one place outside of the scheduler ... */ 17122 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17123 struct sip_peer *peer_ptr = peer; 17124 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17125 } 17126 17127 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 17128 * inherit the reference that the current callback already has. */ 17129 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 17130 if (peer->pokeexpire == -1) { 17131 ASTOBJ_UNREF(peer, sip_destroy_peer); 17132 } 17133 17134 return 0; 17135 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 17140 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_callid_pvt(), build_via(), sip_peer::call, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), sip_destroy(), sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), sip_pvt::username, and XMIT_ERROR.
Referenced by build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
17141 { 17142 struct sip_pvt *p; 17143 int xmitres = 0; 17144 17145 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 17146 /* IF we have no IP, or this isn't to be monitored, return 17147 imeediately after clearing things out */ 17148 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17149 struct sip_peer *peer_ptr = peer; 17150 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17151 } 17152 peer->lastms = 0; 17153 peer->call = NULL; 17154 return 0; 17155 } 17156 if (peer->call) { 17157 if (sipdebug) 17158 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 17159 sip_destroy(peer->call); 17160 } 17161 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 17162 return -1; 17163 17164 p->sa = peer->addr; 17165 p->recv = peer->addr; 17166 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 17167 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17168 17169 /* Send OPTIONs to peer's fullcontact */ 17170 if (!ast_strlen_zero(peer->fullcontact)) 17171 ast_string_field_set(p, fullcontact, peer->fullcontact); 17172 17173 if (!ast_strlen_zero(peer->tohost)) 17174 ast_string_field_set(p, tohost, peer->tohost); 17175 else 17176 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 17177 17178 /* Recalculate our side, and recalculate Call ID */ 17179 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17180 p->ourip = __ourip; 17181 build_via(p); 17182 build_callid_pvt(p); 17183 17184 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17185 struct sip_peer *peer_ptr = peer; 17186 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17187 } 17188 17189 p->relatedpeer = ASTOBJ_REF(peer); 17190 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17191 #ifdef VOCAL_DATA_HACK 17192 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 17193 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 17194 #else 17195 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 17196 #endif 17197 gettimeofday(&peer->ps, NULL); 17198 if (xmitres == XMIT_ERROR) { 17199 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 17200 } else { 17201 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17202 struct sip_peer *peer_ptr = peer; 17203 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17204 } 17205 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 17206 if (peer->pokeexpire == -1) { 17207 struct sip_peer *peer_ptr = peer; 17208 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17209 } 17210 } 17211 17212 return 0; 17213 }
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 8507 of file chan_sip.c.
References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
08508 { 08509 struct sip_peer *peer = (struct sip_peer *) data; 08510 08511 peer->pokeexpire = -1; 08512 08513 sip_poke_peer(peer); 08514 08515 ASTOBJ_UNREF(peer, sip_destroy_peer); 08516 08517 return 0; 08518 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10906 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and TRUE.
10907 { 10908 struct sip_peer *peer; 10909 struct sip_user *user; 10910 int pruneuser = FALSE; 10911 int prunepeer = FALSE; 10912 int multi = FALSE; 10913 char *name = NULL; 10914 regex_t regexbuf; 10915 10916 switch (argc) { 10917 case 4: 10918 if (!strcasecmp(argv[3], "user")) 10919 return RESULT_SHOWUSAGE; 10920 if (!strcasecmp(argv[3], "peer")) 10921 return RESULT_SHOWUSAGE; 10922 if (!strcasecmp(argv[3], "like")) 10923 return RESULT_SHOWUSAGE; 10924 if (!strcasecmp(argv[3], "all")) { 10925 multi = TRUE; 10926 pruneuser = prunepeer = TRUE; 10927 } else { 10928 pruneuser = prunepeer = TRUE; 10929 name = argv[3]; 10930 } 10931 break; 10932 case 5: 10933 if (!strcasecmp(argv[4], "like")) 10934 return RESULT_SHOWUSAGE; 10935 if (!strcasecmp(argv[3], "all")) 10936 return RESULT_SHOWUSAGE; 10937 if (!strcasecmp(argv[3], "like")) { 10938 multi = TRUE; 10939 name = argv[4]; 10940 pruneuser = prunepeer = TRUE; 10941 } else if (!strcasecmp(argv[3], "user")) { 10942 pruneuser = TRUE; 10943 if (!strcasecmp(argv[4], "all")) 10944 multi = TRUE; 10945 else 10946 name = argv[4]; 10947 } else if (!strcasecmp(argv[3], "peer")) { 10948 prunepeer = TRUE; 10949 if (!strcasecmp(argv[4], "all")) 10950 multi = TRUE; 10951 else 10952 name = argv[4]; 10953 } else 10954 return RESULT_SHOWUSAGE; 10955 break; 10956 case 6: 10957 if (strcasecmp(argv[4], "like")) 10958 return RESULT_SHOWUSAGE; 10959 if (!strcasecmp(argv[3], "user")) { 10960 pruneuser = TRUE; 10961 name = argv[5]; 10962 } else if (!strcasecmp(argv[3], "peer")) { 10963 prunepeer = TRUE; 10964 name = argv[5]; 10965 } else 10966 return RESULT_SHOWUSAGE; 10967 break; 10968 default: 10969 return RESULT_SHOWUSAGE; 10970 } 10971 10972 if (multi && name) { 10973 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10974 return RESULT_SHOWUSAGE; 10975 } 10976 10977 if (multi) { 10978 if (prunepeer) { 10979 int pruned = 0; 10980 10981 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10982 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10983 ASTOBJ_RDLOCK(iterator); 10984 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10985 ASTOBJ_UNLOCK(iterator); 10986 continue; 10987 }; 10988 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10989 ASTOBJ_MARK(iterator); 10990 pruned++; 10991 } 10992 ASTOBJ_UNLOCK(iterator); 10993 } while (0) ); 10994 if (pruned) { 10995 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10996 ast_cli(fd, "%d peers pruned.\n", pruned); 10997 } else 10998 ast_cli(fd, "No peers found to prune.\n"); 10999 ASTOBJ_CONTAINER_UNLOCK(&peerl); 11000 } 11001 if (pruneuser) { 11002 int pruned = 0; 11003 11004 ASTOBJ_CONTAINER_WRLOCK(&userl); 11005 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11006 ASTOBJ_RDLOCK(iterator); 11007 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11008 ASTOBJ_UNLOCK(iterator); 11009 continue; 11010 }; 11011 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11012 ASTOBJ_MARK(iterator); 11013 pruned++; 11014 } 11015 ASTOBJ_UNLOCK(iterator); 11016 } while (0) ); 11017 if (pruned) { 11018 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 11019 ast_cli(fd, "%d users pruned.\n", pruned); 11020 } else 11021 ast_cli(fd, "No users found to prune.\n"); 11022 ASTOBJ_CONTAINER_UNLOCK(&userl); 11023 } 11024 } else { 11025 if (prunepeer) { 11026 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 11027 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11028 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 11029 ASTOBJ_CONTAINER_LINK(&peerl, peer); 11030 } else 11031 ast_cli(fd, "Peer '%s' pruned.\n", name); 11032 ASTOBJ_UNREF(peer, sip_destroy_peer); 11033 } else 11034 ast_cli(fd, "Peer '%s' not found.\n", name); 11035 } 11036 if (pruneuser) { 11037 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 11038 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11039 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 11040 ASTOBJ_CONTAINER_LINK(&userl, user); 11041 } else 11042 ast_cli(fd, "User '%s' pruned.\n", name); 11043 ASTOBJ_UNREF(user, sip_destroy_user); 11044 } else 11045 ast_cli(fd, "User '%s' not found.\n", name); 11046 } 11047 } 11048 11049 return RESULT_SUCCESS; 11050 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4614 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, ast_channel::name, 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().
04615 { 04616 struct ast_frame *fr; 04617 struct sip_pvt *p = ast->tech_pvt; 04618 int faxdetected = FALSE; 04619 04620 ast_mutex_lock(&p->lock); 04621 fr = sip_rtp_read(ast, p, &faxdetected); 04622 p->lastrtprx = time(NULL); 04623 04624 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04625 /* 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 */ 04626 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04627 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04628 if (!p->pendinginvite) { 04629 if (option_debug > 2) 04630 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04631 p->t38.state = T38_LOCAL_REINVITE; 04632 transmit_reinvite_with_t38_sdp(p); 04633 if (option_debug > 1) 04634 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04635 } 04636 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04637 if (option_debug > 2) 04638 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04639 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04640 } 04641 } 04642 04643 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04644 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04645 fr = &ast_null_frame; 04646 } 04647 04648 ast_mutex_unlock(&p->lock); 04649 return fr; 04650 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1812 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().
01813 { 01814 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01815 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8310 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().
08311 { 08312 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08313 return p->refer ? 1 : 0; 08314 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 8047 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_registry::hostname, sip_pvt::lock, LOG_NOTICE, manager_event(), sip_registry::needdns, 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, transmit_register(), TRUE, and sip_registry::username.
Referenced by transmit_register().
08048 { 08049 08050 /* if we are here, our registration timed out, so we'll just do it over */ 08051 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 08052 struct sip_pvt *p; 08053 int res; 08054 08055 /* if we couldn't get a reference to the registry object, punt */ 08056 if (!r) 08057 return 0; 08058 08059 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 08060 if (r->call) { 08061 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 08062 in the single SIP manager thread. */ 08063 p = r->call; 08064 ast_mutex_lock(&p->lock); 08065 if (p->registry) 08066 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 08067 r->call = NULL; 08068 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 08069 /* Pretend to ACK anything just in case */ 08070 __sip_pretend_ack(p); 08071 ast_mutex_unlock(&p->lock); 08072 } 08073 /* If we have a limit, stop registration and give up */ 08074 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 08075 /* Ok, enough is enough. Don't try any more */ 08076 /* We could add an external notification here... 08077 steal it from app_voicemail :-) */ 08078 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 08079 r->regstate = REG_STATE_FAILED; 08080 } else { 08081 r->regstate = REG_STATE_UNREGISTERED; 08082 r->timeout = -1; 08083 r->needdns = TRUE; 08084 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 08085 } 08086 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)); 08087 ASTOBJ_UNREF(r, sip_registry_destroy); 08088 return 0; 08089 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4954 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::contact, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), TRUE, and username.
04955 { 04956 struct sip_registry *reg; 04957 int portnum = 0; 04958 char username[256] = ""; 04959 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04960 char *porta=NULL; 04961 char *contact=NULL; 04962 04963 if (!value) 04964 return -1; 04965 ast_copy_string(username, value, sizeof(username)); 04966 /* First split around the last '@' then parse the two components. */ 04967 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04968 if (hostname) 04969 *hostname++ = '\0'; 04970 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04971 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04972 return -1; 04973 } 04974 /* split user[:secret[:authuser]] */ 04975 secret = strchr(username, ':'); 04976 if (secret) { 04977 *secret++ = '\0'; 04978 authuser = strchr(secret, ':'); 04979 if (authuser) 04980 *authuser++ = '\0'; 04981 } 04982 /* split host[:port][/contact] */ 04983 contact = strchr(hostname, '/'); 04984 if (contact) 04985 *contact++ = '\0'; 04986 if (ast_strlen_zero(contact)) 04987 contact = "s"; 04988 porta = strchr(hostname, ':'); 04989 if (porta) { 04990 *porta++ = '\0'; 04991 portnum = atoi(porta); 04992 if (portnum == 0) { 04993 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04994 return -1; 04995 } 04996 } 04997 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04998 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04999 return -1; 05000 } 05001 05002 if (ast_string_field_init(reg, 256)) { 05003 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 05004 free(reg); 05005 return -1; 05006 } 05007 05008 regobjs++; 05009 ASTOBJ_INIT(reg); 05010 ast_string_field_set(reg, contact, contact); 05011 if (!ast_strlen_zero(username)) 05012 ast_string_field_set(reg, username, username); 05013 if (hostname) 05014 ast_string_field_set(reg, hostname, hostname); 05015 if (authuser) 05016 ast_string_field_set(reg, authuser, authuser); 05017 if (secret) 05018 ast_string_field_set(reg, secret, secret); 05019 reg->expire = -1; 05020 reg->timeout = -1; 05021 reg->refresh = default_expiry; 05022 reg->portno = portnum; 05023 reg->callid_valid = FALSE; 05024 reg->ocseq = INITIAL_CSEQ; 05025 reg->needdns = TRUE; 05026 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 05027 ASTOBJ_UNREF(reg,sip_registry_destroy); 05028 return 0; 05029 }
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 3216 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, sip_registry::hostname, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), sip_registry::timeout, and sip_registry::username.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03217 { 03218 /* Really delete */ 03219 if (option_debug > 2) 03220 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03221 03222 if (reg->call) { 03223 /* Clear registry before destroying to ensure 03224 we don't get reentered trying to grab the registry lock */ 03225 reg->call->registry = NULL; 03226 if (option_debug > 2) 03227 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03228 sip_destroy(reg->call); 03229 } 03230 AST_SCHED_DEL(sched, reg->expire); 03231 AST_SCHED_DEL(sched, reg->timeout); 03232 ast_string_field_free_memory(reg); 03233 regobjs--; 03234 free(reg); 03235 03236 }
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 12862 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12863 { 12864 struct sip_pvt *p = (struct sip_pvt *) data; 12865 12866 ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ 12867 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12868 p->waitid = -1; 12869 check_pendings(p); 12870 ast_mutex_unlock(&p->lock); 12871 return 0; 12872 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 19368 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), sip_reload_lock, and TRUE.
Referenced by reload().
19369 { 19370 ast_mutex_lock(&sip_reload_lock); 19371 if (sip_reloading) 19372 ast_verbose("Previous SIP reload not yet done\n"); 19373 else { 19374 sip_reloading = TRUE; 19375 if (fd) 19376 sip_reloadreason = CHANNEL_CLI_RELOAD; 19377 else 19378 sip_reloadreason = CHANNEL_MODULE_RELOAD; 19379 } 19380 ast_mutex_unlock(&sip_reload_lock); 19381 restart_monitor(); 19382 19383 return 0; 19384 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 17325 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::peername, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
17326 { 17327 int oldformat; 17328 struct sip_pvt *p; 17329 struct ast_channel *tmpc = NULL; 17330 char *ext, *host; 17331 char tmp[256]; 17332 char *dest = data; 17333 17334 oldformat = format; 17335 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 17336 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)); 17337 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 17338 return NULL; 17339 } 17340 if (option_debug) 17341 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 17342 17343 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 17344 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 17345 *cause = AST_CAUSE_SWITCH_CONGESTION; 17346 return NULL; 17347 } 17348 17349 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 17350 17351 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 17352 sip_destroy(p); 17353 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 17354 *cause = AST_CAUSE_SWITCH_CONGESTION; 17355 return NULL; 17356 } 17357 17358 ast_copy_string(tmp, dest, sizeof(tmp)); 17359 host = strchr(tmp, '@'); 17360 if (host) { 17361 *host++ = '\0'; 17362 ext = tmp; 17363 } else { 17364 ext = strchr(tmp, '/'); 17365 if (ext) 17366 *ext++ = '\0'; 17367 host = tmp; 17368 } 17369 17370 if (create_addr(p, host, NULL)) { 17371 *cause = AST_CAUSE_UNREGISTERED; 17372 if (option_debug > 2) 17373 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 17374 sip_destroy(p); 17375 return NULL; 17376 } 17377 if (ast_strlen_zero(p->peername) && ext) 17378 ast_string_field_set(p, peername, ext); 17379 /* Recalculate our side, and recalculate Call ID */ 17380 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17381 p->ourip = __ourip; 17382 build_via(p); 17383 build_callid_pvt(p); 17384 17385 /* We have an extension to call, don't use the full contact here */ 17386 /* This to enable dialing registered peers with extension dialling, 17387 like SIP/peername/extension 17388 SIP/peername will still use the full contact */ 17389 if (ext) { 17390 ast_string_field_set(p, username, ext); 17391 ast_string_field_free(p, fullcontact); 17392 } 17393 #if 0 17394 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 17395 #endif 17396 p->prefcodec = oldformat; /* Format for this call */ 17397 ast_mutex_lock(&p->lock); 17398 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 17399 ast_mutex_unlock(&p->lock); 17400 if (!tmpc) 17401 sip_destroy(p); 17402 ast_update_use_count(); 17403 restart_monitor(); 17404 return tmpc; 17405 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 8015 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, sip_registry::hostname, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), sipdebug, and sip_registry::username.
Referenced by handle_response_register(), and sip_send_all_registers().
08016 { 08017 /* if we are here, we know that we need to reregister. */ 08018 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 08019 08020 /* if we couldn't get a reference to the registry object, punt */ 08021 if (!r) 08022 return 0; 08023 08024 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 08025 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 08026 /* Since registry's are only added/removed by the the monitor thread, this 08027 may be overkill to reference/dereference at all here */ 08028 if (sipdebug) 08029 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 08030 08031 r->expire = -1; 08032 __sip_do_register(r); 08033 ASTOBJ_UNREF(r, sip_registry_destroy); 08034 return 0; 08035 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static] |
Read RTP from network.
Definition at line 4542 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::name, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04543 { 04544 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04545 struct ast_frame *f; 04546 04547 if (!p->rtp) { 04548 /* We have no RTP allocated for this channel */ 04549 return &ast_null_frame; 04550 } 04551 04552 switch(ast->fdno) { 04553 case 0: 04554 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04555 break; 04556 case 1: 04557 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04558 break; 04559 case 2: 04560 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04561 break; 04562 case 3: 04563 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04564 break; 04565 case 5: 04566 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04567 break; 04568 default: 04569 f = &ast_null_frame; 04570 } 04571 /* Don't forward RFC2833 if we're not supposed to */ 04572 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 04573 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 04574 ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 04575 return &ast_null_frame; 04576 } 04577 04578 /* We already hold the channel lock */ 04579 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04580 return f; 04581 04582 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04583 if (!(f->subclass & p->jointcapability)) { 04584 if (option_debug) { 04585 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04586 ast_getformatname(f->subclass), p->owner->name); 04587 } 04588 return &ast_null_frame; 04589 } 04590 if (option_debug) 04591 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04592 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04593 ast_set_read_format(p->owner, p->owner->readformat); 04594 ast_set_write_format(p->owner, p->owner->writeformat); 04595 } 04596 04597 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04598 f = ast_dsp_process(p->owner, p->vad, f); 04599 if (f && f->frametype == AST_FRAME_DTMF) { 04600 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04601 if (option_debug) 04602 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04603 *faxdetect = 1; 04604 } else if (option_debug) { 04605 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04606 } 04607 } 04608 } 04609 04610 return f; 04611 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2192 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
02193 { 02194 if (ms < 0) { 02195 if (p->timer_t1 == 0) 02196 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02197 ms = p->timer_t1 * 64; 02198 } 02199 if (sip_debug_test_pvt(p)) 02200 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02201 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02202 append_history(p, "SchedDestroy", "%d ms", ms); 02203 02204 AST_SCHED_DEL(sched, p->autokillid); 02205 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02206 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 19325 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
19326 { 19327 int ms; 19328 int regspacing; 19329 if (!regobjs) 19330 return; 19331 regspacing = default_expiry * 1000/regobjs; 19332 if (regspacing > 100) 19333 regspacing = 100; 19334 ms = regspacing; 19335 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 19336 ASTOBJ_WRLOCK(iterator); 19337 AST_SCHED_DEL(sched, iterator->expire); 19338 ms += regspacing; 19339 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 19340 ASTOBJ_UNLOCK(iterator); 19341 } while (0) 19342 ); 19343 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
int | force | |||
) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 16833 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by handle_request_subscribe().
16834 { 16835 /* Called with peerl lock, but releases it */ 16836 struct sip_pvt *p; 16837 int newmsgs, oldmsgs; 16838 16839 /* Do we have an IP address? If not, skip this peer */ 16840 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16841 return 0; 16842 16843 /* Check for messages */ 16844 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16845 16846 peer->lastmsgcheck = time(NULL); 16847 16848 /* Return now if it's the same thing we told them last time */ 16849 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16850 return 0; 16851 } 16852 16853 16854 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16855 16856 if (peer->mwipvt) { 16857 /* Base message on subscription */ 16858 p = peer->mwipvt; 16859 } else { 16860 /* Build temporary dialog for this message */ 16861 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16862 return -1; 16863 if (create_addr_from_peer(p, peer)) { 16864 /* Maybe they're not registered, etc. */ 16865 sip_destroy(p); 16866 return 0; 16867 } 16868 /* Recalculate our side, and recalculate Call ID */ 16869 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16870 p->ourip = __ourip; 16871 build_via(p); 16872 build_callid_pvt(p); 16873 /* Destroy this session after 32 secs */ 16874 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16875 } 16876 /* Send MWI */ 16877 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16878 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16879 return 0; 16880 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4018 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.
04019 { 04020 struct sip_pvt *p = ast->tech_pvt; 04021 int res = 0; 04022 04023 ast_mutex_lock(&p->lock); 04024 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04025 case SIP_DTMF_INBAND: 04026 res = -1; /* Tell Asterisk to generate inband indications */ 04027 break; 04028 case SIP_DTMF_RFC2833: 04029 if (p->rtp) 04030 ast_rtp_senddigit_begin(p->rtp, digit); 04031 break; 04032 default: 04033 break; 04034 } 04035 ast_mutex_unlock(&p->lock); 04036 04037 return res; 04038 }
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 4042 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
04043 { 04044 struct sip_pvt *p = ast->tech_pvt; 04045 int res = 0; 04046 04047 ast_mutex_lock(&p->lock); 04048 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04049 case SIP_DTMF_INFO: 04050 transmit_info_with_digit(p, digit, duration); 04051 break; 04052 case SIP_DTMF_RFC2833: 04053 if (p->rtp) 04054 ast_rtp_senddigit_end(p->rtp, digit); 04055 break; 04056 case SIP_DTMF_INBAND: 04057 res = -1; /* Tell Asterisk to stop inband indications */ 04058 break; 04059 } 04060 ast_mutex_unlock(&p->lock); 04061 04062 return res; 04063 }
static int sip_sendtext | ( | struct ast_channel * | ast, | |
const char * | text | |||
) | [static] |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
Definition at line 2497 of file chan_sip.c.
References ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02498 { 02499 struct sip_pvt *p = ast->tech_pvt; 02500 int debug = sip_debug_test_pvt(p); 02501 02502 if (debug) 02503 ast_verbose("Sending text %s on %s\n", text, ast->name); 02504 if (!p) 02505 return -1; 02506 /* NOT ast_strlen_zero, because a zero-length message is specifically 02507 * allowed by RFC 3428 (See section 10, Examples) */ 02508 if (!text) 02509 return 0; 02510 if (debug) 02511 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02512 transmit_message_with_text(p, text); 02513 return 0; 02514 }
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 19055 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), 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::callid, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
19056 { 19057 struct sip_pvt *p; 19058 int changed = 0; 19059 19060 p = chan->tech_pvt; 19061 if (!p) 19062 return -1; 19063 19064 /* Disable early RTP bridge */ 19065 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 19066 return 0; 19067 19068 ast_mutex_lock(&p->lock); 19069 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 19070 /* If we're destroyed, don't bother */ 19071 ast_mutex_unlock(&p->lock); 19072 return 0; 19073 } 19074 19075 /* if this peer cannot handle reinvites of the media stream to devices 19076 that are known to be behind a NAT, then stop the process now 19077 */ 19078 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 19079 ast_mutex_unlock(&p->lock); 19080 return 0; 19081 } 19082 19083 if (rtp) { 19084 changed |= ast_rtp_get_peer(rtp, &p->redirip); 19085 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 19086 memset(&p->redirip, 0, sizeof(p->redirip)); 19087 changed = 1; 19088 } 19089 if (vrtp) { 19090 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 19091 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 19092 memset(&p->vredirip, 0, sizeof(p->vredirip)); 19093 changed = 1; 19094 } 19095 if (codecs) { 19096 if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) { 19097 p->redircodecs = codecs; 19098 p->jointcapability &= codecs; 19099 p->capability &= codecs; 19100 changed = 1; 19101 } 19102 } 19103 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 19104 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 19105 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 19106 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 19107 if (option_debug) 19108 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)); 19109 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 19110 if (option_debug > 2) { 19111 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)); 19112 } 19113 transmit_reinvite_with_sdp(p); 19114 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19115 if (option_debug > 2) { 19116 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)); 19117 } 19118 /* We have a pending Invite. Send re-invite when we're done with the invite */ 19119 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19120 } 19121 } 19122 /* Reset lastrtprx timer */ 19123 p->lastrtprx = p->lastrtptx = time(NULL); 19124 ast_mutex_unlock(&p->lock); 19125 return 0; 19126 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18882 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::callid, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
18883 { 18884 struct sip_pvt *p; 18885 18886 p = chan->tech_pvt; 18887 if (!p) 18888 return -1; 18889 ast_mutex_lock(&p->lock); 18890 if (udptl) 18891 ast_udptl_get_peer(udptl, &p->udptlredirip); 18892 else 18893 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18894 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18895 if (!p->pendinginvite) { 18896 if (option_debug > 2) { 18897 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); 18898 } 18899 transmit_reinvite_with_t38_sdp(p); 18900 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18901 if (option_debug > 2) { 18902 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); 18903 } 18904 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18905 } 18906 } 18907 /* Reset lastrtprx timer */ 18908 p->lastrtprx = p->lastrtptx = time(NULL); 18909 ast_mutex_unlock(&p->lock); 18910 return 0; 18911 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11787 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, iflock, sip_pvt::jointcapability, sip_pvt::lastmsg, len(), sip_pvt::maxcallbitrate, ast_channel::name, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, transfermode2str(), sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.
11788 { 11789 struct sip_pvt *cur; 11790 size_t len; 11791 int found = 0; 11792 11793 if (argc != 4) 11794 return RESULT_SHOWUSAGE; 11795 len = strlen(argv[3]); 11796 ast_mutex_lock(&iflock); 11797 for (cur = iflist; cur; cur = cur->next) { 11798 if (!strncasecmp(cur->callid, argv[3], len)) { 11799 char formatbuf[SIPBUFSIZE/2]; 11800 ast_cli(fd,"\n"); 11801 if (cur->subscribed != NONE) 11802 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11803 else 11804 ast_cli(fd, " * SIP Call\n"); 11805 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11806 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11807 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11808 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11809 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11810 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11811 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11812 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11813 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11814 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11815 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11816 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11817 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11818 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)" ); 11819 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11820 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11821 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11822 if (!ast_strlen_zero(cur->username)) 11823 ast_cli(fd, " Username: %s\n", cur->username); 11824 if (!ast_strlen_zero(cur->peername)) 11825 ast_cli(fd, " Peername: %s\n", cur->peername); 11826 if (!ast_strlen_zero(cur->uri)) 11827 ast_cli(fd, " Original uri: %s\n", cur->uri); 11828 if (!ast_strlen_zero(cur->cid_num)) 11829 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11830 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11831 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11832 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11833 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11834 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11835 ast_cli(fd, " SIP Options: "); 11836 if (cur->sipoptions) { 11837 int x; 11838 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11839 if (cur->sipoptions & sip_options[x].id) 11840 ast_cli(fd, "%s ", sip_options[x].text); 11841 } 11842 } else 11843 ast_cli(fd, "(none)\n"); 11844 ast_cli(fd, "\n\n"); 11845 found++; 11846 } 11847 } 11848 ast_mutex_unlock(&iflock); 11849 if (!found) 11850 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11851 return RESULT_SUCCESS; 11852 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11573 of file chan_sip.c.
References __sip_show_channels().
11574 { 11575 return __sip_show_channels(fd, argc, argv, 0); 11576 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 11084 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::list, domain::mode, RESULT_SUCCESS, and S_OR.
11085 { 11086 struct domain *d; 11087 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 11088 11089 if (AST_LIST_EMPTY(&domain_list)) { 11090 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 11091 return RESULT_SUCCESS; 11092 } else { 11093 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 11094 AST_LIST_LOCK(&domain_list); 11095 AST_LIST_TRAVERSE(&domain_list, d, list) 11096 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 11097 domain_mode_to_text(d->mode)); 11098 AST_LIST_UNLOCK(&domain_list); 11099 ast_cli(fd, "\n"); 11100 return RESULT_SUCCESS; 11101 } 11102 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11855 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, sip_pvt::callid, sip_pvt::history, iflist, iflock, len(), sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
11856 { 11857 struct sip_pvt *cur; 11858 size_t len; 11859 int found = 0; 11860 11861 if (argc != 4) 11862 return RESULT_SHOWUSAGE; 11863 if (!recordhistory) 11864 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11865 len = strlen(argv[3]); 11866 ast_mutex_lock(&iflock); 11867 for (cur = iflist; cur; cur = cur->next) { 11868 if (!strncasecmp(cur->callid, argv[3], len)) { 11869 struct sip_history *hist; 11870 int x = 0; 11871 11872 ast_cli(fd,"\n"); 11873 if (cur->subscribed != NONE) 11874 ast_cli(fd, " * Subscription\n"); 11875 else 11876 ast_cli(fd, " * SIP Call\n"); 11877 if (cur->history) 11878 AST_LIST_TRAVERSE(cur->history, hist, list) 11879 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11880 if (x == 0) 11881 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11882 found++; 11883 } 11884 } 11885 ast_mutex_unlock(&iflock); 11886 if (!found) 11887 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11888 return RESULT_SUCCESS; 11889 }
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 10509 of file chan_sip.c.
References ast_cli(), ast_copy_string(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
10510 { 10511 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 10512 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 10513 char ilimits[40]; 10514 char iused[40]; 10515 int showall = FALSE; 10516 10517 if (argc < 3) 10518 return RESULT_SHOWUSAGE; 10519 10520 if (argc == 4 && !strcmp(argv[3],"all")) 10521 showall = TRUE; 10522 10523 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 10524 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10525 ASTOBJ_RDLOCK(iterator); 10526 if (iterator->call_limit) 10527 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10528 else 10529 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10530 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 10531 if (showall || iterator->call_limit) 10532 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10533 ASTOBJ_UNLOCK(iterator); 10534 } while (0) ); 10535 10536 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 10537 10538 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10539 ASTOBJ_RDLOCK(iterator); 10540 if (iterator->call_limit) 10541 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10542 else 10543 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10544 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 10545 if (showall || iterator->call_limit) 10546 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10547 ASTOBJ_UNLOCK(iterator); 10548 } while (0) ); 10549 10550 return RESULT_SUCCESS; 10551 #undef FORMAT 10552 #undef FORMAT2 10553 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10830 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10831 { 10832 char tmp[256]; 10833 if (argc != 3) 10834 return RESULT_SHOWUSAGE; 10835 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10836 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10837 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10838 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10839 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10840 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10841 return RESULT_SUCCESS; 10842 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 11136 of file chan_sip.c.
References _sip_show_peer().
11137 { 11138 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 11139 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10686 of file chan_sip.c.
References _sip_show_peers().
10687 { 10688 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10689 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 11409 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.
11410 { 11411 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 11412 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 11413 char host[80]; 11414 char tmpdat[256]; 11415 struct tm tm; 11416 11417 11418 if (argc != 3) 11419 return RESULT_SHOWUSAGE; 11420 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 11421 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 11422 ASTOBJ_RDLOCK(iterator); 11423 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 11424 if (iterator->regtime) { 11425 ast_localtime(&iterator->regtime, &tm, NULL); 11426 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 11427 } else { 11428 tmpdat[0] = 0; 11429 } 11430 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 11431 ASTOBJ_UNLOCK(iterator); 11432 } while(0)); 11433 return RESULT_SUCCESS; 11434 #undef FORMAT 11435 #undef FORMAT2 11436 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 11439 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().
11440 { 11441 int realtimepeers; 11442 int realtimeusers; 11443 char codec_buf[SIPBUFSIZE]; 11444 11445 realtimepeers = ast_check_realtime("sippeers"); 11446 realtimeusers = ast_check_realtime("sipusers"); 11447 11448 if (argc != 3) 11449 return RESULT_SHOWUSAGE; 11450 ast_cli(fd, "\n\nGlobal Settings:\n"); 11451 ast_cli(fd, "----------------\n"); 11452 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 11453 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 11454 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 11455 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 11456 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 11457 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11458 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11459 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11460 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 11461 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 11462 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 11463 ast_cli(fd, " Our auth realm %s\n", global_realm); 11464 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 11465 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 11466 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 11467 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 11468 ast_cli(fd, " User Agent: %s\n", global_useragent); 11469 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 11470 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 11471 ast_cli(fd, " Caller ID: %s\n", default_callerid); 11472 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 11473 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 11474 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 11475 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 11476 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 11477 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 11478 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 11479 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11480 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 11481 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 11482 #endif 11483 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 11484 if (!realtimepeers && !realtimeusers) 11485 ast_cli(fd, " SIP realtime: Disabled\n" ); 11486 else 11487 ast_cli(fd, " SIP realtime: Enabled\n" ); 11488 11489 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 11490 ast_cli(fd, "---------------------------\n"); 11491 ast_cli(fd, " Codecs: "); 11492 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 11493 ast_cli(fd, "%s\n", codec_buf); 11494 ast_cli(fd, " Codec Order: "); 11495 print_codec_to_cli(fd, &default_prefs); 11496 ast_cli(fd, "\n"); 11497 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 11498 ast_cli(fd, " No premature media: %s\n", global_prematuremediafilter ? "Yes" : "No"); 11499 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 11500 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 11501 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 11502 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 11503 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 11504 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 11505 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 11506 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 11507 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 11508 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 11509 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 11510 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 11511 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 11512 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 11513 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 11514 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 11515 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 11516 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 11517 ast_cli(fd, "\nDefault Settings:\n"); 11518 ast_cli(fd, "-----------------\n"); 11519 ast_cli(fd, " Context: %s\n", default_context); 11520 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 11521 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 11522 ast_cli(fd, " Qualify: %d\n", default_qualify); 11523 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 11524 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" ); 11525 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 11526 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 11527 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 11528 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 11529 11530 11531 if (realtimepeers || realtimeusers) { 11532 ast_cli(fd, "\nRealtime SIP Settings:\n"); 11533 ast_cli(fd, "----------------------\n"); 11534 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 11535 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 11536 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 11537 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 11538 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 11539 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 11540 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 11541 } 11542 ast_cli(fd, "\n----\n"); 11543 return RESULT_SUCCESS; 11544 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11579 of file chan_sip.c.
References __sip_show_channels().
11580 { 11581 return __sip_show_channels(fd, argc, argv, 1); 11582 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11354 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, sip_user::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.
11355 { 11356 char cbuf[256]; 11357 struct sip_user *user; 11358 struct ast_variable *v; 11359 int load_realtime; 11360 11361 if (argc < 4) 11362 return RESULT_SHOWUSAGE; 11363 11364 /* Load from realtime storage? */ 11365 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11366 11367 user = find_user(argv[3], load_realtime); 11368 if (user) { 11369 ast_cli(fd,"\n\n"); 11370 ast_cli(fd, " * Name : %s\n", user->name); 11371 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11372 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11373 ast_cli(fd, " Context : %s\n", user->context); 11374 ast_cli(fd, " Language : %s\n", user->language); 11375 if (!ast_strlen_zero(user->accountcode)) 11376 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11377 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11378 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11379 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11380 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11381 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11382 ast_cli(fd, " Callgroup : "); 11383 print_group(fd, user->callgroup, 0); 11384 ast_cli(fd, " Pickupgroup : "); 11385 print_group(fd, user->pickupgroup, 0); 11386 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 11387 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 11388 ast_cli(fd, " Codec Order : ("); 11389 print_codec_to_cli(fd, &user->prefs); 11390 ast_cli(fd, ")\n"); 11391 11392 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 11393 if (user->chanvars) { 11394 ast_cli(fd, " Variables :\n"); 11395 for (v = user->chanvars ; v ; v = v->next) 11396 ast_cli(fd, " %s = %s\n", v->name, v->value); 11397 } 11398 ast_cli(fd,"\n"); 11399 ASTOBJ_UNREF(user,sip_destroy_user); 11400 } else { 11401 ast_cli(fd,"User %s not found.\n", argv[3]); 11402 ast_cli(fd,"\n"); 11403 } 11404 11405 return RESULT_SUCCESS; 11406 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10609 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, TRUE, and userl.
10610 { 10611 regex_t regexbuf; 10612 int havepattern = FALSE; 10613 10614 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10615 10616 switch (argc) { 10617 case 5: 10618 if (!strcasecmp(argv[3], "like")) { 10619 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10620 return RESULT_SHOWUSAGE; 10621 havepattern = TRUE; 10622 } else 10623 return RESULT_SHOWUSAGE; 10624 case 3: 10625 break; 10626 default: 10627 return RESULT_SHOWUSAGE; 10628 } 10629 10630 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10631 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10632 ASTOBJ_RDLOCK(iterator); 10633 10634 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10635 ASTOBJ_UNLOCK(iterator); 10636 continue; 10637 } 10638 10639 ast_cli(fd, FORMAT, iterator->name, 10640 iterator->secret, 10641 iterator->accountcode, 10642 iterator->context, 10643 iterator->ha ? "Yes" : "No", 10644 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10645 ASTOBJ_UNLOCK(iterator); 10646 } while (0) 10647 ); 10648 10649 if (havepattern) 10650 regfree(®exbuf); 10651 10652 return RESULT_SUCCESS; 10653 #undef FORMAT 10654 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 19239 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, and transmit_response_reliable().
Referenced by sip_transfer().
19240 { 19241 char *cdest; 19242 char *extension, *host, *port; 19243 char tmp[80]; 19244 19245 cdest = ast_strdupa(dest); 19246 19247 extension = strsep(&cdest, "@"); 19248 host = strsep(&cdest, ":"); 19249 port = strsep(&cdest, ":"); 19250 if (ast_strlen_zero(extension)) { 19251 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 19252 return 0; 19253 } 19254 19255 /* we'll issue the redirect message here */ 19256 if (!host) { 19257 char *localtmp; 19258 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 19259 if (ast_strlen_zero(tmp)) { 19260 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 19261 return 0; 19262 } 19263 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 19264 char lhost[80], lport[80]; 19265 memset(lhost, 0, sizeof(lhost)); 19266 memset(lport, 0, sizeof(lport)); 19267 localtmp++; 19268 /* This is okey because lhost and lport are as big as tmp */ 19269 sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport); 19270 if (ast_strlen_zero(lhost)) { 19271 ast_log(LOG_ERROR, "Can't find the host address\n"); 19272 return 0; 19273 } 19274 host = ast_strdupa(lhost); 19275 if (!ast_strlen_zero(lport)) { 19276 port = ast_strdupa(lport); 19277 } 19278 } 19279 } 19280 19281 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 19282 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 19283 19284 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 19285 sip_alreadygone(p); 19286 return 0; 19287 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 4066 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().
04067 { 04068 struct sip_pvt *p = ast->tech_pvt; 04069 int res; 04070 04071 if (dest == NULL) /* functions below do not take a NULL */ 04072 dest = ""; 04073 ast_mutex_lock(&p->lock); 04074 if (ast->_state == AST_STATE_RING) 04075 res = sip_sipredirect(p, dest); 04076 else 04077 res = transmit_refer(p, dest); 04078 ast_mutex_unlock(&p->lock); 04079 return res; 04080 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14705 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14706 { 14707 char *uri1 = ast_strdupa(input1); 14708 char *uri2 = ast_strdupa(input2); 14709 char *host1; 14710 char *host2; 14711 char *params1; 14712 char *params2; 14713 char *headers1; 14714 char *headers2; 14715 14716 /* Strip off "sip:" from the URI. We know this is present 14717 * because it was checked back in parse_request() 14718 */ 14719 strsep(&uri1, ":"); 14720 strsep(&uri2, ":"); 14721 14722 if ((host1 = strchr(uri1, '@'))) { 14723 *host1++ = '\0'; 14724 } 14725 if ((host2 = strchr(uri2, '@'))) { 14726 *host2++ = '\0'; 14727 } 14728 14729 /* Check for mismatched username and passwords. This is the 14730 * only case-sensitive comparison of a SIP URI 14731 */ 14732 if ((host1 && !host2) || 14733 (host2 && !host1) || 14734 (host1 && host2 && strcmp(uri1, uri2))) { 14735 return 1; 14736 } 14737 14738 if (!host1) 14739 host1 = uri1; 14740 if (!host2) 14741 host2 = uri2; 14742 14743 /* Strip off the parameters and headers so we can compare 14744 * host and port 14745 */ 14746 14747 if ((params1 = strchr(host1, ';'))) { 14748 *params1++ = '\0'; 14749 } 14750 if ((params2 = strchr(host2, ';'))) { 14751 *params2++ = '\0'; 14752 } 14753 14754 /* Headers come after parameters, but there may be headers without 14755 * parameters, thus the S_OR 14756 */ 14757 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14758 *headers1++ = '\0'; 14759 } 14760 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14761 *headers2++ = '\0'; 14762 } 14763 14764 /* Now the host/port are properly isolated. We can get by with a string comparison 14765 * because the SIP URI checking rules have some interesting exceptions that make 14766 * this possible. I will note 2 in particular 14767 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14768 * IP address are not considered a match with SIP URI's. 14769 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14770 * This includes if one URI explicitly contains port 5060 and the other implies it 14771 * by not having a port specified. 14772 */ 14773 14774 if (strcasecmp(host1, host2)) { 14775 return 1; 14776 } 14777 14778 /* Headers have easier rules to follow, so do those first */ 14779 if (sip_uri_headers_cmp(headers1, headers2)) { 14780 return 1; 14781 } 14782 14783 /* And now the parameters. Ugh */ 14784 return sip_uri_params_cmp(params1, params2); 14785 }
static int sip_uri_headers_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.
input1 | Headers from URI 1 | |
input2 | Headers from URI 2 |
Definition at line 14659 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14660 { 14661 char *headers1 = NULL; 14662 char *headers2 = NULL; 14663 int zerolength1 = 0; 14664 int zerolength2 = 0; 14665 int different = 0; 14666 char *header1; 14667 14668 if (ast_strlen_zero(input1)) { 14669 zerolength1 = 1; 14670 } else { 14671 headers1 = ast_strdupa(input1); 14672 } 14673 14674 if (ast_strlen_zero(input2)) { 14675 zerolength2 = 1; 14676 } else { 14677 headers2 = ast_strdupa(input2); 14678 } 14679 14680 if ((zerolength1 && !zerolength2) || 14681 (zerolength2 && !zerolength1)) 14682 return 1; 14683 14684 if (zerolength1 && zerolength2) 14685 return 0; 14686 14687 /* At this point, we can definitively state that both inputs are 14688 * not zero-length. First, one more optimization. If the length 14689 * of the headers is not equal, then we definitely have no match 14690 */ 14691 if (strlen(headers1) != strlen(headers2)) { 14692 return 1; 14693 } 14694 14695 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14696 if (!strcasestr(headers2, header1)) { 14697 different = 1; 14698 break; 14699 } 14700 } 14701 14702 return different; 14703 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 14519 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14520 { 14521 char *params1 = NULL; 14522 char *params2 = NULL; 14523 char *pos1; 14524 char *pos2; 14525 int zerolength1 = 0; 14526 int zerolength2 = 0; 14527 int maddrmatch = 0; 14528 int ttlmatch = 0; 14529 int usermatch = 0; 14530 int methodmatch = 0; 14531 14532 if (ast_strlen_zero(input1)) { 14533 zerolength1 = 1; 14534 } else { 14535 params1 = ast_strdupa(input1); 14536 } 14537 if (ast_strlen_zero(input2)) { 14538 zerolength2 = 1; 14539 } else { 14540 params2 = ast_strdupa(input2); 14541 } 14542 14543 /*Quick optimization. If both params are zero-length, then 14544 * they match 14545 */ 14546 if (zerolength1 && zerolength2) { 14547 return 0; 14548 } 14549 14550 pos1 = params1; 14551 while (!ast_strlen_zero(pos1)) { 14552 char *name1 = pos1; 14553 char *value1 = strchr(pos1, '='); 14554 char *semicolon1 = strchr(pos1, ';'); 14555 int matched = 0; 14556 if (semicolon1) { 14557 *semicolon1++ = '\0'; 14558 } 14559 if (!value1) { 14560 goto fail; 14561 } 14562 *value1++ = '\0'; 14563 /* Checkpoint reached. We have the name and value parsed for param1 14564 * We have to duplicate params2 each time through the second loop 14565 * or else we can't search and replace the semicolons with \0 each 14566 * time 14567 */ 14568 pos2 = ast_strdupa(params2); 14569 while (!ast_strlen_zero(pos2)) { 14570 char *name2 = pos2; 14571 char *value2 = strchr(pos2, '='); 14572 char *semicolon2 = strchr(pos2, ';'); 14573 if (semicolon2) { 14574 *semicolon2++ = '\0'; 14575 } 14576 if (!value2) { 14577 goto fail; 14578 } 14579 *value2++ = '\0'; 14580 if (!strcasecmp(name1, name2)) { 14581 if (strcasecmp(value1, value2)) { 14582 goto fail; 14583 } else { 14584 matched = 1; 14585 break; 14586 } 14587 } 14588 pos2 = semicolon2; 14589 } 14590 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14591 if (!strcasecmp(name1, "maddr")) { 14592 if (matched) { 14593 maddrmatch = 1; 14594 } else { 14595 goto fail; 14596 } 14597 } else if (!strcasecmp(name1, "ttl")) { 14598 if (matched) { 14599 ttlmatch = 1; 14600 } else { 14601 goto fail; 14602 } 14603 } else if (!strcasecmp(name1, "user")) { 14604 if (matched) { 14605 usermatch = 1; 14606 } else { 14607 goto fail; 14608 } 14609 } else if (!strcasecmp(name1, "method")) { 14610 if (matched) { 14611 methodmatch = 1; 14612 } else { 14613 goto fail; 14614 } 14615 } 14616 pos1 = semicolon1; 14617 } 14618 14619 /* We've made it out of that horrible O(m*n) construct and there are no 14620 * failures yet. We're not done yet, though, because params2 could have 14621 * an maddr, ttl, user, or method header and params1 did not. 14622 */ 14623 pos2 = params2; 14624 while (!ast_strlen_zero(pos2)) { 14625 char *name2 = pos2; 14626 char *value2 = strchr(pos2, '='); 14627 char *semicolon2 = strchr(pos2, ';'); 14628 if (semicolon2) { 14629 *semicolon2++ = '\0'; 14630 } 14631 if (!value2) { 14632 goto fail; 14633 } 14634 *value2++ = '\0'; 14635 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14636 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14637 (!strcasecmp(name2, "user") && !usermatch) || 14638 (!strcasecmp(name2, "method") && !methodmatch)) { 14639 goto fail; 14640 } 14641 } 14642 return 0; 14643 14644 fail: 14645 return 1; 14646 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3878 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), t38properties::direct, sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, sip_pvt::pendinginvite, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PROGRESS_SENT, t38properties::state, ast_frame::subclass, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, ast_channel::tech_pvt, transmit_provisional_response(), transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.
03879 { 03880 struct sip_pvt *p = ast->tech_pvt; 03881 int res = 0; 03882 03883 switch (frame->frametype) { 03884 case AST_FRAME_VOICE: 03885 if (!(frame->subclass & ast->nativeformats)) { 03886 char s1[512], s2[512], s3[512]; 03887 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03888 frame->subclass, 03889 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03890 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03891 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03892 ast->readformat, 03893 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03894 ast->writeformat); 03895 return 0; 03896 } 03897 if (p) { 03898 ast_mutex_lock(&p->lock); 03899 if (p->rtp) { 03900 /* If channel is not up, activate early media session */ 03901 if ((ast->_state != AST_STATE_UP) && 03902 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03903 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03904 ast_rtp_new_source(p->rtp); 03905 if (!global_prematuremediafilter) { 03906 p->invitestate = INV_EARLY_MEDIA; 03907 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 03908 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03909 } 03910 } else if (p->t38.state == T38_ENABLED && !p->t38.direct) { 03911 /* drop frame, can't sent VOICE frames while in T.38 mode */ 03912 } else { 03913 p->lastrtptx = time(NULL); 03914 res = ast_rtp_write(p->rtp, frame); 03915 } 03916 } 03917 ast_mutex_unlock(&p->lock); 03918 } 03919 break; 03920 case AST_FRAME_VIDEO: 03921 if (p) { 03922 ast_mutex_lock(&p->lock); 03923 if (p->vrtp) { 03924 /* Activate video early media */ 03925 if ((ast->_state != AST_STATE_UP) && 03926 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03927 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03928 p->invitestate = INV_EARLY_MEDIA; 03929 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 03930 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03931 } 03932 p->lastrtptx = time(NULL); 03933 res = ast_rtp_write(p->vrtp, frame); 03934 } 03935 ast_mutex_unlock(&p->lock); 03936 } 03937 break; 03938 case AST_FRAME_IMAGE: 03939 return 0; 03940 break; 03941 case AST_FRAME_MODEM: 03942 if (p) { 03943 ast_mutex_lock(&p->lock); 03944 /* UDPTL requires two-way communication, so early media is not needed here. 03945 we simply forget the frames if we get modem frames before the bridge is up. 03946 Fax will re-transmit. 03947 */ 03948 if (ast->_state == AST_STATE_UP) { 03949 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 03950 if (!p->pendinginvite) { 03951 p->t38.state = T38_LOCAL_REINVITE; 03952 transmit_reinvite_with_t38_sdp(p); 03953 } 03954 } else if (p->t38.state == T38_ENABLED) { 03955 res = ast_udptl_write(p->udptl, frame); 03956 } 03957 } 03958 ast_mutex_unlock(&p->lock); 03959 } 03960 break; 03961 default: 03962 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03963 return 0; 03964 } 03965 03966 return res; 03967 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16713 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len(), sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), netlock, option_debug, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, S_OR, sched, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
16714 { 16715 struct sip_request req; 16716 struct sockaddr_in sin = { 0, }; 16717 struct sip_pvt *p; 16718 int res; 16719 socklen_t len = sizeof(sin); 16720 int nounlock = 0; 16721 int recount = 0; 16722 int lockretry; 16723 16724 memset(&req, 0, sizeof(req)); 16725 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16726 if (res < 0) { 16727 #if !defined(__FreeBSD__) 16728 if (errno == EAGAIN) 16729 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16730 else 16731 #endif 16732 if (errno != ECONNREFUSED) 16733 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16734 return 1; 16735 } 16736 if (option_debug && res == sizeof(req.data) - 1) 16737 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16738 16739 req.data[res] = '\0'; 16740 req.len = res; 16741 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16742 ast_set_flag(&req, SIP_PKT_DEBUG); 16743 if (pedanticsipchecking) 16744 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16745 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16746 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 16747 16748 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16749 return 1; 16750 16751 req.method = find_sip_method(req.rlPart1); 16752 16753 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16754 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16755 16756 if (req.headers < 2) /* Must have at least two headers */ 16757 return 1; 16758 16759 /* Process request, with netlock held, and with usual deadlock avoidance */ 16760 for (lockretry = 10; lockretry > 0; lockretry--) { 16761 ast_mutex_lock(&netlock); 16762 16763 /* Find the active SIP dialog or create a new one */ 16764 p = find_call(&req, &sin, req.method); /* returns p locked */ 16765 if (p == NULL) { 16766 if (option_debug) 16767 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16768 ast_mutex_unlock(&netlock); 16769 return 1; 16770 } 16771 /* Go ahead and lock the owner if it has one -- we may need it */ 16772 /* because this is deadlock-prone, we need to try and unlock if failed */ 16773 if (!p->owner || !ast_channel_trylock(p->owner)) 16774 break; /* locking succeeded */ 16775 if (lockretry != 1) { 16776 ast_mutex_unlock(&p->lock); 16777 ast_mutex_unlock(&netlock); 16778 /* Sleep for a very short amount of time */ 16779 usleep(1); 16780 } 16781 } 16782 p->recv = sin; 16783 16784 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16785 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16786 16787 if (!lockretry) { 16788 if (!queue_request(p, &req)) { 16789 /* the request has been queued for later handling */ 16790 ast_mutex_unlock(&p->lock); 16791 ast_mutex_unlock(&netlock); 16792 return 1; 16793 } 16794 16795 /* This is unsafe, since p->owner is not locked. */ 16796 if (p->owner) 16797 ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - ")); 16798 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16799 if (req.method != SIP_ACK) 16800 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16801 /* XXX We could add retry-after to make sure they come back */ 16802 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16803 ast_mutex_unlock(&p->lock); 16804 ast_mutex_unlock(&netlock); 16805 return 1; 16806 } 16807 16808 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16809 handled in order 16810 */ 16811 if (!AST_LIST_EMPTY(&p->request_queue)) { 16812 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16813 process_request_queue(p, &recount, &nounlock); 16814 } 16815 16816 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16817 /* Request failed */ 16818 if (option_debug) 16819 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16820 } 16821 16822 if (p->owner && !nounlock) 16823 ast_channel_unlock(p->owner); 16824 ast_mutex_unlock(&p->lock); 16825 ast_mutex_unlock(&netlock); 16826 if (recount) 16827 ast_update_use_count(); 16828 16829 return 1; 16830 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 13452 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().
13453 { 13454 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13455 if (p->rtp) 13456 ast_rtp_stop(p->rtp); 13457 if (p->vrtp) 13458 ast_rtp_stop(p->vrtp); 13459 if (p->udptl) 13460 ast_udptl_stop(p->udptl); 13461 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 11547 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
11548 { 11549 int i; 11550 11551 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11552 if (subscription_types[i].type == subtype) { 11553 return subscription_types[i].text; 11554 } 11555 } 11556 return subscription_types[0].text; 11557 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6834 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_sdp().
06835 { 06836 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06837 06838 if (maxrate & T38FAX_RATE_14400) { 06839 if (option_debug > 1) 06840 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06841 return 14400; 06842 } else if (maxrate & T38FAX_RATE_12000) { 06843 if (option_debug > 1) 06844 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06845 return 12000; 06846 } else if (maxrate & T38FAX_RATE_9600) { 06847 if (option_debug > 1) 06848 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06849 return 9600; 06850 } else if (maxrate & T38FAX_RATE_7200) { 06851 if (option_debug > 1) 06852 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06853 return 7200; 06854 } else if (maxrate & T38FAX_RATE_4800) { 06855 if (option_debug > 1) 06856 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06857 return 4800; 06858 } else if (maxrate & T38FAX_RATE_2400) { 06859 if (option_debug > 1) 06860 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06861 return 2400; 06862 } else { 06863 if (option_debug > 1) 06864 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06865 return 0; 06866 } 06867 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17890 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
17891 { 17892 struct sip_peer *peer; 17893 17894 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17895 return NULL; 17896 17897 apeerobjs++; 17898 ASTOBJ_INIT(peer); 17899 set_peer_defaults(peer); 17900 17901 ast_copy_string(peer->name, name, sizeof(peer->name)); 17902 17903 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17904 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17905 peer->prefs = default_prefs; 17906 reg_source_db(peer); 17907 17908 return peer; 17909 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6596 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06597 { 06598 struct sip_pvt *p = data; 06599 06600 ast_string_field_free_memory(p); 06601 06602 free(data); 06603 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10556 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().
10557 { 10558 if (mode == TRANSFER_OPENFORALL) 10559 return "open"; 10560 else if (mode == TRANSFER_CLOSED) 10561 return "closed"; 10562 return "strict"; 10563 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
struct sip_request * | req, | |||
enum xmittype | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 9247 of file chan_sip.c.
References ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, keys, sip_pvt::randdata, s, set_nonce_randdata(), SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, ast_dynamic_str::str, transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
09248 { 09249 /* We have to emulate EXACTLY what we'd get with a good peer 09250 * and a bad password, or else we leak information. */ 09251 const char *response = "407 Proxy Authentication Required"; 09252 const char *reqheader = "Proxy-Authorization"; 09253 const char *respheader = "Proxy-Authenticate"; 09254 const char *authtoken; 09255 struct ast_dynamic_str *buf; 09256 char *c; 09257 09258 /* table of recognised keywords, and their value in the digest */ 09259 enum keys { K_NONCE, K_LAST }; 09260 struct x { 09261 const char *key; 09262 const char *s; 09263 } *i, keys[] = { 09264 [K_NONCE] = { "nonce=", "" }, 09265 [K_LAST] = { NULL, NULL} 09266 }; 09267 09268 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09269 response = "401 Unauthorized"; 09270 reqheader = "Authorization"; 09271 respheader = "WWW-Authenticate"; 09272 } 09273 authtoken = get_header(req, reqheader); 09274 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09275 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09276 * information */ 09277 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09278 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09279 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09280 return; 09281 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09282 /* We have no auth, so issue challenge and request authentication */ 09283 set_nonce_randdata(p, 1); 09284 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09285 /* Schedule auto destroy in 32 seconds */ 09286 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09287 return; 09288 } 09289 09290 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 09291 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09292 return; 09293 } 09294 09295 /* Make a copy of the response and parse it */ 09296 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 09297 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09298 return; 09299 } 09300 09301 c = buf->str; 09302 09303 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09304 for (i = keys; i->key != NULL; i++) { 09305 const char *separator = ","; /* default */ 09306 09307 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 09308 continue; 09309 } 09310 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09311 c += strlen(i->key); 09312 if (*c == '"') { /* in quotes. Skip first and look for last */ 09313 c++; 09314 separator = "\""; 09315 } 09316 i->s = c; 09317 strsep(&c, separator); 09318 break; 09319 } 09320 if (i->key == NULL) { /* not found, jump after space or comma */ 09321 strsep(&c, " ,"); 09322 } 09323 } 09324 09325 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 09326 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 09327 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09328 set_nonce_randdata(p, 1); 09329 } 09330 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09331 09332 /* Schedule auto destroy in 32 seconds */ 09333 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09334 } else { 09335 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09336 } 09337 }
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 8391 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08392 { 08393 struct sip_request req; 08394 08395 reqprep(&req, p, SIP_INFO, 0, 1); 08396 add_digit(&req, digit, duration); 08397 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08398 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8401 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08402 { 08403 struct sip_request req; 08404 08405 reqprep(&req, p, SIP_INFO, 0, 1); 08406 add_vidupdate(&req); 08407 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08408 }
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 7624 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), 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(), ast_var_t::entries, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, ast_channel::name, sip_pvt::ocseq, sip_pvt::offered_media, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07625 { 07626 struct sip_request req; 07627 07628 req.method = sipmethod; 07629 if (init) { /* Seems like init always is 2 */ 07630 /* Bump branch even on initial requests */ 07631 p->branch ^= ast_random(); 07632 p->invite_branch = p->branch; 07633 build_via(p); 07634 if (init > 1) 07635 initreqprep(&req, p, sipmethod); 07636 else 07637 reqprep(&req, p, sipmethod, 0, 0); 07638 } else 07639 reqprep(&req, p, sipmethod, 0, 1); 07640 07641 if (p->options && p->options->auth) 07642 add_header(&req, p->options->authheader, p->options->auth); 07643 append_date(&req); 07644 if (sipmethod == SIP_REFER) { /* Call transfer */ 07645 if (p->refer) { 07646 char buf[SIPBUFSIZE]; 07647 if (!ast_strlen_zero(p->refer->refer_to)) 07648 add_header(&req, "Refer-To", p->refer->refer_to); 07649 if (!ast_strlen_zero(p->refer->referred_by)) { 07650 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07651 add_header(&req, "Referred-By", buf); 07652 } 07653 } 07654 } 07655 /* This new INVITE is part of an attended transfer. Make sure that the 07656 other end knows and replace the current call with this new call */ 07657 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07658 add_header(&req, "Replaces", p->options->replaces); 07659 add_header(&req, "Require", "replaces"); 07660 } 07661 07662 add_header(&req, "Allow", ALLOWED_METHODS); 07663 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07664 if (p->options && p->options->addsipheaders && p->owner) { 07665 struct ast_channel *chan = p->owner; /* The owner channel */ 07666 struct varshead *headp; 07667 07668 ast_channel_lock(chan); 07669 07670 headp = &chan->varshead; 07671 07672 if (!headp) 07673 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07674 else { 07675 const struct ast_var_t *current; 07676 AST_LIST_TRAVERSE(headp, current, entries) { 07677 /* SIPADDHEADER: Add SIP header to outgoing call */ 07678 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07679 char *content, *end; 07680 const char *header = ast_var_value(current); 07681 char *headdup = ast_strdupa(header); 07682 07683 /* Strip of the starting " (if it's there) */ 07684 if (*headdup == '"') 07685 headdup++; 07686 if ((content = strchr(headdup, ':'))) { 07687 *content++ = '\0'; 07688 content = ast_skip_blanks(content); /* Skip white space */ 07689 /* Strip the ending " (if it's there) */ 07690 end = content + strlen(content) -1; 07691 if (*end == '"') 07692 *end = '\0'; 07693 07694 add_header(&req, headdup, content); 07695 if (sipdebug) 07696 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07697 } 07698 } 07699 } 07700 } 07701 07702 ast_channel_unlock(chan); 07703 } 07704 if (sdp) { 07705 memset(p->offered_media, 0, sizeof(p->offered_media)); 07706 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 07707 ast_udptl_offered_from_local(p->udptl, 1); 07708 if (option_debug) 07709 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07710 add_sdp(&req, p, 0, 1); 07711 } else if (p->rtp) 07712 add_sdp(&req, p, 1, 0); 07713 } else { 07714 add_header_contentLength(&req, 0); 07715 } 07716 07717 if (!p->initreq.headers || init > 2) 07718 initialize_initreq(p, &req); 07719 p->lastinvite = p->ocseq; 07720 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07721 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 8300 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().
08301 { 08302 struct sip_request req; 08303 08304 reqprep(&req, p, SIP_MESSAGE, 0, 1); 08305 add_text(&req, text); 08306 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08307 }
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 7912 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_pvt::fromdomain, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, ourport, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, STANDARD_SIP_PORT, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07913 { 07914 struct sip_request req; 07915 char tmp[500]; 07916 char *t = tmp; 07917 size_t maxbytes = sizeof(tmp); 07918 07919 initreqprep(&req, p, SIP_NOTIFY); 07920 add_header(&req, "Event", "message-summary"); 07921 add_header(&req, "Content-Type", default_notifymime); 07922 07923 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07924 /* if we listen to non-standard SIP port we have to specify the SIP port 07925 in the URI, except domains are used - in this case the SRV records should be 07926 used to redirect the client to the non-standard SIP port */ 07927 if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) { 07928 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n", 07929 S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport); 07930 } else { 07931 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07932 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07933 } 07934 /* Cisco has a bug in the SIP stack where it can't accept the 07935 (0/0) notification. This can temporarily be disabled in 07936 sip.conf with the "buggymwi" option */ 07937 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)")); 07938 07939 if (p->subscribed) { 07940 if (p->expiry) 07941 add_header(&req, "Subscription-State", "active"); 07942 else /* Expired */ 07943 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07944 } 07945 07946 if (t > tmp + sizeof(tmp)) 07947 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07948 07949 add_header_contentLength(&req, strlen(tmp)); 07950 add_line(&req, tmp); 07951 07952 if (!p->initreq.headers) 07953 initialize_initreq(p, &req); 07954 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07955 }
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 7966 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::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07967 { 07968 struct sip_request req; 07969 char tmp[SIPBUFSIZE/2]; 07970 07971 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07972 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07973 add_header(&req, "Event", tmp); 07974 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07975 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07976 add_header(&req, "Allow", ALLOWED_METHODS); 07977 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07978 07979 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07980 add_header_contentLength(&req, strlen(tmp)); 07981 add_line(&req, tmp); 07982 07983 if (!p->initreq.headers) 07984 initialize_initreq(p, &req); 07985 07986 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07987 }
static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
int | with_sdp | |||
) | [static] |
Definition at line 6735 of file chan_sip.c.
References transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite(), sip_indicate(), and sip_write().
06736 { 06737 int res; 06738 06739 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE) : transmit_response(p, msg, req))) { 06740 p->last_provisional = msg; 06741 update_provisional_keepalive(p, with_sdp); 06742 } 06743 06744 return res; 06745 }
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 8321 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, 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::our_contact, 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, sip_pvt::theirtag, and XMIT_RELIABLE.
Referenced by sip_transfer().
08322 { 08323 struct sip_request req = { 08324 .headers = 0, 08325 }; 08326 char from[256]; 08327 const char *of; 08328 char *c; 08329 char referto[256]; 08330 char *ttag, *ftag; 08331 char *theirtag = ast_strdupa(p->theirtag); 08332 08333 if (option_debug || sipdebug) 08334 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08335 08336 /* Are we transfering an inbound or outbound call ? */ 08337 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08338 of = get_header(&p->initreq, "To"); 08339 ttag = theirtag; 08340 ftag = p->tag; 08341 } else { 08342 of = get_header(&p->initreq, "From"); 08343 ftag = theirtag; 08344 ttag = p->tag; 08345 } 08346 08347 ast_copy_string(from, of, sizeof(from)); 08348 of = get_in_brackets(from); 08349 ast_string_field_set(p, from, of); 08350 if (strncasecmp(of, "sip:", 4)) 08351 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08352 else 08353 of += 4; 08354 /* Get just the username part */ 08355 if ((c = strchr(dest, '@'))) 08356 c = NULL; 08357 else if ((c = strchr(of, '@'))) 08358 *c++ = '\0'; 08359 if (c) 08360 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08361 else 08362 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08363 08364 /* save in case we get 407 challenge */ 08365 sip_refer_allocate(p); 08366 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08367 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08368 p->refer->status = REFER_SENT; /* Set refer status */ 08369 08370 reqprep(&req, p, SIP_REFER, 0, 1); 08371 08372 add_header(&req, "Refer-To", referto); 08373 add_header(&req, "Allow", ALLOWED_METHODS); 08374 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08375 if (!ast_strlen_zero(p->our_contact)) 08376 add_header(&req, "Referred-By", p->our_contact); 08377 08378 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08379 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08380 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08381 08382 /*! \todo In theory, we should hang around and wait for a reply, before 08383 returning to the dial plan here. Don't know really how that would 08384 affect the transfer() app or the pbx, but, well, to make this 08385 useful we should have a STATUS code on transfer(). 08386 */ 08387 }
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 8092 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, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, create_addr(), DEFAULT_MAX_FORWARDS, sip_registry::domain, exten, FALSE, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromuser, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_registry::md5secret, sip_registry::needdns, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, sip_registry::secret, 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_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, TRUE, sip_pvt::uri, sip_registry::us, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
08093 { 08094 struct sip_request req; 08095 char from[256]; 08096 char to[256]; 08097 char tmp[80]; 08098 char addr[80]; 08099 struct sip_pvt *p; 08100 char *fromdomain; 08101 08102 /* exit if we are already in process with this registrar ?*/ 08103 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 08104 if (r) { 08105 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 08106 } 08107 return 0; 08108 } 08109 08110 if (r->call) { /* We have a registration */ 08111 if (!auth) { 08112 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 08113 return 0; 08114 } else { 08115 p = r->call; 08116 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 08117 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 08118 } 08119 } else { 08120 /* Build callid for registration if we haven't registered before */ 08121 if (!r->callid_valid) { 08122 build_callid_registry(r, __ourip, default_fromdomain); 08123 r->callid_valid = TRUE; 08124 } 08125 /* Allocate SIP packet for registration */ 08126 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 08127 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 08128 return 0; 08129 } 08130 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 08131 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 08132 /* Find address to hostname if we haven't tried to connect 08133 * or a connection error has occurred */ 08134 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 08135 /* we have what we hope is a temporary network error, 08136 * probably DNS. We need to reschedule a registration try */ 08137 sip_destroy(p); 08138 08139 if (r->timeout > -1) 08140 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 08141 else 08142 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); 08143 08144 AST_SCHED_DEL(sched, r->timeout); 08145 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08146 r->regattempts++; 08147 return 0; 08148 } 08149 if (r->needdns) { 08150 memcpy(&r->us, &p->sa, sizeof(r->us)); 08151 } 08152 r->needdns = FALSE; 08153 /* Copy back Call-ID in case create_addr changed it */ 08154 ast_string_field_set(r, callid, p->callid); 08155 if (r->portno) { 08156 p->sa.sin_port = htons(r->portno); 08157 p->recv.sin_port = htons(r->portno); 08158 } else /* Set registry port to the port set from the peer definition/srv or default */ 08159 r->portno = ntohs(p->sa.sin_port); 08160 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 08161 r->call=p; /* Save pointer to SIP packet */ 08162 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 08163 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 08164 ast_string_field_set(p, peersecret, r->secret); 08165 if (!ast_strlen_zero(r->md5secret)) 08166 ast_string_field_set(p, peermd5secret, r->md5secret); 08167 /* User name in this realm 08168 - if authuser is set, use that, otherwise use username */ 08169 if (!ast_strlen_zero(r->authuser)) { 08170 ast_string_field_set(p, peername, r->authuser); 08171 ast_string_field_set(p, authname, r->authuser); 08172 } else if (!ast_strlen_zero(r->username)) { 08173 ast_string_field_set(p, peername, r->username); 08174 ast_string_field_set(p, authname, r->username); 08175 ast_string_field_set(p, fromuser, r->username); 08176 } 08177 if (!ast_strlen_zero(r->username)) 08178 ast_string_field_set(p, username, r->username); 08179 /* Save extension in packet */ 08180 ast_string_field_set(p, exten, r->contact); 08181 08182 /* 08183 check which address we should use in our contact header 08184 based on whether the remote host is on the external or 08185 internal network so we can register through nat 08186 */ 08187 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08188 p->ourip = bindaddr.sin_addr; 08189 build_contact(p); 08190 } 08191 08192 /* set up a timeout */ 08193 if (auth == NULL) { 08194 if (r->timeout > -1) 08195 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 08196 AST_SCHED_DEL(sched, r->timeout); 08197 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08198 if (option_debug) 08199 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 08200 } 08201 08202 if ((fromdomain = strchr(r->username, '@'))) { 08203 /* the domain name is just behind '@' */ 08204 fromdomain++ ; 08205 /* We have a domain in the username for registration */ 08206 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 08207 if (!ast_strlen_zero(p->theirtag)) 08208 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 08209 else 08210 snprintf(to, sizeof(to), "<sip:%s>", r->username); 08211 08212 /* If the registration username contains '@', then the domain should be used as 08213 the equivalent of "fromdomain" for the registration */ 08214 if (ast_strlen_zero(p->fromdomain)) { 08215 ast_string_field_set(p, fromdomain, fromdomain); 08216 } 08217 } else { 08218 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 08219 if (!ast_strlen_zero(p->theirtag)) 08220 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 08221 else 08222 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 08223 } 08224 08225 /* Fromdomain is what we are registering to, regardless of actual 08226 host name from SRV */ 08227 if (!ast_strlen_zero(p->fromdomain)) { 08228 if (r->portno && r->portno != STANDARD_SIP_PORT) 08229 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 08230 else 08231 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 08232 } else { 08233 if (r->portno && r->portno != STANDARD_SIP_PORT) 08234 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 08235 else 08236 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 08237 } 08238 ast_string_field_set(p, uri, addr); 08239 08240 p->branch ^= ast_random(); 08241 08242 init_req(&req, sipmethod, addr); 08243 08244 /* Add to CSEQ */ 08245 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 08246 p->ocseq = r->ocseq; 08247 08248 build_via(p); 08249 add_header(&req, "Via", p->via); 08250 add_header(&req, "From", from); 08251 add_header(&req, "To", to); 08252 add_header(&req, "Call-ID", p->callid); 08253 add_header(&req, "CSeq", tmp); 08254 if (!ast_strlen_zero(global_useragent)) 08255 add_header(&req, "User-Agent", global_useragent); 08256 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08257 08258 08259 if (auth) /* Add auth header */ 08260 add_header(&req, authheader, auth); 08261 else if (!ast_strlen_zero(r->nonce)) { 08262 char digest[1024]; 08263 08264 /* We have auth data to reuse, build a digest header! */ 08265 if (sipdebug) 08266 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 08267 ast_string_field_set(p, realm, r->realm); 08268 ast_string_field_set(p, nonce, r->nonce); 08269 ast_string_field_set(p, domain, r->domain); 08270 ast_string_field_set(p, opaque, r->opaque); 08271 ast_string_field_set(p, qop, r->qop); 08272 r->noncecount++; 08273 p->noncecount = r->noncecount; 08274 08275 memset(digest,0,sizeof(digest)); 08276 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 08277 add_header(&req, "Authorization", digest); 08278 else 08279 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 08280 08281 } 08282 08283 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 08284 add_header(&req, "Expires", tmp); 08285 add_header(&req, "Contact", p->our_contact); 08286 add_header(&req, "Event", "registration"); 08287 add_header_contentLength(&req, 0); 08288 08289 initialize_initreq(p, &req); 08290 if (sip_debug_test_pvt(p)) 08291 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 08292 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 08293 r->regattempts++; /* Another attempt */ 08294 if (option_debug > 3) 08295 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 08296 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08297 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7337 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
07338 { 07339 struct sip_request req; 07340 07341 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07342 07343 add_header(&req, "Allow", ALLOWED_METHODS); 07344 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07345 if (sipdebug) 07346 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07347 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07348 append_history(p, "ReInv", "Re-invite sent"); 07349 memset(p->offered_media, 0, sizeof(p->offered_media)); 07350 add_sdp(&req, p, 1, 0); 07351 /* Use this as the basis */ 07352 initialize_initreq(p, &req); 07353 p->lastinvite = p->ocseq; 07354 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07355 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07356 }
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 7362 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, sip_pvt::offered_media, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), sip_set_udptl_peer(), and sip_write().
07363 { 07364 struct sip_request req; 07365 07366 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07367 07368 add_header(&req, "Allow", ALLOWED_METHODS); 07369 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07370 if (sipdebug) 07371 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07372 memset(p->offered_media, 0, sizeof(p->offered_media)); 07373 add_sdp(&req, p, 0, 1); 07374 07375 /* Use this as the basis */ 07376 initialize_initreq(p, &req); 07377 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07378 p->lastinvite = p->ocseq; 07379 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07380 }
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 8413 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().
08414 { 08415 struct sip_request resp; 08416 08417 if (sipmethod == SIP_ACK) 08418 p->invitestate = INV_CONFIRMED; 08419 08420 reqprep(&resp, p, sipmethod, seqno, newbranch); 08421 add_header_contentLength(&resp, 0); 08422 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08423 }
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 8426 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(), sip_pvt::callid, sip_pvt::hangupcause, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
08427 { 08428 struct sip_request resp; 08429 08430 reqprep(&resp, p, sipmethod, seqno, newbranch); 08431 if (!ast_strlen_zero(p->realm)) { 08432 char digest[1024]; 08433 08434 memset(digest, 0, sizeof(digest)); 08435 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08436 if (p->options && p->options->auth_type == PROXY_AUTH) 08437 add_header(&resp, "Proxy-Authorization", digest); 08438 else if (p->options && p->options->auth_type == WWW_AUTH) 08439 add_header(&resp, "Authorization", digest); 08440 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08441 add_header(&resp, "Proxy-Authorization", digest); 08442 } else 08443 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08444 } 08445 /* If we are hanging up and know a cause for that, send it in clear text to make 08446 debugging easier. */ 08447 if (sipmethod == SIP_BYE) { 08448 char buf[10]; 08449 08450 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08451 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08452 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08453 } 08454 08455 add_header_contentLength(&resp, 0); 08456 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08457 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6657 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06658 { 06659 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06660 }
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 6676 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(), sip_indicate(), and sip_sipredirect().
06677 { 06678 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06679 }
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 6606 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, ast_threadstorage_get(), build_via(), check_via(), do_setnat(), sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, ts_temp_pvt, and XMIT_UNRELIABLE.
06607 { 06608 struct sip_pvt *p = NULL; 06609 06610 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06611 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06612 return -1; 06613 } 06614 06615 /* if the structure was just allocated, initialize it */ 06616 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06617 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06618 if (ast_string_field_init(p, 512)) 06619 return -1; 06620 } 06621 06622 /* Initialize the bare minimum */ 06623 p->method = intended_method; 06624 06625 if (sin) { 06626 p->sa = *sin; 06627 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06628 p->ourip = __ourip; 06629 } else 06630 p->ourip = __ourip; 06631 06632 p->branch = ast_random(); 06633 make_our_tag(p->tag, sizeof(p->tag)); 06634 p->ocseq = INITIAL_CSEQ; 06635 06636 if (useglobal_nat && sin) { 06637 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06638 p->recv = *sin; 06639 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06640 } 06641 check_via(p, req); 06642 06643 ast_string_field_set(p, fromdomain, default_fromdomain); 06644 build_via(p); 06645 ast_string_field_set(p, callid, callid); 06646 06647 /* Use this temporary pvt structure to send the message */ 06648 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06649 06650 /* Free the string fields, but not the pool space */ 06651 ast_string_field_reset_all(p); 06652 06653 return 0; 06654 }
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 6704 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06705 { 06706 struct sip_request resp; 06707 respprep(&resp, p, msg, req); 06708 add_header(&resp, "Accept", "application/sdp"); 06709 add_header_contentLength(&resp, 0); 06710 return send_response(p, &resp, reliable, 0); 06711 }
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 6714 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), send_response(), and sip_pvt::username.
Referenced by check_auth(), and transmit_fake_auth_response().
06715 { 06716 struct sip_request resp; 06717 char tmp[512]; 06718 int seqno = 0; 06719 06720 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06721 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06722 return -1; 06723 } 06724 /* Stale means that they sent us correct authentication, but 06725 based it on an old challenge (nonce) */ 06726 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06727 respprep(&resp, p, msg, req); 06728 add_header(&resp, header, tmp); 06729 add_header_contentLength(&resp, 0); 06730 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06731 return send_response(p, &resp, reliable, seqno); 06732 }
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 6694 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06695 { 06696 struct sip_request resp; 06697 respprep(&resp, p, msg, req); 06698 append_date(&resp); 06699 add_header_contentLength(&resp, 0); 06700 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06701 }
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 7261 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().
07262 { 07263 struct sip_request resp; 07264 int seqno; 07265 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07266 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07267 return -1; 07268 } 07269 respprep(&resp, p, msg, req); 07270 if (p->rtp) { 07271 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07272 if (option_debug) 07273 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 07274 ast_rtp_codec_setpref(p->rtp, &p->prefs); 07275 } 07276 try_suggested_sip_codec(p); 07277 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 07278 p->t38.state = T38_ENABLED; 07279 add_sdp(&resp, p, 1, 1); 07280 } else { 07281 add_sdp(&resp, p, 1, 0); 07282 } 07283 } else 07284 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 07285 if (reliable && !p->pendinginvite) 07286 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07287 return send_response(p, &resp, reliable, seqno); 07288 }
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 7222 of file chan_sip.c.
References add_sdp(), ast_log(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), and sip_handle_t38_reinvite().
07223 { 07224 struct sip_request resp; 07225 int seqno; 07226 07227 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07228 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07229 return -1; 07230 } 07231 respprep(&resp, p, msg, req); 07232 if (p->udptl) { 07233 add_sdp(&resp, p, 0, 1); 07234 } else 07235 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 07236 if (retrans && !p->pendinginvite) 07237 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07238 return send_response(p, &resp, retrans, seqno); 07239 }
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 6663 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06664 { 06665 struct sip_request resp; 06666 respprep(&resp, p, msg, req); 06667 append_date(&resp); 06668 add_header(&resp, "Unsupported", unsupported); 06669 add_header_contentLength(&resp, 0); 06670 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06671 }
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 7958 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().
07959 { 07960 if (!p->initreq.headers) /* Initialize first request before sending */ 07961 initialize_initreq(p, req); 07962 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07963 }
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 7724 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_copy_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, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
07725 { 07726 char tmp[4000], from[256], to[256]; 07727 char *t = tmp, *c, *mfrom, *mto; 07728 size_t maxbytes = sizeof(tmp); 07729 struct sip_request req; 07730 char hint[AST_MAX_EXTENSION]; 07731 char *statestring = "terminated"; 07732 const struct cfsubscription_types *subscriptiontype; 07733 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07734 char *pidfstate = "--"; 07735 char *pidfnote= "Ready"; 07736 07737 memset(from, 0, sizeof(from)); 07738 memset(to, 0, sizeof(to)); 07739 memset(tmp, 0, sizeof(tmp)); 07740 07741 switch (state) { 07742 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07743 statestring = (global_notifyringing) ? "early" : "confirmed"; 07744 local_state = NOTIFY_INUSE; 07745 pidfstate = "busy"; 07746 pidfnote = "Ringing"; 07747 break; 07748 case AST_EXTENSION_RINGING: 07749 statestring = "early"; 07750 local_state = NOTIFY_INUSE; 07751 pidfstate = "busy"; 07752 pidfnote = "Ringing"; 07753 break; 07754 case AST_EXTENSION_INUSE: 07755 statestring = "confirmed"; 07756 local_state = NOTIFY_INUSE; 07757 pidfstate = "busy"; 07758 pidfnote = "On the phone"; 07759 break; 07760 case AST_EXTENSION_BUSY: 07761 statestring = "confirmed"; 07762 local_state = NOTIFY_CLOSED; 07763 pidfstate = "busy"; 07764 pidfnote = "On the phone"; 07765 break; 07766 case AST_EXTENSION_UNAVAILABLE: 07767 statestring = "terminated"; 07768 local_state = NOTIFY_CLOSED; 07769 pidfstate = "away"; 07770 pidfnote = "Unavailable"; 07771 break; 07772 case AST_EXTENSION_ONHOLD: 07773 statestring = "confirmed"; 07774 local_state = NOTIFY_CLOSED; 07775 pidfstate = "busy"; 07776 pidfnote = "On Hold"; 07777 break; 07778 case AST_EXTENSION_NOT_INUSE: 07779 default: 07780 /* Default setting */ 07781 break; 07782 } 07783 07784 subscriptiontype = find_subscription_type(p->subscribed); 07785 07786 /* Check which device/devices we are watching and if they are registered */ 07787 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07788 char *hint2 = hint, *individual_hint = NULL; 07789 int hint_count = 0, unavailable_count = 0; 07790 07791 while ((individual_hint = strsep(&hint2, "&"))) { 07792 hint_count++; 07793 07794 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07795 unavailable_count++; 07796 } 07797 07798 /* If none of the hinted devices are registered, we will 07799 * override notification and show no availability. 07800 */ 07801 if (hint_count > 0 && hint_count == unavailable_count) { 07802 local_state = NOTIFY_CLOSED; 07803 pidfstate = "away"; 07804 pidfnote = "Not online"; 07805 } 07806 } 07807 07808 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07809 c = get_in_brackets(from); 07810 if (strncasecmp(c, "sip:", 4)) { 07811 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07812 return -1; 07813 } 07814 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07815 07816 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07817 c = get_in_brackets(to); 07818 if (strncasecmp(c, "sip:", 4)) { 07819 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07820 return -1; 07821 } 07822 mto = strsep(&c, ";"); /* trim ; and beyond */ 07823 07824 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07825 07826 07827 add_header(&req, "Event", subscriptiontype->event); 07828 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07829 switch(state) { 07830 case AST_EXTENSION_DEACTIVATED: 07831 if (timeout) 07832 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07833 else { 07834 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07835 add_header(&req, "Retry-After", "60"); 07836 } 07837 break; 07838 case AST_EXTENSION_REMOVED: 07839 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07840 break; 07841 default: 07842 if (p->expiry) 07843 add_header(&req, "Subscription-State", "active"); 07844 else /* Expired */ 07845 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07846 } 07847 switch (p->subscribed) { 07848 case XPIDF_XML: 07849 case CPIM_PIDF_XML: 07850 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07851 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07852 ast_build_string(&t, &maxbytes, "<presence>\n"); 07853 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07854 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07855 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07856 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07857 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07858 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07859 break; 07860 case PIDF_XML: /* Eyebeam supports this format */ 07861 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07862 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); 07863 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07864 if (pidfstate[0] != '-') 07865 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07866 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07867 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07868 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07869 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07870 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07871 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07872 else 07873 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07874 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07875 break; 07876 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07877 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07878 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); 07879 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07880 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07881 else 07882 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07883 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07884 if (state == AST_EXTENSION_ONHOLD) { 07885 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07886 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07887 "</target>\n</local>\n", mto); 07888 } 07889 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07890 break; 07891 case NONE: 07892 default: 07893 break; 07894 } 07895 07896 if (t > tmp + sizeof(tmp)) 07897 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07898 07899 add_header_contentLength(&req, strlen(tmp)); 07900 add_line(&req, tmp); 07901 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07902 07903 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07904 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3833 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03834 { 03835 int fmt; 03836 const char *codec; 03837 03838 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03839 if (!codec) 03840 return; 03841 03842 fmt = ast_getformatbyname(codec); 03843 if (fmt) { 03844 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03845 if (p->jointcapability & fmt) { 03846 p->jointcapability &= fmt; 03847 p->capability &= fmt; 03848 } else 03849 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03850 } else 03851 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03852 return; 03853 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 19566 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, iflock, localaddr, monlock, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
19567 { 19568 struct sip_pvt *p, *pl; 19569 19570 /* First, take us out of the channel type list */ 19571 ast_channel_unregister(&sip_tech); 19572 19573 /* Unregister dial plan functions */ 19574 ast_custom_function_unregister(&sipchaninfo_function); 19575 ast_custom_function_unregister(&sippeer_function); 19576 ast_custom_function_unregister(&sip_header_function); 19577 ast_custom_function_unregister(&checksipdomain_function); 19578 19579 /* Unregister dial plan applications */ 19580 ast_unregister_application(app_dtmfmode); 19581 ast_unregister_application(app_sipaddheader); 19582 19583 /* Unregister CLI commands */ 19584 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 19585 19586 /* Disconnect from the RTP subsystem */ 19587 ast_rtp_proto_unregister(&sip_rtp); 19588 19589 /* Disconnect from UDPTL */ 19590 ast_udptl_proto_unregister(&sip_udptl); 19591 19592 /* Unregister AMI actions */ 19593 ast_manager_unregister("SIPpeers"); 19594 ast_manager_unregister("SIPshowpeer"); 19595 19596 ast_mutex_lock(&iflock); 19597 /* Hangup all interfaces if they have an owner */ 19598 for (p = iflist; p ; p = p->next) { 19599 if (p->owner) 19600 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 19601 } 19602 ast_mutex_unlock(&iflock); 19603 19604 ast_mutex_lock(&monlock); 19605 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 19606 pthread_cancel(monitor_thread); 19607 pthread_kill(monitor_thread, SIGURG); 19608 pthread_join(monitor_thread, NULL); 19609 } 19610 monitor_thread = AST_PTHREADT_STOP; 19611 ast_mutex_unlock(&monlock); 19612 19613 restartdestroy: 19614 ast_mutex_lock(&iflock); 19615 /* Destroy all the interfaces and free their memory */ 19616 p = iflist; 19617 while (p) { 19618 pl = p; 19619 p = p->next; 19620 if (__sip_destroy(pl, TRUE) < 0) { 19621 /* Something is still bridged, let it react to getting a hangup */ 19622 iflist = p; 19623 ast_mutex_unlock(&iflock); 19624 usleep(1); 19625 goto restartdestroy; 19626 } 19627 } 19628 iflist = NULL; 19629 ast_mutex_unlock(&iflock); 19630 19631 /* Free memory for local network address mask */ 19632 ast_free_ha(localaddr); 19633 19634 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19635 ASTOBJ_CONTAINER_DESTROY(&userl); 19636 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 19637 ASTOBJ_CONTAINER_DESTROY(&peerl); 19638 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19639 ASTOBJ_CONTAINER_DESTROY(®l); 19640 19641 clear_realm_authentication(authl); 19642 clear_sip_domains(); 19643 close(sipsock); 19644 sched_context_destroy(sched); 19645 19646 return 0; 19647 }
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 3380 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_peer::flags, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, sip_peer::name, name, option_debug, sip_pvt::peername, 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, sipdebug, and sip_pvt::username.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03381 { 03382 char name[256]; 03383 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03384 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03385 struct sip_user *u = NULL; 03386 struct sip_peer *p = NULL; 03387 03388 if (option_debug > 2) 03389 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03390 03391 /* Test if we need to check call limits, in order to avoid 03392 realtime lookups if we do not need it */ 03393 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03394 return 0; 03395 03396 ast_copy_string(name, fup->username, sizeof(name)); 03397 03398 /* Check the list of users only for incoming calls */ 03399 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03400 inuse = &u->inUse; 03401 call_limit = &u->call_limit; 03402 inringing = NULL; 03403 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03404 inuse = &p->inUse; 03405 call_limit = &p->call_limit; 03406 inringing = &p->inRinging; 03407 ast_copy_string(name, fup->peername, sizeof(name)); 03408 } 03409 if (!p && !u) { 03410 if (option_debug > 1) 03411 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03412 return 0; 03413 } 03414 03415 switch(event) { 03416 /* incoming and outgoing affects the inUse counter */ 03417 case DEC_CALL_LIMIT: 03418 if ( *inuse > 0 ) { 03419 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03420 (*inuse)--; 03421 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03422 } 03423 } else { 03424 *inuse = 0; 03425 } 03426 if (inringing) { 03427 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03428 if (*inringing > 0) 03429 (*inringing)--; 03430 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03431 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03432 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03433 } 03434 } 03435 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03436 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03437 sip_peer_hold(fup, 0); 03438 } 03439 if (option_debug > 1 || sipdebug) { 03440 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03441 } 03442 break; 03443 03444 case INC_CALL_RINGING: 03445 case INC_CALL_LIMIT: 03446 if (*call_limit > 0 ) { 03447 /* Let call limit affect only outgoing calls */ 03448 if (outgoing && (*inuse >= *call_limit)) { 03449 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); 03450 if (u) 03451 ASTOBJ_UNREF(u, sip_destroy_user); 03452 else 03453 ASTOBJ_UNREF(p, sip_destroy_peer); 03454 return -1; 03455 } 03456 } 03457 if (inringing && (event == INC_CALL_RINGING)) { 03458 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03459 (*inringing)++; 03460 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03461 } 03462 } 03463 /* Continue */ 03464 (*inuse)++; 03465 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03466 if (option_debug > 1 || sipdebug) { 03467 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03468 } 03469 break; 03470 03471 case DEC_CALL_RINGING: 03472 if (inringing) { 03473 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03474 if (*inringing > 0) 03475 (*inringing)--; 03476 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03477 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03478 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03479 } 03480 } 03481 break; 03482 03483 default: 03484 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03485 } 03486 if (p) { 03487 ast_device_state_changed("SIP/%s", p->name); 03488 ASTOBJ_UNREF(p, sip_destroy_peer); 03489 } else /* u must be set */ 03490 ASTOBJ_UNREF(u, sip_destroy_user); 03491 return 0; 03492 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2627 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, sip_peer::lastms, sip_peer::name, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02628 { 02629 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02630 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02631 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02632 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02633 } 02634 }
static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2369 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_sched_id, sched, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
02370 { 02371 AST_SCHED_DEL(sched, pvt->provisional_keepalive_sched_id); 02372 02373 pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT, 02374 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, pvt); 02375 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 19653 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1265 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 574 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 594 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 19130 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 19132 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19653 of file chan_sip.c.
Definition at line 1254 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 553 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1259 of file chan_sip.c.
unsigned int chan_idx [static] |
Definition at line 402 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT, .key_init = check_auth_buf_init , } [static] |
Definition at line 8998 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 19392 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 19397 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 568 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 235 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 12483 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1268 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 532 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 529 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 533 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 226 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 531 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 540 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 537 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 538 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 534 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 541 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 535 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 530 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 536 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 19129 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 19135 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 570 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 194 of file chan_sip.c.
Referenced by complete_dpreply(), and process_clearcache().
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1262 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1261 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1260 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 561 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 562 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 578 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 550 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 577 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 575 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
struct ast_ha* global_contact_ha = NULL [static] |
Global list of addresses dynamic peers are not allowed to use.
Definition at line 586 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), and reload_config().
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 544 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 587 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 597 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), handle_response_peerpoke(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_poke_noanswer(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 233 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 546 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 580 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 564 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 549 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 548 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 545 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 571 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 558 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 559 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 572 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 554 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 547 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 556 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 557 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 555 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 560 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 576 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] |
Definition at line 851 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 566 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 565 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 567 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 573 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 12500 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
ast_mutex_t iflock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
struct io_context* io [static] |
The IO context
Definition at line 618 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1264 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 11105 of file chan_sip.c.
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 10656 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 192 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 191 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 612 of file chan_sip.c.
ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Definition at line 606 of file chan_sip.c.
ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
Definition at line 604 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 12492 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 12496 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 236 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 1270 of file chan_sip.c.
Referenced by complete_sipnotify(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 12432 of file chan_sip.c.
int ourport [static] |
Definition at line 1267 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1266 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 552 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 12474 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 569 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 595 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 593 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 591 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 617 of file chan_sip.c.
char seen_lastms = 0 [static] |
Definition at line 195 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 12456 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 12452 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 12427 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 12460 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 12447 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 12513 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 12469 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 12464 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 12479 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 12517 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 12509 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 12442 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 12437 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
ast_mutex_t sip_reload_lock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 12505 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 614 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 615 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 1673 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 1615 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 1641 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 1682 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
Structure to declare a dialplan function: SIPCHANINFO.
Definition at line 12758 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12678 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1258 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 619 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 592 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 551 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 590 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 19128 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 19133 of file chan_sip.c.
struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT, .key_init = temp_pvt_init , } [static] |
struct ast_user_list userl [static] |
The user list: Users and friends.