#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/astobj2.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 | provisional_keepalive_data |
provisional keep alive scheduler item data More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_extenstate_update |
struct | sip_extenstate_updates |
list of extension state updates for the dialog list. 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 | sip_via |
Structure to store Via information. 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 %-15.15s %-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 %-15.15s %-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 %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-15.15s %-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_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_FORWARD_LOOP_DETECTED (1 << 31) |
#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_content (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_extensionstate_update (char *context, char *exten, int state, void *data) |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add 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 int | addr_is_multicast (struct in_addr *addr) |
Check if an ip is an multicast IP. addr the address to check. | |
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 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_extenstate_updates (struct sip_pvt *pvt) |
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 void | clear_extenstate_updates (struct sip_pvt *pvt) |
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 void | clearmarked_extenstate_updates (void) |
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 int | finalize_content (struct sip_request *req) |
Add 'Content-Length' header to 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 void | free_via (struct sip_via *v) |
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 void | markall_extenstate_updates (void) |
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 int | notify_extenstate_update (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
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 struct sip_via * | parse_via (const char *header) |
Parse a Via header. | |
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 | process_via (struct sip_pvt *p, const struct sip_request *req) |
Process the Via header according to RFC 3261 section 18.2.2. | |
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 void | remove_provisional_keepalive_sched (struct sip_pvt *pvt) |
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 provisional_keepalive_data *data, int with_sdp) |
This is called by the scheduler to resend the last provisional message in a dialog. | |
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 to compare URI parameters | |
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 void | unmark_extenstate_update (struct sip_pvt *pvt) |
static void * | unref_provisional_keepalive (struct provisional_keepalive_data *data) |
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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 = ((ast_mutex_t) 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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | netlock = ((ast_mutex_t) 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 = NULL |
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 = ((ast_mutex_t) 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 483 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 1962 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), 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(), notify_extenstate_update(), 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 374 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 375 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 373 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 9399 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 622 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 624 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 515 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 519 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 506 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 190 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 207 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 206 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 522 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 175 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 177 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 205 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 504 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 507 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 517 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 518 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 520 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 516 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 176 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 209 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 510 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 521 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 513 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 512 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 514 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 214 of file chan_sip.c.
Referenced by __sip_autodestruct(), auto_congest(), 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(), notify_extenstate_update(), 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 524 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 505 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 182 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 184 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 188 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 181 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 155 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1091 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 %-15.15s %-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 %-15.15s %-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 %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-15.15s %-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 623 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 224 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 168 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 199 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 216 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 1089 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 210 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 240 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 416 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 215 of file chan_sip.c.
Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().
#define RTP 1 |
Definition at line 239 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 222 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 7274 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 742 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 783 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 771 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 772 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 757 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 758 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 762 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 760 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 761 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 759 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 788 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 756 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 786 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 749 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 785 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 776 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 775 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 218 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 219 of file chan_sip.c.
Referenced by parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 220 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 764 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 768 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 765 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 766 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 767 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 743 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 747 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 782 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 744 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 429 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 430 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 433 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 432 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 434 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 428 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 431 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 420 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 755 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 810 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 809 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 822 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 817 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 820 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 819 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 803 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 804 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 805 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 825 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 806 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_FORWARD_LOOP_DETECTED)
Definition at line 829 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_FORWARD_LOOP_DETECTED (1 << 31) |
31: Do call forward when receiving 482 Loop Detected
Definition at line 827 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), handle_response(), and sip_show_settings().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 802 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 812 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 823 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 821 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 826 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 798 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
Definition at line 797 of file chan_sip.c.
Referenced by expire_register(), and sip_show_settings().
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 795 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 799 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 796 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 807 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 801 of file chan_sip.c.
Referenced by handle_response(), and notify_extenstate_update().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 811 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 813 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 815 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 816 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 814 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 824 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 808 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 748 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 835 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 837 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 836 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 778 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 780 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 781 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 746 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 750 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 753 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), sip_do_reload(), 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 773 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 784 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 211 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 751 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 754 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 752 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 162 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), build_contact(), 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 866 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 867 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 868 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 489 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), process_via(), 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 415 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 486 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 841 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 860 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 861 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 856 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 857 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 858 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 859 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 846 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 845 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 843 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 842 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 849 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 848 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp(), process_sdp_a_image(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 850 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 852 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 853 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 854 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp_a_image().
#define TRUE 1 |
Definition at line 159 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1720 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 166 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 164 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 349 of file chan_sip.c.
00349 { 00350 AUTH_SUCCESSFUL = 0, 00351 AUTH_CHALLENGE_SENT = 1, 00352 AUTH_SECRET_FAILED = -1, 00353 AUTH_USERNAME_MISMATCH = -2, 00354 AUTH_NOT_FOUND = -3, 00355 AUTH_FAKE_AUTH = -4, 00356 AUTH_UNKNOWN_DOMAIN = -5, 00357 AUTH_PEER_NOT_DYNAMIC = -6, 00358 AUTH_ACL_FAILED = -7, 00359 };
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 705 of file chan_sip.c.
00705 { 00706 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00707 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00708 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 259 of file chan_sip.c.
00259 { 00260 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00261 INV_CALLING = 1, /*!< Invite sent, no answer */ 00262 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00263 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00264 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00265 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00266 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00267 The only way out of this is a BYE from one side */ 00268 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00269 };
enum media_type |
Definition at line 286 of file chan_sip.c.
00286 { 00287 PARSE_REGISTER_DENIED, 00288 PARSE_REGISTER_FAILED, 00289 PARSE_REGISTER_UPDATE, 00290 PARSE_REGISTER_QUERY, 00291 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 896 of file chan_sip.c.
00896 { 00897 REFER_IDLE, /*!< No REFER is in progress */ 00898 REFER_SENT, /*!< Sent REFER to transferee */ 00899 REFER_RECEIVED, /*!< Received REFER from transferer */ 00900 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00901 REFER_ACCEPTED, /*!< Accepted by transferee */ 00902 REFER_RINGING, /*!< Target Ringing */ 00903 REFER_200OK, /*!< Answered by transfer target */ 00904 REFER_FAILED, /*!< REFER declined - go on */ 00905 REFER_NOAUTH /*!< We had no auth for REFER */ 00906 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 343 of file chan_sip.c.
00343 { 00344 PROXY_AUTH, 00345 WWW_AUTH, 00346 };
enum sip_result |
Definition at line 251 of file chan_sip.c.
00251 { 00252 AST_SUCCESS = 0, 00253 AST_FAILURE = -1, 00254 };
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 318 of file chan_sip.c.
00318 { 00319 SIP_UNKNOWN, /* Unknown response */ 00320 SIP_RESPONSE, /* Not request, response to outbound request */ 00321 SIP_REGISTER, 00322 SIP_OPTIONS, 00323 SIP_NOTIFY, 00324 SIP_INVITE, 00325 SIP_ACK, 00326 SIP_PRACK, /* Not supported at all */ 00327 SIP_BYE, 00328 SIP_REFER, 00329 SIP_SUBSCRIBE, 00330 SIP_MESSAGE, 00331 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00332 SIP_INFO, 00333 SIP_CANCEL, 00334 SIP_PUBLISH, /* Not supported at all */ 00335 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00336 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 362 of file chan_sip.c.
00362 { 00363 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00364 REG_STATE_REGSENT, /*!< Registration request sent */ 00365 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00366 REG_STATE_REGISTERED, /*!< Registered and done */ 00367 REG_STATE_REJECTED, /*!< Registration rejected */ 00368 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00369 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00370 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00371 };
enum subscriptiontype |
Definition at line 293 of file chan_sip.c.
00293 { 00294 NONE = 0, 00295 XPIDF_XML, 00296 DIALOG_INFO_XML, 00297 CPIM_PIDF_XML, 00298 PIDF_XML, 00299 MWI_NOTIFICATION 00300 };
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 877 of file chan_sip.c.
00877 { 00878 T38_DISABLED = 0, /*!< Not enabled */ 00879 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00880 T38_PEER_DIRECT, /*!< Offered from peer */ 00881 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00882 T38_ENABLED /*!< Negotiated (enabled) */ 00883 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 245 of file chan_sip.c.
00245 { 00246 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00247 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00248 };
enum xmittype |
Definition at line 279 of file chan_sip.c.
00279 { 00280 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00281 If it fails, it's critical and will cause a teardown of the session */ 00282 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00283 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00284 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4675 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04676 { 04677 int pass; 04678 04679 /* 04680 * Technically you can place arbitrary whitespace both before and after the ':' in 04681 * a header, although RFC3261 clearly says you shouldn't before, and place just 04682 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04683 * a good idea to say you can do it, and if you can do it, why in the hell would. 04684 * you say you shouldn't. 04685 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04686 * and we always allow spaces after that for compatibility. 04687 */ 04688 for (pass = 0; name && pass < 2;pass++) { 04689 int x, len = strlen(name); 04690 for (x=*start; x<req->headers; x++) { 04691 if (!strncasecmp(req->header[x], name, len)) { 04692 char *r = req->header[x] + len; /* skip name */ 04693 if (pedanticsipchecking) 04694 r = ast_skip_blanks(r); 04695 04696 if (*r == ':') { 04697 *start = x+1; 04698 return ast_skip_blanks(r+1); 04699 } 04700 } 04701 } 04702 if (pass == 0) /* Try aliases */ 04703 name = find_alias(name, NULL); 04704 } 04705 04706 /* Don't return NULL, so get_header is always a valid pointer */ 04707 return ""; 04708 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 20459 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8997 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().
08998 { 08999 struct hostent *hp; 09000 struct ast_hostent ahp; 09001 int port; 09002 char *c, *host, *pt; 09003 char contact_buf[256]; 09004 char *contact; 09005 09006 /* Work on a copy */ 09007 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 09008 contact = contact_buf; 09009 09010 /* Make sure it's a SIP URL */ 09011 if (strncasecmp(contact, "sip:", 4)) { 09012 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 09013 } else 09014 contact += 4; 09015 09016 /* Ditch arguments */ 09017 /* XXX this code is replicated also shortly below */ 09018 09019 /* Grab host */ 09020 host = strchr(contact, '@'); 09021 if (!host) { /* No username part */ 09022 host = contact; 09023 c = NULL; 09024 } else { 09025 *host++ = '\0'; 09026 } 09027 pt = strchr(host, ':'); 09028 if (pt) { 09029 *pt++ = '\0'; 09030 port = atoi(pt); 09031 } else 09032 port = STANDARD_SIP_PORT; 09033 09034 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 09035 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 09036 09037 /* XXX This could block for a long time XXX */ 09038 /* We should only do this if it's a name, not an IP */ 09039 hp = ast_gethostbyname(host, &ahp); 09040 if (!hp) { 09041 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 09042 return -1; 09043 } 09044 sin->sin_family = AF_INET; 09045 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 09046 sin->sin_port = htons(port); 09047 09048 return 0; 09049 }
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 2291 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().
02292 { 02293 struct sip_pkt *cur, *prev = NULL; 02294 02295 /* Just in case... */ 02296 char *msg; 02297 int res = FALSE; 02298 02299 msg = sip_methods[sipmethod].text; 02300 02301 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02302 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02303 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02304 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02305 if (!resp && (seqno == p->pendinginvite)) { 02306 if (option_debug) 02307 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02308 p->pendinginvite = 0; 02309 } 02310 /* this is our baby */ 02311 res = TRUE; 02312 UNLINK(cur, p->packets, prev); 02313 if (cur->retransid > -1) { 02314 if (sipdebug && option_debug > 3) 02315 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02316 } 02317 /* This odd section is designed to thwart a 02318 * race condition in the packet scheduler. There are 02319 * two conditions under which deleting the packet from the 02320 * scheduler can fail. 02321 * 02322 * 1. The packet has been removed from the scheduler because retransmission 02323 * is being attempted. The problem is that if the packet is currently attempting 02324 * retransmission and we are at this point in the code, then that MUST mean 02325 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02326 * lock temporarily to allow retransmission. 02327 * 02328 * 2. The packet has reached its maximum number of retransmissions and has 02329 * been permanently removed from the packet scheduler. If this is the case, then 02330 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02331 * of the retransid to -1 is ensured since in both cases p's lock is held. 02332 */ 02333 AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock); 02334 free(cur); 02335 break; 02336 } 02337 } 02338 if (option_debug) 02339 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"); 02340 return res; 02341 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2193 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_EXTENSION_DEACTIVATED, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEADLOCK_AVOIDANCE, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_pvt::lastmsg, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02194 { 02195 struct sip_pvt *p = (struct sip_pvt *)data; 02196 02197 /* If this is a subscription, tell the phone that we got a timeout */ 02198 if (p->subscribed) { 02199 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02200 p->subscribed = NONE; 02201 append_history(p, "Subscribestatus", "timeout"); 02202 if (option_debug > 2) 02203 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02204 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02205 } 02206 02207 /* If there are packets still waiting for delivery, delay the destruction */ 02208 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02209 * of code make a sort of "safety relief valve", that allows sip channels 02210 * that were created via INVITE, then thru some sequence were CANCELED, 02211 * to die, rather than infinitely be rescheduled */ 02212 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02213 char method_str[31]; 02214 if (option_debug > 2) 02215 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02216 append_history(p, "ReliableXmit", "timeout"); 02217 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 02218 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 02219 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02220 } 02221 } 02222 return 10000; 02223 } 02224 02225 /* Reset schedule ID */ 02226 p->autokillid = -1; 02227 02228 if (option_debug) 02229 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02230 append_history(p, "AutoDestroy", "%s", p->callid); 02231 02232 /* 02233 * Lock both the pvt and the channel safely so that we can queue up a frame. 02234 */ 02235 ast_mutex_lock(&p->lock); 02236 while (p->owner && ast_channel_trylock(p->owner)) { 02237 DEADLOCK_AVOIDANCE(&p->lock); 02238 } 02239 02240 if (p->owner) { 02241 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02242 ast_queue_hangup(p->owner); 02243 ast_channel_unlock(p->owner); 02244 ast_mutex_unlock(&p->lock); 02245 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02246 if (option_debug > 2) 02247 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02248 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02249 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02250 ast_mutex_unlock(&p->lock); 02251 } else { 02252 ast_mutex_unlock(&p->lock); 02253 sip_destroy(p); 02254 } 02255 02256 return 0; 02257 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3392 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_mutex_lock(), ast_mutex_unlock(), 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, clear_extenstate_updates(), 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, remove_provisional_keepalive_sched(), 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, unref_provisional_keepalive(), update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03393 { 03394 struct sip_pvt *cur, *prev = NULL; 03395 struct sip_pkt *cp; 03396 struct sip_request *req; 03397 03398 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03399 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03400 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03401 return -1; 03402 } 03403 03404 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03405 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03406 return -1; 03407 } 03408 03409 if (sip_debug_test_pvt(p) || option_debug > 2) 03410 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03411 03412 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03413 update_call_counter(p, DEC_CALL_LIMIT); 03414 if (option_debug > 1) 03415 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03416 } 03417 03418 /* Unlink us from the owner if we have one */ 03419 if (p->owner) { 03420 if (lockowner) 03421 ast_channel_lock(p->owner); 03422 if (option_debug) 03423 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03424 p->owner->tech_pvt = NULL; 03425 /* Make sure that the channel knows its backend is going away */ 03426 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03427 if (lockowner) 03428 ast_channel_unlock(p->owner); 03429 /* Give the channel a chance to react before deallocation */ 03430 usleep(1); 03431 } 03432 03433 /* Remove link from peer to subscription of MWI */ 03434 if (p->relatedpeer) { 03435 if (p->relatedpeer->mwipvt == p) { 03436 p->relatedpeer->mwipvt = NULL; 03437 } 03438 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03439 } 03440 03441 if (dumphistory) 03442 sip_dump_history(p); 03443 03444 if (p->options) 03445 free(p->options); 03446 03447 if (p->stateid > -1) 03448 ast_extension_state_del(p->stateid, NULL); 03449 03450 /* remove any pending extension notify that could be left in 03451 * the extension update queue relating to this dialog. */ 03452 clear_extenstate_updates(p); 03453 03454 AST_SCHED_DEL(sched, p->initid); 03455 AST_SCHED_DEL(sched, p->waitid); 03456 AST_SCHED_DEL(sched, p->autokillid); 03457 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03458 03459 remove_provisional_keepalive_sched(p); 03460 if (p->provisional_keepalive_data) { 03461 ast_mutex_lock(&p->lock); 03462 p->provisional_keepalive_data = unref_provisional_keepalive(p->provisional_keepalive_data); 03463 ast_mutex_unlock(&p->lock); 03464 } 03465 03466 if (p->rtp) { 03467 ast_rtp_destroy(p->rtp); 03468 } 03469 if (p->vrtp) { 03470 ast_rtp_destroy(p->vrtp); 03471 } 03472 if (p->udptl) 03473 ast_udptl_destroy(p->udptl); 03474 if (p->refer) 03475 free(p->refer); 03476 if (p->route) { 03477 free_old_route(p->route); 03478 p->route = NULL; 03479 } 03480 if (p->registry) { 03481 if (p->registry->call == p) 03482 p->registry->call = NULL; 03483 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03484 } 03485 03486 /* Clear history */ 03487 if (p->history) { 03488 struct sip_history *hist; 03489 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03490 free(hist); 03491 p->history_entries--; 03492 } 03493 free(p->history); 03494 p->history = NULL; 03495 } 03496 03497 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03498 ast_free(req); 03499 } 03500 03501 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03502 if (cur == p) { 03503 UNLINK(cur, iflist, prev); 03504 break; 03505 } 03506 } 03507 if (!cur) { 03508 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03509 return 0; 03510 } 03511 03512 /* remove all current packets in this dialog */ 03513 while((cp = p->packets)) { 03514 p->packets = p->packets->next; 03515 AST_SCHED_DEL(sched, cp->retransid); 03516 free(cp); 03517 } 03518 if (p->chanvars) { 03519 ast_variables_destroy(p->chanvars); 03520 p->chanvars = NULL; 03521 } 03522 ast_mutex_destroy(&p->lock); 03523 03524 ast_string_field_free_memory(p); 03525 03526 free(p); 03527 return 0; 03528 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 8414 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
08415 { 08416 int res; 08417 08418 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 08419 return res; 08420 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2345 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().
02346 { 02347 struct sip_pkt *cur = NULL; 02348 02349 while (p->packets) { 02350 int method; 02351 if (cur == p->packets) { 02352 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02353 return; 02354 } 02355 cur = p->packets; 02356 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02357 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02358 } 02359 }
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 2140 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().
02141 { 02142 struct sip_pkt *pkt; 02143 int siptimer_a = DEFAULT_RETRANS; 02144 int xmitres = 0; 02145 int respid; 02146 02147 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02148 return AST_FAILURE; 02149 memcpy(pkt->data, data, len); 02150 pkt->method = sipmethod; 02151 pkt->packetlen = len; 02152 pkt->next = p->packets; 02153 pkt->owner = p; 02154 pkt->seqno = seqno; 02155 pkt->data[len] = '\0'; 02156 if (resp) { 02157 ast_set_flag(pkt, FLAG_RESPONSE); 02158 /* Parse out the response code */ 02159 if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) { 02160 pkt->response_code = respid; 02161 } 02162 } 02163 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02164 pkt->retransid = -1; 02165 if (fatal) 02166 ast_set_flag(pkt, FLAG_FATAL); 02167 if (pkt->timer_t1) 02168 siptimer_a = pkt->timer_t1 * 2; 02169 02170 if (option_debug > 3 && sipdebug) 02171 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02172 pkt->retransid = -1; 02173 pkt->next = p->packets; 02174 p->packets = pkt; 02175 if (sipmethod == SIP_INVITE) { 02176 /* Note this is a pending invite */ 02177 p->pendinginvite = seqno; 02178 } 02179 02180 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02181 02182 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02183 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02184 return AST_FAILURE; 02185 } else { 02186 /* Schedule retransmission */ 02187 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02188 return AST_SUCCESS; 02189 } 02190 }
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 2362 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().
02363 { 02364 struct sip_pkt *cur; 02365 int res = FALSE; 02366 02367 for (cur = p->packets; cur; cur = cur->next) { 02368 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02369 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02370 /* this is our baby */ 02371 if (cur->retransid > -1) { 02372 if (option_debug > 3 && sipdebug) 02373 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02374 } 02375 AST_SCHED_DEL(sched, cur->retransid); 02376 res = TRUE; 02377 break; 02378 } 02379 } 02380 if (option_debug) 02381 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"); 02382 return res; 02383 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 12200 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().
12201 { 12202 #define FORMAT3L "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 12203 #define FORMAT3H "%-15.15s %-15.15s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 12204 #define FORMAT2 "%-15.15s %-15.15s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 12205 #define FORMAT "%-15.15s %-15.15s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 12206 struct sip_pvt *cur; 12207 int numchans = 0; 12208 int usedchans = 0; 12209 char *referstatus = NULL; 12210 12211 if (argc != 3) 12212 return RESULT_SHOWUSAGE; 12213 ast_mutex_lock(&iflock); 12214 cur = iflist; 12215 if (!subscriptions) 12216 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 12217 else 12218 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 12219 for (; cur; cur = cur->next) { 12220 referstatus = ""; 12221 if (cur->refer) { /* SIP transfer in progress */ 12222 referstatus = referstatus2str(cur->refer->status); 12223 } 12224 if (cur->subscribed == NONE && !subscriptions) { 12225 char formatbuf[SIPBUFSIZE/2]; 12226 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 12227 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 12228 cur->callid, 12229 cur->ocseq, cur->icseq, 12230 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 12231 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 12232 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 12233 cur->lastmsg , 12234 referstatus 12235 ); 12236 numchans++; 12237 } 12238 if (cur->subscribed != NONE && subscriptions) { 12239 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 12240 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 12241 cur->callid, 12242 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 12243 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 12244 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 12245 subscription_type2str(cur->subscribed), 12246 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 12247 cur->expiry 12248 ); 12249 numchans++; 12250 } 12251 if (cur->owner) { /* Count SIP dialog owned by a real channel */ 12252 usedchans++; 12253 } 12254 } 12255 ast_mutex_unlock(&iflock); 12256 if (!subscriptions) 12257 ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 12258 else 12259 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 12260 ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 12261 return RESULT_SUCCESS; 12262 #undef FORMAT 12263 #undef FORMAT2 12264 #undef FORMAT3 12265 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1887 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().
01888 { 01889 int res; 01890 const struct sockaddr_in *dst = sip_real_dst(p); 01891 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01892 01893 if (res == -1) { 01894 switch (errno) { 01895 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01896 case EHOSTUNREACH: /* Host can't be reached */ 01897 case ENETDOWN: /* Inteface down */ 01898 case ENETUNREACH: /* Network failure */ 01899 case ECONNREFUSED: /* ICMP port unreachable */ 01900 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01901 } 01902 01903 } 01904 01905 if (res != len) 01906 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)); 01907 return res; 01908 }
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 6960 of file chan_sip.c.
References add_header(), 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().
06961 { 06962 struct sip_request resp; 06963 int seqno = 0; 06964 06965 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06966 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06967 return -1; 06968 } 06969 respprep(&resp, p, msg, req); 06970 /* If we are cancelling an incoming invite for some reason, add information 06971 about the reason why we are doing this in clear text */ 06972 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06973 char buf[10]; 06974 06975 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06976 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06977 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06978 } 06979 return send_response(p, &resp, reliable, seqno); 06980 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 20459 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 11756 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_FORWARD_LOOP_DETECTED, 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().
11757 { 11758 char status[30] = ""; 11759 char cbuf[256]; 11760 struct sip_peer *peer; 11761 char codec_buf[512]; 11762 struct ast_codec_pref *pref; 11763 struct ast_variable *v; 11764 struct sip_auth *auth; 11765 int x = 0, codec = 0, load_realtime; 11766 int realtimepeers; 11767 11768 realtimepeers = ast_check_realtime("sippeers"); 11769 11770 if (argc < 4) 11771 return RESULT_SHOWUSAGE; 11772 11773 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11774 peer = find_peer(argv[3], NULL, load_realtime, 0); 11775 if (s) { /* Manager */ 11776 if (peer) { 11777 const char *id = astman_get_header(m,"ActionID"); 11778 11779 astman_append(s, "Response: Success\r\n"); 11780 if (!ast_strlen_zero(id)) 11781 astman_append(s, "ActionID: %s\r\n",id); 11782 } else { 11783 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 11784 astman_send_error(s, m, cbuf); 11785 return 0; 11786 } 11787 } 11788 if (peer && type==0 ) { /* Normal listing */ 11789 ast_cli(fd,"\n\n"); 11790 ast_cli(fd, " * Name : %s\n", peer->name); 11791 if (realtimepeers) { /* Realtime is enabled */ 11792 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 11793 } 11794 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 11795 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 11796 for (auth = peer->auth; auth; auth = auth->next) { 11797 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 11798 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 11799 } 11800 ast_cli(fd, " Context : %s\n", peer->context); 11801 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 11802 ast_cli(fd, " Language : %s\n", peer->language); 11803 if (!ast_strlen_zero(peer->accountcode)) 11804 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 11805 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 11806 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 11807 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 11808 if (!ast_strlen_zero(peer->fromuser)) 11809 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 11810 if (!ast_strlen_zero(peer->fromdomain)) 11811 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 11812 ast_cli(fd, " Callgroup : "); 11813 print_group(fd, peer->callgroup, 0); 11814 ast_cli(fd, " Pickupgroup : "); 11815 print_group(fd, peer->pickupgroup, 0); 11816 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 11817 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 11818 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 11819 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 11820 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 11821 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 11822 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 11823 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 11824 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))); 11825 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11826 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 11827 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 11828 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11829 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 11830 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 11831 #endif 11832 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 11833 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 11834 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 11835 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 11836 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 11837 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 11838 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11839 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11840 ast_cli(fd, " Forward Loop : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No"); 11841 11842 /* - is enumerated */ 11843 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11844 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 11845 ast_cli(fd, " ToHost : %s\n", peer->tohost); 11846 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)); 11847 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 11848 if (!ast_strlen_zero(global_regcontext)) 11849 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 11850 ast_cli(fd, " Def. Username: %s\n", peer->username); 11851 ast_cli(fd, " SIP Options : "); 11852 if (peer->sipoptions) { 11853 int lastoption = -1; 11854 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11855 if (sip_options[x].id != lastoption) { 11856 if (peer->sipoptions & sip_options[x].id) 11857 ast_cli(fd, "%s ", sip_options[x].text); 11858 lastoption = x; 11859 } 11860 } 11861 } else 11862 ast_cli(fd, "(none)"); 11863 11864 ast_cli(fd, "\n"); 11865 ast_cli(fd, " Codecs : "); 11866 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11867 ast_cli(fd, "%s\n", codec_buf); 11868 ast_cli(fd, " Codec Order : ("); 11869 print_codec_to_cli(fd, &peer->prefs); 11870 ast_cli(fd, ")\n"); 11871 11872 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 11873 ast_cli(fd, " Status : "); 11874 peer_status(peer, status, sizeof(status)); 11875 ast_cli(fd, "%s\n",status); 11876 ast_cli(fd, " Useragent : %s\n", peer->useragent); 11877 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 11878 if (peer->chanvars) { 11879 ast_cli(fd, " Variables :\n"); 11880 for (v = peer->chanvars ; v ; v = v->next) 11881 ast_cli(fd, " %s = %s\n", v->name, v->value); 11882 } 11883 ast_cli(fd,"\n"); 11884 ASTOBJ_UNREF(peer,sip_destroy_peer); 11885 } else if (peer && type == 1) { /* manager listing */ 11886 char buf[256]; 11887 astman_append(s, "Channeltype: SIP\r\n"); 11888 astman_append(s, "ObjectName: %s\r\n", peer->name); 11889 astman_append(s, "ChanObjectType: peer\r\n"); 11890 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 11891 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 11892 astman_append(s, "Context: %s\r\n", peer->context); 11893 astman_append(s, "Language: %s\r\n", peer->language); 11894 if (!ast_strlen_zero(peer->accountcode)) 11895 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 11896 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 11897 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 11898 if (!ast_strlen_zero(peer->fromuser)) 11899 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 11900 if (!ast_strlen_zero(peer->fromdomain)) 11901 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 11902 astman_append(s, "Callgroup: "); 11903 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 11904 astman_append(s, "Pickupgroup: "); 11905 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 11906 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 11907 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 11908 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 11909 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 11910 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 11911 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 11912 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 11913 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 11914 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))); 11915 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11916 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 11917 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 11918 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 11919 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 11920 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 11921 11922 /* - is enumerated */ 11923 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11924 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 11925 astman_append(s, "ToHost: %s\r\n", peer->tohost); 11926 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)); 11927 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)); 11928 astman_append(s, "Default-Username: %s\r\n", peer->username); 11929 if (!ast_strlen_zero(global_regcontext)) 11930 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 11931 astman_append(s, "Codecs: "); 11932 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11933 astman_append(s, "%s\r\n", codec_buf); 11934 astman_append(s, "CodecOrder: "); 11935 pref = &peer->prefs; 11936 for(x = 0; x < 32 ; x++) { 11937 codec = ast_codec_pref_index(pref,x); 11938 if (!codec) 11939 break; 11940 astman_append(s, "%s", ast_getformatname(codec)); 11941 if (x < 31 && ast_codec_pref_index(pref,x+1)) 11942 astman_append(s, ","); 11943 } 11944 11945 astman_append(s, "\r\n"); 11946 astman_append(s, "Status: "); 11947 peer_status(peer, status, sizeof(status)); 11948 astman_append(s, "%s\r\n", status); 11949 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 11950 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 11951 if (peer->chanvars) { 11952 for (v = peer->chanvars ; v ; v = v->next) { 11953 astman_append(s, "ChanVariable:\n"); 11954 astman_append(s, " %s,%s\r\n", v->name, v->value); 11955 } 11956 } 11957 11958 ASTOBJ_UNREF(peer,sip_destroy_peer); 11959 11960 } else { 11961 ast_cli(fd,"Peer %s not found.\n", argv[3]); 11962 ast_cli(fd,"\n"); 11963 } 11964 11965 return RESULT_SUCCESS; 11966 }
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 11299 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().
11300 { 11301 regex_t regexbuf; 11302 int havepattern = FALSE; 11303 11304 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 11305 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 11306 11307 char name[256]; 11308 int total_peers = 0; 11309 int peers_mon_online = 0; 11310 int peers_mon_offline = 0; 11311 int peers_unmon_offline = 0; 11312 int peers_unmon_online = 0; 11313 const char *id; 11314 char idtext[256] = ""; 11315 int realtimepeers; 11316 11317 realtimepeers = ast_check_realtime("sippeers"); 11318 11319 if (s) { /* Manager - get ActionID */ 11320 id = astman_get_header(m,"ActionID"); 11321 if (!ast_strlen_zero(id)) 11322 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 11323 } 11324 11325 switch (argc) { 11326 case 5: 11327 if (!strcasecmp(argv[3], "like")) { 11328 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 11329 return RESULT_SHOWUSAGE; 11330 havepattern = TRUE; 11331 } else 11332 return RESULT_SHOWUSAGE; 11333 case 3: 11334 break; 11335 default: 11336 return RESULT_SHOWUSAGE; 11337 } 11338 11339 if (!s) /* Normal list */ 11340 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 11341 11342 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11343 char status[20] = ""; 11344 char srch[2000]; 11345 char pstatus; 11346 11347 ASTOBJ_RDLOCK(iterator); 11348 11349 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11350 ASTOBJ_UNLOCK(iterator); 11351 continue; 11352 } 11353 11354 if (!ast_strlen_zero(iterator->username) && !s) 11355 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 11356 else 11357 ast_copy_string(name, iterator->name, sizeof(name)); 11358 11359 pstatus = peer_status(iterator, status, sizeof(status)); 11360 if (pstatus == 1) 11361 peers_mon_online++; 11362 else if (pstatus == 0) 11363 peers_mon_offline++; 11364 else { 11365 if (iterator->addr.sin_port == 0) 11366 peers_unmon_offline++; 11367 else 11368 peers_unmon_online++; 11369 } 11370 11371 snprintf(srch, sizeof(srch), FORMAT, name, 11372 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 11373 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 11374 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 11375 iterator->ha ? " A " : " ", /* permit/deny */ 11376 ntohs(iterator->addr.sin_port), status, 11377 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 11378 11379 if (!s) {/* Normal CLI list */ 11380 ast_cli(fd, FORMAT, name, 11381 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 11382 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 11383 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 11384 iterator->ha ? " A " : " ", /* permit/deny */ 11385 11386 ntohs(iterator->addr.sin_port), status, 11387 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 11388 } else { /* Manager format */ 11389 /* The names here need to be the same as other channels */ 11390 astman_append(s, 11391 "Event: PeerEntry\r\n%s" 11392 "Channeltype: SIP\r\n" 11393 "ObjectName: %s\r\n" 11394 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 11395 "IPaddress: %s\r\n" 11396 "IPport: %d\r\n" 11397 "Dynamic: %s\r\n" 11398 "Natsupport: %s\r\n" 11399 "VideoSupport: %s\r\n" 11400 "ACL: %s\r\n" 11401 "Status: %s\r\n" 11402 "RealtimeDevice: %s\r\n\r\n", 11403 idtext, 11404 iterator->name, 11405 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 11406 ntohs(iterator->addr.sin_port), 11407 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 11408 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 11409 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 11410 iterator->ha ? "yes" : "no", /* permit/deny */ 11411 status, 11412 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 11413 } 11414 11415 ASTOBJ_UNLOCK(iterator); 11416 11417 total_peers++; 11418 } while(0) ); 11419 11420 if (!s) 11421 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 11422 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 11423 11424 if (havepattern) 11425 regfree(®exbuf); 11426 11427 if (total) 11428 *total = total_peers; 11429 11430 11431 return RESULT_SUCCESS; 11432 #undef FORMAT 11433 #undef FORMAT2 11434 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 16575 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.
16576 { 16577 struct ast_rtp_quality qos; 16578 struct sip_pvt *p = chan->tech_pvt; 16579 char *all = "", *parse = ast_strdupa(preparse); 16580 AST_DECLARE_APP_ARGS(args, 16581 AST_APP_ARG(param); 16582 AST_APP_ARG(type); 16583 AST_APP_ARG(field); 16584 ); 16585 AST_STANDARD_APP_ARGS(args, parse); 16586 16587 /* Sanity check */ 16588 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 16589 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 16590 return 0; 16591 } 16592 16593 if (strcasecmp(args.param, "rtpqos")) 16594 return 0; 16595 16596 /* Default arguments of audio,all */ 16597 if (ast_strlen_zero(args.type)) 16598 args.type = "audio"; 16599 if (ast_strlen_zero(args.field)) 16600 args.field = "all"; 16601 16602 memset(buf, 0, buflen); 16603 memset(&qos, 0, sizeof(qos)); 16604 16605 if (p == NULL) { 16606 return -1; 16607 } 16608 16609 if (strcasecmp(args.type, "AUDIO") == 0) { 16610 all = ast_rtp_get_quality(p->rtp, &qos); 16611 } else if (strcasecmp(args.type, "VIDEO") == 0) { 16612 all = ast_rtp_get_quality(p->vrtp, &qos); 16613 } 16614 16615 if (strcasecmp(args.field, "local_ssrc") == 0) 16616 snprintf(buf, buflen, "%u", qos.local_ssrc); 16617 else if (strcasecmp(args.field, "local_lostpackets") == 0) 16618 snprintf(buf, buflen, "%u", qos.local_lostpackets); 16619 else if (strcasecmp(args.field, "local_jitter") == 0) 16620 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 16621 else if (strcasecmp(args.field, "local_count") == 0) 16622 snprintf(buf, buflen, "%u", qos.local_count); 16623 else if (strcasecmp(args.field, "remote_ssrc") == 0) 16624 snprintf(buf, buflen, "%u", qos.remote_ssrc); 16625 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 16626 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 16627 else if (strcasecmp(args.field, "remote_jitter") == 0) 16628 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 16629 else if (strcasecmp(args.field, "remote_count") == 0) 16630 snprintf(buf, buflen, "%u", qos.remote_count); 16631 else if (strcasecmp(args.field, "rtt") == 0) 16632 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 16633 else if (strcasecmp(args.field, "all") == 0) 16634 ast_copy_string(buf, all, buflen); 16635 else { 16636 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 16637 return -1; 16638 } 16639 return 0; 16640 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2396 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02397 { 02398 if (!req->lines) { 02399 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02400 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02401 req->len += strlen(req->data + req->len); 02402 } 02403 }
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 7170 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().
07173 { 07174 int rtp_code; 07175 struct ast_format_list fmt; 07176 07177 07178 if (debug) 07179 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 07180 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 07181 return; 07182 07183 if (p->rtp) { 07184 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 07185 fmt = ast_codec_pref_getsize(pref, codec); 07186 } 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 */ 07187 return; 07188 ast_build_string(m_buf, m_size, " %d", rtp_code); 07189 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 07190 ast_rtp_lookup_mime_subtype(1, codec, 07191 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 07192 sample_rate); 07193 if (codec == AST_FORMAT_G729A) { 07194 /* Indicate that we don't support VAD (G.729 annex B) */ 07195 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 07196 } else if (codec == AST_FORMAT_G723_1) { 07197 /* Indicate that we don't support VAD (G.723.1 annex A) */ 07198 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 07199 } else if (codec == AST_FORMAT_ILBC) { 07200 /* Add information about us using only 20/30 ms packetization */ 07201 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 07202 } 07203 07204 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 07205 *min_packet_size = fmt.cur_ms; 07206 07207 /* Our first codec packetization processed cannot be less than zero */ 07208 if ((*min_packet_size) == 0 && fmt.cur_ms) 07209 *min_packet_size = fmt.cur_ms; 07210 }
static int add_content | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 6491 of file chan_sip.c.
References ast_log(), sip_request::content, sip_request::data, sip_request::len, and sip_request::lines.
Referenced by add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify().
06492 { 06493 if (req->lines) { 06494 ast_log(LOG_WARNING, "Can't add more content when the content has been finalized\n"); 06495 return -1; 06496 } 06497 06498 if (req->len + strlen(req->content) + strlen(line) >= sizeof(req->data) - 4) { 06499 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 06500 return -1; 06501 } 06502 06503 snprintf(req->content + strlen(req->content), sizeof(req->content) - strlen(req->content), "%s", line); 06504 return 0; 06505 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 7140 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_digit().
07141 { 07142 char tmp[256]; 07143 07144 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 07145 add_header(req, "Content-Type", "application/dtmf-relay"); 07146 add_content(req, tmp); 07147 return 0; 07148 }
static int add_extensionstate_update | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 9601 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, AST_PTHREADT_STOP, sip_extenstate_update::list, and update().
Referenced by handle_request_subscribe().
09602 { 09603 struct sip_extenstate_update *update; 09604 size_t exten_len = strlen(exten); 09605 size_t context_len = strlen(context); 09606 09607 if (!(update = ast_calloc(1, sizeof(*update) + exten_len + context_len + 2))) { 09608 return -1; 09609 } 09610 09611 strcpy(update->exten, exten); 09612 09613 update->context = (char *) (update->exten + exten_len + 1); 09614 strcpy(update->context, context); 09615 09616 update->state = state; 09617 update->pvt = data; 09618 09619 AST_LIST_LOCK(&sip_extenstate_updates); 09620 AST_LIST_INSERT_TAIL(&sip_extenstate_updates, update, list); 09621 AST_LIST_UNLOCK(&sip_extenstate_updates); 09622 09623 /* Tell the do_monitor thread it has to do stuff! That thread is so lazy :( */ 09624 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 09625 pthread_kill(monitor_thread, SIGURG); 09626 } 09627 09628 return 0; 09629 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 6437 of file chan_sip.c.
References ast_log(), sip_request::content, sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and SIP_MAX_HEADERS.
06438 { 06439 int maxlen = sizeof(req->data) - 4 - req->len - strlen(req->content); /* 4 bytes are for two \r\n ? */ 06440 06441 if (req->headers == SIP_MAX_HEADERS) { 06442 ast_log(LOG_WARNING, "Out of SIP header space\n"); 06443 return -1; 06444 } 06445 06446 if (req->lines) { 06447 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 06448 return -1; 06449 } 06450 06451 if (maxlen <= 0) { 06452 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 06453 return -1; 06454 } 06455 06456 req->header[req->headers] = req->data + req->len; 06457 06458 if (compactheaders) 06459 var = find_alias(var, var); 06460 06461 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 06462 req->len += strlen(req->header[req->headers]); 06463 req->headers++; 06464 06465 return 0; 06466 }
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 7249 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().
07252 { 07253 int rtp_code; 07254 07255 if (debug) 07256 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 07257 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 07258 return; 07259 07260 ast_build_string(m_buf, m_size, " %d", rtp_code); 07261 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 07262 ast_rtp_lookup_mime_subtype(0, format, 0), 07263 sample_rate); 07264 if (format == AST_RTP_DTMF) 07265 /* Indicate we support DTMF and FLASH... */ 07266 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 07267 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 18407 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().
18408 { 18409 char authcopy[256]; 18410 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 18411 struct sip_auth *a, *b, *auth; 18412 18413 if (ast_strlen_zero(configuration)) 18414 return authlist; 18415 18416 if (option_debug) 18417 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 18418 18419 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 18420 18421 username = authcopy; 18422 /* split user[:secret] and realm */ 18423 realm = strrchr(username, '@'); 18424 if (realm) 18425 *realm++ = '\0'; 18426 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 18427 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 18428 return authlist; 18429 } 18430 18431 /* parse username at ':' for secret, or '#" for md5secret */ 18432 if ((secret = strchr(username, ':'))) { 18433 *secret++ = '\0'; 18434 } else if ((md5secret = strchr(username, '#'))) { 18435 *md5secret++ = '\0'; 18436 } 18437 18438 if (!(auth = ast_calloc(1, sizeof(*auth)))) 18439 return authlist; 18440 18441 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 18442 ast_copy_string(auth->username, username, sizeof(auth->username)); 18443 if (secret) 18444 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 18445 if (md5secret) 18446 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 18447 18448 /* find the end of the list */ 18449 for (b = NULL, a = authlist; a ; b = a, a = a->next) 18450 ; 18451 if (b) 18452 b->next = auth; /* Add structure add end of list */ 18453 else 18454 authlist = auth; 18455 18456 if (option_verbose > 2) 18457 ast_verbose("Added authentication for realm %s\n", realm); 18458 18459 return authlist; 18460 18461 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 6606 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by initreqprep(), and reqprep().
06607 { 06608 char r[SIPBUFSIZE*2], *p; 06609 int n, rem = sizeof(r); 06610 06611 if (!route) 06612 return; 06613 06614 p = r; 06615 for (;route ; route = route->next) { 06616 n = strlen(route->hop); 06617 if (rem < n+3) /* we need room for ",<route>" */ 06618 break; 06619 if (p != r) { /* add a separator after fist route */ 06620 *p++ = ','; 06621 --rem; 06622 } 06623 *p++ = '<'; 06624 ast_copy_string(p, route->hop, rem); /* cannot fail */ 06625 p += n; 06626 *p++ = '>'; 06627 rem -= (n+2); 06628 } 06629 *p = '\0'; 06630 add_header(req, "Route", r); 06631 }
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 7277 of file chan_sip.c.
References add_codec_to_sdp(), add_content(), add_header(), 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, LOG_DEBUG, LOG_NOTICE, 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::redircodecs, 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.
07278 { 07279 int alreadysent = 0; 07280 int doing_directmedia = FALSE; 07281 07282 struct sockaddr_in sin; 07283 struct sockaddr_in vsin; 07284 struct sockaddr_in dest; 07285 struct sockaddr_in vdest = { 0, }; 07286 07287 /* SDP fields */ 07288 char *version = "v=0\r\n"; /* Protocol version */ 07289 char *subject = "s=session\r\n"; /* Subject of the session */ 07290 char owner[256]; /* Session owner/creator */ 07291 char connection[256]; /* Connection data */ 07292 char *stime = "t=0 0\r\n"; /* Time the session is active */ 07293 char bandwidth[256] = ""; /* Max bitrate */ 07294 char *hold; 07295 char m_audio[256]; /* Media declaration line for audio */ 07296 char m_video[256]; /* Media declaration line for video */ 07297 char m_modem[256]; /* Media declaration line for t38 */ 07298 char a_audio[1024]; /* Attributes for audio */ 07299 char a_video[1024]; /* Attributes for video */ 07300 char a_modem[1024]; /* Attributes for t38 */ 07301 char *m_audio_next = m_audio; 07302 char *m_video_next = m_video; 07303 char *m_modem_next = m_modem; 07304 size_t m_audio_left = sizeof(m_audio); 07305 size_t m_video_left = sizeof(m_video); 07306 size_t m_modem_left = sizeof(m_modem); 07307 char *a_audio_next = a_audio; 07308 char *a_video_next = a_video; 07309 char *a_modem_next = a_modem; 07310 size_t a_audio_left = sizeof(a_audio); 07311 size_t a_video_left = sizeof(a_video); 07312 size_t a_modem_left = sizeof(a_modem); 07313 char dummy_answer[256]; 07314 07315 int x; 07316 int capability = 0; 07317 int needvideo = FALSE; 07318 int debug = sip_debug_test_pvt(p); 07319 int min_audio_packet_size = 0; 07320 int min_video_packet_size = 0; 07321 07322 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 07323 m_modem[0] = '\0'; 07324 07325 if (!p->rtp) { 07326 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 07327 return AST_FAILURE; 07328 } 07329 07330 /* Set RTP Session ID and version */ 07331 if (!p->sessionid) { 07332 p->sessionid = getpid(); 07333 p->sessionversion = p->sessionid; 07334 } else 07335 p->sessionversion++; 07336 07337 /* Get our addresses */ 07338 ast_rtp_get_us(p->rtp, &sin); 07339 if (p->vrtp) 07340 ast_rtp_get_us(p->vrtp, &vsin); 07341 07342 /* Is this a re-invite to move the media out, then use the original offer from caller */ 07343 if (p->redirip.sin_addr.s_addr) { 07344 dest.sin_port = p->redirip.sin_port; 07345 dest.sin_addr = p->redirip.sin_addr; 07346 doing_directmedia = p->redircodecs ? TRUE : FALSE; 07347 } else { 07348 dest.sin_addr = p->ourip; 07349 dest.sin_port = sin.sin_port; 07350 } 07351 07352 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 07353 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 07354 07355 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 07356 hold = "a=recvonly\r\n"; 07357 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 07358 hold = "a=inactive\r\n"; 07359 else 07360 hold = "a=sendrecv\r\n"; 07361 07362 if (add_audio) { 07363 char codecbuf[SIPBUFSIZE]; 07364 capability = p->jointcapability; 07365 07366 if (option_debug > 1) { 07367 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"); 07368 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 07369 } 07370 07371 if (doing_directmedia) { 07372 capability &= p->redircodecs; 07373 if (option_debug > 1) { 07374 ast_log(LOG_NOTICE, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability)); 07375 } 07376 } 07377 07378 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 07379 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 07380 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 07381 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 07382 } 07383 #endif 07384 07385 /* Check if we need video in this call */ 07386 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 07387 if (p->vrtp) { 07388 needvideo = TRUE; 07389 if (option_debug > 1) 07390 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 07391 } else if (option_debug > 1) 07392 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 07393 } 07394 07395 07396 /* Ok, we need video. Let's add what we need for video and set codecs. 07397 Video is handled differently than audio since we can not transcode. */ 07398 if (needvideo) { 07399 /* Determine video destination */ 07400 if (p->vredirip.sin_addr.s_addr) { 07401 vdest.sin_addr = p->vredirip.sin_addr; 07402 vdest.sin_port = p->vredirip.sin_port; 07403 } else { 07404 vdest.sin_addr = p->ourip; 07405 vdest.sin_port = vsin.sin_port; 07406 } 07407 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vsin.sin_port)); 07408 07409 /* Build max bitrate string */ 07410 if (p->maxcallbitrate) 07411 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 07412 if (debug) 07413 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 07414 } 07415 07416 if (debug) 07417 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 07418 07419 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 07420 07421 /* Now, start adding audio codecs. These are added in this order: 07422 - First what was requested by the calling channel 07423 - Then preferences in order from sip.conf device config for this peer/user 07424 - Then other codecs in capabilities, including video 07425 */ 07426 07427 /* Prefer the audio codec we were requested to use, first, no matter what 07428 Note that p->prefcodec can include video codecs, so mask them out 07429 */ 07430 if (capability & p->prefcodec) { 07431 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 07432 07433 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07434 &m_audio_next, &m_audio_left, 07435 &a_audio_next, &a_audio_left, 07436 debug, &min_audio_packet_size); 07437 alreadysent |= codec; 07438 } 07439 07440 /* Start by sending our preferred audio codecs */ 07441 for (x = 0; x < 32; x++) { 07442 int codec; 07443 07444 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 07445 break; 07446 07447 if (!(capability & codec)) 07448 continue; 07449 07450 if (alreadysent & codec) 07451 continue; 07452 07453 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 07454 &m_audio_next, &m_audio_left, 07455 &a_audio_next, &a_audio_left, 07456 debug, &min_audio_packet_size); 07457 alreadysent |= codec; 07458 } 07459 07460 /* Now send any other common audio and video codecs, and non-codec formats: */ 07461 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 07462 if (!(capability & x)) /* Codec not requested */ 07463 continue; 07464 07465 if (alreadysent & x) /* Already added to SDP */ 07466 continue; 07467 07468 if (x <= AST_FORMAT_MAX_AUDIO) 07469 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 07470 &m_audio_next, &m_audio_left, 07471 &a_audio_next, &a_audio_left, 07472 debug, &min_audio_packet_size); 07473 else 07474 add_codec_to_sdp(p, x, 90000, 07475 &m_video_next, &m_video_left, 07476 &a_video_next, &a_video_left, 07477 debug, &min_video_packet_size); 07478 } 07479 07480 /* Now add DTMF RFC2833 telephony-event as a codec */ 07481 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 07482 if (!(p->jointnoncodeccapability & x)) 07483 continue; 07484 07485 add_noncodec_to_sdp(p, x, 8000, 07486 &m_audio_next, &m_audio_left, 07487 &a_audio_next, &a_audio_left, 07488 debug); 07489 } 07490 07491 if (option_debug > 2) 07492 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 07493 07494 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 07495 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 07496 07497 if (min_audio_packet_size) 07498 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 07499 07500 if (min_video_packet_size) 07501 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 07502 07503 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 07504 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 07505 07506 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 07507 if (needvideo) 07508 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 07509 } 07510 07511 if (add_t38 && p->udptl) { 07512 struct sockaddr_in udptlsin; 07513 struct sockaddr_in udptldest = { 0, }; 07514 07515 ast_udptl_get_us(p->udptl, &udptlsin); 07516 07517 if (p->udptlredirip.sin_addr.s_addr) { 07518 udptldest.sin_port = p->udptlredirip.sin_port; 07519 udptldest.sin_addr = p->udptlredirip.sin_addr; 07520 } else { 07521 udptldest.sin_addr = p->ourip; 07522 udptldest.sin_port = udptlsin.sin_port; 07523 } 07524 07525 if (debug) { 07526 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 07527 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 07528 p->t38.capability, 07529 p->t38.peercapability, 07530 p->t38.jointcapability); 07531 } 07532 07533 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 07534 07535 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 07536 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 07537 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 07538 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 07539 if ((x = t38_get_rate(p->t38.jointcapability))) 07540 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 07541 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 07542 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 07543 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 07544 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 07545 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 07546 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 07547 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 07548 x = ast_udptl_get_local_max_datagram(p->udptl); 07549 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 07550 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 07551 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 07552 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 07553 } 07554 07555 add_header(resp, "Content-Type", "application/sdp"); 07556 add_content(resp, version); 07557 add_content(resp, owner); 07558 add_content(resp, subject); 07559 add_content(resp, connection); 07560 if (needvideo) /* only if video response is appropriate */ 07561 add_content(resp, bandwidth); 07562 add_content(resp, stime); 07563 if (add_audio) { 07564 add_content(resp, m_audio); 07565 add_content(resp, a_audio); 07566 add_content(resp, hold); 07567 } else if (p->offered_media[SDP_AUDIO].offered) { 07568 snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text); 07569 add_content(resp, dummy_answer); 07570 } 07571 if (needvideo) { /* only if video response is appropriate */ 07572 add_content(resp, m_video); 07573 add_content(resp, a_video); 07574 add_content(resp, hold); /* Repeat hold for the video stream */ 07575 } else if (p->offered_media[SDP_VIDEO].offered) { 07576 snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text); 07577 add_content(resp, dummy_answer); 07578 } 07579 if (add_t38) { 07580 add_content(resp, m_modem); 07581 add_content(resp, a_modem); 07582 } else if (p->offered_media[SDP_IMAGE].offered) { 07583 add_content(resp, "m=image 0 udptl t38\r\n"); 07584 } 07585 07586 /* Update lastrtprx when we send our SDP */ 07587 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 07588 07589 if (option_debug > 2) { 07590 char buf[SIPBUFSIZE]; 07591 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 07592 } 07593 07594 return AST_SUCCESS; 07595 }
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 18343 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.
18344 { 18345 struct domain *d; 18346 18347 if (ast_strlen_zero(domain)) { 18348 ast_log(LOG_WARNING, "Zero length domain.\n"); 18349 return 1; 18350 } 18351 18352 if (!(d = ast_calloc(1, sizeof(*d)))) 18353 return 0; 18354 18355 ast_copy_string(d->domain, domain, sizeof(d->domain)); 18356 18357 if (!ast_strlen_zero(context)) 18358 ast_copy_string(d->context, context, sizeof(d->context)); 18359 18360 d->mode = mode; 18361 18362 AST_LIST_LOCK(&domain_list); 18363 AST_LIST_INSERT_TAIL(&domain_list, d, list); 18364 AST_LIST_UNLOCK(&domain_list); 18365 18366 if (sipdebug) 18367 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 18368 18369 return 1; 18370 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 7130 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_message_with_text().
07131 { 07132 /* XXX Convert \n's to \r\n's XXX */ 07133 add_header(req, "Content-Type", "text/plain"); 07134 add_content(req, text); 07135 return 0; 07136 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 7152 of file chan_sip.c.
References add_content(), and add_header().
Referenced by transmit_info_with_vidupdate().
07153 { 07154 const char *xml_is_a_huge_waste_of_space = 07155 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 07156 " <media_control>\r\n" 07157 " <vc_primitive>\r\n" 07158 " <to_encoder>\r\n" 07159 " <picture_fast_update>\r\n" 07160 " </picture_fast_update>\r\n" 07161 " </to_encoder>\r\n" 07162 " </vc_primitive>\r\n" 07163 " </media_control>\r\n"; 07164 add_header(req, "Content-Type", "application/media_control+xml"); 07165 add_content(req, xml_is_a_huge_waste_of_space); 07166 return 0; 07167 }
static int addr_is_multicast | ( | struct in_addr * | addr | ) | [static] |
Check if an ip is an multicast IP. addr the address to check.
This function checks if an address is in the 224.0.0.0/4 network block.
Definition at line 5132 of file chan_sip.c.
Referenced by process_via().
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 7067 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().
07068 { 07069 char tmpdat[256]; 07070 struct tm tm; 07071 time_t t = time(NULL); 07072 07073 gmtime_r(&t, &tm); 07074 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 07075 add_header(req, "Date", tmpdat); 07076 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1995 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01996 { 01997 va_list ap; 01998 01999 if (!p) 02000 return; 02001 02002 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 02003 && !recordhistory && !dumphistory) { 02004 return; 02005 } 02006 02007 va_start(ap, fmt); 02008 append_history_va(p, fmt, ap); 02009 va_end(ap); 02010 02011 return; 02012 }
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 1968 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().
01969 { 01970 char buf[80], *c = buf; /* max history length */ 01971 struct sip_history *hist; 01972 int l; 01973 01974 vsnprintf(buf, sizeof(buf), fmt, ap); 01975 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01976 l = strlen(buf) + 1; 01977 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01978 return; 01979 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01980 free(hist); 01981 return; 01982 } 01983 memcpy(hist->event, buf, l); 01984 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01985 struct sip_history *oldest; 01986 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01987 p->history_entries--; 01988 free(oldest); 01989 } 01990 AST_LIST_INSERT_TAIL(p->history, hist, list); 01991 p->history_entries++; 01992 }
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 14746 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().
14747 { 14748 if (chan && chan->_state == AST_STATE_UP) { 14749 if (ast_test_flag(chan, AST_FLAG_MOH)) 14750 ast_moh_stop(chan); 14751 else if (chan->generatordata) 14752 ast_deactivate_generator(chan); 14753 } 14754 }
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 1928 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, 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().
01929 { 01930 struct sockaddr_in theirs, ours; 01931 01932 /* Get our local information */ 01933 ast_ouraddrfor(them, us); 01934 theirs.sin_addr = *them; 01935 ours.sin_addr = *us; 01936 01937 if (localaddr && externip.sin_addr.s_addr && 01938 (ast_apply_ha(localaddr, &theirs)) && 01939 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01940 if (externexpire && time(NULL) >= externexpire) { 01941 struct ast_hostent ahp; 01942 struct hostent *hp; 01943 01944 externexpire = time(NULL) + externrefresh; 01945 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01946 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01947 } else 01948 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01949 } 01950 *us = externip.sin_addr; 01951 if (option_debug) { 01952 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01953 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01954 } 01955 } else if (bindaddr.sin_addr.s_addr) 01956 *us = bindaddr.sin_addr; 01957 return AST_SUCCESS; 01958 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 14758 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.
14759 { 14760 int res = 0; 14761 struct ast_channel *peera = NULL, 14762 *peerb = NULL, 14763 *peerc = NULL, 14764 *peerd = NULL; 14765 14766 14767 /* We will try to connect the transferee with the target and hangup 14768 all channels to the transferer */ 14769 if (option_debug > 3) { 14770 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 14771 if (transferer->chan1) 14772 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 14773 else 14774 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 14775 if (target->chan1) 14776 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 14777 else 14778 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 14779 if (transferer->chan2) 14780 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 14781 else 14782 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 14783 if (target->chan2) 14784 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)"); 14785 else 14786 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 14787 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 14788 } 14789 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 14790 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 14791 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 14792 peerc = transferer->chan2; /* Asterisk to Transferee */ 14793 peerd = target->chan2; /* Asterisk to Target */ 14794 if (option_debug > 2) 14795 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 14796 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 14797 peera = target->chan1; /* Transferer to PBX -> target channel */ 14798 peerb = transferer->chan1; /* Transferer to IVR*/ 14799 peerc = target->chan2; /* Asterisk to Target */ 14800 peerd = transferer->chan2; /* Nothing */ 14801 if (option_debug > 2) 14802 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 14803 } 14804 14805 if (peera && peerb && peerc && (peerb != peerc)) { 14806 ast_quiet_chan(peera); /* Stop generators */ 14807 ast_quiet_chan(peerb); 14808 ast_quiet_chan(peerc); 14809 if (peerd) 14810 ast_quiet_chan(peerd); 14811 14812 if (option_debug > 3) 14813 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 14814 if (ast_channel_masquerade(peerb, peerc)) { 14815 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 14816 res = -1; 14817 } else 14818 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 14819 return res; 14820 } else { 14821 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 14822 if (transferer->chan1) 14823 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 14824 if (target->chan1) 14825 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 14826 return -2; 14827 } 14828 return 0; 14829 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 3255 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(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, ast_channel::name, sip_pvt::owner, and sip_scheddestroy().
03256 { 03257 struct sip_pvt *p = (struct sip_pvt *)nothing; 03258 03259 ast_mutex_lock(&p->lock); 03260 p->initid = -1; 03261 if (p->owner) { 03262 /* XXX fails on possible deadlock */ 03263 if (!ast_channel_trylock(p->owner)) { 03264 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03265 append_history(p, "Cong", "Auto-congesting (timer)"); 03266 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03267 ast_channel_unlock(p->owner); 03268 } 03269 03270 /* Give the channel a chance to act before we proceed with destruction */ 03271 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03272 } 03273 ast_mutex_unlock(&p->lock); 03274 return 0; 03275 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4843 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().
04844 { 04845 char buf[33]; 04846 04847 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04848 04849 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04850 04851 }
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 4854 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().
04855 { 04856 char buf[33]; 04857 04858 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04859 04860 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04861 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7772 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ast_uri_encode(), sip_pvt::exten, ourport, SIPBUFSIZE, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
07773 { 07774 char tmp[SIPBUFSIZE]; 07775 char *user; 07776 07777 user = ast_uri_encode(p->exten, tmp, sizeof(tmp), 1); 07778 07779 /* Construct Contact: header */ 07780 if (ourport != STANDARD_SIP_PORT) 07781 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip), ourport); 07782 else 07783 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user, ast_strlen_zero(user) ? "" : "@", ast_inet_ntoa(p->ourip)); 07784 }
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 18675 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::useragent, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
18676 { 18677 struct sip_peer *peer = NULL; 18678 struct ast_ha *oldha = NULL; 18679 int obproxyfound=0; 18680 int found=0; 18681 int firstpass=1; 18682 int format=0; /* Ama flags */ 18683 time_t regseconds = 0; 18684 char *varname = NULL, *varval = NULL; 18685 struct ast_variable *tmpvar = NULL; 18686 struct ast_flags peerflags[2] = {{(0)}}; 18687 struct ast_flags mask[2] = {{(0)}}; 18688 int alt_fullcontact = alt ? 1 : 0; 18689 char fullcontact[sizeof(peer->fullcontact)] = ""; 18690 18691 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 18692 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 18693 /* We also use a case-sensitive comparison (unlike find_peer) so 18694 that case changes made to the peer name will be properly handled 18695 during reload 18696 */ 18697 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 18698 18699 if (peer) { 18700 /* Already in the list, remove it and it will be added back (or FREE'd) */ 18701 found = 1; 18702 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 18703 firstpass = 0; 18704 } else { 18705 if (!(peer = ast_calloc(1, sizeof(*peer)))) 18706 return NULL; 18707 18708 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 18709 rpeerobjs++; 18710 else 18711 speerobjs++; 18712 ASTOBJ_INIT(peer); 18713 } 18714 /* Note that our peer HAS had its reference count incrased */ 18715 if (firstpass) { 18716 peer->lastmsgssent = -1; 18717 oldha = peer->ha; 18718 peer->ha = NULL; 18719 set_peer_defaults(peer); /* Set peer defaults */ 18720 } 18721 if (!found && name) 18722 ast_copy_string(peer->name, name, sizeof(peer->name)); 18723 18724 /* If we have channel variables, remove them (reload) */ 18725 if (peer->chanvars) { 18726 ast_variables_destroy(peer->chanvars); 18727 peer->chanvars = NULL; 18728 /* XXX should unregister ? */ 18729 } 18730 18731 if (found) 18732 peer->portinuri = 0; 18733 18734 /* If we have realm authentication information, remove them (reload) */ 18735 clear_realm_authentication(peer->auth); 18736 peer->auth = NULL; 18737 18738 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 18739 if (!devstate_only) { 18740 if (handle_common_options(&peerflags[0], &mask[0], v)) { 18741 continue; 18742 } 18743 if (realtime && !strcasecmp(v->name, "regseconds")) { 18744 ast_get_time_t(v->value, ®seconds, 0, NULL); 18745 } else if (realtime && !strcasecmp(v->name, "name")) { 18746 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 18747 } else if (realtime && !strcasecmp(v->name, "useragent")) { 18748 ast_copy_string(peer->useragent, v->value, sizeof(peer->useragent)); 18749 } else if (realtime && !strcasecmp(v->name, "fullcontact")) { 18750 if (alt_fullcontact && !alt) { 18751 /* Reset, because the alternate also has a fullcontact and we 18752 * do NOT want the field value to be doubled. It might be 18753 * tempting to skip this, but the first table might not have 18754 * fullcontact and since we're here, we know that the alternate 18755 * absolutely does. */ 18756 alt_fullcontact = 0; 18757 fullcontact[0] = '\0'; 18758 } 18759 /* Reconstruct field, because realtime separates our value at the ';' */ 18760 if (!ast_strlen_zero(fullcontact)) { 18761 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 18762 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 18763 } else { 18764 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 18765 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 18766 } 18767 } else if (!strcasecmp(v->name, "secret")) { 18768 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 18769 } else if (!strcasecmp(v->name, "md5secret")) { 18770 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 18771 } else if (!strcasecmp(v->name, "auth")) { 18772 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 18773 } else if (!strcasecmp(v->name, "callerid")) { 18774 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 18775 } else if (!strcasecmp(v->name, "fullname")) { 18776 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 18777 } else if (!strcasecmp(v->name, "trunkname")) { 18778 /* This is actually for a trunk, so we don't want to override callerid */ 18779 ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name)); 18780 } else if (!strcasecmp(v->name, "cid_number")) { 18781 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 18782 } else if (!strcasecmp(v->name, "context")) { 18783 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 18784 } else if (!strcasecmp(v->name, "subscribecontext")) { 18785 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 18786 } else if (!strcasecmp(v->name, "fromdomain")) { 18787 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 18788 } else if (!strcasecmp(v->name, "usereqphone")) { 18789 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 18790 } else if (!strcasecmp(v->name, "fromuser")) { 18791 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 18792 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 18793 if (!strcasecmp(v->value, "dynamic")) { 18794 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 18795 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 18796 } else { 18797 /* They'll register with us */ 18798 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 18799 /* Initialize stuff if this is a new peer, or if it used to be 18800 * non-dynamic before the reload. */ 18801 memset(&peer->addr.sin_addr, 0, 4); 18802 if (peer->addr.sin_port) { 18803 /* If we've already got a port, make it the default rather than absolute */ 18804 peer->defaddr.sin_port = peer->addr.sin_port; 18805 peer->addr.sin_port = 0; 18806 } 18807 } 18808 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18809 } 18810 } else { 18811 /* Non-dynamic. Make sure we become that way if we're not */ 18812 if (!AST_SCHED_DEL(sched, peer->expire)) { 18813 struct sip_peer *peer_ptr = peer; 18814 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18815 } 18816 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18817 if (!strcasecmp(v->name, "outboundproxy")) { 18818 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 18819 ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name); 18820 ASTOBJ_UNREF(peer, sip_destroy_peer); 18821 return NULL; 18822 } 18823 } 18824 if (!strcasecmp(v->name, "outboundproxy")) 18825 obproxyfound=1; 18826 else { 18827 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 18828 if (!peer->addr.sin_port) 18829 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18830 } 18831 if (global_dynamic_exclude_static) { 18832 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 18833 } 18834 } 18835 } else if (!strcasecmp(v->name, "defaultip")) { 18836 if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) { 18837 ASTOBJ_UNREF(peer, sip_destroy_peer); 18838 return NULL; 18839 } 18840 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 18841 if (!ast_strlen_zero(v->value)) { 18842 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 18843 } 18844 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18845 if (!ast_strlen_zero(v->value)) { 18846 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 18847 } 18848 } else if (!strcasecmp(v->name, "port")) { 18849 peer->portinuri = 1; 18850 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 18851 peer->defaddr.sin_port = htons(atoi(v->value)); 18852 else 18853 peer->addr.sin_port = htons(atoi(v->value)); 18854 } else if (!strcasecmp(v->name, "callingpres")) { 18855 peer->callingpres = ast_parse_caller_presentation(v->value); 18856 if (peer->callingpres == -1) 18857 peer->callingpres = atoi(v->value); 18858 } else if (!strcasecmp(v->name, "username")) { 18859 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 18860 } else if (!strcasecmp(v->name, "language")) { 18861 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 18862 } else if (!strcasecmp(v->name, "regexten")) { 18863 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 18864 } else if (!strcasecmp(v->name, "amaflags")) { 18865 format = ast_cdr_amaflags2int(v->value); 18866 if (format < 0) { 18867 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 18868 } else { 18869 peer->amaflags = format; 18870 } 18871 } else if (!strcasecmp(v->name, "accountcode")) { 18872 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 18873 } else if (!strcasecmp(v->name, "mohinterpret") 18874 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18875 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 18876 } else if (!strcasecmp(v->name, "mohsuggest")) { 18877 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 18878 } else if (!strcasecmp(v->name, "mailbox")) { 18879 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 18880 } else if (!strcasecmp(v->name, "hasvoicemail")) { 18881 /* People expect that if 'hasvoicemail' is set, that the mailbox will 18882 * be also set, even if not explicitly specified. */ 18883 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 18884 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 18885 } 18886 } else if (!strcasecmp(v->name, "subscribemwi")) { 18887 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 18888 } else if (!strcasecmp(v->name, "vmexten")) { 18889 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 18890 } else if (!strcasecmp(v->name, "callgroup")) { 18891 peer->callgroup = ast_get_group(v->value); 18892 } else if (!strcasecmp(v->name, "allowtransfer")) { 18893 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18894 } else if (!strcasecmp(v->name, "pickupgroup")) { 18895 peer->pickupgroup = ast_get_group(v->value); 18896 } else if (!strcasecmp(v->name, "allow")) { 18897 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 18898 } else if (!strcasecmp(v->name, "disallow")) { 18899 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 18900 } else if (!strcasecmp(v->name, "autoframing")) { 18901 peer->autoframing = ast_true(v->value); 18902 } else if (!strcasecmp(v->name, "rtptimeout")) { 18903 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 18904 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18905 peer->rtptimeout = global_rtptimeout; 18906 } 18907 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18908 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 18909 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18910 peer->rtpholdtimeout = global_rtpholdtimeout; 18911 } 18912 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18913 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 18914 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18915 peer->rtpkeepalive = global_rtpkeepalive; 18916 } 18917 } else if (!strcasecmp(v->name, "setvar")) { 18918 /* Set peer channel variable */ 18919 varname = ast_strdupa(v->value); 18920 if ((varval = strchr(varname, '='))) { 18921 *varval++ = '\0'; 18922 if ((tmpvar = ast_variable_new(varname, varval))) { 18923 tmpvar->next = peer->chanvars; 18924 peer->chanvars = tmpvar; 18925 } 18926 } 18927 } 18928 } 18929 18930 /* These apply to devstate lookups */ 18931 if (realtime && !strcasecmp(v->name, "lastms")) { 18932 sscanf(v->value, "%30d", &peer->lastms); 18933 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 18934 inet_aton(v->value, &(peer->addr.sin_addr)); 18935 } else if (!strcasecmp(v->name, "qualify")) { 18936 if (!strcasecmp(v->value, "no")) { 18937 peer->maxms = 0; 18938 } else if (!strcasecmp(v->value, "yes")) { 18939 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 18940 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 18941 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); 18942 peer->maxms = 0; 18943 } 18944 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 18945 /* This would otherwise cause a network storm, where the 18946 * qualify response refreshes the peer from the database, 18947 * which in turn causes another qualify to be sent, ad 18948 * infinitum. */ 18949 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); 18950 peer->maxms = 0; 18951 } 18952 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 18953 peer->call_limit = atoi(v->value); 18954 if (peer->call_limit < 0) { 18955 peer->call_limit = 0; 18956 } 18957 } 18958 } 18959 18960 if (!ast_strlen_zero(fullcontact)) { 18961 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 18962 /* We have a hostname in the fullcontact, but if we don't have an 18963 * address listed on the entry (or if it's 'dynamic'), then we need to 18964 * parse the entry to obtain the IP address, so a dynamic host can be 18965 * contacted immediately after reload (as opposed to waiting for it to 18966 * register once again). But if we have an address for this peer and NAT was 18967 * specified, use that address instead. */ 18968 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 18969 __set_address_from_contact(fullcontact, &peer->addr); 18970 } 18971 } 18972 18973 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !obproxyfound && !ast_strlen_zero(peer->tohost)) { 18974 if (ast_get_ip_or_srv(&peer->addr, peer->tohost, srvlookup && !peer->portinuri ? "_sip._udp" : NULL)) { 18975 ast_log(LOG_ERROR, "host lookup failed for %s, on peer %s, removing peer\n", peer->tohost, peer->name); 18976 ASTOBJ_UNREF(peer, sip_destroy_peer); 18977 return NULL; 18978 } 18979 } 18980 18981 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 18982 time_t nowtime = time(NULL); 18983 18984 if ((nowtime - regseconds) > 0) { 18985 destroy_association(peer); 18986 memset(&peer->addr, 0, sizeof(peer->addr)); 18987 peer->lastms = -1; 18988 if (option_debug) 18989 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 18990 } 18991 } 18992 18993 /* Startup regular pokes */ 18994 if (realtime && peer->lastms > 0) { 18995 ASTOBJ_REF(peer); 18996 sip_poke_peer(peer); 18997 } 18998 18999 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 19000 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 19001 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 19002 global_allowsubscribe = TRUE; /* No global ban any more */ 19003 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 19004 reg_source_db(peer); 19005 ASTOBJ_UNMARK(peer); 19006 ast_free_ha(oldha); 19007 return peer; 19008 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 12971 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().
12972 { 12973 char a1[256]; 12974 char a2[256]; 12975 char a1_hash[256]; 12976 char a2_hash[256]; 12977 char resp[256]; 12978 char resp_hash[256]; 12979 char uri[256]; 12980 char opaque[256] = ""; 12981 char cnonce[80]; 12982 const char *username; 12983 const char *secret; 12984 const char *md5secret; 12985 struct sip_auth *auth = NULL; /* Realm authentication */ 12986 12987 if (!ast_strlen_zero(p->domain)) 12988 ast_copy_string(uri, p->domain, sizeof(uri)); 12989 else if (!ast_strlen_zero(p->uri)) 12990 ast_copy_string(uri, p->uri, sizeof(uri)); 12991 else 12992 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12993 12994 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12995 12996 /* Check if we have separate auth credentials */ 12997 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12998 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12999 13000 if (auth) { 13001 if (sipdebug && option_debug > 1) 13002 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 13003 username = auth->username; 13004 secret = auth->secret; 13005 md5secret = auth->md5secret; 13006 if (sipdebug) 13007 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 13008 } else { 13009 /* No authentication, use peer or register= config */ 13010 username = p->authname; 13011 secret = p->peersecret; 13012 md5secret = p->peermd5secret; 13013 } 13014 if (ast_strlen_zero(username)) /* We have no authentication */ 13015 return -1; 13016 13017 /* Calculate SIP digest response */ 13018 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 13019 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 13020 if (!ast_strlen_zero(md5secret)) 13021 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 13022 else 13023 ast_md5_hash(a1_hash,a1); 13024 ast_md5_hash(a2_hash,a2); 13025 13026 p->noncecount++; 13027 if (!ast_strlen_zero(p->qop)) 13028 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 13029 else 13030 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 13031 ast_md5_hash(resp_hash, resp); 13032 13033 /* only include the opaque string if it's set */ 13034 if (!ast_strlen_zero(p->opaque)) { 13035 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 13036 } 13037 13038 /* XXX We hard code our qop to "auth" for now. XXX */ 13039 if (!ast_strlen_zero(p->qop)) 13040 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); 13041 else 13042 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); 13043 13044 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 13045 13046 return 0; 13047 }
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 9279 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().
09280 { 09281 struct sip_route *thishop, *head, *tail; 09282 int start = 0; 09283 int len; 09284 const char *rr, *contact, *c; 09285 09286 /* Once a persistant route is set, don't fool with it */ 09287 if (p->route && p->route_persistant) { 09288 if (option_debug) 09289 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 09290 return; 09291 } 09292 09293 if (p->route) { 09294 free_old_route(p->route); 09295 p->route = NULL; 09296 } 09297 09298 /* We only want to create the route set the first time this is called */ 09299 p->route_persistant = 1; 09300 09301 /* Build a tailq, then assign it to p->route when done. 09302 * If backwards, we add entries from the head so they end up 09303 * in reverse order. However, we do need to maintain a correct 09304 * tail pointer because the contact is always at the end. 09305 */ 09306 head = NULL; 09307 tail = head; 09308 /* 1st we pass through all the hops in any Record-Route headers */ 09309 for (;;) { 09310 /* Each Record-Route header */ 09311 rr = __get_header(req, "Record-Route", &start); 09312 if (*rr == '\0') 09313 break; 09314 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 09315 ++rr; 09316 len = strcspn(rr, ">") + 1; 09317 /* Make a struct route */ 09318 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 09319 /* ast_calloc is not needed because all fields are initialized in this block */ 09320 ast_copy_string(thishop->hop, rr, len); 09321 if (option_debug > 1) 09322 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 09323 /* Link in */ 09324 if (backwards) { 09325 /* Link in at head so they end up in reverse order */ 09326 thishop->next = head; 09327 head = thishop; 09328 /* If this was the first then it'll be the tail */ 09329 if (!tail) 09330 tail = thishop; 09331 } else { 09332 thishop->next = NULL; 09333 /* Link in at the end */ 09334 if (tail) 09335 tail->next = thishop; 09336 else 09337 head = thishop; 09338 tail = thishop; 09339 } 09340 } 09341 } 09342 } 09343 09344 /* Only append the contact if we are dealing with a strict router */ 09345 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 09346 /* 2nd append the Contact: if there is one */ 09347 /* Can be multiple Contact headers, comma separated values - we just take the first */ 09348 contact = get_header(req, "Contact"); 09349 if (!ast_strlen_zero(contact)) { 09350 if (option_debug > 1) 09351 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 09352 /* Look for <: delimited address */ 09353 c = strchr(contact, '<'); 09354 if (c) { 09355 /* Take to > */ 09356 ++c; 09357 len = strcspn(c, ">") + 1; 09358 } else { 09359 /* No <> - just take the lot */ 09360 c = contact; 09361 len = strlen(contact) + 1; 09362 } 09363 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 09364 /* ast_calloc is not needed because all fields are initialized in this block */ 09365 ast_copy_string(thishop->hop, c, len); 09366 thishop->next = NULL; 09367 /* Goes at the end */ 09368 if (tail) 09369 tail->next = thishop; 09370 else 09371 head = thishop; 09372 } 09373 } 09374 } 09375 09376 /* Store as new route */ 09377 p->route = head; 09378 09379 /* For debugging dump what we ended up with */ 09380 if (sip_debug_test_pvt(p)) 09381 list_route(p->route); 09382 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7787 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().
07788 { 07789 int send_pres_tags = TRUE; 07790 const char *privacy=NULL; 07791 const char *screen=NULL; 07792 char buf[256]; 07793 const char *clid = default_callerid; 07794 const char *clin = NULL; 07795 const char *fromdomain; 07796 07797 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07798 return; 07799 07800 if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num)) 07801 clid = p->owner->cid.cid_num; 07802 if (p->owner && p->owner->cid.cid_name) 07803 clin = p->owner->cid.cid_name; 07804 if (ast_strlen_zero(clin)) 07805 clin = clid; 07806 07807 switch (p->callingpres) { 07808 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07809 privacy = "off"; 07810 screen = "no"; 07811 break; 07812 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07813 privacy = "off"; 07814 screen = "yes"; 07815 break; 07816 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07817 privacy = "off"; 07818 screen = "no"; 07819 break; 07820 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07821 privacy = "off"; 07822 screen = "yes"; 07823 break; 07824 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07825 privacy = "full"; 07826 screen = "no"; 07827 break; 07828 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07829 privacy = "full"; 07830 screen = "yes"; 07831 break; 07832 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07833 privacy = "full"; 07834 screen = "no"; 07835 break; 07836 case AST_PRES_PROHIB_NETWORK_NUMBER: 07837 privacy = "full"; 07838 screen = "yes"; 07839 break; 07840 case AST_PRES_NUMBER_NOT_AVAILABLE: 07841 send_pres_tags = FALSE; 07842 break; 07843 default: 07844 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07845 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07846 privacy = "full"; 07847 else 07848 privacy = "off"; 07849 screen = "no"; 07850 break; 07851 } 07852 07853 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07854 07855 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07856 if (send_pres_tags) 07857 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07858 ast_string_field_set(p, rpid, buf); 07859 07860 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07861 S_OR(p->fromuser, clid), 07862 fromdomain, p->tag); 07863 }
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 18492 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.
18493 { 18494 struct sip_user *user; 18495 int format; 18496 struct ast_ha *oldha = NULL; 18497 char *varname = NULL, *varval = NULL; 18498 struct ast_variable *tmpvar = NULL; 18499 struct ast_flags userflags[2] = {{(0)}}; 18500 struct ast_flags mask[2] = {{(0)}}; 18501 18502 18503 if (!(user = ast_calloc(1, sizeof(*user)))) 18504 return NULL; 18505 18506 suserobjs++; 18507 ASTOBJ_INIT(user); 18508 ast_copy_string(user->name, name, sizeof(user->name)); 18509 oldha = user->ha; 18510 user->ha = NULL; 18511 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 18512 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 18513 user->capability = global_capability; 18514 user->allowtransfer = global_allowtransfer; 18515 user->maxcallbitrate = default_maxcallbitrate; 18516 user->autoframing = global_autoframing; 18517 user->prefs = default_prefs; 18518 /* set default context */ 18519 strcpy(user->context, default_context); 18520 strcpy(user->language, default_language); 18521 strcpy(user->mohinterpret, default_mohinterpret); 18522 strcpy(user->mohsuggest, default_mohsuggest); 18523 /* First we walk through the v parameters list and then the alt parameters list */ 18524 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 18525 if (handle_common_options(&userflags[0], &mask[0], v)) 18526 continue; 18527 18528 if (!strcasecmp(v->name, "context")) { 18529 ast_copy_string(user->context, v->value, sizeof(user->context)); 18530 } else if (!strcasecmp(v->name, "subscribecontext")) { 18531 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 18532 } else if (!strcasecmp(v->name, "setvar")) { 18533 varname = ast_strdupa(v->value); 18534 if ((varval = strchr(varname,'='))) { 18535 *varval++ = '\0'; 18536 if ((tmpvar = ast_variable_new(varname, varval))) { 18537 tmpvar->next = user->chanvars; 18538 user->chanvars = tmpvar; 18539 } 18540 } 18541 } else if (!strcasecmp(v->name, "permit") || 18542 !strcasecmp(v->name, "deny")) { 18543 user->ha = ast_append_ha(v->name, v->value, user->ha); 18544 } else if (!strcasecmp(v->name, "allowtransfer")) { 18545 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18546 } else if (!strcasecmp(v->name, "secret")) { 18547 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 18548 } else if (!strcasecmp(v->name, "md5secret")) { 18549 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 18550 } else if (!strcasecmp(v->name, "callerid")) { 18551 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 18552 } else if (!strcasecmp(v->name, "fullname")) { 18553 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 18554 } else if (!strcasecmp(v->name, "trunkname")) { 18555 /* This is actually for a trunk, so we don't want to override callerid */ 18556 ast_copy_string(user->cid_name, "", sizeof(user->cid_name)); 18557 } else if (!strcasecmp(v->name, "cid_number")) { 18558 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 18559 } else if (!strcasecmp(v->name, "callgroup")) { 18560 user->callgroup = ast_get_group(v->value); 18561 } else if (!strcasecmp(v->name, "pickupgroup")) { 18562 user->pickupgroup = ast_get_group(v->value); 18563 } else if (!strcasecmp(v->name, "language")) { 18564 ast_copy_string(user->language, v->value, sizeof(user->language)); 18565 } else if (!strcasecmp(v->name, "mohinterpret") 18566 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18567 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 18568 } else if (!strcasecmp(v->name, "mohsuggest")) { 18569 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 18570 } else if (!strcasecmp(v->name, "accountcode")) { 18571 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 18572 } else if (!strcasecmp(v->name, "call-limit")) { 18573 user->call_limit = atoi(v->value); 18574 if (user->call_limit < 0) 18575 user->call_limit = 0; 18576 } else if (!strcasecmp(v->name, "amaflags")) { 18577 format = ast_cdr_amaflags2int(v->value); 18578 if (format < 0) { 18579 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 18580 } else { 18581 user->amaflags = format; 18582 } 18583 } else if (!strcasecmp(v->name, "allow")) { 18584 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 18585 } else if (!strcasecmp(v->name, "disallow")) { 18586 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 18587 } else if (!strcasecmp(v->name, "autoframing")) { 18588 user->autoframing = ast_true(v->value); 18589 } else if (!strcasecmp(v->name, "callingpres")) { 18590 user->callingpres = ast_parse_caller_presentation(v->value); 18591 if (user->callingpres == -1) 18592 user->callingpres = atoi(v->value); 18593 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18594 user->maxcallbitrate = atoi(v->value); 18595 if (user->maxcallbitrate < 0) 18596 user->maxcallbitrate = default_maxcallbitrate; 18597 } 18598 /* We can't just report unknown options here because this may be a 18599 * type=friend entry. All user options are valid for a peer, but not 18600 * the other way around. */ 18601 } 18602 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 18603 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 18604 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 18605 global_allowsubscribe = TRUE; /* No global ban any more */ 18606 ast_free_ha(oldha); 18607 return user; 18608 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1912 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().
01913 { 01914 /* Work around buggy UNIDEN UIP200 firmware */ 01915 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01916 01917 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01918 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01919 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01920 }
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 5617 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().
05618 { 05619 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05620 sip_peer_hold(dialog, holdstate); 05621 if (global_callevents) 05622 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05623 "Channel: %s\r\n" 05624 "Uniqueid: %s\r\n", 05625 dialog->owner->name, 05626 dialog->owner->uniqueid); 05627 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05628 if (!holdstate) { /* Put off remote hold */ 05629 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05630 return; 05631 } 05632 /* No address for RTP, we're on hold */ 05633 05634 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05635 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05636 else if (sendonly == 2) /* Inactive stream */ 05637 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05638 else 05639 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05640 return; 05641 }
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 9406 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().
09409 { 09410 const char *response = "407 Proxy Authentication Required"; 09411 const char *reqheader = "Proxy-Authorization"; 09412 const char *respheader = "Proxy-Authenticate"; 09413 const char *authtoken; 09414 char a1_hash[256]; 09415 char resp_hash[256]=""; 09416 char *c; 09417 int wrongnonce = FALSE; 09418 int good_response; 09419 const char *usednonce = p->randdata; 09420 struct ast_dynamic_str *buf; 09421 int res; 09422 09423 /* table of recognised keywords, and their value in the digest */ 09424 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 09425 struct x { 09426 const char *key; 09427 const char *s; 09428 } *i, keys[] = { 09429 [K_RESP] = { "response=", "" }, 09430 [K_URI] = { "uri=", "" }, 09431 [K_USER] = { "username=", "" }, 09432 [K_NONCE] = { "nonce=", "" }, 09433 [K_LAST] = { NULL, NULL} 09434 }; 09435 09436 /* Always OK if no secret */ 09437 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 09438 return AUTH_SUCCESSFUL; 09439 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09440 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 09441 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 09442 different circumstances! What a surprise. */ 09443 response = "401 Unauthorized"; 09444 reqheader = "Authorization"; 09445 respheader = "WWW-Authenticate"; 09446 } 09447 authtoken = get_header(req, reqheader); 09448 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09449 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09450 information */ 09451 if (!reliable) { 09452 /* Resend message if this was NOT a reliable delivery. Otherwise the 09453 retransmission should get it */ 09454 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09455 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09456 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09457 } 09458 return AUTH_CHALLENGE_SENT; 09459 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09460 /* We have no auth, so issue challenge and request authentication */ 09461 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 09462 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09463 /* Schedule auto destroy in 32 seconds */ 09464 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09465 return AUTH_CHALLENGE_SENT; 09466 } 09467 09468 /* --- We have auth, so check it */ 09469 09470 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 09471 an example in the spec of just what it is you're doing a hash on. */ 09472 09473 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 09474 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09475 09476 /* Make a copy of the response and parse it */ 09477 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 09478 09479 if (res == AST_DYNSTR_BUILD_FAILED) 09480 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 09481 09482 c = buf->str; 09483 09484 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 09485 for (i = keys; i->key != NULL; i++) { 09486 const char *separator = ","; /* default */ 09487 09488 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 09489 continue; 09490 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09491 c += strlen(i->key); 09492 if (*c == '"') { /* in quotes. Skip first and look for last */ 09493 c++; 09494 separator = "\""; 09495 } 09496 i->s = c; 09497 strsep(&c, separator); 09498 break; 09499 } 09500 if (i->key == NULL) /* not found, jump after space or comma */ 09501 strsep(&c, " ,"); 09502 } 09503 09504 /* Verify that digest username matches the username we auth as */ 09505 if (strcmp(username, keys[K_USER].s)) { 09506 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 09507 username, keys[K_USER].s); 09508 /* Oops, we're trying something here */ 09509 return AUTH_USERNAME_MISMATCH; 09510 } 09511 09512 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 09513 * If this check fails, send 401 with new nonce */ 09514 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 09515 wrongnonce = TRUE; 09516 usednonce = keys[K_NONCE].s; 09517 } else { 09518 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 09519 } 09520 09521 if (!ast_strlen_zero(md5secret)) 09522 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 09523 else { 09524 char a1[256]; 09525 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 09526 ast_md5_hash(a1_hash, a1); 09527 } 09528 09529 /* compute the expected response to compare with what we received */ 09530 { 09531 char a2[256]; 09532 char a2_hash[256]; 09533 char resp[256]; 09534 09535 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 09536 S_OR(keys[K_URI].s, uri)); 09537 ast_md5_hash(a2_hash, a2); 09538 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 09539 ast_md5_hash(resp_hash, resp); 09540 } 09541 09542 good_response = keys[K_RESP].s && 09543 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 09544 if (wrongnonce) { 09545 if (good_response) { 09546 if (sipdebug) 09547 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "From")); 09548 /* We got working auth token, based on stale nonce . */ 09549 set_nonce_randdata(p, 0); 09550 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 09551 } else { 09552 /* Everything was wrong, so give the device one more try with a new challenge */ 09553 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09554 if (sipdebug) 09555 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 09556 set_nonce_randdata(p, 1); 09557 } else { 09558 if (sipdebug) 09559 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 09560 } 09561 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09562 } 09563 09564 /* Schedule auto destroy in 32 seconds */ 09565 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09566 return AUTH_CHALLENGE_SENT; 09567 } 09568 if (good_response) { 09569 append_history(p, "AuthOK", "Auth challenge successful for %s", username); 09570 return AUTH_SUCCESSFUL; 09571 } 09572 09573 /* Ok, we have a bad username/secret pair */ 09574 /* Tell the UAS not to re-send this authentication data, because 09575 it will continue to fail 09576 */ 09577 09578 return AUTH_SECRET_FAILED; 09579 }
static void check_auth_buf_init | ( | void | ) | [static] |
static void check_extenstate_updates | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9635 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, notify_extenstate_update(), sip_extenstate_update::pvt, and update().
Referenced by do_monitor().
09636 { 09637 struct sip_extenstate_update *update = NULL; 09638 09639 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09640 /* avoid holding the lock if possible */ 09641 return; 09642 } 09643 09644 do { 09645 if (update) { 09646 /* The notify can not happen while the list lock is held. */ 09647 notify_extenstate_update(update->context, update->exten, update->state, pvt); 09648 ast_free(update); 09649 } 09650 09651 AST_LIST_LOCK(&sip_extenstate_updates); 09652 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09653 if (update->pvt == pvt) { 09654 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09655 break; 09656 } 09657 } 09658 AST_LIST_TRAVERSE_SAFE_END 09659 AST_LIST_UNLOCK(&sip_extenstate_updates); 09660 } while (update); 09661 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 13452 of file chan_sip.c.
References ast_clear_flag, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_CANCELLED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lastinvite, LOG_DEBUG, option_debug, sip_pvt::owner, 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().
13453 { 13454 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 13455 /* if we can't BYE, then this is really a pending CANCEL */ 13456 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) { 13457 p->invitestate = INV_CANCELLED; 13458 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 13459 /* Actually don't destroy us yet, wait for the 487 on our original 13460 INVITE, but do set an autodestruct just in case we never get it. */ 13461 } else { 13462 /* We have a pending outbound invite, don't send someting 13463 new in-transaction */ 13464 if (p->pendinginvite) 13465 return; 13466 13467 if (p->owner) { 13468 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); 13469 } 13470 /* Perhaps there is an SD change INVITE outstanding */ 13471 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 13472 } 13473 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 13474 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13475 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 13476 /* if we can't REINVITE, hold it for later */ 13477 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 13478 if (option_debug) 13479 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 13480 } else { 13481 if (option_debug) 13482 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 13483 /* Didn't get to reinvite yet, so do it now */ 13484 transmit_reinvite_with_sdp(p); 13485 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 13486 } 13487 } 13488 }
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 18373 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().
18374 { 18375 struct domain *d; 18376 int result = 0; 18377 18378 AST_LIST_LOCK(&domain_list); 18379 AST_LIST_TRAVERSE(&domain_list, d, list) { 18380 if (strcasecmp(d->domain, domain)) 18381 continue; 18382 18383 if (len && !ast_strlen_zero(d->context)) 18384 ast_copy_string(context, d->context, len); 18385 18386 result = 1; 18387 break; 18388 } 18389 AST_LIST_UNLOCK(&domain_list); 18390 18391 return result; 18392 }
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 11045 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
11046 { 11047 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 11048 }
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 10712 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_variables_destroy(), 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().
10715 { 10716 struct sip_user *user = NULL; 10717 struct sip_peer *peer; 10718 char from[256], *c; 10719 char *of; 10720 char rpid_num[50]; 10721 const char *rpid; 10722 enum check_auth_result res = AUTH_SUCCESSFUL; 10723 char *t; 10724 char calleridname[50]; 10725 int debug=sip_debug_test_addr(sin); 10726 struct ast_variable *tmpvar = NULL, *v = NULL; 10727 char *uri2 = ast_strdupa(uri); 10728 10729 /* Terminate URI */ 10730 t = uri2; 10731 while (*t && *t > 32 && *t != ';') 10732 t++; 10733 *t = '\0'; 10734 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 10735 if (pedanticsipchecking) 10736 ast_uri_decode(from); 10737 /* XXX here tries to map the username for invite things */ 10738 memset(calleridname, 0, sizeof(calleridname)); 10739 get_calleridname(from, calleridname, sizeof(calleridname)); 10740 if (calleridname[0]) 10741 ast_string_field_set(p, cid_name, calleridname); 10742 10743 rpid = get_header(req, "Remote-Party-ID"); 10744 memset(rpid_num, 0, sizeof(rpid_num)); 10745 if (!ast_strlen_zero(rpid)) 10746 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 10747 10748 of = get_in_brackets(from); 10749 if (ast_strlen_zero(p->exten)) { 10750 t = uri2; 10751 if (!strncasecmp(t, "sip:", 4)) 10752 t+= 4; 10753 ast_string_field_set(p, exten, t); 10754 t = strchr(p->exten, '@'); 10755 if (t) 10756 *t = '\0'; 10757 if (ast_strlen_zero(p->our_contact)) 10758 build_contact(p); 10759 } 10760 /* save the URI part of the From header */ 10761 ast_string_field_set(p, from, of); 10762 if (strncasecmp(of, "sip:", 4)) { 10763 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 10764 } else 10765 of += 4; 10766 /* Get just the username part */ 10767 if ((c = strchr(of, '@'))) { 10768 char *tmp; 10769 *c = '\0'; 10770 if ((c = strchr(of, ':'))) 10771 *c = '\0'; 10772 tmp = ast_strdupa(of); 10773 /* We need to be able to handle auth-headers looking like 10774 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 10775 */ 10776 tmp = strsep(&tmp, ";"); 10777 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10778 ast_shrink_phone_number(tmp); 10779 ast_string_field_set(p, cid_num, tmp); 10780 } 10781 10782 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 10783 user = find_user(of, 1); 10784 10785 /* Find user based on user name in the from header */ 10786 if (user && ast_apply_ha(user->ha, sin)) { 10787 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10788 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10789 if (sipmethod == SIP_INVITE) { 10790 /* destroy old channel vars and copy new channel vars */ 10791 ast_variables_destroy(p->chanvars); 10792 p->chanvars = NULL; 10793 for (v = user->chanvars ; v ; v = v->next) { 10794 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10795 tmpvar->next = p->chanvars; 10796 p->chanvars = tmpvar; 10797 } 10798 } 10799 } 10800 p->prefs = user->prefs; 10801 /* Set Frame packetization */ 10802 if (p->rtp) { 10803 ast_rtp_codec_setpref(p->rtp, &p->prefs); 10804 p->autoframing = user->autoframing; 10805 } 10806 /* replace callerid if rpid found, and not restricted */ 10807 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10808 char *tmp; 10809 if (*calleridname) 10810 ast_string_field_set(p, cid_name, calleridname); 10811 tmp = ast_strdupa(rpid_num); 10812 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10813 ast_shrink_phone_number(tmp); 10814 ast_string_field_set(p, cid_num, tmp); 10815 } 10816 10817 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 10818 10819 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10820 if (sip_cancel_destroy(p)) 10821 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10822 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 10823 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10824 /* Copy SIP extensions profile from INVITE */ 10825 if (p->sipoptions) 10826 user->sipoptions = p->sipoptions; 10827 10828 /* If we have a call limit, set flag */ 10829 if (user->call_limit) 10830 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10831 if (!ast_strlen_zero(user->context)) 10832 ast_string_field_set(p, context, user->context); 10833 if (!ast_strlen_zero(user->cid_num)) { 10834 char *tmp = ast_strdupa(user->cid_num); 10835 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10836 ast_shrink_phone_number(tmp); 10837 ast_string_field_set(p, cid_num, tmp); 10838 } 10839 if (!ast_strlen_zero(user->cid_name)) 10840 ast_string_field_set(p, cid_name, user->cid_name); 10841 ast_string_field_set(p, username, user->name); 10842 ast_string_field_set(p, peername, user->name); 10843 ast_string_field_set(p, peersecret, user->secret); 10844 ast_string_field_set(p, peermd5secret, user->md5secret); 10845 ast_string_field_set(p, subscribecontext, user->subscribecontext); 10846 ast_string_field_set(p, accountcode, user->accountcode); 10847 ast_string_field_set(p, language, user->language); 10848 ast_string_field_set(p, mohsuggest, user->mohsuggest); 10849 ast_string_field_set(p, mohinterpret, user->mohinterpret); 10850 p->allowtransfer = user->allowtransfer; 10851 p->amaflags = user->amaflags; 10852 p->callgroup = user->callgroup; 10853 p->pickupgroup = user->pickupgroup; 10854 if (user->callingpres) /* User callingpres setting will override RPID header */ 10855 p->callingpres = user->callingpres; 10856 10857 /* Set default codec settings for this call */ 10858 p->capability = user->capability; /* User codec choice */ 10859 p->jointcapability = user->capability; /* Our codecs */ 10860 if (p->peercapability) /* AND with peer's codecs */ 10861 p->jointcapability &= p->peercapability; 10862 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10863 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10864 p->noncodeccapability |= AST_RTP_DTMF; 10865 else 10866 p->noncodeccapability &= ~AST_RTP_DTMF; 10867 p->jointnoncodeccapability = p->noncodeccapability; 10868 if (p->t38.peercapability) 10869 p->t38.jointcapability &= p->t38.peercapability; 10870 p->maxcallbitrate = user->maxcallbitrate; 10871 /* If we do not support video, remove video from call structure */ 10872 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10873 ast_rtp_destroy(p->vrtp); 10874 p->vrtp = NULL; 10875 } 10876 } 10877 if (user && debug) 10878 ast_verbose("Found user '%s'\n", user->name); 10879 } else { 10880 if (user) { 10881 if (!authpeer && debug) 10882 ast_verbose("Found user '%s', but fails host access\n", user->name); 10883 ASTOBJ_UNREF(user,sip_destroy_user); 10884 } 10885 user = NULL; 10886 } 10887 10888 if (!user) { 10889 /* If we didn't find a user match, check for peers */ 10890 if (sipmethod == SIP_SUBSCRIBE) 10891 /* For subscribes, match on peer name only */ 10892 peer = find_peer(of, NULL, 1, 0); 10893 else 10894 /* Look for peer based on the IP address we received data from */ 10895 /* If peer is registered from this IP address or have this as a default 10896 IP address, this call is from the peer 10897 */ 10898 peer = find_peer(NULL, &p->recv, 1, 0); 10899 10900 if (peer) { 10901 /* Set Frame packetization */ 10902 if (p->rtp) { 10903 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 10904 p->autoframing = peer->autoframing; 10905 } 10906 if (debug) 10907 ast_verbose("Found peer '%s'\n", peer->name); 10908 10909 /* Take the peer */ 10910 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10911 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10912 10913 /* Copy SIP extensions profile to peer */ 10914 if (p->sipoptions) 10915 peer->sipoptions = p->sipoptions; 10916 10917 /* replace callerid if rpid found, and not restricted */ 10918 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10919 char *tmp = ast_strdupa(rpid_num); 10920 if (*calleridname) 10921 ast_string_field_set(p, cid_name, calleridname); 10922 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10923 ast_shrink_phone_number(tmp); 10924 ast_string_field_set(p, cid_num, tmp); 10925 } 10926 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 10927 10928 ast_string_field_set(p, peersecret, peer->secret); 10929 ast_string_field_set(p, peermd5secret, peer->md5secret); 10930 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 10931 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 10932 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 10933 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 10934 p->callingpres = peer->callingpres; 10935 if (peer->maxms && peer->lastms) 10936 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 10937 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 10938 /* Pretend there is no required authentication */ 10939 ast_string_field_free(p, peersecret); 10940 ast_string_field_free(p, peermd5secret); 10941 } 10942 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10943 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10944 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10945 /* If we have a call limit, set flag */ 10946 if (peer->call_limit) 10947 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10948 ast_string_field_set(p, peername, peer->name); 10949 ast_string_field_set(p, authname, peer->name); 10950 10951 if (sipmethod == SIP_INVITE) { 10952 /* destroy old channel vars and copy new channel vars */ 10953 ast_variables_destroy(p->chanvars); 10954 p->chanvars = NULL; 10955 for (v = peer->chanvars ; v ; v = v->next) { 10956 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10957 tmpvar->next = p->chanvars; 10958 p->chanvars = tmpvar; 10959 } 10960 } 10961 } 10962 if (authpeer) { 10963 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10964 } 10965 10966 if (!ast_strlen_zero(peer->username)) { 10967 ast_string_field_set(p, username, peer->username); 10968 /* Use the default username for authentication on outbound calls */ 10969 /* XXX this takes the name from the caller... can we override ? */ 10970 ast_string_field_set(p, authname, peer->username); 10971 } 10972 if (!ast_strlen_zero(peer->cid_num)) { 10973 char *tmp = ast_strdupa(peer->cid_num); 10974 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 10975 ast_shrink_phone_number(tmp); 10976 ast_string_field_set(p, cid_num, tmp); 10977 } 10978 if (!ast_strlen_zero(peer->cid_name)) 10979 ast_string_field_set(p, cid_name, peer->cid_name); 10980 ast_string_field_set(p, fullcontact, peer->fullcontact); 10981 if (!ast_strlen_zero(peer->context)) 10982 ast_string_field_set(p, context, peer->context); 10983 ast_string_field_set(p, peersecret, peer->secret); 10984 ast_string_field_set(p, peermd5secret, peer->md5secret); 10985 ast_string_field_set(p, language, peer->language); 10986 ast_string_field_set(p, accountcode, peer->accountcode); 10987 p->amaflags = peer->amaflags; 10988 p->callgroup = peer->callgroup; 10989 p->pickupgroup = peer->pickupgroup; 10990 p->capability = peer->capability; 10991 p->prefs = peer->prefs; 10992 p->jointcapability = peer->capability; 10993 if (p->peercapability) 10994 p->jointcapability &= p->peercapability; 10995 p->maxcallbitrate = peer->maxcallbitrate; 10996 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10997 ast_rtp_destroy(p->vrtp); 10998 p->vrtp = NULL; 10999 } 11000 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 11001 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 11002 p->noncodeccapability |= AST_RTP_DTMF; 11003 else 11004 p->noncodeccapability &= ~AST_RTP_DTMF; 11005 p->jointnoncodeccapability = p->noncodeccapability; 11006 if (p->t38.peercapability) 11007 p->t38.jointcapability &= p->t38.peercapability; 11008 } 11009 ASTOBJ_UNREF(peer, sip_destroy_peer); 11010 } else { 11011 if (debug) 11012 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 11013 11014 /* do we allow guests? */ 11015 if (!global_allowguest) { 11016 if (global_alwaysauthreject) 11017 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 11018 else 11019 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 11020 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 11021 char *tmp = ast_strdupa(rpid_num); 11022 if (*calleridname) 11023 ast_string_field_set(p, cid_name, calleridname); 11024 if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp)) 11025 ast_shrink_phone_number(tmp); 11026 ast_string_field_set(p, cid_num, tmp); 11027 } 11028 } 11029 11030 } 11031 11032 if (user) 11033 ASTOBJ_UNREF(user, sip_destroy_user); 11034 11035 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 11036 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 11037 } 11038 11039 return res; 11040 }
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 10569 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().
10570 { 10571 char via[512]; 10572 char *c, *pt, *maddr; 10573 struct hostent *hp; 10574 struct ast_hostent ahp; 10575 10576 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 10577 10578 /* Work on the leftmost value of the topmost Via header */ 10579 c = strchr(via, ','); 10580 if (c) 10581 *c = '\0'; 10582 10583 /* Check for rport */ 10584 c = strstr(via, ";rport"); 10585 if (c && (c[6] != '=')) /* rport query, not answer */ 10586 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 10587 10588 /* Check for maddr */ 10589 maddr = strstr(via, "maddr="); 10590 if (maddr) { 10591 maddr += 6; 10592 c = maddr + strspn(maddr, "0123456789."); 10593 *c = '\0'; 10594 } 10595 10596 c = strchr(via, ';'); 10597 if (c) 10598 *c = '\0'; 10599 10600 c = strchr(via, ' '); 10601 if (c) { 10602 *c = '\0'; 10603 c = ast_skip_blanks(c+1); 10604 if (strcasecmp(via, "SIP/2.0/UDP")) { 10605 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 10606 return; 10607 } 10608 pt = strchr(c, ':'); 10609 if (pt) 10610 *pt++ = '\0'; /* remember port pointer */ 10611 /* Use maddr if found */ 10612 if (maddr) 10613 c = maddr; 10614 hp = ast_gethostbyname(c, &ahp); 10615 if (!hp) { 10616 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 10617 return; 10618 } 10619 memset(&p->sa, 0, sizeof(p->sa)); 10620 p->sa.sin_family = AF_INET; 10621 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 10622 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 10623 10624 if (sip_debug_test_pvt(p)) { 10625 const struct sockaddr_in *dst = sip_real_dst(p); 10626 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 10627 } 10628 } 10629 }
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 11489 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
11490 { 11491 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 11492 11493 while ((oldcontext = strsep(&old, "&"))) { 11494 stalecontext = '\0'; 11495 ast_copy_string(newlist, new, sizeof(newlist)); 11496 stringp = newlist; 11497 while ((newcontext = strsep(&stringp, "&"))) { 11498 if (strcmp(newcontext, oldcontext) == 0) { 11499 /* This is not the context you're looking for */ 11500 stalecontext = '\0'; 11501 break; 11502 } else if (strcmp(newcontext, oldcontext)) { 11503 stalecontext = oldcontext; 11504 } 11505 11506 } 11507 if (stalecontext) 11508 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 11509 } 11510 }
static void clear_extenstate_updates | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9737 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, sip_extenstate_update::pvt, and update().
Referenced by __sip_destroy().
09738 { 09739 struct sip_extenstate_update *update = NULL; 09740 09741 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09742 /* avoid holding the lock if possible */ 09743 return; 09744 } 09745 09746 AST_LIST_LOCK(&sip_extenstate_updates); 09747 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09748 if (update->pvt == pvt) { 09749 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09750 ast_free(update); 09751 } 09752 } 09753 AST_LIST_TRAVERSE_SAFE_END 09754 AST_LIST_UNLOCK(&sip_extenstate_updates); 09755 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 18464 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
18465 { 18466 struct sip_auth *a = authlist; 18467 struct sip_auth *b; 18468 18469 while (a) { 18470 b = a; 18471 a = a->next; 18472 free(b); 18473 } 18474 18475 return 1; 18476 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 18395 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().
18396 { 18397 struct domain *d; 18398 18399 AST_LIST_LOCK(&domain_list); 18400 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 18401 free(d); 18402 AST_LIST_UNLOCK(&domain_list); 18403 }
static void clearmarked_extenstate_updates | ( | void | ) | [static] |
Definition at line 9667 of file chan_sip.c.
References ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, sip_extenstate_update::list, and update().
Referenced by do_monitor().
09668 { 09669 struct sip_extenstate_update *update = NULL; 09670 09671 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09672 /* avoid holding the lock if possible */ 09673 return; 09674 } 09675 09676 AST_LIST_LOCK(&sip_extenstate_updates); 09677 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 09678 if (update->marked) { 09679 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 09680 ast_free(update); 09681 } 09682 } 09683 AST_LIST_TRAVERSE_SAFE_END 09684 AST_LIST_UNLOCK(&sip_extenstate_updates); 09685 09686 }
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 12317 of file chan_sip.c.
References complete_sip_peer().
12318 { 12319 if (pos == 3) 12320 return complete_sip_peer(word, state, 0); 12321 12322 return NULL; 12323 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 12291 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().
12292 { 12293 char *result = NULL; 12294 int wordlen = strlen(word); 12295 int which = 0; 12296 12297 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 12298 /* locking of the object is not required because only the name and flags are being compared */ 12299 if (!strncasecmp(word, iterator->name, wordlen) && 12300 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 12301 ++which > state) 12302 result = ast_strdup(iterator->name); 12303 } while(0) ); 12304 return result; 12305 }
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 12385 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
12386 { 12387 if (pos == 4) 12388 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 12389 return NULL; 12390 }
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 12393 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
12394 { 12395 if (pos == 4) 12396 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 12397 12398 return NULL; 12399 }
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 12308 of file chan_sip.c.
References complete_sip_peer().
12309 { 12310 if (pos == 3) 12311 return complete_sip_peer(word, state, 0); 12312 12313 return NULL; 12314 }
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 12346 of file chan_sip.c.
References complete_sip_user().
12347 { 12348 if (pos == 3) 12349 return complete_sip_user(word, state, 0); 12350 12351 return NULL; 12352 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 12326 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().
12327 { 12328 char *result = NULL; 12329 int wordlen = strlen(word); 12330 int which = 0; 12331 12332 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 12333 /* locking of the object is not required because only the name and flags are being compared */ 12334 if (!strncasecmp(word, iterator->name, wordlen)) { 12335 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 12336 continue; 12337 if (++which > state) { 12338 result = ast_strdup(iterator->name); 12339 } 12340 } 12341 } while(0) ); 12342 return result; 12343 }
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 12268 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
12269 { 12270 int which=0; 12271 struct sip_pvt *cur; 12272 char *c = NULL; 12273 int wordlen = strlen(word); 12274 12275 if (pos != 3) { 12276 return NULL; 12277 } 12278 12279 ast_mutex_lock(&iflock); 12280 for (cur = iflist; cur; cur = cur->next) { 12281 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 12282 c = ast_strdup(cur->callid); 12283 break; 12284 } 12285 } 12286 ast_mutex_unlock(&iflock); 12287 return c; 12288 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 12355 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
12356 { 12357 char *c = NULL; 12358 12359 if (pos == 2) { 12360 int which = 0; 12361 char *cat = NULL; 12362 int wordlen = strlen(word); 12363 12364 /* do completion for notify type */ 12365 12366 if (!notify_types) 12367 return NULL; 12368 12369 while ( (cat = ast_category_browse(notify_types, cat)) ) { 12370 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 12371 c = ast_strdup(cat); 12372 break; 12373 } 12374 } 12375 return c; 12376 } 12377 12378 if (pos > 2) 12379 return complete_sip_peer(word, state, 0); 12380 12381 return NULL; 12382 }
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 6519 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
06520 { 06521 int start = 0; 06522 int copied = 0; 06523 for (;;) { 06524 const char *tmp = __get_header(orig, field, &start); 06525 06526 if (ast_strlen_zero(tmp)) 06527 break; 06528 /* Add what we're responding to */ 06529 add_header(req, field, tmp); 06530 copied++; 06531 } 06532 return copied ? 0 : -1; 06533 }
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 6508 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
06509 { 06510 const char *tmp = get_header(orig, field); 06511 06512 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 06513 return add_header(req, field, tmp); 06514 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 06515 return -1; 06516 }
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 7618 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().
07619 { 07620 long offset; 07621 int x; 07622 offset = ((void *)dst) - ((void *)src); 07623 /* First copy stuff */ 07624 memcpy(dst, src, sizeof(*dst)); 07625 /* Now fix pointer arithmetic */ 07626 for (x=0; x < src->headers; x++) 07627 dst->header[x] += offset; 07628 for (x=0; x < src->lines; x++) 07629 dst->line[x] += offset; 07630 dst->rlPart1 += offset; 07631 dst->rlPart2 += offset; 07632 }
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 6541 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().
06542 { 06543 int copied = 0; 06544 int start = 0; 06545 06546 for (;;) { 06547 char new[512]; 06548 const char *oh = __get_header(orig, field, &start); 06549 06550 if (ast_strlen_zero(oh)) 06551 break; 06552 06553 if (!copied) { /* Only check for empty rport in topmost via header */ 06554 char leftmost[512], *others, *rport; 06555 06556 /* Only work on leftmost value */ 06557 ast_copy_string(leftmost, oh, sizeof(leftmost)); 06558 others = strchr(leftmost, ','); 06559 if (others) 06560 *others++ = '\0'; 06561 06562 /* Find ;rport; (empty request) */ 06563 rport = strstr(leftmost, ";rport"); 06564 if (rport && *(rport+6) == '=') 06565 rport = NULL; /* We already have a parameter to rport */ 06566 06567 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 06568 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 06569 /* We need to add received port - rport */ 06570 char *end; 06571 06572 rport = strstr(leftmost, ";rport"); 06573 06574 if (rport) { 06575 end = strchr(rport + 1, ';'); 06576 if (end) 06577 memmove(rport, end, strlen(end) + 1); 06578 else 06579 *rport = '\0'; 06580 } 06581 06582 /* Add rport to first VIA header if requested */ 06583 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 06584 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06585 ntohs(p->recv.sin_port), 06586 others ? "," : "", others ? others : ""); 06587 } else { 06588 /* We should *always* add a received to the topmost via */ 06589 snprintf(new, sizeof(new), "%s;received=%s%s%s", 06590 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06591 others ? "," : "", others ? others : ""); 06592 } 06593 oh = new; /* the header to copy */ 06594 } /* else add the following via headers untouched */ 06595 add_header(req, field, oh); 06596 copied++; 06597 } 06598 if (!copied) { 06599 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 06600 return -1; 06601 } 06602 return 0; 06603 }
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 3179 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.
03180 { 03181 struct hostent *hp; 03182 struct ast_hostent ahp; 03183 struct sip_peer *p; 03184 char *port; 03185 int portno = 0; 03186 char host[MAXHOSTNAMELEN], *hostn; 03187 char peer[256]; 03188 03189 ast_copy_string(peer, opeer, sizeof(peer)); 03190 port = strchr(peer, ':'); 03191 if (port) { 03192 *port++ = '\0'; 03193 dialog->portinuri = 1; 03194 } 03195 dialog->sa.sin_family = AF_INET; 03196 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 03197 p = find_peer(peer, NULL, 1, 0); 03198 03199 if (p) { 03200 int res = create_addr_from_peer(dialog, p); 03201 if (port) { 03202 portno = atoi(port); 03203 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 03204 } 03205 ASTOBJ_UNREF(p, sip_destroy_peer); 03206 return res; 03207 } 03208 03209 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 03210 03211 ast_string_field_set(dialog, tohost, peer); 03212 03213 if (sin) { 03214 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 03215 if (!sin->sin_port) { 03216 if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { 03217 portno = STANDARD_SIP_PORT; 03218 } 03219 } else { 03220 portno = ntohs(sin->sin_port); 03221 } 03222 } else { 03223 hostn = peer; 03224 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 03225 * an A record lookup should be used instead of SRV. 03226 */ 03227 if (!port && srvlookup) { 03228 char service[MAXHOSTNAMELEN]; 03229 int tportno; 03230 int ret; 03231 03232 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 03233 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 03234 if (ret > 0) { 03235 hostn = host; 03236 portno = tportno; 03237 } 03238 } 03239 if (!portno) 03240 portno = port ? atoi(port) : STANDARD_SIP_PORT; 03241 03242 hp = ast_gethostbyname(hostn, &ahp); 03243 if (!hp) { 03244 ast_log(LOG_WARNING, "No such host: %s\n", peer); 03245 return -1; 03246 } 03247 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 03248 } 03249 dialog->sa.sin_port = htons(portno); 03250 dialog->recv = dialog->sa; 03251 return 0; 03252 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 3068 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::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_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().
03069 { 03070 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 03071 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 03072 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 03073 dialog->recv = dialog->sa; 03074 } else 03075 return -1; 03076 03077 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 03078 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 03079 dialog->capability = peer->capability; 03080 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 03081 ast_rtp_destroy(dialog->vrtp); 03082 dialog->vrtp = NULL; 03083 } 03084 dialog->prefs = peer->prefs; 03085 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 03086 dialog->t38.capability = global_t38_capability; 03087 if (dialog->udptl) { 03088 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 03089 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 03090 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 03091 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 03092 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 03093 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 03094 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 03095 if (option_debug > 1) 03096 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 03097 } 03098 dialog->t38.jointcapability = dialog->t38.capability; 03099 } else if (dialog->udptl) { 03100 ast_udptl_destroy(dialog->udptl); 03101 dialog->udptl = NULL; 03102 } 03103 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 03104 03105 if (dialog->rtp) { 03106 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 03107 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 03108 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 03109 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 03110 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 03111 /* Set Frame packetization */ 03112 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 03113 dialog->autoframing = peer->autoframing; 03114 } 03115 if (dialog->vrtp) { 03116 ast_rtp_setdtmf(dialog->vrtp, 0); 03117 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 03118 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 03119 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 03120 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 03121 } 03122 03123 ast_string_field_set(dialog, peername, peer->name); 03124 ast_string_field_set(dialog, authname, peer->username); 03125 ast_string_field_set(dialog, username, peer->username); 03126 ast_string_field_set(dialog, peersecret, peer->secret); 03127 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 03128 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 03129 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 03130 ast_string_field_set(dialog, tohost, peer->tohost); 03131 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 03132 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 03133 char *tmpcall; 03134 char *c; 03135 tmpcall = ast_strdupa(dialog->callid); 03136 c = strchr(tmpcall, '@'); 03137 if (c) { 03138 *c = '\0'; 03139 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 03140 } 03141 } 03142 if (ast_strlen_zero(dialog->tohost)) 03143 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 03144 if (!ast_strlen_zero(peer->fromdomain)) 03145 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 03146 if (!ast_strlen_zero(peer->fromuser)) 03147 ast_string_field_set(dialog, fromuser, peer->fromuser); 03148 if (!ast_strlen_zero(peer->language)) 03149 ast_string_field_set(dialog, language, peer->language); 03150 dialog->maxtime = peer->maxms; 03151 dialog->callgroup = peer->callgroup; 03152 dialog->pickupgroup = peer->pickupgroup; 03153 dialog->peerauth = peer->auth; 03154 dialog->allowtransfer = peer->allowtransfer; 03155 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 03156 /* Minimum is settable or default to 100 ms */ 03157 if (peer->maxms && peer->lastms) 03158 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 03159 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 03160 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 03161 dialog->noncodeccapability |= AST_RTP_DTMF; 03162 else 03163 dialog->noncodeccapability &= ~AST_RTP_DTMF; 03164 dialog->jointnoncodeccapability = dialog->noncodeccapability; 03165 ast_string_field_set(dialog, context, peer->context); 03166 dialog->rtptimeout = peer->rtptimeout; 03167 if (peer->call_limit) 03168 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 03169 dialog->maxcallbitrate = peer->maxcallbitrate; 03170 if (!dialog->portinuri) 03171 dialog->portinuri = peer->portinuri; 03172 03173 return 0; 03174 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8833 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(), and expire_register().
08834 { 08835 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08836 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 08837 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", NULL); 08838 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08839 } else 08840 ast_db_del("SIP/Registry", peer->name); 08841 } 08842 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 7667 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().
07668 { 07669 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07670 07671 if (!*e) 07672 return -1; 07673 req->rlPart1 = e; /* method or protocol */ 07674 e = ast_skip_nonblanks(e); 07675 if (*e) 07676 *e++ = '\0'; 07677 /* Get URI or status code */ 07678 e = ast_skip_blanks(e); 07679 if ( !*e ) 07680 return -1; 07681 ast_trim_blanks(e); 07682 07683 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07684 if (strlen(e) < 3) /* status code is 3 digits */ 07685 return -1; 07686 req->rlPart2 = e; 07687 } else { /* We have a request */ 07688 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07689 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07690 e++; 07691 if (!*e) 07692 return -1; 07693 } 07694 req->rlPart2 = e; /* URI */ 07695 e = ast_skip_nonblanks(e); 07696 if (*e) 07697 *e++ = '\0'; 07698 e = ast_skip_blanks(e); 07699 if (strcasecmp(e, "SIP/2.0") ) { 07700 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07701 return -1; 07702 } 07703 } 07704 return 1; 07705 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 17637 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_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), ast_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, check_extenstate_updates(), clearmarked_extenstate_updates(), DEADLOCK_AVOIDANCE, does_peer_need_mwi(), FALSE, iflist, iflock, io, LOG_DEBUG, LOG_NOTICE, markall_extenstate_updates(), monlock, sip_pvt::next, option_debug, option_verbose, peerl, sched, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_reload_lock, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, unmark_extenstate_update(), and VERBOSE_PREFIX_1.
17638 { 17639 int res; 17640 struct sip_pvt *sip; 17641 struct sip_peer *peer = NULL; 17642 time_t t; 17643 int fastrestart = FALSE; 17644 int lastpeernum = -1; 17645 int curpeernum; 17646 int reloading; 17647 17648 /* Add an I/O event to our SIP UDP socket */ 17649 if (sipsock > -1) 17650 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 17651 17652 /* From here on out, we die whenever asked */ 17653 for(;;) { 17654 /* Check for a reload request */ 17655 ast_mutex_lock(&sip_reload_lock); 17656 reloading = sip_reloading; 17657 sip_reloading = FALSE; 17658 ast_mutex_unlock(&sip_reload_lock); 17659 if (reloading) { 17660 if (option_verbose > 0) 17661 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 17662 sip_do_reload(sip_reloadreason); 17663 17664 /* Change the I/O fd of our UDP socket */ 17665 if (sipsock > -1) { 17666 if (sipsock_read_id) 17667 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 17668 else 17669 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 17670 } else if (sipsock_read_id) { 17671 ast_io_remove(io, sipsock_read_id); 17672 sipsock_read_id = NULL; 17673 } 17674 } 17675 17676 /* we only want to mark the extenstate updates for destruction 17677 * if the dialog list is being traversed */ 17678 if (!fastrestart) { 17679 markall_extenstate_updates(); 17680 } 17681 17682 restartsearch: 17683 /* Check for interfaces needing to be killed and for pending extension state notifications. */ 17684 ast_mutex_lock(&iflock); 17685 t = time(NULL); 17686 /* don't scan the interface list if it hasn't been a reasonable period 17687 of time since the last time we did it (when MWI is being sent, we can 17688 get back to this point every millisecond or less) 17689 */ 17690 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 17691 /*! \note If we can't get a lock on an interface, skip it and come 17692 * back later. Note that there is the possibility of a deadlock with 17693 * sip_hangup otherwise, because sip_hangup is called with the channel 17694 * locked first, and the iface lock is attempted second. 17695 */ 17696 if (ast_mutex_trylock(&sip->lock)) { 17697 /* make sure to unmark any extension state updates for this pvt so 17698 * they can be sent out when we come back to it. */ 17699 unmark_extenstate_update(sip); 17700 continue; 17701 } 17702 17703 /* since we are iterating through all the sip_pvts here, this is a good place 17704 * to send out extension state updates. */ 17705 check_extenstate_updates(sip); 17706 17707 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 17708 if (sip->rtp && sip->owner && 17709 (sip->owner->_state == AST_STATE_UP) && 17710 !sip->redirip.sin_addr.s_addr && 17711 sip->t38.state != T38_ENABLED) { 17712 if (sip->lastrtptx && 17713 ast_rtp_get_rtpkeepalive(sip->rtp) && 17714 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 17715 /* Need to send an empty RTP packet */ 17716 sip->lastrtptx = time(NULL); 17717 ast_rtp_sendcng(sip->rtp, 0); 17718 } 17719 if (sip->lastrtprx && 17720 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 17721 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 17722 /* Might be a timeout now -- see if we're on hold */ 17723 struct sockaddr_in sin = { 0, }; 17724 ast_rtp_get_peer(sip->rtp, &sin); 17725 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 17726 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 17727 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 17728 /* Needs a hangup */ 17729 if (ast_rtp_get_rtptimeout(sip->rtp)) { 17730 while (sip->owner && ast_channel_trylock(sip->owner)) { 17731 DEADLOCK_AVOIDANCE(&sip->lock); 17732 } 17733 if (sip->owner) { 17734 ast_log(LOG_NOTICE, 17735 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 17736 sip->owner->name, 17737 (long) (t - sip->lastrtprx)); 17738 /* Issue a softhangup */ 17739 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 17740 ast_channel_unlock(sip->owner); 17741 /* forget the timeouts for this call, since a hangup 17742 has already been requested and we don't want to 17743 repeatedly request hangups 17744 */ 17745 ast_rtp_set_rtptimeout(sip->rtp, 0); 17746 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 17747 if (sip->vrtp) { 17748 ast_rtp_set_rtptimeout(sip->vrtp, 0); 17749 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 17750 } 17751 } 17752 } 17753 } 17754 } 17755 } 17756 /* If we have sessions that needs to be destroyed, do it now */ 17757 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 17758 !sip->owner) { 17759 ast_mutex_unlock(&sip->lock); 17760 __sip_destroy(sip, 1); 17761 ast_mutex_unlock(&iflock); 17762 usleep(1); 17763 goto restartsearch; 17764 } 17765 ast_mutex_unlock(&sip->lock); 17766 } 17767 ast_mutex_unlock(&iflock); 17768 17769 /* we only want to clear the extension state updates if the dialog list was traversed */ 17770 if (!fastrestart) { 17771 clearmarked_extenstate_updates(); 17772 } 17773 17774 /* XXX TODO The scheduler usage in this module does not have sufficient 17775 * synchronization being done between running the scheduler and places 17776 * scheduling tasks. As it is written, any scheduled item may not run 17777 * any sooner than about 1 second, regardless of whether a sooner time 17778 * was asked for. */ 17779 17780 pthread_testcancel(); 17781 /* Wait for sched or io */ 17782 res = ast_sched_wait(sched); 17783 if ((res < 0) || (res > 1000)) 17784 res = 1000; 17785 /* If we might need to send more mailboxes, don't wait long at all.*/ 17786 if (fastrestart) 17787 res = 1; 17788 res = ast_io_wait(io, res); 17789 if (option_debug && res > 20) 17790 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 17791 ast_mutex_lock(&monlock); 17792 res = ast_sched_runq(sched); 17793 if (option_debug && res >= 20) 17794 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 17795 17796 /* Send MWI notifications to peers - static and cached realtime peers */ 17797 t = time(NULL); 17798 fastrestart = FALSE; 17799 curpeernum = 0; 17800 peer = NULL; 17801 /* Find next peer that needs mwi */ 17802 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 17803 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 17804 fastrestart = TRUE; 17805 lastpeernum = curpeernum; 17806 peer = ASTOBJ_REF(iterator); 17807 }; 17808 curpeernum++; 17809 } while (0) 17810 ); 17811 /* Send MWI to the peer */ 17812 if (peer) { 17813 ASTOBJ_WRLOCK(peer); 17814 sip_send_mwi_to_peer(peer, FALSE); 17815 ASTOBJ_UNLOCK(peer); 17816 ASTOBJ_UNREF(peer,sip_destroy_peer); 17817 } else { 17818 /* Reset where we come from */ 17819 lastpeernum = -1; 17820 } 17821 ast_mutex_unlock(&monlock); 17822 } 17823 /* Never reached */ 17824 return NULL; 17825 17826 }
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 12872 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().
12873 { 12874 char digest[1024]; 12875 12876 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 12877 return -2; 12878 12879 p->authtries++; 12880 if (option_debug > 1) 12881 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 12882 memset(digest, 0, sizeof(digest)); 12883 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 12884 /* No way to authenticate */ 12885 return -1; 12886 } 12887 /* Now we have a reply digest */ 12888 p->options->auth = digest; 12889 p->options->authheader = respheader; 12890 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 12891 }
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 12851 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().
12852 { 12853 char digest[1024]; 12854 p->authtries++; 12855 memset(digest,0,sizeof(digest)); 12856 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 12857 /* There's nothing to use for authentication */ 12858 /* No digest challenge in request */ 12859 if (sip_debug_test_pvt(p) && p->registry) 12860 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 12861 /* No old challenge */ 12862 return -1; 12863 } 12864 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 12865 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 12866 if (sip_debug_test_pvt(p) && p->registry) 12867 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 12868 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 12869 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 3044 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().
03045 { 03046 const char *mode = natflags ? "On" : "Off"; 03047 03048 if (p->rtp) { 03049 if (option_debug) 03050 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 03051 ast_rtp_setnat(p->rtp, natflags); 03052 } 03053 if (p->vrtp) { 03054 if (option_debug) 03055 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 03056 ast_rtp_setnat(p->vrtp, natflags); 03057 } 03058 if (p->udptl) { 03059 if (option_debug) 03060 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 03061 ast_udptl_setnat(p->udptl, natflags); 03062 } 03063 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 17616 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.
Referenced by do_monitor().
17617 { 17618 time_t t = time(NULL); 17619 17620 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 17621 !peer->mwipvt) { /* We don't have a subscription */ 17622 peer->lastmsgcheck = t; /* Reset timer */ 17623 return FALSE; 17624 } 17625 17626 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 17627 return TRUE; 17628 17629 return FALSE; 17630 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 11685 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
11686 { 11687 switch (mode) { 11688 case SIP_DOMAIN_AUTO: 11689 return "[Automatic]"; 11690 case SIP_DOMAIN_CONFIG: 11691 return "[Configured]"; 11692 } 11693 11694 return ""; 11695 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 11458 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().
11459 { 11460 switch (mode) { 11461 case SIP_DTMF_RFC2833: 11462 return "rfc2833"; 11463 case SIP_DTMF_INFO: 11464 return "info"; 11465 case SIP_DTMF_INBAND: 11466 return "inband"; 11467 case SIP_DTMF_AUTO: 11468 return "auto"; 11469 } 11470 return "<error>"; 11471 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8845 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().
08846 { 08847 struct sip_peer *peer = (struct sip_peer *)data; 08848 08849 if (!peer) /* Hmmm. We have no peer. Weird. */ 08850 return 0; 08851 08852 memset(&peer->addr, 0, sizeof(peer->addr)); 08853 08854 destroy_association(peer); /* remove registration data from storage */ 08855 08856 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08857 register_peer_exten(peer, FALSE); /* Remove regexten */ 08858 peer->expire = -1; 08859 peer->portinuri = 0; 08860 ast_device_state_changed("SIP/%s", peer->name); 08861 08862 /* Do we need to release this peer from memory? 08863 Only for realtime peers and autocreated peers 08864 */ 08865 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08866 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08867 struct sip_peer *peer_ptr = peer_ptr; 08868 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08869 if (peer_ptr) { 08870 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08871 } 08872 } 08873 08874 ASTOBJ_UNREF(peer, sip_destroy_peer); 08875 08876 return 0; 08877 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7759 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().
07760 { 07761 char stripped[SIPBUFSIZE]; 07762 char *c; 07763 07764 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07765 c = get_in_brackets(stripped); 07766 c = strsep(&c, ";"); /* trim ; and beyond */ 07767 if (!ast_strlen_zero(c)) 07768 ast_string_field_set(p, uri, c); 07769 }
static int finalize_content | ( | struct sip_request * | req | ) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 6469 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), sip_request::content, sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
06470 { 06471 char clen[10]; 06472 06473 if (req->lines) { 06474 ast_log(LOG_WARNING, "finalize_content() called on a message that has already been finalized\n"); 06475 return -1; 06476 } 06477 06478 snprintf(clen, sizeof(clen), "%zd", strlen(req->content)); 06479 add_header(req, "Content-Length", clen); 06480 06481 if (!ast_strlen_zero(req->content)) { 06482 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n%s", req->content); 06483 req->len += strlen(req->data + req->len); 06484 } 06485 06486 req->lines = !ast_strlen_zero(req->content); 06487 return 0; 06488 }
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 4638 of file chan_sip.c.
References aliases.
04639 { 04640 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04641 static const struct cfalias { 04642 char * const fullname; 04643 char * const shortname; 04644 } aliases[] = { 04645 { "Content-Type", "c" }, 04646 { "Content-Encoding", "e" }, 04647 { "From", "f" }, 04648 { "Call-ID", "i" }, 04649 { "Contact", "m" }, 04650 { "Content-Length", "l" }, 04651 { "Subject", "s" }, 04652 { "To", "t" }, 04653 { "Supported", "k" }, 04654 { "Refer-To", "r" }, 04655 { "Referred-By", "b" }, 04656 { "Allow-Events", "u" }, 04657 { "Event", "o" }, 04658 { "Via", "v" }, 04659 { "Accept-Contact", "a" }, 04660 { "Reject-Contact", "j" }, 04661 { "Request-Disposition", "d" }, 04662 { "Session-Expires", "x" }, 04663 { "Identity", "y" }, 04664 { "Identity-Info", "n" }, 04665 }; 04666 int x; 04667 04668 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04669 if (!strcasecmp(aliases[x].fullname, name)) 04670 return aliases[x].shortname; 04671 04672 return _default; 04673 }
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 5189 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().
05190 { 05191 struct sip_pvt *p = NULL; 05192 char *tag = ""; /* note, tag is never NULL */ 05193 char totag[128]; 05194 char fromtag[128]; 05195 const char *callid = get_header(req, "Call-ID"); 05196 const char *from = get_header(req, "From"); 05197 const char *to = get_header(req, "To"); 05198 const char *cseq = get_header(req, "Cseq"); 05199 05200 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 05201 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 05202 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 05203 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 05204 return NULL; /* Invalid packet */ 05205 05206 if (pedanticsipchecking) { 05207 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 05208 we need more to identify a branch - so we have to check branch, from 05209 and to tags to identify a call leg. 05210 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 05211 in sip.conf 05212 */ 05213 if (gettag(req, "To", totag, sizeof(totag))) 05214 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 05215 gettag(req, "From", fromtag, sizeof(fromtag)); 05216 05217 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 05218 05219 if (option_debug > 4 ) 05220 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); 05221 } 05222 05223 ast_mutex_lock(&iflock); 05224 for (p = iflist; p; p = p->next) { 05225 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 05226 int found = FALSE; 05227 if (ast_strlen_zero(p->callid)) 05228 continue; 05229 if (req->method == SIP_REGISTER) 05230 found = (!strcmp(p->callid, callid)); 05231 else { 05232 found = !strcmp(p->callid, callid); 05233 if (pedanticsipchecking && found) { 05234 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 05235 } 05236 } 05237 05238 if (option_debug > 4) 05239 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); 05240 05241 /* If we get a new request within an existing to-tag - check the to tag as well */ 05242 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 05243 if (p->tag[0] == '\0' && totag[0]) { 05244 /* We have no to tag, but they have. Wrong dialog */ 05245 found = FALSE; 05246 } else if (totag[0]) { /* Both have tags, compare them */ 05247 if (strcmp(totag, p->tag)) { 05248 found = FALSE; /* This is not our packet */ 05249 } 05250 } 05251 if (!found && option_debug > 4) 05252 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); 05253 } 05254 if (found) { 05255 /* Found the call */ 05256 ast_mutex_lock(&p->lock); 05257 ast_mutex_unlock(&iflock); 05258 return p; 05259 } 05260 } 05261 ast_mutex_unlock(&iflock); 05262 05263 /* See if the method is capable of creating a dialog */ 05264 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 05265 if (intended_method == SIP_REFER) { 05266 /* We do support REFER, but not outside of a dialog yet */ 05267 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 05268 } else if (intended_method == SIP_NOTIFY) { 05269 /* We do not support out-of-dialog NOTIFY either, 05270 like voicemail notification, so cancel that early */ 05271 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 No subscription"); 05272 } else { 05273 /* Ok, time to create a new SIP dialog object, a pvt */ 05274 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 05275 /* Ok, we've created a dialog, let's go and process it */ 05276 ast_mutex_lock(&p->lock); 05277 } else { 05278 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 05279 getting a dialog from sip_alloc. 05280 05281 Without a dialog we can't retransmit and handle ACKs and all that, but at least 05282 send an error message. 05283 05284 Sorry, we apologize for the inconvienience 05285 */ 05286 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 05287 if (option_debug > 3) 05288 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 05289 } 05290 } 05291 return p; 05292 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 05293 /* A method we do not support, let's take it on the volley */ 05294 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 05295 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 05296 /* This is a request outside of a dialog that we don't know about 05297 ...never reply to an ACK! 05298 */ 05299 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 05300 } 05301 /* We do not respond to responses for dialogs that we don't know about, we just drop 05302 the session quickly */ 05303 05304 return p; 05305 }
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 2594 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02595 { 02596 char last_char = '\0'; 02597 const char *s; 02598 for (s = start; *s && s != lim; last_char = *s++) { 02599 if (*s == '"' && last_char != '\\') 02600 break; 02601 } 02602 return s; 02603 }
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 2956 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02957 { 02958 struct sip_peer *p = NULL; 02959 02960 if (peer) 02961 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02962 else 02963 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02964 02965 if (!p && (realtime || devstate_only)) 02966 p = realtime_peer(peer, sin, devstate_only); 02967 02968 return p; 02969 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 18479 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
18480 { 18481 struct sip_auth *a; 18482 18483 for (a = authlist; a; a = a->next) { 18484 if (!strcasecmp(a->realm, realm)) 18485 break; 18486 } 18487 18488 return a; 18489 }
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 5525 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().
05526 { 05527 const char *content_type; 05528 const char *content_length; 05529 const char *search; 05530 char *boundary; 05531 unsigned int x; 05532 int boundaryisquoted = FALSE; 05533 int found_application_sdp = FALSE; 05534 int found_end_of_headers = FALSE; 05535 05536 content_length = get_header(req, "Content-Length"); 05537 05538 if (!ast_strlen_zero(content_length)) { 05539 if (sscanf(content_length, "%30u", &x) != 1) { 05540 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05541 return 0; 05542 } 05543 05544 /* Content-Length of zero means there can't possibly be an 05545 SDP here, even if the Content-Type says there is */ 05546 if (x == 0) 05547 return 0; 05548 } 05549 05550 content_type = get_header(req, "Content-Type"); 05551 05552 /* if the body contains only SDP, this is easy */ 05553 if (!strncasecmp(content_type, "application/sdp", 15)) { 05554 req->sdp_start = 0; 05555 req->sdp_count = req->lines; 05556 return req->lines ? 1 : 0; 05557 } 05558 05559 /* if it's not multipart/mixed, there cannot be an SDP */ 05560 if (strncasecmp(content_type, "multipart/mixed", 15)) 05561 return 0; 05562 05563 /* if there is no boundary marker, it's invalid */ 05564 if ((search = strcasestr(content_type, ";boundary="))) 05565 search += 10; 05566 else if ((search = strcasestr(content_type, "; boundary="))) 05567 search += 11; 05568 else 05569 return 0; 05570 05571 if (ast_strlen_zero(search)) 05572 return 0; 05573 05574 /* If the boundary is quoted with ", remove quote */ 05575 if (*search == '\"') { 05576 search++; 05577 boundaryisquoted = TRUE; 05578 } 05579 05580 /* make a duplicate of the string, with two extra characters 05581 at the beginning */ 05582 boundary = ast_strdupa(search - 2); 05583 boundary[0] = boundary[1] = '-'; 05584 /* Remove final quote */ 05585 if (boundaryisquoted) 05586 boundary[strlen(boundary) - 1] = '\0'; 05587 05588 /* search for the boundary marker, the empty line delimiting headers from 05589 sdp part and the end boundry if it exists */ 05590 05591 for (x = 0; x < (req->lines ); x++) { 05592 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05593 if(found_application_sdp && found_end_of_headers){ 05594 req->sdp_count = (x - 1) - req->sdp_start; 05595 return 1; 05596 } 05597 found_application_sdp = FALSE; 05598 } 05599 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05600 found_application_sdp = TRUE; 05601 05602 if(strlen(req->line[x]) == 0 ){ 05603 if(found_application_sdp && !found_end_of_headers){ 05604 req->sdp_start = x; 05605 found_end_of_headers = TRUE; 05606 } 05607 } 05608 } 05609 if(found_application_sdp && found_end_of_headers) { 05610 req->sdp_count = x - req->sdp_start; 05611 return TRUE; 05612 } 05613 return FALSE; 05614 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1795 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().
01796 { 01797 int i, res = 0; 01798 01799 if (ast_strlen_zero(msg)) 01800 return 0; 01801 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01802 if (method_match(i, msg)) 01803 res = sip_methods[i].id; 01804 } 01805 return res; 01806 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 12175 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
12176 { 12177 int i; 12178 12179 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 12180 if (subscription_types[i].type == subtype) { 12181 return &subscription_types[i]; 12182 } 12183 } 12184 return &subscription_types[0]; 12185 }
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 3035 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
03036 { 03037 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 03038 if (!u && realtime) 03039 u = realtime_user(name); 03040 return u; 03041 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 9256 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
09257 { 09258 struct sip_route *next; 09259 09260 while (route) { 09261 next = route->next; 09262 free(route); 09263 route = next; 09264 } 09265 }
static void free_via | ( | struct sip_via * | v | ) | [static] |
Definition at line 5008 of file chan_sip.c.
References ast_free, and sip_via::via.
Referenced by parse_via(), and process_via().
05009 { 05010 if (!v) { 05011 return; 05012 } 05013 05014 ast_free(v->via); 05015 ast_free(v); 05016 }
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 13208 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
13209 { 13210 if (ast_strlen_zero(data)) { 13211 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 13212 return -1; 13213 } 13214 if (check_sip_domain(data, NULL, 0)) 13215 ast_copy_string(buf, data, len); 13216 else 13217 buf[0] = '\0'; 13218 return 0; 13219 }
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 13144 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.
13145 { 13146 struct sip_pvt *p; 13147 const char *content = NULL; 13148 AST_DECLARE_APP_ARGS(args, 13149 AST_APP_ARG(header); 13150 AST_APP_ARG(number); 13151 ); 13152 int i, number, start = 0; 13153 13154 if (ast_strlen_zero(data)) { 13155 ast_log(LOG_WARNING, "This function requires a header name.\n"); 13156 return -1; 13157 } 13158 13159 ast_channel_lock(chan); 13160 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 13161 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 13162 ast_channel_unlock(chan); 13163 return -1; 13164 } 13165 13166 AST_STANDARD_APP_ARGS(args, data); 13167 if (!args.number) { 13168 number = 1; 13169 } else { 13170 sscanf(args.number, "%30d", &number); 13171 if (number < 1) 13172 number = 1; 13173 } 13174 13175 p = chan->tech_pvt; 13176 13177 /* If there is no private structure, this channel is no longer alive */ 13178 if (!p) { 13179 ast_channel_unlock(chan); 13180 return -1; 13181 } 13182 13183 for (i = 0; i < number; i++) 13184 content = __get_header(&p->initreq, args.header, &start); 13185 13186 if (ast_strlen_zero(content)) { 13187 ast_channel_unlock(chan); 13188 return -1; 13189 } 13190 13191 ast_copy_string(buf, content, len); 13192 ast_channel_unlock(chan); 13193 13194 return 0; 13195 }
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 13327 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.
13328 { 13329 struct sip_pvt *p; 13330 13331 *buf = 0; 13332 13333 if (!data) { 13334 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 13335 return -1; 13336 } 13337 13338 ast_channel_lock(chan); 13339 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 13340 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 13341 ast_channel_unlock(chan); 13342 return -1; 13343 } 13344 13345 p = chan->tech_pvt; 13346 13347 /* If there is no private structure, this channel is no longer alive */ 13348 if (!p) { 13349 ast_channel_unlock(chan); 13350 return -1; 13351 } 13352 13353 if (!strcasecmp(data, "peerip")) { 13354 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 13355 } else if (!strcasecmp(data, "recvip")) { 13356 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 13357 } else if (!strcasecmp(data, "from")) { 13358 ast_copy_string(buf, p->from, len); 13359 } else if (!strcasecmp(data, "uri")) { 13360 ast_copy_string(buf, p->uri, len); 13361 } else if (!strcasecmp(data, "useragent")) { 13362 ast_copy_string(buf, p->useragent, len); 13363 } else if (!strcasecmp(data, "peername")) { 13364 ast_copy_string(buf, p->peername, len); 13365 } else if (!strcasecmp(data, "t38passthrough")) { 13366 if (p->t38.state == T38_DISABLED) { 13367 ast_copy_string(buf, "0", len); 13368 } else { /* T38 is offered or enabled in this call */ 13369 ast_copy_string(buf, "1", len); 13370 } 13371 } else { 13372 ast_channel_unlock(chan); 13373 return -1; 13374 } 13375 ast_channel_unlock(chan); 13376 13377 return 0; 13378 }
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 13233 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.
13234 { 13235 struct sip_peer *peer; 13236 char *colname; 13237 13238 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 13239 *colname++ = '\0'; 13240 else if ((colname = strchr(data, '|'))) 13241 *colname++ = '\0'; 13242 else 13243 colname = "ip"; 13244 13245 if (!(peer = find_peer(data, NULL, 1, 0))) 13246 return -1; 13247 13248 if (!strcasecmp(colname, "ip")) { 13249 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 13250 } else if (!strcasecmp(colname, "status")) { 13251 peer_status(peer, buf, len); 13252 } else if (!strcasecmp(colname, "language")) { 13253 ast_copy_string(buf, peer->language, len); 13254 } else if (!strcasecmp(colname, "regexten")) { 13255 ast_copy_string(buf, peer->regexten, len); 13256 } else if (!strcasecmp(colname, "limit")) { 13257 snprintf(buf, len, "%d", peer->call_limit); 13258 } else if (!strcasecmp(colname, "curcalls")) { 13259 snprintf(buf, len, "%d", peer->inUse); 13260 } else if (!strcasecmp(colname, "accountcode")) { 13261 ast_copy_string(buf, peer->accountcode, len); 13262 } else if (!strcasecmp(colname, "useragent")) { 13263 ast_copy_string(buf, peer->useragent, len); 13264 } else if (!strcasecmp(colname, "mailbox")) { 13265 ast_copy_string(buf, peer->mailbox, len); 13266 } else if (!strcasecmp(colname, "context")) { 13267 ast_copy_string(buf, peer->context, len); 13268 } else if (!strcasecmp(colname, "expire")) { 13269 snprintf(buf, len, "%d", peer->expire); 13270 } else if (!strcasecmp(colname, "dynamic")) { 13271 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 13272 } else if (!strcasecmp(colname, "callerid_name")) { 13273 ast_copy_string(buf, peer->cid_name, len); 13274 } else if (!strcasecmp(colname, "callerid_num")) { 13275 ast_copy_string(buf, peer->cid_num, len); 13276 } else if (!strcasecmp(colname, "codecs")) { 13277 ast_getformatname_multiple(buf, len -1, peer->capability); 13278 } else if (!strncasecmp(colname, "codec[", 6)) { 13279 char *codecnum; 13280 int index = 0, codec = 0; 13281 13282 codecnum = colname + 6; /* move past the '[' */ 13283 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 13284 index = atoi(codecnum); 13285 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 13286 ast_copy_string(buf, ast_getformatname(codec), len); 13287 } else { 13288 buf[0] = '\0'; 13289 } 13290 } else { 13291 buf[0] = '\0'; 13292 } 13293 13294 ASTOBJ_UNREF(peer, sip_destroy_peer); 13295 13296 return 0; 13297 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4830 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04831 { 04832 long val[4]; 04833 int x; 04834 04835 for (x=0; x<4; x++) 04836 val[x] = ast_random(); 04837 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04838 04839 return buf; 04840 }
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 10509 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().
10510 { 10511 char tmp[256] = "", *c, *a; 10512 struct sip_request *req = oreq ? oreq : &p->initreq; 10513 struct sip_refer *referdata = NULL; 10514 const char *transfer_context = NULL; 10515 10516 if (!p->refer && !sip_refer_allocate(p)) 10517 return -1; 10518 10519 referdata = p->refer; 10520 10521 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 10522 c = get_in_brackets(tmp); 10523 10524 if (pedanticsipchecking) 10525 ast_uri_decode(c); 10526 10527 if (strncasecmp(c, "sip:", 4)) { 10528 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 10529 return -1; 10530 } 10531 c += 4; 10532 if ((a = strchr(c, ';'))) /* Remove arguments */ 10533 *a = '\0'; 10534 10535 if ((a = strchr(c, '@'))) { /* Separate Domain */ 10536 *a++ = '\0'; 10537 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 10538 } 10539 10540 if (sip_debug_test_pvt(p)) 10541 ast_verbose("Looking for %s in %s\n", c, p->context); 10542 10543 if (p->owner) /* Mimic behaviour in res_features.c */ 10544 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 10545 10546 /* By default, use the context in the channel sending the REFER */ 10547 if (ast_strlen_zero(transfer_context)) { 10548 transfer_context = S_OR(p->owner->macrocontext, 10549 S_OR(p->context, default_context)); 10550 } 10551 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 10552 /* This is a blind transfer */ 10553 if (option_debug) 10554 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 10555 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 10556 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 10557 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 10558 referdata->refer_call = NULL; 10559 /* Set new context */ 10560 ast_string_field_set(p, context, transfer_context); 10561 return 0; 10562 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 10563 return 1; 10564 } 10565 10566 return -1; 10567 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4622 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04623 { 04624 int x; 04625 int len = strlen(name); 04626 char *r; 04627 04628 for (x = 0; x < req->lines; x++) { 04629 r = get_body_by_line(req->line[x], name, len); 04630 if (r[0] != '\0') 04631 return r; 04632 } 04633 04634 return ""; 04635 }
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 4567 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04568 { 04569 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04570 return ast_skip_blanks(line + nameLen + 1); 04571 04572 return ""; 04573 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 10632 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
10633 { 10634 const char *end = strchr(input,'<'); /* first_bracket */ 10635 const char *tmp = strchr(input,'"'); /* first quote */ 10636 int bytes = 0; 10637 int maxbytes = outputsize - 1; 10638 10639 if (!end || end == input) /* we require a part in brackets */ 10640 return NULL; 10641 10642 end--; /* move just before "<" */ 10643 10644 if (tmp && tmp <= end) { 10645 /* The quote (tmp) precedes the bracket (end+1). 10646 * Find the matching quote and return the content. 10647 */ 10648 end = strchr(tmp+1, '"'); 10649 if (!end) 10650 return NULL; 10651 bytes = (int) (end - tmp); 10652 /* protect the output buffer */ 10653 if (bytes > maxbytes) 10654 bytes = maxbytes; 10655 ast_copy_string(output, tmp + 1, bytes); 10656 } else { 10657 /* No quoted string, or it is inside brackets. */ 10658 /* clear the empty characters in the begining*/ 10659 input = ast_skip_blanks(input); 10660 /* clear the empty characters in the end */ 10661 while(*end && *end < 33 && end > input) 10662 end--; 10663 if (end >= input) { 10664 bytes = (int) (end - input) + 2; 10665 /* protect the output buffer */ 10666 if (bytes > maxbytes) 10667 bytes = maxbytes; 10668 ast_copy_string(output, input, bytes); 10669 } else 10670 return NULL; 10671 } 10672 return output; 10673 }
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 10131 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, 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().
10132 { 10133 char tmp[256] = "", *uri, *a; 10134 char tmpf[256] = "", *from; 10135 struct sip_request *req; 10136 char *colon; 10137 char *decoded_uri; 10138 10139 req = oreq; 10140 if (!req) 10141 req = &p->initreq; 10142 10143 /* Find the request URI */ 10144 if (req->rlPart2) 10145 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 10146 10147 if (pedanticsipchecking) 10148 ast_uri_decode(tmp); 10149 10150 uri = get_in_brackets(tmp); 10151 10152 if (strncasecmp(uri, "sip:", 4)) { 10153 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 10154 return -1; 10155 } 10156 uri += 4; 10157 10158 /* Now find the From: caller ID and name */ 10159 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 10160 if (!ast_strlen_zero(tmpf)) { 10161 if (pedanticsipchecking) 10162 ast_uri_decode(tmpf); 10163 from = get_in_brackets(tmpf); 10164 } else { 10165 from = NULL; 10166 } 10167 10168 if (!ast_strlen_zero(from)) { 10169 if (strncasecmp(from, "sip:", 4)) { 10170 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 10171 return -1; 10172 } 10173 from += 4; 10174 if ((a = strchr(from, '@'))) 10175 *a++ = '\0'; 10176 else 10177 a = from; /* just a domain */ 10178 from = strsep(&from, ";"); /* Remove userinfo options */ 10179 a = strsep(&a, ";"); /* Remove URI options */ 10180 ast_string_field_set(p, fromdomain, a); 10181 } 10182 10183 /* Skip any options and find the domain */ 10184 10185 /* Get the target domain */ 10186 if ((a = strchr(uri, '@'))) { 10187 *a++ = '\0'; 10188 } else { /* No username part */ 10189 a = uri; 10190 uri = "s"; /* Set extension to "s" */ 10191 } 10192 colon = strchr(a, ':'); /* Remove :port */ 10193 if (colon) 10194 *colon = '\0'; 10195 10196 uri = strsep(&uri, ";"); /* Remove userinfo options */ 10197 a = strsep(&a, ";"); /* Remove URI options */ 10198 10199 ast_string_field_set(p, domain, a); 10200 10201 if (!AST_LIST_EMPTY(&domain_list)) { 10202 char domain_context[AST_MAX_EXTENSION]; 10203 10204 domain_context[0] = '\0'; 10205 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 10206 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 10207 if (option_debug) 10208 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 10209 return -2; 10210 } 10211 } 10212 /* If we have a context defined, overwrite the original context */ 10213 if (!ast_strlen_zero(domain_context)) 10214 ast_string_field_set(p, context, domain_context); 10215 } 10216 10217 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 10218 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 10219 ast_string_field_set(p, context, p->subscribecontext); 10220 10221 if (sip_debug_test_pvt(p)) 10222 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 10223 10224 /* Since extensions.conf can have unescaped characters, try matching a 10225 * decoded uri in addition to the non-decoded uri. */ 10226 decoded_uri = ast_strdupa(uri); 10227 ast_uri_decode(decoded_uri); 10228 10229 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 10230 if (req->method == SIP_SUBSCRIBE) { 10231 char hint[AST_MAX_EXTENSION]; 10232 int which = 0; 10233 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) || 10234 (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) { 10235 if (!oreq) { 10236 ast_string_field_set(p, exten, which ? decoded_uri : uri); 10237 } 10238 return 0; 10239 } else { 10240 return -1; 10241 } 10242 } else { 10243 int which = 0; 10244 /* Check the dialplan for the username part of the request URI, 10245 the domain will be stored in the SIPDOMAIN variable 10246 Return 0 if we have a matching extension */ 10247 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || 10248 (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) || 10249 !strcmp(decoded_uri, ast_pickup_ext())) { 10250 if (!oreq) { 10251 ast_string_field_set(p, exten, which ? decoded_uri : uri); 10252 } 10253 return 0; 10254 } 10255 } 10256 10257 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 10258 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 10259 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 10260 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 10261 return 1; 10262 } 10263 10264 return -1; 10265 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4711 of file chan_sip.c.
References __get_header().
04712 { 04713 int start = 0; 04714 return __get_header(req, name, &start); 04715 }
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 2616 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().
02617 { 02618 const char *parse = tmp; 02619 char *first_bracket; 02620 02621 /* 02622 * Skip any quoted text until we find the part in brackets. 02623 * On any error give up and return the full string. 02624 */ 02625 while ( (first_bracket = strchr(parse, '<')) ) { 02626 char *first_quote = strchr(parse, '"'); 02627 02628 if (!first_quote || first_quote > first_bracket) 02629 break; /* no need to look at quoted part */ 02630 /* the bracket is within quotes, so ignore it */ 02631 parse = find_closing_quote(first_quote + 1, NULL); 02632 if (!*parse) { /* not found, return full string ? */ 02633 /* XXX or be robust and return in-bracket part ? */ 02634 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02635 break; 02636 } 02637 parse++; 02638 } 02639 if (first_bracket) { 02640 char *second_bracket = strchr(first_bracket + 1, '>'); 02641 if (second_bracket) { 02642 *second_bracket = '\0'; 02643 tmp = first_bracket + 1; 02644 } else { 02645 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02646 } 02647 } 02648 return tmp; 02649 }
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 5649 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().
05650 { 05651 const char *m; 05652 const char *c; 05653 int miterator = req->sdp_start; 05654 int citerator = req->sdp_start; 05655 int x = 0; 05656 int numberofports; 05657 int len; 05658 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 05659 struct ast_hostent audiohp; 05660 struct hostent *hp; 05661 05662 c = get_sdp_iterate(&citerator, req, "c"); 05663 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05664 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05665 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 05666 } 05667 /* We only want the m and c lines for audio */ 05668 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 05669 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05670 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 05671 (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05672 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 05673 /* See if there's a c= line for this media stream. 05674 * XXX There is no guarantee that we'll be grabbing the c= line for this 05675 * particular media stream here. However, this is the same logic used in process_sdp. 05676 */ 05677 c = get_sdp_iterate(&citerator, req, "c"); 05678 if (!ast_strlen_zero(c)) { 05679 sscanf(c, "IN IP4 %256s", host); 05680 } 05681 break; 05682 } 05683 } 05684 05685 if (ast_strlen_zero(host) || x == 0) { 05686 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 05687 return -1; 05688 } 05689 05690 hp = ast_gethostbyname(host, &audiohp); 05691 if (!hp) { 05692 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 05693 return -1; 05694 } 05695 05696 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 05697 sin->sin_port = htons(x); 05698 return 0; 05699 }
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 11051 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
11052 { 11053 int x; 11054 int y; 11055 11056 buf[0] = '\0'; 11057 y = len - strlen(buf) - 5; 11058 if (y < 0) 11059 y = 0; 11060 for (x=0;x<req->lines;x++) { 11061 strncat(buf, req->line[x], y); /* safe */ 11062 y -= strlen(req->line[x]) + 1; 11063 if (y < 0) 11064 y = 0; 11065 if (y != 0) 11066 strcat(buf, "\n"); /* safe */ 11067 } 11068 return 0; 11069 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 10102 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().
10103 { 10104 char tmp[256], *c, *a; 10105 struct sip_request *req; 10106 10107 req = oreq; 10108 if (!req) 10109 req = &p->initreq; 10110 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 10111 if (ast_strlen_zero(tmp)) 10112 return 0; 10113 c = get_in_brackets(tmp); 10114 if (strncasecmp(c, "sip:", 4)) { 10115 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 10116 return -1; 10117 } 10118 c += 4; 10119 a = c; 10120 strsep(&a, "@;"); /* trim anything after @ or ; */ 10121 if (sip_debug_test_pvt(p)) 10122 ast_verbose("RDNIS is %s\n", c); 10123 ast_string_field_set(p, rdnis, c); 10124 10125 return 0; 10126 }
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 10338 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::callid, 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, sip_debug_test_pvt(), sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_refer().
10339 { 10340 10341 const char *p_referred_by = NULL; 10342 char *h_refer_to = NULL; 10343 char *h_referred_by = NULL; 10344 char *refer_to; 10345 const char *p_refer_to; 10346 char *referred_by_uri = NULL; 10347 char *ptr; 10348 struct sip_request *req = NULL; 10349 const char *transfer_context = NULL; 10350 struct sip_refer *referdata; 10351 10352 10353 req = outgoing_req; 10354 referdata = transferer->refer; 10355 10356 if (!req) 10357 req = &transferer->initreq; 10358 10359 p_refer_to = get_header(req, "Refer-To"); 10360 if (ast_strlen_zero(p_refer_to)) { 10361 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 10362 return -2; /* Syntax error */ 10363 } 10364 h_refer_to = ast_strdupa(p_refer_to); 10365 refer_to = get_in_brackets(h_refer_to); 10366 if (pedanticsipchecking) 10367 ast_uri_decode(refer_to); 10368 10369 if (strncasecmp(refer_to, "sip:", 4)) { 10370 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 10371 return -3; 10372 } 10373 refer_to += 4; /* Skip sip: */ 10374 10375 /* Get referred by header if it exists */ 10376 p_referred_by = get_header(req, "Referred-By"); 10377 if (!ast_strlen_zero(p_referred_by)) { 10378 char *lessthan; 10379 h_referred_by = ast_strdupa(p_referred_by); 10380 if (pedanticsipchecking) 10381 ast_uri_decode(h_referred_by); 10382 10383 /* Store referrer's caller ID name */ 10384 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 10385 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 10386 *(lessthan - 1) = '\0'; /* Space */ 10387 } 10388 10389 referred_by_uri = get_in_brackets(h_referred_by); 10390 if(strncasecmp(referred_by_uri, "sip:", 4)) { 10391 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 10392 referred_by_uri = (char *) NULL; 10393 } else { 10394 referred_by_uri += 4; /* Skip sip: */ 10395 } 10396 } 10397 10398 /* Check for arguments in the refer_to header */ 10399 if ((ptr = strcasestr(refer_to, "replaces="))) { 10400 char *to = NULL, *from = NULL; 10401 10402 /* This is an attended transfer */ 10403 referdata->attendedtransfer = 1; 10404 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 10405 ast_uri_decode(referdata->replaces_callid); 10406 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 10407 *ptr++ = '\0'; 10408 } 10409 10410 if (ptr) { 10411 /* Find the different tags before we destroy the string */ 10412 to = strcasestr(ptr, "to-tag="); 10413 from = strcasestr(ptr, "from-tag="); 10414 } 10415 10416 /* Grab the to header */ 10417 if (to) { 10418 ptr = to + 7; 10419 if ((to = strchr(ptr, '&'))) 10420 *to = '\0'; 10421 if ((to = strchr(ptr, ';'))) 10422 *to = '\0'; 10423 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 10424 } 10425 10426 if (from) { 10427 ptr = from + 9; 10428 if ((to = strchr(ptr, '&'))) 10429 *to = '\0'; 10430 if ((to = strchr(ptr, ';'))) 10431 *to = '\0'; 10432 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 10433 } 10434 10435 if (!strcmp(referdata->replaces_callid, transferer->callid) && 10436 (!pedanticsipchecking || 10437 (!strcmp(referdata->replaces_callid_fromtag, transferer->theirtag) && 10438 !strcmp(referdata->replaces_callid_totag, transferer->tag)))) { 10439 ast_log(LOG_WARNING, "Got an attempt to replace own Call-ID on %s\n", transferer->callid); 10440 return -4; 10441 } 10442 10443 if (option_debug > 1) { 10444 if (!pedanticsipchecking) 10445 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 10446 else 10447 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>" ); 10448 } 10449 } 10450 10451 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 10452 char *urioption = NULL, *domain; 10453 *ptr++ = '\0'; 10454 10455 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 10456 *urioption++ = '\0'; 10457 10458 domain = ptr; 10459 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 10460 *ptr = '\0'; 10461 10462 /* Save the domain for the dial plan */ 10463 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 10464 if (urioption) 10465 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 10466 } 10467 10468 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 10469 *ptr = '\0'; 10470 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 10471 10472 if (referred_by_uri) { 10473 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 10474 *ptr = '\0'; 10475 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 10476 } else { 10477 referdata->referred_by[0] = '\0'; 10478 } 10479 10480 /* Determine transfer context */ 10481 if (transferer->owner) /* Mimic behaviour in res_features.c */ 10482 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 10483 10484 /* By default, use the context in the channel sending the REFER */ 10485 if (ast_strlen_zero(transfer_context)) { 10486 transfer_context = S_OR(transferer->owner->macrocontext, 10487 S_OR(transferer->context, default_context)); 10488 } 10489 10490 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 10491 10492 /* Either an existing extension or the parking extension */ 10493 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 10494 if (sip_debug_test_pvt(transferer)) { 10495 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 10496 } 10497 /* We are ready to transfer to the extension */ 10498 return 0; 10499 } 10500 if (sip_debug_test_pvt(transferer)) 10501 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 10502 10503 /* Failure, we can't find this extension */ 10504 return -1; 10505 }
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 10679 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
10680 { 10681 char *start; 10682 char *end; 10683 10684 start = strchr(input,':'); 10685 if (!start) { 10686 output[0] = '\0'; 10687 return 0; 10688 } 10689 start++; 10690 10691 /* we found "number" */ 10692 ast_copy_string(output,start,maxlen); 10693 output[maxlen-1] = '\0'; 10694 10695 end = strchr(output,'@'); 10696 if (end) 10697 *end = '\0'; 10698 else 10699 output[0] = '\0'; 10700 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 10701 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 10702 10703 return 0; 10704 }
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 4579 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, sip_request::sdp_count, and sip_request::sdp_start.
04580 { 04581 int len = strlen(name); 04582 04583 while (*start < (req->sdp_start + req->sdp_count)) { 04584 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04585 if (r[0] != '\0') 04586 return r; 04587 } 04588 04589 /* if the line was not found, ensure that *start points past the SDP */ 04590 (*start)++; 04591 04592 return ""; 04593 }
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 4600 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().
04601 { 04602 char type = '\0'; 04603 const char *line = NULL; 04604 04605 if (stop > (req->sdp_start + req->sdp_count)) { 04606 stop = req->sdp_start + req->sdp_count; 04607 } 04608 04609 while (*start < stop) { 04610 line = req->line[(*start)++]; 04611 if (line[1] == '=') { 04612 type = line[0]; 04613 *value = ast_skip_blanks(line + 2); 04614 break; 04615 } 04616 } 04617 04618 return type; 04619 }
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 10269 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().
10270 { 10271 struct sip_pvt *sip_pvt_ptr; 10272 10273 ast_mutex_lock(&iflock); 10274 10275 if (option_debug > 3 && totag) { 10276 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 10277 } 10278 10279 /* Search interfaces and find the match */ 10280 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 10281 if (!strcmp(sip_pvt_ptr->callid, callid)) { 10282 int match = 1; 10283 10284 if (option_debug > 3) 10285 ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag); 10286 10287 /* Go ahead and lock it (and its owner) before returning */ 10288 ast_mutex_lock(&sip_pvt_ptr->lock); 10289 10290 /* Check if tags match. If not, this is not the call we want 10291 * (With a forking SIP proxy, several call legs share the 10292 * call id, but have different tags) 10293 */ 10294 if (pedanticsipchecking) { 10295 /* RFC 3891 10296 * > 3. User Agent Server Behavior: Receiving a Replaces Header 10297 * > The Replaces header contains information used to match an existing 10298 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 10299 * > with a Replaces header, the User Agent (UA) attempts to match this 10300 * > information with a confirmed or early dialog. The User Agent Server 10301 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 10302 * > present in an incoming request. In other words, the to-tag parameter 10303 * > is compared to the local tag, and the from-tag parameter is compared 10304 * > to the remote tag. 10305 * 10306 * Thus, the totag is always compared to the local tag, regardless if 10307 * this our call is an incoming or outgoing call. 10308 */ 10309 if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag))) 10310 match = 0; 10311 } 10312 10313 if (!match) { 10314 ast_mutex_unlock(&sip_pvt_ptr->lock); 10315 continue; 10316 } 10317 10318 if (option_debug > 3 && totag) 10319 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 10320 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 10321 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 10322 10323 /* deadlock avoidance... */ 10324 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 10325 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 10326 } 10327 break; 10328 } 10329 } 10330 ast_mutex_unlock(&iflock); 10331 if (option_debug > 3 && !sip_pvt_ptr) 10332 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 10333 return sip_pvt_ptr; 10334 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 14836 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
14837 { 14838 const char *thetag; 14839 14840 if (!tagbuf) 14841 return NULL; 14842 tagbuf[0] = '\0'; /* reset the buffer */ 14843 thetag = get_header(req, header); 14844 thetag = strcasestr(thetag, ";tag="); 14845 if (thetag) { 14846 thetag += 5; 14847 ast_copy_string(tagbuf, thetag, tagbufsize); 14848 return strsep(&tagbuf, ";"); 14849 } 14850 return NULL; 14851 }
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 18227 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_FORWARD_LOOP_DETECTED, 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().
18228 { 18229 int res = 1; 18230 18231 if (!strcasecmp(v->name, "trustrpid")) { 18232 ast_set_flag(&mask[0], SIP_TRUSTRPID); 18233 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 18234 } else if (!strcasecmp(v->name, "sendrpid")) { 18235 ast_set_flag(&mask[0], SIP_SENDRPID); 18236 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 18237 } else if (!strcasecmp(v->name, "g726nonstandard")) { 18238 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 18239 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 18240 } else if (!strcasecmp(v->name, "useclientcode")) { 18241 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 18242 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 18243 } else if (!strcasecmp(v->name, "dtmfmode")) { 18244 ast_set_flag(&mask[0], SIP_DTMF); 18245 ast_clear_flag(&flags[0], SIP_DTMF); 18246 if (!strcasecmp(v->value, "inband")) 18247 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 18248 else if (!strcasecmp(v->value, "rfc2833")) 18249 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 18250 else if (!strcasecmp(v->value, "info")) 18251 ast_set_flag(&flags[0], SIP_DTMF_INFO); 18252 else if (!strcasecmp(v->value, "auto")) 18253 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 18254 else { 18255 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 18256 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 18257 } 18258 } else if (!strcasecmp(v->name, "nat")) { 18259 ast_set_flag(&mask[0], SIP_NAT); 18260 ast_clear_flag(&flags[0], SIP_NAT); 18261 if (!strcasecmp(v->value, "never")) 18262 ast_set_flag(&flags[0], SIP_NAT_NEVER); 18263 else if (!strcasecmp(v->value, "route")) 18264 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 18265 else if (ast_true(v->value)) 18266 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 18267 else 18268 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 18269 } else if (!strcasecmp(v->name, "canreinvite")) { 18270 ast_set_flag(&mask[0], SIP_REINVITE); 18271 ast_clear_flag(&flags[0], SIP_REINVITE); 18272 if(ast_true(v->value)) { 18273 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 18274 } else if (!ast_false(v->value)) { 18275 char buf[64]; 18276 char *word, *next = buf; 18277 18278 ast_copy_string(buf, v->value, sizeof(buf)); 18279 while ((word = strsep(&next, ","))) { 18280 if(!strcasecmp(word, "update")) { 18281 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 18282 } else if(!strcasecmp(word, "nonat")) { 18283 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 18284 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 18285 } else { 18286 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 18287 } 18288 } 18289 } 18290 } else if (!strcasecmp(v->name, "insecure")) { 18291 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18292 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18293 set_insecure_flags(flags, v->value, v->lineno); 18294 } else if (!strcasecmp(v->name, "progressinband")) { 18295 ast_set_flag(&mask[0], SIP_PROG_INBAND); 18296 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 18297 if (ast_true(v->value)) 18298 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 18299 else if (strcasecmp(v->value, "never")) 18300 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 18301 } else if (!strcasecmp(v->name, "promiscredir")) { 18302 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 18303 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 18304 } else if (!strcasecmp(v->name, "videosupport")) { 18305 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 18306 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 18307 } else if (!strcasecmp(v->name, "allowoverlap")) { 18308 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 18309 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 18310 } else if (!strcasecmp(v->name, "allowsubscribe")) { 18311 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 18312 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 18313 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 18314 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 18315 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 18316 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 18317 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 18318 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 18319 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 18320 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 18321 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 18322 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 18323 #endif 18324 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 18325 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 18326 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 18327 } else if (!strcasecmp(v->name, "buggymwi")) { 18328 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 18329 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 18330 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 18331 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 18332 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 18333 } else if (!strcasecmp(v->name, "forwardloopdetected")) { 18334 ast_set_flag(&mask[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); 18335 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_FORWARD_LOOP_DETECTED); 18336 } else 18337 res = 0; 18338 18339 return res; 18340 }
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 15026 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().
15027 { 15028 int earlyreplace = 0; 15029 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 15030 struct ast_channel *c = p->owner; /* Our incoming call */ 15031 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 15032 struct ast_channel *targetcall; /* The bridge to the take-over target */ 15033 15034 /* Check if we're in ring state */ 15035 if (replacecall->_state == AST_STATE_RING) 15036 earlyreplace = 1; 15037 15038 /* Check if we have a bridge */ 15039 if (!(targetcall = ast_bridged_channel(replacecall))) { 15040 /* We have no bridge */ 15041 if (!earlyreplace) { 15042 if (option_debug > 1) 15043 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 15044 oneleggedreplace = 1; 15045 } 15046 } 15047 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 15048 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 15049 15050 if (option_debug > 3) { 15051 if (targetcall) 15052 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); 15053 else 15054 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 15055 } 15056 15057 if (ignore) { 15058 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 15059 /* We should answer something here. If we are here, the 15060 call we are replacing exists, so an accepted 15061 can't harm */ 15062 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 15063 /* Do something more clever here */ 15064 if (c) { 15065 *nounlock = 1; 15066 ast_channel_unlock(c); 15067 } 15068 ast_channel_unlock(replacecall); 15069 ast_mutex_unlock(&p->refer->refer_call->lock); 15070 return 1; 15071 } 15072 if (!c) { 15073 /* What to do if no channel ??? */ 15074 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 15075 transmit_response_reliable(p, "503 Service Unavailable", req); 15076 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 15077 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15078 ast_channel_unlock(replacecall); 15079 ast_mutex_unlock(&p->refer->refer_call->lock); 15080 return 1; 15081 } 15082 append_history(p, "Xfer", "INVITE/Replace received"); 15083 /* We have three channels to play with 15084 channel c: New incoming call 15085 targetcall: Call from PBX to target 15086 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 15087 replacecall: The owner of the previous 15088 We need to masq C into refer_call to connect to 15089 targetcall; 15090 If we are talking to internal audio stream, target call is null. 15091 */ 15092 15093 /* Fake call progress */ 15094 transmit_response(p, "100 Trying", req); 15095 ast_setstate(c, AST_STATE_RING); 15096 15097 /* Masquerade the new call into the referred call to connect to target call 15098 Targetcall is not touched by the masq */ 15099 15100 /* Answer the incoming call and set channel to UP state */ 15101 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 15102 15103 ast_setstate(c, AST_STATE_UP); 15104 15105 /* Stop music on hold and other generators */ 15106 ast_quiet_chan(replacecall); 15107 ast_quiet_chan(targetcall); 15108 if (option_debug > 3) 15109 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 15110 15111 /* Make sure that the masq does not free our PVT for the old call */ 15112 if (! earlyreplace && ! oneleggedreplace ) 15113 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15114 15115 /* Prepare the masquerade - if this does not happen, we will be gone */ 15116 if(ast_channel_masquerade(replacecall, c)) 15117 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 15118 else if (option_debug > 3) 15119 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 15120 15121 /* C should now be in place of replacecall */ 15122 if (ast_do_masquerade(replacecall)) { 15123 ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n"); 15124 } 15125 15126 if (earlyreplace || oneleggedreplace ) { 15127 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 15128 } 15129 15130 ast_setstate(c, AST_STATE_DOWN); 15131 if (option_debug > 3) { 15132 struct ast_channel *test; 15133 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 15134 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 15135 if (replacecall) 15136 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 15137 if (p->owner) { 15138 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 15139 test = ast_bridged_channel(p->owner); 15140 if (test) 15141 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 15142 else 15143 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 15144 } else 15145 ast_log(LOG_DEBUG, " -- No channel yet \n"); 15146 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 15147 } 15148 15149 /* unlock sip pvt and owner so hangup can do its thing */ 15150 ast_channel_unlock(replacecall); 15151 ast_channel_unlock(c); 15152 ast_mutex_unlock(&p->refer->refer_call->lock); 15153 ast_mutex_unlock(&p->lock); 15154 *nounlock = 1; 15155 15156 /* The call should be down with no ast_channel, so hang it up */ 15157 c->tech_pvt = NULL; 15158 ast_hangup(c); 15159 15160 ast_mutex_lock(&p->lock); /* lock PVT structure again after hangup */ 15161 15162 return 0; 15163 }
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).
called with p and p->owner locked
Definition at line 17118 of file chan_sip.c.
References __get_header(), __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, sip_pvt::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, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_peer::useragent.
17119 { 17120 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 17121 relatively static */ 17122 const char *cmd; 17123 const char *cseq; 17124 const char *useragent; 17125 const char *via; 17126 const char *callid; 17127 int via_pos = 0; 17128 int seqno; 17129 int len; 17130 int ignore = FALSE; 17131 int respid; 17132 int res = 0; 17133 int debug = sip_debug_test_pvt(p); 17134 char *e; 17135 int error = 0; 17136 int oldmethod = p->method; 17137 int acked = 0; 17138 17139 /* RFC 3261 - 8.1.1 A valid SIP request must contain To, From, CSeq, Call-ID and Via. 17140 * 8.2.6.2 Response must have To, From, Call-ID CSeq, and Via related to the request, 17141 * so we can check to make sure these fields exist for all requests and responses */ 17142 cseq = get_header(req, "Cseq"); 17143 cmd = req->header[0]; 17144 /* Save the via_pos so we can check later that responses only have 1 Via header */ 17145 via = __get_header(req, "Via", &via_pos); 17146 /* This must exist already because we've called find_call by now */ 17147 callid = get_header(req, "Call-ID"); 17148 17149 /* Must have Cseq */ 17150 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq) || ast_strlen_zero(via)) { 17151 ast_log(LOG_ERROR, "Dropping this SIP message with Call-ID '%s', it's incomplete.\n", callid); 17152 error = 1; 17153 } 17154 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 17155 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 17156 error = 1; 17157 } 17158 if (error) { 17159 if (!p->initreq.headers) /* New call */ 17160 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 17161 return -1; 17162 } 17163 /* Get the command XXX */ 17164 17165 cmd = req->rlPart1; 17166 e = ast_skip_blanks(req->rlPart2); 17167 17168 /* Save useragent of the client */ 17169 useragent = get_header(req, "User-Agent"); 17170 if (!ast_strlen_zero(useragent)) 17171 ast_string_field_set(p, useragent, useragent); 17172 17173 /* Find out SIP method for incoming request */ 17174 if (req->method == SIP_RESPONSE) { /* Response to our request */ 17175 /* Response to our request -- Do some sanity checks */ 17176 if (ast_strlen_zero(e)) { 17177 return 0; 17178 } 17179 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 17180 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 17181 return 0; 17182 } 17183 if (respid <= 0) { 17184 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 17185 return 0; 17186 } 17187 /* RFC 3261 - 8.1.3.3 If more than one Via header field value is present in a reponse 17188 * the UAC SHOULD discard the message. This is not perfect, as it will not catch multiple 17189 * headers joined with a comma. Fixing that would pretty much involve writing a new parser */ 17190 if (!ast_strlen_zero(__get_header(req, "via", &via_pos))) { 17191 ast_log(LOG_WARNING, "Misrouted SIP response '%s' with Call-ID '%s', too many vias\n", e, callid); 17192 return 0; 17193 } 17194 if (!p->initreq.headers) { 17195 if (option_debug) 17196 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we don't know about. Cseq %d Cmd %s\n", seqno, cmd); 17197 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17198 return 0; 17199 } 17200 if (p->ocseq && (p->ocseq < seqno)) { 17201 if (option_debug) 17202 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 17203 return -1; 17204 } else { 17205 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 17206 extract_uri(p, req); 17207 } 17208 handle_response(p, respid, e + len, req, seqno); 17209 } 17210 return 0; 17211 } 17212 17213 /* New SIP request coming in 17214 (could be new request in existing SIP dialog as well...) 17215 */ 17216 17217 p->method = req->method; /* Find out which SIP method they are using */ 17218 if (option_debug > 3) 17219 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 17220 17221 if (p->icseq && (p->icseq > seqno) ) { 17222 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 17223 if (option_debug > 2) 17224 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 17225 } else { 17226 if (option_debug) 17227 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 17228 if (req->method != SIP_ACK) 17229 transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 17230 return -1; 17231 } 17232 } else if (p->icseq && 17233 p->icseq == seqno && 17234 req->method != SIP_ACK && 17235 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 17236 /* ignore means "don't do anything with it" but still have to 17237 respond appropriately. We do this if we receive a repeat of 17238 the last sequence number */ 17239 ignore = 2; 17240 ast_set_flag(req, SIP_PKT_IGNORE); 17241 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 17242 if (option_debug > 2) 17243 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 17244 } 17245 17246 if (seqno >= p->icseq) 17247 /* Next should follow monotonically (but not necessarily 17248 incrementally -- thanks again to the genius authors of SIP -- 17249 increasing */ 17250 p->icseq = seqno; 17251 17252 /* Find their tag if we haven't got it */ 17253 if (ast_strlen_zero(p->theirtag)) { 17254 char tag[128]; 17255 17256 gettag(req, "From", tag, sizeof(tag)); 17257 ast_string_field_set(p, theirtag, tag); 17258 } 17259 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 17260 17261 if (pedanticsipchecking) { 17262 /* If this is a request packet without a from tag, it's not 17263 correct according to RFC 3261 */ 17264 /* Check if this a new request in a new dialog with a totag already attached to it, 17265 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 17266 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 17267 /* If this is a first request and it got a to-tag, it is not for us */ 17268 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 17269 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 17270 /* Will cease to exist after ACK */ 17271 } else if (req->method != SIP_ACK) { 17272 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 17273 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17274 } 17275 return res; 17276 } 17277 } 17278 17279 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 17280 transmit_response(p, "400 Bad request", req); 17281 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17282 return -1; 17283 } 17284 17285 /* Handle various incoming SIP methods in requests */ 17286 switch (p->method) { 17287 case SIP_OPTIONS: 17288 res = handle_request_options(p, req); 17289 break; 17290 case SIP_INVITE: 17291 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 17292 break; 17293 case SIP_REFER: 17294 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 17295 break; 17296 case SIP_CANCEL: 17297 res = handle_request_cancel(p, req); 17298 break; 17299 case SIP_BYE: 17300 res = handle_request_bye(p, req); 17301 break; 17302 case SIP_MESSAGE: 17303 res = handle_request_message(p, req); 17304 break; 17305 case SIP_SUBSCRIBE: 17306 res = handle_request_subscribe(p, req, sin, seqno, e); 17307 break; 17308 case SIP_REGISTER: 17309 res = handle_request_register(p, req, sin, e); 17310 break; 17311 case SIP_INFO: 17312 if (ast_test_flag(req, SIP_PKT_DEBUG)) 17313 ast_verbose("Receiving INFO!\n"); 17314 if (!ignore) 17315 handle_request_info(p, req); 17316 else /* if ignoring, transmit response */ 17317 transmit_response(p, "200 OK", req); 17318 break; 17319 case SIP_NOTIFY: 17320 res = handle_request_notify(p, req, sin, seqno, e); 17321 break; 17322 case SIP_ACK: 17323 /* Make sure we don't ignore this */ 17324 if (seqno == p->pendinginvite) { 17325 p->invitestate = INV_TERMINATED; 17326 p->pendinginvite = 0; 17327 acked = __sip_ack(p, seqno, FLAG_RESPONSE, 0); 17328 if (find_sdp(req)) { 17329 if (process_sdp(p, req)) 17330 return -1; 17331 } 17332 check_pendings(p); 17333 } else if (p->glareinvite == seqno) { 17334 /* handle ack for the 491 pending send for glareinvite */ 17335 p->glareinvite = 0; 17336 acked = __sip_ack(p, seqno, 1, 0); 17337 } 17338 if (!acked) { 17339 /* Got an ACK that did not match anything. Ignore 17340 * silently and restore previous method */ 17341 p->method = oldmethod; 17342 } 17343 /* Got an ACK that we did not match. Ignore silently */ 17344 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 17345 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17346 break; 17347 default: 17348 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 17349 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 17350 cmd, ast_inet_ntoa(p->sa.sin_addr)); 17351 /* If this is some new method, and we don't have a call, destroy it now */ 17352 if (!p->initreq.headers) 17353 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17354 break; 17355 } 17356 return res; 17357 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 16643 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().
16644 { 16645 struct ast_channel *c=NULL; 16646 int res; 16647 struct ast_channel *bridged_to; 16648 16649 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 16650 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 16651 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 16652 16653 __sip_pretend_ack(p); 16654 16655 p->invitestate = INV_TERMINATED; 16656 16657 copy_request(&p->initreq, req); 16658 check_via(p, req); 16659 sip_alreadygone(p); 16660 16661 /* Get RTCP quality before end of call */ 16662 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 16663 char *audioqos, *videoqos; 16664 if (p->rtp) { 16665 audioqos = ast_rtp_get_quality(p->rtp, NULL); 16666 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16667 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 16668 if (p->owner) 16669 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 16670 } 16671 if (p->vrtp) { 16672 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 16673 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16674 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 16675 if (p->owner) 16676 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 16677 } 16678 } 16679 16680 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16681 16682 if (!ast_strlen_zero(get_header(req, "Also"))) { 16683 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 16684 ast_inet_ntoa(p->recv.sin_addr)); 16685 if (ast_strlen_zero(p->context)) 16686 ast_string_field_set(p, context, default_context); 16687 res = get_also_info(p, req); 16688 if (!res) { 16689 c = p->owner; 16690 if (c) { 16691 bridged_to = ast_bridged_channel(c); 16692 if (bridged_to) { 16693 /* Don't actually hangup here... */ 16694 ast_queue_control(c, AST_CONTROL_UNHOLD); 16695 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 16696 } else 16697 ast_queue_hangup(p->owner); 16698 } 16699 } else { 16700 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 16701 if (p->owner) 16702 ast_queue_hangup(p->owner); 16703 } 16704 } else if (p->owner) { 16705 ast_queue_hangup(p->owner); 16706 if (option_debug > 2) 16707 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 16708 } else { 16709 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16710 if (option_debug > 2) 16711 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 16712 } 16713 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16714 transmit_response(p, "200 OK", req); 16715 16716 return 1; 16717 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 16513 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().
16514 { 16515 16516 check_via(p, req); 16517 sip_alreadygone(p); 16518 16519 /* At this point, we could have cancelled the invite at the same time 16520 as the other side sends a CANCEL. Our final reply with error code 16521 might not have been received by the other side before the CANCEL 16522 was sent, so let's just give up retransmissions and waiting for 16523 ACK on our error code. The call is hanging up any way. */ 16524 if (p->invitestate == INV_TERMINATED) 16525 __sip_pretend_ack(p); 16526 else 16527 p->invitestate = INV_CANCELLED; 16528 16529 if (p->owner && p->owner->_state == AST_STATE_UP) { 16530 /* This call is up, cancel is ignored, we need a bye */ 16531 transmit_response(p, "200 OK", req); 16532 if (option_debug) 16533 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 16534 return 0; 16535 } 16536 16537 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 16538 update_call_counter(p, DEC_CALL_LIMIT); 16539 16540 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 16541 if (p->owner) 16542 ast_queue_hangup(p->owner); 16543 else 16544 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16545 if (p->initreq.len > 0) { 16546 struct sip_pkt *pkt, *prev_pkt; 16547 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 16548 * a reliable 487, then we don't want to schedule another one on top of the previous 16549 * one. 16550 * 16551 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 16552 * response in this situation. What if we've sent all of our reliable responses 16553 * already and now all of a sudden, we get this second CANCEL? 16554 * 16555 * The only way to do this correctly is to cancel our previously-scheduled reliably- 16556 * transmitted response and send a new one in its place. 16557 */ 16558 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 16559 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 16560 AST_SCHED_DEL(sched, pkt->retransid); 16561 UNLINK(pkt, p->packets, prev_pkt); 16562 ast_free(pkt); 16563 break; 16564 } 16565 } 16566 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 16567 transmit_response(p, "200 OK", req); 16568 return 1; 16569 } else { 16570 transmit_response(p, "481 Call Leg Does Not Exist", req); 16571 return 0; 16572 } 16573 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 12540 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().
12541 { 12542 char buf[1024]; 12543 unsigned int event; 12544 const char *c = get_header(req, "Content-Type"); 12545 12546 /* Need to check the media/type */ 12547 if (!strcasecmp(c, "application/dtmf-relay") || 12548 !strcasecmp(c, "application/DTMF") || 12549 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 12550 unsigned int duration = 0; 12551 12552 /* Try getting the "signal=" part */ 12553 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 12554 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 12555 transmit_response(p, "200 OK", req); /* Should return error */ 12556 return; 12557 } else { 12558 ast_copy_string(buf, c, sizeof(buf)); 12559 } 12560 12561 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 12562 duration = atoi(c); 12563 if (!duration) 12564 duration = 100; /* 100 ms */ 12565 12566 if (!p->owner) { /* not a PBX call */ 12567 transmit_response(p, "481 Call leg/transaction does not exist", req); 12568 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12569 return; 12570 } 12571 12572 if (ast_strlen_zero(buf)) { 12573 transmit_response(p, "200 OK", req); 12574 return; 12575 } 12576 12577 if (buf[0] == '*') 12578 event = 10; 12579 else if (buf[0] == '#') 12580 event = 11; 12581 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 12582 event = 12 + buf[0] - 'A'; 12583 else 12584 event = atoi(buf); 12585 if (event == 16) { 12586 /* send a FLASH event */ 12587 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 12588 ast_queue_frame(p->owner, &f); 12589 if (sipdebug) 12590 ast_verbose("* DTMF-relay event received: FLASH\n"); 12591 } else { 12592 /* send a DTMF event */ 12593 struct ast_frame f = { AST_FRAME_DTMF, }; 12594 if (event < 10) { 12595 f.subclass = '0' + event; 12596 } else if (event < 11) { 12597 f.subclass = '*'; 12598 } else if (event < 12) { 12599 f.subclass = '#'; 12600 } else if (event < 16) { 12601 f.subclass = 'A' + (event - 12); 12602 } 12603 f.len = duration; 12604 ast_queue_frame(p->owner, &f); 12605 if (sipdebug) 12606 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 12607 } 12608 transmit_response(p, "200 OK", req); 12609 return; 12610 } else if (!strcasecmp(c, "application/media_control+xml")) { 12611 /* Eh, we'll just assume it's a fast picture update for now */ 12612 if (p->owner) 12613 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 12614 transmit_response(p, "200 OK", req); 12615 return; 12616 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 12617 /* Client code (from SNOM phone) */ 12618 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 12619 if (p->owner && p->owner->cdr) 12620 ast_cdr_setuserfield(p->owner, c); 12621 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 12622 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 12623 transmit_response(p, "200 OK", req); 12624 } else { 12625 transmit_response(p, "403 Unauthorized", req); 12626 } 12627 return; 12628 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 12629 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 12630 transmit_response(p, "200 OK", req); 12631 return; 12632 } 12633 12634 /* Other type of INFO message, not really understood by Asterisk */ 12635 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 12636 12637 /* Nothing in the header is interesting, now check if content-length is 0 */ 12638 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 12639 transmit_response(p, "200 OK", req); 12640 return; 12641 } /* else ... there issomething in the message body, do something with it if you need to */ 12642 12643 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 12644 transmit_response(p, "415 Unsupported media type", req); 12645 return; 12646 }
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 15442 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_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_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().
15443 { 15444 int res = 1; 15445 int gotdest; 15446 const char *p_replaces; 15447 char *replace_id = NULL; 15448 int refer_locked = 0; 15449 const char *required; 15450 unsigned int required_profile = 0; 15451 struct ast_channel *c = NULL; /* New channel */ 15452 int reinvite = 0; 15453 15454 /* Find out what they support */ 15455 if (!p->sipoptions) { 15456 const char *supported = get_header(req, "Supported"); 15457 if (!ast_strlen_zero(supported)) 15458 parse_sip_options(p, supported); 15459 } 15460 15461 /* Find out what they require */ 15462 required = get_header(req, "Require"); 15463 if (!ast_strlen_zero(required)) { 15464 required_profile = parse_sip_options(NULL, required); 15465 if (required_profile && !(required_profile & SIP_OPT_REPLACES)) { 15466 /* At this point we only support REPLACES */ 15467 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 15468 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 15469 p->invitestate = INV_COMPLETED; 15470 if (!p->lastinvite) 15471 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15472 res = -1; 15473 goto request_invite_cleanup; 15474 } 15475 } 15476 15477 /* Check if this is a loop */ 15478 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 15479 /* This is a call to ourself. Send ourselves an error code and stop 15480 processing immediately, as SIP really has no good mechanism for 15481 being able to call yourself */ 15482 /* If pedantic is on, we need to check the tags. If they're different, this is 15483 in fact a forked call through a SIP proxy somewhere. */ 15484 int different; 15485 if (pedanticsipchecking) 15486 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 15487 else 15488 different = strcmp(p->initreq.rlPart2, req->rlPart2); 15489 if (!different) { 15490 transmit_response(p, "482 Loop Detected", req); 15491 p->invitestate = INV_COMPLETED; 15492 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15493 res = 0; 15494 goto request_invite_cleanup; 15495 } else { 15496 /* This is a spiral. What we need to do is to just change the outgoing INVITE 15497 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 15498 * that should be all we need to do. 15499 */ 15500 char *uri = ast_strdupa(req->rlPart2); 15501 char *at = strchr(uri, '@'); 15502 char *peerorhost; 15503 if (option_debug > 2) { 15504 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 15505 } 15506 transmit_response(p, "100 Trying", req); 15507 if (at) { 15508 *at = '\0'; 15509 } 15510 /* Parse out "sip:" */ 15511 if ((peerorhost = strchr(uri, ':'))) { 15512 *peerorhost++ = '\0'; 15513 } 15514 ast_string_field_free(p, theirtag); 15515 /* Treat this as if there were a call forward instead... 15516 */ 15517 ast_string_field_set(p->owner, call_forward, peerorhost); 15518 ast_queue_control(p->owner, AST_CONTROL_BUSY); 15519 res = 0; 15520 goto request_invite_cleanup; 15521 } 15522 } 15523 15524 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 15525 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) { 15526 /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we 15527 * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero). 15528 * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set. 15529 * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with 15530 * credentials based on one we challenged earlier. 15531 * 15532 * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous 15533 * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response 15534 * from the previous transaction from the list of outstanding packets. 15535 */ 15536 __sip_ack(p, p->pendinginvite, FLAG_RESPONSE, 0); 15537 } else { 15538 /* We already have a pending invite. Sorry. You are on hold. */ 15539 p->glareinvite = seqno; 15540 if (p->rtp && find_sdp(req)) { 15541 struct sockaddr_in sin; 15542 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 15543 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 15544 } else { 15545 ast_rtp_set_alt_peer(p->rtp, &sin); 15546 } 15547 if (p->vrtp) { 15548 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 15549 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 15550 } else { 15551 ast_rtp_set_alt_peer(p->vrtp, &sin); 15552 } 15553 } 15554 } 15555 transmit_response_reliable(p, "491 Request Pending", req); 15556 if (option_debug) 15557 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 15558 /* Don't destroy dialog here */ 15559 res = 0; 15560 goto request_invite_cleanup; 15561 } 15562 } 15563 15564 p_replaces = get_header(req, "Replaces"); 15565 if (!ast_strlen_zero(p_replaces)) { 15566 /* We have a replaces header */ 15567 char *ptr; 15568 char *fromtag = NULL; 15569 char *totag = NULL; 15570 char *start, *to; 15571 int error = 0; 15572 15573 if (p->owner) { 15574 if (option_debug > 2) 15575 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 15576 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 15577 /* Do not destroy existing call */ 15578 res = -1; 15579 goto request_invite_cleanup; 15580 } 15581 15582 if (sipdebug && option_debug > 2) 15583 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 15584 /* Create a buffer we can manipulate */ 15585 replace_id = ast_strdupa(p_replaces); 15586 ast_uri_decode(replace_id); 15587 15588 if (!p->refer && !sip_refer_allocate(p)) { 15589 transmit_response_reliable(p, "500 Server Internal Error", req); 15590 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 15591 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15592 p->invitestate = INV_COMPLETED; 15593 res = -1; 15594 goto request_invite_cleanup; 15595 } 15596 15597 /* Todo: (When we find phones that support this) 15598 if the replaces header contains ";early-only" 15599 we can only replace the call in early 15600 stage, not after it's up. 15601 15602 If it's not in early mode, 486 Busy. 15603 */ 15604 15605 /* Skip leading whitespace */ 15606 replace_id = ast_skip_blanks(replace_id); 15607 15608 start = replace_id; 15609 while ( (ptr = strsep(&start, ";")) ) { 15610 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 15611 if ( (to = strcasestr(ptr, "to-tag=") ) ) 15612 totag = to + 7; /* skip the keyword */ 15613 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 15614 fromtag = to + 9; /* skip the keyword */ 15615 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 15616 } 15617 } 15618 15619 if (sipdebug && option_debug > 3) 15620 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>"); 15621 15622 15623 /* Try to find call that we are replacing 15624 If we have a Replaces header, we need to cancel that call if we succeed with this call 15625 */ 15626 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 15627 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 15628 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 15629 error = 1; 15630 } else { 15631 refer_locked = 1; 15632 } 15633 15634 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 15635 15636 /* The matched call is the call from the transferer to Asterisk . 15637 We want to bridge the bridged part of the call to the 15638 incoming invite, thus taking over the refered call */ 15639 15640 if (p->refer->refer_call == p) { 15641 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 15642 p->refer->refer_call = NULL; 15643 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 15644 error = 1; 15645 } 15646 15647 if (!error && !p->refer->refer_call->owner) { 15648 /* Oops, someting wrong anyway, no owner, no call */ 15649 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 15650 /* Check for better return code */ 15651 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 15652 error = 1; 15653 } 15654 15655 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 ) { 15656 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 15657 transmit_response_reliable(p, "603 Declined (Replaces)", req); 15658 error = 1; 15659 } 15660 15661 if (error) { /* Give up this dialog */ 15662 append_history(p, "Xfer", "INVITE/Replace Failed."); 15663 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15664 ast_mutex_unlock(&p->lock); 15665 if (p->refer->refer_call) { 15666 ast_mutex_unlock(&p->refer->refer_call->lock); 15667 if (p->refer->refer_call->owner) { 15668 ast_channel_unlock(p->refer->refer_call->owner); 15669 } 15670 } 15671 refer_locked = 0; 15672 p->invitestate = INV_COMPLETED; 15673 res = -1; 15674 goto request_invite_cleanup; 15675 } 15676 } 15677 15678 15679 /* Check if this is an INVITE that sets up a new dialog or 15680 a re-invite in an existing dialog */ 15681 15682 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15683 int newcall = (p->initreq.headers ? TRUE : FALSE); 15684 15685 if (sip_cancel_destroy(p)) 15686 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15687 /* This also counts as a pending invite */ 15688 p->pendinginvite = seqno; 15689 check_via(p, req); 15690 15691 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 15692 if (!p->owner) { /* Not a re-invite */ 15693 if (debug) 15694 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 15695 if (newcall) 15696 append_history(p, "Invite", "New call: %s", p->callid); 15697 parse_ok_contact(p, req); 15698 } else { /* Re-invite on existing call */ 15699 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 15700 /* Handle SDP here if we already have an owner */ 15701 if (find_sdp(req)) { 15702 if (process_sdp(p, req)) { 15703 transmit_response_reliable(p, "488 Not acceptable here", req); 15704 if (!p->lastinvite) 15705 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15706 res = -1; 15707 goto request_invite_cleanup; 15708 } 15709 ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); 15710 } else { 15711 p->jointcapability = p->capability; 15712 if (option_debug > 2) 15713 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 15714 /* Some devices signal they want to be put off hold by sending a re-invite 15715 *without* an SDP, which is supposed to mean "Go back to your state" 15716 and since they put os on remote hold, we go back to off hold */ 15717 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 15718 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 15719 /* Activate a re-invite */ 15720 ast_queue_frame(p->owner, &ast_null_frame); 15721 change_hold_state(p, req, FALSE, 0); 15722 } 15723 } 15724 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 15725 append_history(p, "ReInv", "Re-invite received"); 15726 } 15727 } else if (debug) 15728 ast_verbose("Ignoring this INVITE request\n"); 15729 15730 15731 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 15732 /* This is a new invite */ 15733 /* Handle authentication if this is our first invite */ 15734 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 15735 if (res == AUTH_CHALLENGE_SENT) { 15736 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 15737 res = 0; 15738 goto request_invite_cleanup; 15739 } 15740 if (res < 0) { /* Something failed in authentication */ 15741 if (res == AUTH_FAKE_AUTH) { 15742 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15743 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 15744 } else { 15745 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 15746 transmit_response_reliable(p, "403 Forbidden", req); 15747 } 15748 p->invitestate = INV_COMPLETED; 15749 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15750 ast_string_field_free(p, theirtag); 15751 res = 0; 15752 goto request_invite_cleanup; 15753 15754 } 15755 15756 /* We have a succesful authentication, process the SDP portion if there is one */ 15757 if (find_sdp(req)) { 15758 if (process_sdp(p, req)) { 15759 /* Unacceptable codecs */ 15760 transmit_response_reliable(p, "488 Not acceptable here", req); 15761 p->invitestate = INV_COMPLETED; 15762 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15763 if (option_debug) 15764 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 15765 res = -1; 15766 goto request_invite_cleanup; 15767 } 15768 } else { /* No SDP in invite, call control session */ 15769 p->jointcapability = p->capability; 15770 if (option_debug > 1) 15771 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 15772 } 15773 15774 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 15775 /* This seems redundant ... see !p-owner above */ 15776 if (p->owner) 15777 ast_queue_frame(p->owner, &ast_null_frame); 15778 15779 15780 /* Initialize the context if it hasn't been already */ 15781 if (ast_strlen_zero(p->context)) 15782 ast_string_field_set(p, context, default_context); 15783 15784 15785 /* Check number of concurrent calls -vs- incoming limit HERE */ 15786 if (option_debug) 15787 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 15788 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 15789 if (res < 0) { 15790 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 15791 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 15792 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15793 p->invitestate = INV_COMPLETED; 15794 } 15795 res = 0; 15796 goto request_invite_cleanup; 15797 } 15798 gotdest = get_destination(p, NULL); /* Get destination right away */ 15799 get_rdnis(p, NULL); /* Get redirect information */ 15800 extract_uri(p, req); /* Get the Contact URI */ 15801 build_contact(p); /* Build our contact header */ 15802 15803 if (p->rtp) { 15804 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 15805 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 15806 } 15807 15808 if (!replace_id && gotdest) { /* No matching extension found */ 15809 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 15810 transmit_response_reliable(p, "484 Address Incomplete", req); 15811 else { 15812 char *decoded_exten = ast_strdupa(p->exten); 15813 15814 transmit_response_reliable(p, "404 Not Found", req); 15815 ast_uri_decode(decoded_exten); 15816 ast_log(LOG_NOTICE, "Call from '%s' to extension" 15817 " '%s' rejected because extension not found.\n", 15818 S_OR(p->username, p->peername), decoded_exten); 15819 } 15820 p->invitestate = INV_COMPLETED; 15821 update_call_counter(p, DEC_CALL_LIMIT); 15822 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15823 res = 0; 15824 goto request_invite_cleanup; 15825 } else { 15826 /* If no extension was specified, use the s one */ 15827 /* Basically for calling to IP/Host name only */ 15828 if (ast_strlen_zero(p->exten)) 15829 ast_string_field_set(p, exten, "s"); 15830 /* Initialize our tag */ 15831 15832 make_our_tag(p->tag, sizeof(p->tag)); 15833 /* First invitation - create the channel */ 15834 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 15835 *recount = 1; 15836 15837 /* Save Record-Route for any later requests we make on this dialogue */ 15838 build_route(p, req, 0); 15839 15840 if (c) { 15841 /* Pre-lock the call */ 15842 ast_channel_lock(c); 15843 } 15844 } 15845 } else { 15846 if (option_debug > 1 && sipdebug) { 15847 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15848 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 15849 else 15850 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 15851 } 15852 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 15853 reinvite = 1; 15854 c = p->owner; 15855 } 15856 15857 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15858 p->lastinvite = seqno; 15859 15860 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 15861 /* Go and take over the target call */ 15862 if (sipdebug && option_debug > 3) 15863 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 15864 15865 res = handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin, nounlock); 15866 refer_locked = 0; 15867 goto request_invite_cleanup; 15868 } 15869 15870 15871 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 15872 enum ast_channel_state c_state = c->_state; 15873 15874 if (c_state != AST_STATE_UP && reinvite && 15875 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 15876 /* If these conditions are true, and the channel is still in the 'ringing' 15877 * state, then this likely means that we have a situation where the initial 15878 * INVITE transaction has completed *but* the channel's state has not yet been 15879 * changed to UP. The reason this could happen is if the reinvite is received 15880 * on the SIP socket prior to an application calling ast_read on this channel 15881 * to read the answer frame we earlier queued on it. In this case, the reinvite 15882 * is completely legitimate so we need to handle this the same as if the channel 15883 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 15884 */ 15885 c_state = AST_STATE_UP; 15886 } 15887 15888 switch(c_state) { 15889 case AST_STATE_DOWN: 15890 if (option_debug > 1) 15891 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 15892 transmit_provisional_response(p, "100 Trying", req, 0); 15893 p->invitestate = INV_PROCEEDING; 15894 ast_setstate(c, AST_STATE_RING); 15895 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 15896 enum ast_pbx_result res; 15897 15898 res = ast_pbx_start(c); 15899 15900 switch(res) { 15901 case AST_PBX_FAILED: 15902 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 15903 p->invitestate = INV_COMPLETED; 15904 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15905 transmit_response(p, "503 Unavailable", req); 15906 else 15907 transmit_response_reliable(p, "503 Unavailable", req); 15908 break; 15909 case AST_PBX_CALL_LIMIT: 15910 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 15911 p->invitestate = INV_COMPLETED; 15912 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15913 transmit_response(p, "480 Temporarily Unavailable", req); 15914 else 15915 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 15916 break; 15917 case AST_PBX_SUCCESS: 15918 /* nothing to do */ 15919 break; 15920 } 15921 15922 if (res) { 15923 15924 /* Unlock locks so ast_hangup can do its magic */ 15925 ast_mutex_unlock(&c->lock); 15926 *nounlock = 1; 15927 ast_mutex_unlock(&p->lock); 15928 ast_hangup(c); 15929 ast_mutex_lock(&p->lock); 15930 c = NULL; 15931 } 15932 } else { /* Pickup call in call group */ 15933 ast_channel_unlock(c); 15934 *nounlock = 1; 15935 ast_mutex_unlock(&p->lock); 15936 if (ast_pickup_call(c)) { 15937 ast_mutex_lock(&p->lock); 15938 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 15939 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15940 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 15941 else 15942 transmit_response_reliable(p, "503 Unavailable", req); 15943 sip_alreadygone(p); 15944 /* Unlock locks so ast_hangup can do its magic */ 15945 ast_mutex_unlock(&p->lock); 15946 c->hangupcause = AST_CAUSE_CALL_REJECTED; 15947 } else { 15948 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15949 } 15950 ast_hangup(c); 15951 ast_mutex_lock(&p->lock); 15952 p->invitestate = INV_COMPLETED; 15953 c = NULL; 15954 } 15955 break; 15956 case AST_STATE_RING: 15957 transmit_provisional_response(p, "100 Trying", req, 0); 15958 p->invitestate = INV_PROCEEDING; 15959 break; 15960 case AST_STATE_RINGING: 15961 transmit_provisional_response(p, "180 Ringing", req, 0); 15962 p->invitestate = INV_PROCEEDING; 15963 break; 15964 case AST_STATE_UP: 15965 if (option_debug > 1) 15966 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 15967 15968 transmit_response(p, "100 Trying", req); 15969 15970 if (p->t38.state == T38_PEER_REINVITE) { 15971 struct ast_channel *bridgepeer = NULL; 15972 struct sip_pvt *bridgepvt = NULL; 15973 15974 if ((bridgepeer = ast_bridged_channel(p->owner))) { 15975 /* 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*/ 15976 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 15977 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 15978 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 15979 if (bridgepvt->t38.state == T38_DISABLED) { 15980 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 15981 /* Send re-invite to the bridged channel */ 15982 sip_handle_t38_reinvite(bridgepeer, p, 1); 15983 } else { /* Something is wrong with peers udptl struct */ 15984 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 15985 ast_mutex_lock(&bridgepvt->lock); 15986 bridgepvt->t38.state = T38_DISABLED; 15987 ast_mutex_unlock(&bridgepvt->lock); 15988 if (option_debug > 1) 15989 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 15990 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15991 transmit_response(p, "488 Not acceptable here", req); 15992 else 15993 transmit_response_reliable(p, "488 Not acceptable here", req); 15994 15995 } 15996 } else { 15997 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 15998 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15999 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 16000 p->t38.state = T38_ENABLED; 16001 if (option_debug) 16002 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16003 } 16004 } else { 16005 /* Other side is not a SIP channel */ 16006 if (ast_test_flag(req, SIP_PKT_IGNORE)) 16007 transmit_response(p, "488 Not acceptable here", req); 16008 else 16009 transmit_response_reliable(p, "488 Not acceptable here", req); 16010 p->t38.state = T38_DISABLED; 16011 if (option_debug > 1) 16012 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16013 16014 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 16015 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16016 } 16017 } else { 16018 /* we are not bridged in a call */ 16019 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16020 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 16021 p->t38.state = T38_ENABLED; 16022 if (option_debug) 16023 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 16024 } 16025 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 16026 /* If this is not a re-invite or something to ignore - it's critical */ 16027 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16028 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 16029 } 16030 p->invitestate = INV_TERMINATED; 16031 break; 16032 default: 16033 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 16034 transmit_response(p, "100 Trying", req); 16035 break; 16036 } 16037 } else { 16038 if (p && (p->autokillid == -1)) { 16039 const char *msg; 16040 16041 if (!p->jointcapability) 16042 msg = "488 Not Acceptable Here (codec error)"; 16043 else { 16044 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 16045 msg = "503 Unavailable"; 16046 } 16047 if (ast_test_flag(req, SIP_PKT_IGNORE)) 16048 transmit_response(p, msg, req); 16049 else 16050 transmit_response_reliable(p, msg, req); 16051 p->invitestate = INV_COMPLETED; 16052 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16053 } 16054 } 16055 return res; 16056 16057 request_invite_cleanup: 16058 16059 if (refer_locked && p->refer && p->refer->refer_call) { 16060 ast_mutex_unlock(&p->refer->refer_call->lock); 16061 if (p->refer->refer_call->owner) { 16062 ast_channel_unlock(p->refer->refer_call->owner); 16063 } 16064 } 16065 16066 return res; 16067 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 16720 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().
16721 { 16722 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16723 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16724 ast_verbose("Receiving message!\n"); 16725 receive_message(p, req); 16726 } else 16727 transmit_response(p, "202 Accepted", req); 16728 return 1; 16729 }
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 14854 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().
14855 { 14856 /* This is mostly a skeleton for future improvements */ 14857 /* Mostly created to return proper answers on notifications on outbound REFER's */ 14858 int res = 0; 14859 const char *event = get_header(req, "Event"); 14860 char *eventid = NULL; 14861 char *sep; 14862 14863 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 14864 *sep++ = '\0'; 14865 eventid = sep; 14866 } 14867 14868 if (option_debug > 1 && sipdebug) 14869 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 14870 14871 if (strcmp(event, "refer")) { 14872 /* We don't understand this event. */ 14873 /* Here's room to implement incoming voicemail notifications :-) */ 14874 transmit_response(p, "489 Bad event", req); 14875 res = -1; 14876 } else { 14877 /* Save nesting depth for now, since there might be other events we will 14878 support in the future */ 14879 14880 /* Handle REFER notifications */ 14881 14882 char buf[1024]; 14883 char *cmd, *code; 14884 int respcode; 14885 int success = TRUE; 14886 14887 /* EventID for each transfer... EventID is basically the REFER cseq 14888 14889 We are getting notifications on a call that we transfered 14890 We should hangup when we are getting a 200 OK in a sipfrag 14891 Check if we have an owner of this event */ 14892 14893 /* Check the content type */ 14894 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 14895 /* We need a sipfrag */ 14896 transmit_response(p, "400 Bad request", req); 14897 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14898 return -1; 14899 } 14900 14901 /* Get the text of the attachment */ 14902 if (get_msg_text(buf, sizeof(buf), req)) { 14903 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 14904 transmit_response(p, "400 Bad request", req); 14905 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14906 return -1; 14907 } 14908 14909 /* 14910 From the RFC... 14911 A minimal, but complete, implementation can respond with a single 14912 NOTIFY containing either the body: 14913 SIP/2.0 100 Trying 14914 14915 if the subscription is pending, the body: 14916 SIP/2.0 200 OK 14917 if the reference was successful, the body: 14918 SIP/2.0 503 Service Unavailable 14919 if the reference failed, or the body: 14920 SIP/2.0 603 Declined 14921 14922 if the REFER request was accepted before approval to follow the 14923 reference could be obtained and that approval was subsequently denied 14924 (see Section 2.4.7). 14925 14926 If there are several REFERs in the same dialog, we need to 14927 match the ID of the event header... 14928 */ 14929 if (option_debug > 2) 14930 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 14931 cmd = ast_skip_blanks(buf); 14932 code = cmd; 14933 /* We are at SIP/2.0 */ 14934 while(*code && (*code > 32)) { /* Search white space */ 14935 code++; 14936 } 14937 *code++ = '\0'; 14938 code = ast_skip_blanks(code); 14939 sep = code; 14940 sep++; 14941 while(*sep && (*sep > 32)) { /* Search white space */ 14942 sep++; 14943 } 14944 *sep++ = '\0'; /* Response string */ 14945 respcode = atoi(code); 14946 switch (respcode) { 14947 case 100: /* Trying: */ 14948 case 101: /* dialog establishment */ 14949 /* Don't do anything yet */ 14950 break; 14951 case 183: /* Ringing: */ 14952 /* Don't do anything yet */ 14953 break; 14954 case 200: /* OK: The new call is up, hangup this call */ 14955 /* Hangup the call that we are replacing */ 14956 break; 14957 case 301: /* Moved permenantly */ 14958 case 302: /* Moved temporarily */ 14959 /* Do we get the header in the packet in this case? */ 14960 success = FALSE; 14961 break; 14962 case 503: /* Service Unavailable: The new call failed */ 14963 /* Cancel transfer, continue the call */ 14964 success = FALSE; 14965 break; 14966 case 603: /* Declined: Not accepted */ 14967 /* Cancel transfer, continue the current call */ 14968 success = FALSE; 14969 break; 14970 } 14971 if (!success) { 14972 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 14973 } 14974 14975 /* Confirm that we received this packet */ 14976 transmit_response(p, "200 OK", req); 14977 }; 14978 14979 if (!p->lastinvite) 14980 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14981 14982 return res; 14983 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 14986 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().
14987 { 14988 int res; 14989 14990 14991 /* XXX Should we authenticate OPTIONS? XXX */ 14992 14993 if (p->lastinvite) { 14994 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 14995 transmit_response_with_allow(p, "200 OK", req, 0); 14996 return 0; 14997 } 14998 14999 res = get_destination(p, req); 15000 build_contact(p); 15001 15002 if (ast_strlen_zero(p->context)) 15003 ast_string_field_set(p, context, default_context); 15004 15005 if (ast_shutting_down()) 15006 transmit_response_with_allow(p, "503 Unavailable", req, 0); 15007 else if (res < 0) 15008 transmit_response_with_allow(p, "404 Not Found", req, 0); 15009 else 15010 transmit_response_with_allow(p, "200 OK", req, 0); 15011 15012 /* Destroy if this OPTIONS was the opening request, but not if 15013 it's in the middle of a normal call flow. */ 15014 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15015 15016 return res; 15017 }
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 16236 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_indicate(), 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().
16237 { 16238 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 16239 /* Chan2: Call between asterisk and transferee */ 16240 16241 int res = 0; 16242 16243 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16244 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"); 16245 16246 if (!p->owner) { 16247 /* This is a REFER outside of an existing SIP dialog */ 16248 /* We can't handle that, so decline it */ 16249 if (option_debug > 2) 16250 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 16251 transmit_response(p, "603 Declined (No dialog)", req); 16252 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 16253 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 16254 sip_alreadygone(p); 16255 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16256 } 16257 return 0; 16258 } 16259 16260 16261 /* Check if transfer is allowed from this device */ 16262 if (p->allowtransfer == TRANSFER_CLOSED ) { 16263 /* Transfer not allowed, decline */ 16264 transmit_response(p, "603 Declined (policy)", req); 16265 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 16266 /* Do not destroy SIP session */ 16267 return 0; 16268 } 16269 16270 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16271 /* Already have a pending REFER */ 16272 transmit_response(p, "491 Request pending", req); 16273 append_history(p, "Xfer", "Refer failed. Request pending."); 16274 return 0; 16275 } 16276 16277 /* Allocate memory for call transfer data */ 16278 if (!p->refer && !sip_refer_allocate(p)) { 16279 transmit_response(p, "500 Internal Server Error", req); 16280 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 16281 return -3; 16282 } 16283 16284 res = get_refer_info(p, req); /* Extract headers */ 16285 16286 p->refer->status = REFER_SENT; 16287 16288 if (res != 0) { 16289 switch (res) { 16290 case -2: /* Syntax error */ 16291 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 16292 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 16293 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16294 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 16295 break; 16296 case -3: 16297 transmit_response(p, "603 Declined (Non sip: uri)", req); 16298 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 16299 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16300 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 16301 break; 16302 default: 16303 /* Refer-to extension not found, fake a failed transfer */ 16304 transmit_response(p, "202 Accepted", req); 16305 append_history(p, "Xfer", "Refer failed. Bad extension."); 16306 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 16307 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16308 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 16309 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 16310 break; 16311 } 16312 return 0; 16313 } 16314 if (ast_strlen_zero(p->context)) 16315 ast_string_field_set(p, context, default_context); 16316 16317 /* If we do not support SIP domains, all transfers are local */ 16318 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 16319 p->refer->localtransfer = 1; 16320 if (sipdebug && option_debug > 2) 16321 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 16322 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 16323 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 16324 p->refer->localtransfer = 1; 16325 } else if (sipdebug && option_debug > 2) 16326 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 16327 16328 /* Is this a repeat of a current request? Ignore it */ 16329 /* Don't know what else to do right now. */ 16330 if (ignore) 16331 return res; 16332 16333 /* If this is a blind transfer, we have the following 16334 channels to work with: 16335 - chan1, chan2: The current call between transferer and transferee (2 channels) 16336 - target_channel: A new call from the transferee to the target (1 channel) 16337 We need to stay tuned to what happens in order to be able 16338 to bring back the call to the transferer */ 16339 16340 /* If this is a attended transfer, we should have all call legs within reach: 16341 - chan1, chan2: The call between the transferer and transferee (2 channels) 16342 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 16343 We want to bridge chan2 with targetcall_pvt! 16344 16345 The replaces call id in the refer message points 16346 to the call leg between Asterisk and the transferer. 16347 So we need to connect the target and the transferee channel 16348 and hangup the two other channels silently 16349 16350 If the target is non-local, the call ID could be on a remote 16351 machine and we need to send an INVITE with replaces to the 16352 target. We basically handle this as a blind transfer 16353 and let the sip_call function catch that we need replaces 16354 header in the INVITE. 16355 */ 16356 16357 16358 /* Get the transferer's channel */ 16359 current.chan1 = p->owner; 16360 16361 /* Find the other part of the bridge (2) - transferee */ 16362 current.chan2 = ast_bridged_channel(current.chan1); 16363 16364 if (sipdebug && option_debug > 2) 16365 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>"); 16366 16367 if (!current.chan2 && !p->refer->attendedtransfer) { 16368 /* No bridged channel, propably IVR or echo or similar... */ 16369 /* Guess we should masquerade or something here */ 16370 /* Until we figure it out, refuse transfer of such calls */ 16371 if (sipdebug && option_debug > 2) 16372 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 16373 p->refer->status = REFER_FAILED; 16374 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 16375 transmit_response(p, "603 Declined", req); 16376 return -1; 16377 } 16378 16379 if (current.chan2) { 16380 if (sipdebug && option_debug > 3) 16381 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 16382 16383 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 16384 } 16385 16386 ast_set_flag(&p->flags[0], SIP_GOTREFER); 16387 16388 /* From here on failures will be indicated with NOTIFY requests */ 16389 transmit_response(p, "202 Accepted", req); 16390 16391 /* Attended transfer: Find all call legs and bridge transferee with target*/ 16392 if (p->refer->attendedtransfer) { 16393 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 16394 return res; /* We're done with the transfer */ 16395 /* Fall through for remote transfers that we did not find locally */ 16396 if (sipdebug && option_debug > 3) 16397 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 16398 /* Fallthrough if we can't find the call leg internally */ 16399 } 16400 16401 16402 /* Parking a call */ 16403 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 16404 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 16405 *nounlock = 1; 16406 ast_channel_unlock(current.chan1); 16407 copy_request(¤t.req, req); 16408 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16409 p->refer->status = REFER_200OK; 16410 append_history(p, "Xfer", "REFER to call parking."); 16411 if (sipdebug && option_debug > 3) 16412 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 16413 if ((res = sip_park(current.chan2, current.chan1, req, seqno))) { 16414 transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE); 16415 } 16416 return res; 16417 } 16418 16419 /* Blind transfers and remote attended xfers */ 16420 if (current.chan1 && current.chan2) { 16421 if (option_debug > 2) 16422 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 16423 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 16424 } 16425 if (current.chan2) { 16426 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 16427 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 16428 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 16429 /* One for the new channel */ 16430 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 16431 /* Attended transfer to remote host, prepare headers for the INVITE */ 16432 if (p->refer->referred_by) 16433 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 16434 } 16435 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 16436 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 16437 char tempheader[SIPBUFSIZE]; 16438 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 16439 p->refer->replaces_callid_totag ? ";to-tag=" : "", 16440 p->refer->replaces_callid_totag, 16441 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 16442 p->refer->replaces_callid_fromtag); 16443 if (current.chan2) 16444 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 16445 } 16446 /* Must release lock now, because it will not longer 16447 be accessible after the transfer! */ 16448 *nounlock = 1; 16449 ast_channel_unlock(current.chan1); 16450 16451 /* Connect the call */ 16452 16453 /* FAKE ringing if not attended transfer */ 16454 if (!p->refer->attendedtransfer) 16455 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 16456 16457 /* For blind transfer, this will lead to a new call */ 16458 /* For attended transfer to remote host, this will lead to 16459 a new SIP call with a replaces header, if the dial plan allows it 16460 */ 16461 if (!current.chan2) { 16462 /* We have no bridge, so we're talking with Asterisk somehow */ 16463 /* We need to masquerade this call */ 16464 /* What to do to fix this situation: 16465 * Set up the new call in a new channel 16466 * Let the new channel masq into this channel 16467 Please add that code here :-) 16468 */ 16469 p->refer->status = REFER_FAILED; 16470 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 16471 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16472 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 16473 return -1; 16474 } 16475 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 16476 16477 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 16478 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 16479 /* indicate before masquerade so the indication actually makes it to the real channel 16480 when using local channels with MOH passthru */ 16481 ast_indicate(current.chan2, AST_CONTROL_UNHOLD); 16482 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 16483 16484 if (!res) { 16485 /* Success - we have a new channel */ 16486 if (option_debug > 2) 16487 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 16488 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 16489 if (p->refer->localtransfer) 16490 p->refer->status = REFER_200OK; 16491 if (p->owner) 16492 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 16493 append_history(p, "Xfer", "Refer succeeded."); 16494 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16495 /* Do not hangup call, the other side do that when we say 200 OK */ 16496 /* We could possibly implement a timer here, auto congestion */ 16497 res = 0; 16498 } else { 16499 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 16500 if (option_debug > 2) 16501 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 16502 append_history(p, "Xfer", "Refer failed."); 16503 /* Failure of some kind */ 16504 p->refer->status = REFER_FAILED; 16505 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 16506 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 16507 res = -1; 16508 } 16509 return res; 16510 }
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 17054 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, sip_pvt::callid, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_request::headers, sip_pvt::initreq, LOG_NOTICE, sip_request::method, register_verify(), SIP_PKT_DEBUG, SIP_REGISTER, and sip_scheddestroy().
Referenced by handle_request().
17055 { 17056 enum check_auth_result res; 17057 17058 /* If this is not the intial request, and the initial request isn't 17059 * a register, something screwy happened, so bail */ 17060 if (p->initreq.headers && p->initreq.method != SIP_REGISTER) { 17061 ast_log(LOG_WARNING, "Ignoring spurious REGISTER with Call-ID: %s\n", p->callid); 17062 return -1; 17063 } 17064 17065 /* Use this as the basis */ 17066 if (ast_test_flag(req, SIP_PKT_DEBUG)) 17067 ast_verbose("Using latest REGISTER request as basis request\n"); 17068 copy_request(&p->initreq, req); 17069 check_via(p, req); 17070 if ((res = register_verify(p, sin, req, e)) < 0) { 17071 const char *reason; 17072 17073 switch (res) { 17074 case AUTH_SECRET_FAILED: 17075 reason = "Wrong password"; 17076 break; 17077 case AUTH_USERNAME_MISMATCH: 17078 reason = "Username/auth name mismatch"; 17079 break; 17080 case AUTH_NOT_FOUND: 17081 reason = "No matching peer found"; 17082 break; 17083 case AUTH_UNKNOWN_DOMAIN: 17084 reason = "Not a local domain"; 17085 break; 17086 case AUTH_PEER_NOT_DYNAMIC: 17087 reason = "Peer is not supposed to register"; 17088 break; 17089 case AUTH_ACL_FAILED: 17090 reason = "Device does not match ACL"; 17091 break; 17092 default: 17093 reason = "Unknown failure"; 17094 break; 17095 } 17096 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 17097 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 17098 reason); 17099 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 17100 } else 17101 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 17102 17103 if (res < 1) { 17104 /* Destroy the session, but keep us around for just a bit in case they don't 17105 get our 200 OK */ 17106 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17107 } 17108 return res; 17109 }
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 16732 of file chan_sip.c.
References __get_header(), add_extensionstate_update(), 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_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, 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, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, 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().
16733 { 16734 int gotdest = 0; 16735 int res = 0; 16736 int firststate = AST_EXTENSION_REMOVED; 16737 struct sip_peer *authpeer = NULL; 16738 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 16739 int resubscribe = (p->subscribed != NONE) && !ast_test_flag(req, SIP_PKT_IGNORE); 16740 char *temp, *event; 16741 16742 if (p->initreq.headers) { 16743 /* We already have a dialog */ 16744 if (p->initreq.method != SIP_SUBSCRIBE) { 16745 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 16746 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 16747 transmit_response(p, "403 Forbidden (within dialog)", req); 16748 /* Do not destroy session, since we will break the call if we do */ 16749 if (option_debug) 16750 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); 16751 return 0; 16752 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 16753 if (option_debug) { 16754 if (resubscribe) 16755 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 16756 else 16757 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth) or retransmission\n", p->callid); 16758 } 16759 } 16760 } 16761 16762 /* Check if we have a global disallow setting on subscriptions. 16763 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 16764 */ 16765 if (!global_allowsubscribe) { 16766 transmit_response(p, "403 Forbidden (policy)", req); 16767 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16768 return 0; 16769 } 16770 16771 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 16772 const char *to = get_header(req, "To"); 16773 char totag[128]; 16774 16775 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 16776 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 16777 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16778 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 16779 transmit_response(p, "481 Subscription does not exist", req); 16780 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16781 return 0; 16782 } 16783 16784 /* Use this as the basis */ 16785 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16786 ast_verbose("Creating new subscription\n"); 16787 16788 copy_request(&p->initreq, req); 16789 check_via(p, req); 16790 build_route(p, req, 0); 16791 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 16792 ast_verbose("Ignoring this SUBSCRIBE request\n"); 16793 16794 /* Find parameters to Event: header value and remove them for now */ 16795 if (ast_strlen_zero(eventheader)) { 16796 transmit_response(p, "489 Bad Event", req); 16797 if (option_debug > 1) 16798 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 16799 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16800 return 0; 16801 } 16802 16803 if ( (strchr(eventheader, ';'))) { 16804 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 16805 temp = strchr(event, ';'); 16806 *temp = '\0'; /* Remove any options for now */ 16807 /* We might need to use them later :-) */ 16808 } else 16809 event = (char *) eventheader; /* XXX is this legal ? */ 16810 16811 /* Handle authentication if we're new and not a retransmission. We can't just 16812 * use if !(ast_test_flag(req, SIP_PKT_IGNORE), because then we'll end up sending 16813 * a 200 OK if someone retransmits without sending auth */ 16814 if (p->subscribed == NONE || resubscribe) { 16815 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 16816 16817 /* if an authentication response was sent, we are done here */ 16818 if (res == AUTH_CHALLENGE_SENT) { 16819 if (authpeer) 16820 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16821 return 0; 16822 } 16823 if (res < 0) { 16824 if (res == AUTH_FAKE_AUTH) { 16825 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 16826 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 16827 } else { 16828 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 16829 transmit_response_reliable(p, "403 Forbidden", req); 16830 } 16831 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16832 if (authpeer) 16833 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16834 return 0; 16835 } 16836 } 16837 16838 /* Check if this user/peer is allowed to subscribe at all */ 16839 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 16840 transmit_response(p, "403 Forbidden (policy)", req); 16841 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16842 if (authpeer) 16843 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16844 return 0; 16845 } 16846 16847 if (strcmp(event, "message-summary")) { 16848 /* Get destination right away */ 16849 gotdest = get_destination(p, NULL); 16850 } 16851 16852 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 16853 parse_ok_contact(p, req); 16854 16855 build_contact(p); 16856 if (gotdest) { 16857 transmit_response(p, "404 Not Found", req); 16858 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16859 if (authpeer) 16860 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16861 return 0; 16862 } 16863 16864 /* Initialize tag for new subscriptions */ 16865 if (ast_strlen_zero(p->tag)) 16866 make_our_tag(p->tag, sizeof(p->tag)); 16867 16868 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 16869 unsigned int pidf_xml; 16870 const char *accept; 16871 int start = 0; 16872 enum subscriptiontype subscribed = NONE; 16873 const char *unknown_acceptheader = NULL; 16874 16875 if (authpeer) /* No need for authpeer here */ 16876 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16877 16878 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 16879 accept = __get_header(req, "Accept", &start); 16880 while ((subscribed == NONE) && !ast_strlen_zero(accept)) { 16881 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 16882 16883 /* Older versions of Polycom firmware will claim pidf+xml, but really 16884 * they only support xpidf+xml. */ 16885 if (pidf_xml && strstr(p->useragent, "Polycom")) { 16886 subscribed = XPIDF_XML; 16887 } else if (pidf_xml) { 16888 subscribed = PIDF_XML; /* RFC 3863 format */ 16889 } else if (strstr(accept, "application/dialog-info+xml")) { 16890 subscribed = DIALOG_INFO_XML; 16891 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 16892 } else if (strstr(accept, "application/cpim-pidf+xml")) { 16893 subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 16894 } else if (strstr(accept, "application/xpidf+xml")) { 16895 subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 16896 } else { 16897 unknown_acceptheader = accept; 16898 } 16899 /* check to see if there is another Accept header present */ 16900 accept = __get_header(req, "Accept", &start); 16901 } 16902 16903 if (!start) { 16904 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 16905 transmit_response(p, "489 Bad Event", req); 16906 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: " 16907 "stateid: %d, laststate: %d, dialogver: %d, subscribecont: " 16908 "'%s', subscribeuri: '%s'\n", 16909 p->stateid, 16910 p->laststate, 16911 p->dialogver, 16912 p->subscribecontext, 16913 p->subscribeuri); 16914 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16915 return 0; 16916 } 16917 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 16918 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 16919 } else if (subscribed == NONE) { 16920 /* Can't find a format for events that we know about */ 16921 char mybuf[200]; 16922 if (!ast_strlen_zero(unknown_acceptheader)) { 16923 snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader); 16924 } else { 16925 snprintf(mybuf, sizeof(mybuf), "489 Bad Event"); 16926 } 16927 transmit_response(p, mybuf, req); 16928 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:" 16929 "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d," 16930 "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 16931 unknown_acceptheader, 16932 (int)p->subscribed, 16933 p->stateid, 16934 p->laststate, 16935 p->dialogver, 16936 p->subscribecontext, 16937 p->subscribeuri); 16938 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16939 return 0; 16940 } else { 16941 p->subscribed = subscribed; 16942 } 16943 } else if (!strcmp(event, "message-summary")) { 16944 int start = 0; 16945 int found_supported = 0; 16946 const char *acceptheader; 16947 16948 acceptheader = __get_header(req, "Accept", &start); 16949 while (!found_supported && !ast_strlen_zero(acceptheader)) { 16950 found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1; 16951 if (!found_supported && (option_debug > 2)) { 16952 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader); 16953 } 16954 acceptheader = __get_header(req, "Accept", &start); 16955 } 16956 if (start && !found_supported) { 16957 /* Format requested that we do not support */ 16958 transmit_response(p, "406 Not Acceptable", req); 16959 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16960 if (authpeer) /* No need for authpeer here */ 16961 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16962 return 0; 16963 } 16964 /* Looks like they actually want a mailbox status 16965 This version of Asterisk supports mailbox subscriptions 16966 The subscribed URI needs to exist in the dial plan 16967 In most devices, this is configurable to the voicemailmain extension you use 16968 */ 16969 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 16970 transmit_response(p, "404 Not found (no mailbox)", req); 16971 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16972 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 16973 if (authpeer) /* No need for authpeer here */ 16974 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16975 return 0; 16976 } 16977 16978 p->subscribed = MWI_NOTIFICATION; 16979 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 16980 /* We only allow one subscription per peer */ 16981 sip_destroy(authpeer->mwipvt); 16982 authpeer->mwipvt = p; /* Link from peer to pvt */ 16983 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 16984 } else { /* At this point, Asterisk does not understand the specified event */ 16985 transmit_response(p, "489 Bad Event", req); 16986 if (option_debug > 1) 16987 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 16988 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16989 if (authpeer) /* No need for authpeer here */ 16990 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16991 return 0; 16992 } 16993 16994 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 16995 if (p->stateid > -1) 16996 ast_extension_state_del(p->stateid, add_extensionstate_update); 16997 p->stateid = ast_extension_state_add(p->context, p->exten, add_extensionstate_update, p); 16998 } 16999 17000 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 17001 p->lastinvite = seqno; 17002 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 17003 p->expiry = atoi(get_header(req, "Expires")); 17004 17005 /* check if the requested expiry-time is within the approved limits from sip.conf */ 17006 if (p->expiry > max_expiry) 17007 p->expiry = max_expiry; 17008 if (p->expiry < min_expiry && p->expiry > 0) 17009 p->expiry = min_expiry; 17010 17011 if (sipdebug || option_debug > 1) { 17012 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 17013 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 17014 else 17015 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 17016 } 17017 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 17018 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 17019 if (p->expiry > 0) 17020 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 17021 17022 if (p->subscribed == MWI_NOTIFICATION) { 17023 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17024 transmit_response(p, "200 OK", req); 17025 if (p->relatedpeer) { /* Send first notification */ 17026 ASTOBJ_WRLOCK(p->relatedpeer); 17027 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 17028 ASTOBJ_UNLOCK(p->relatedpeer); 17029 } 17030 } else { 17031 17032 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 17033 17034 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)); 17035 transmit_response(p, "404 Not found", req); 17036 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17037 return 0; 17038 } 17039 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 17040 transmit_response(p, "200 OK", req); 17041 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 17042 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 17043 /* hide the 'complete' exten/context in the refer_to field for later display */ 17044 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 17045 17046 } 17047 if (!p->expiry) 17048 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 17049 } 17050 return 1; 17051 }
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 14114 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, 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, notify_extenstate_update(), 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_FORWARD_LOOP_DETECTED, 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.
14115 { 14116 struct ast_channel *owner; 14117 int sipmethod; 14118 int res = 1; 14119 int ack_res; 14120 const char *c = get_header(req, "Cseq"); 14121 /* 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 */ 14122 char *c_copy = ast_strdupa(c); 14123 /* Skip the Cseq and its subsequent spaces */ 14124 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 14125 14126 if (!msg) 14127 msg = ""; 14128 14129 sipmethod = find_sip_method(msg); 14130 14131 owner = p->owner; 14132 if (owner) 14133 owner->hangupcause = hangup_sip2cause(resp); 14134 14135 /* Acknowledge whatever it is destined for */ 14136 if ((resp >= 100) && (resp <= 199)) { 14137 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 14138 } else { 14139 ack_res = __sip_ack(p, seqno, 0, sipmethod); 14140 } 14141 14142 if (ack_res == FALSE) { 14143 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14144 return; 14145 } 14146 14147 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 14148 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 14149 p->pendinginvite = 0; 14150 14151 /* Get their tag if we haven't already */ 14152 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 14153 char tag[128]; 14154 14155 gettag(req, "To", tag, sizeof(tag)); 14156 ast_string_field_set(p, theirtag, tag); 14157 } 14158 14159 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 14160 * in response to a BYE, then we should end the current dialog 14161 * and session. It is known that at least one phone manufacturer 14162 * potentially will send a 404 in response to a BYE, so we'll be 14163 * liberal in what we accept and end the dialog and session if we 14164 * receive any of those responses to a BYE. 14165 */ 14166 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 14167 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14168 return; 14169 } 14170 14171 if (p->relatedpeer && p->method == SIP_OPTIONS) { 14172 /* We don't really care what the response is, just that it replied back. 14173 Well, as long as it's not a 100 response... since we might 14174 need to hang around for something more "definitive" */ 14175 if (resp != 100) 14176 handle_response_peerpoke(p, resp, req); 14177 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 14178 switch(resp) { 14179 case 100: /* 100 Trying */ 14180 case 101: /* 101 Dialog establishment */ 14181 if (sipmethod == SIP_INVITE) 14182 handle_response_invite(p, resp, rest, req, seqno); 14183 break; 14184 case 183: /* 183 Session Progress */ 14185 if (sipmethod == SIP_INVITE) 14186 handle_response_invite(p, resp, rest, req, seqno); 14187 break; 14188 case 180: /* 180 Ringing */ 14189 if (sipmethod == SIP_INVITE) 14190 handle_response_invite(p, resp, rest, req, seqno); 14191 break; 14192 case 182: /* 182 Queued */ 14193 if (sipmethod == SIP_INVITE) 14194 handle_response_invite(p, resp, rest, req, seqno); 14195 break; 14196 case 200: /* 200 OK */ 14197 p->authtries = 0; /* Reset authentication counter */ 14198 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 14199 /* We successfully transmitted a message 14200 or a video update request in INFO */ 14201 /* Nothing happens here - the message is inside a dialog */ 14202 } else if (sipmethod == SIP_INVITE) { 14203 handle_response_invite(p, resp, rest, req, seqno); 14204 } else if (sipmethod == SIP_NOTIFY) { 14205 /* They got the notify, this is the end */ 14206 if (p->owner) { 14207 if (!p->refer) { 14208 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 14209 ast_queue_hangup(p->owner); 14210 } else if (option_debug > 3) 14211 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 14212 } else { 14213 if (p->subscribed == NONE) 14214 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14215 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 14216 /* Ready to send the next state we have on queue */ 14217 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 14218 notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 14219 } 14220 } 14221 } else if (sipmethod == SIP_REGISTER) 14222 res = handle_response_register(p, resp, rest, req, seqno); 14223 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 14224 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14225 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14226 } else if (sipmethod == SIP_SUBSCRIBE) 14227 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14228 break; 14229 case 202: /* Transfer accepted */ 14230 if (sipmethod == SIP_REFER) 14231 handle_response_refer(p, resp, rest, req, seqno); 14232 break; 14233 case 401: /* Not www-authorized on SIP method */ 14234 if (sipmethod == SIP_INVITE) 14235 handle_response_invite(p, resp, rest, req, seqno); 14236 else if (sipmethod == SIP_REFER) 14237 handle_response_refer(p, resp, rest, req, seqno); 14238 else if (p->registry && sipmethod == SIP_REGISTER) 14239 res = handle_response_register(p, resp, rest, req, seqno); 14240 else if (sipmethod == SIP_BYE) { 14241 if (ast_strlen_zero(p->authname)) { 14242 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 14243 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 14244 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14245 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 14246 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14247 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14248 /* We fail to auth bye on our own call, but still needs to tear down the call. 14249 Life, they call it. */ 14250 } 14251 } else { 14252 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 14253 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14254 } 14255 break; 14256 case 403: /* Forbidden - we failed authentication */ 14257 if (sipmethod == SIP_INVITE) 14258 handle_response_invite(p, resp, rest, req, seqno); 14259 else if (p->registry && sipmethod == SIP_REGISTER) 14260 res = handle_response_register(p, resp, rest, req, seqno); 14261 else { 14262 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 14263 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14264 } 14265 break; 14266 case 404: /* Not found */ 14267 if (p->registry && sipmethod == SIP_REGISTER) 14268 res = handle_response_register(p, resp, rest, req, seqno); 14269 else if (sipmethod == SIP_INVITE) 14270 handle_response_invite(p, resp, rest, req, seqno); 14271 else if (owner) 14272 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14273 break; 14274 case 407: /* Proxy auth required */ 14275 if (sipmethod == SIP_INVITE) 14276 handle_response_invite(p, resp, rest, req, seqno); 14277 else if (sipmethod == SIP_REFER) 14278 handle_response_refer(p, resp, rest, req, seqno); 14279 else if (p->registry && sipmethod == SIP_REGISTER) 14280 res = handle_response_register(p, resp, rest, req, seqno); 14281 else if (sipmethod == SIP_BYE) { 14282 if (ast_strlen_zero(p->authname)) { 14283 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 14284 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 14285 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14286 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 14287 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14288 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14289 } 14290 } else /* We can't handle this, giving up in a bad way */ 14291 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14292 14293 break; 14294 case 408: /* Request timeout - terminate dialog */ 14295 if (sipmethod == SIP_INVITE) 14296 handle_response_invite(p, resp, rest, req, seqno); 14297 else if (sipmethod == SIP_REGISTER) 14298 res = handle_response_register(p, resp, rest, req, seqno); 14299 else if (sipmethod == SIP_BYE) { 14300 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14301 if (option_debug) 14302 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 14303 } else { 14304 if (owner) 14305 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14306 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14307 } 14308 break; 14309 case 481: /* Call leg does not exist */ 14310 if (sipmethod == SIP_INVITE) { 14311 handle_response_invite(p, resp, rest, req, seqno); 14312 } else if (sipmethod == SIP_REFER) { 14313 handle_response_refer(p, resp, rest, req, seqno); 14314 } else if (sipmethod == SIP_BYE) { 14315 /* The other side has no transaction to bye, 14316 just assume it's all right then */ 14317 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14318 } else if (sipmethod == SIP_CANCEL) { 14319 /* The other side has no transaction to cancel, 14320 just assume it's all right then */ 14321 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14322 } else if (sipmethod == SIP_NOTIFY) { 14323 /* The other side has no active Subscribe for this Callid. 14324 * Remove this Dialog and old Subscription */ 14325 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14326 } else { 14327 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 14328 /* Guessing that this is not an important request */ 14329 } 14330 break; 14331 case 487: 14332 if (sipmethod == SIP_INVITE) 14333 handle_response_invite(p, resp, rest, req, seqno); 14334 break; 14335 case 488: /* Not acceptable here - codec error */ 14336 case 606: /* Not Acceptable */ 14337 if (sipmethod == SIP_INVITE) 14338 handle_response_invite(p, resp, rest, req, seqno); 14339 break; 14340 case 491: /* Pending */ 14341 if (sipmethod == SIP_INVITE) 14342 handle_response_invite(p, resp, rest, req, seqno); 14343 else { 14344 if (option_debug) 14345 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 14346 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14347 } 14348 break; 14349 case 501: /* Not Implemented */ 14350 if (sipmethod == SIP_INVITE) 14351 handle_response_invite(p, resp, rest, req, seqno); 14352 else if (sipmethod == SIP_REFER) 14353 handle_response_refer(p, resp, rest, req, seqno); 14354 else 14355 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 14356 break; 14357 case 603: /* Declined transfer */ 14358 if (sipmethod == SIP_REFER) { 14359 handle_response_refer(p, resp, rest, req, seqno); 14360 break; 14361 } 14362 /* Fallthrough */ 14363 default: 14364 if ((resp >= 300) && (resp < 700)) { 14365 /* Fatal response */ 14366 if ((option_verbose > 2) && (resp != 487)) 14367 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 14368 14369 if (sipmethod == SIP_INVITE) 14370 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14371 14372 /* XXX Locking issues?? XXX */ 14373 switch(resp) { 14374 case 300: /* Multiple Choices */ 14375 case 301: /* Moved permenantly */ 14376 case 302: /* Moved temporarily */ 14377 case 305: /* Use Proxy */ 14378 parse_moved_contact(p, req); 14379 /* Fall through */ 14380 case 486: /* Busy here */ 14381 case 600: /* Busy everywhere */ 14382 case 603: /* Decline */ 14383 if (p->owner) 14384 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14385 break; 14386 case 482: /* Loop Detected */ 14387 /* 14388 \note Asterisk has historically tried to do a call forward when it 14389 gets a 482, but that behavior isn't necessarily the best course of 14390 action. Go ahead and do it anyway by default, but allow the option 14391 to immediately pass to the next line in the dialplan. */ 14392 if (p->owner && ast_test_flag(&p->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED)) { 14393 if (option_debug) { 14394 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 14395 } 14396 ast_string_field_build(p->owner, call_forward, 14397 "Local/%s@%s", p->username, p->context); 14398 } 14399 /* Fall through */ 14400 case 480: /* Temporarily Unavailable */ 14401 case 404: /* Not Found */ 14402 case 410: /* Gone */ 14403 case 400: /* Bad Request */ 14404 case 500: /* Server error */ 14405 if (sipmethod == SIP_REFER) { 14406 handle_response_refer(p, resp, rest, req, seqno); 14407 break; 14408 } 14409 /* Fall through */ 14410 case 502: /* Bad gateway */ 14411 case 503: /* Service Unavailable */ 14412 case 504: /* Server Timeout */ 14413 if (owner) 14414 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 14415 break; 14416 default: 14417 /* Send hangup */ 14418 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 14419 ast_queue_hangup(p->owner); 14420 break; 14421 } 14422 /* ACK on invite */ 14423 if (sipmethod == SIP_INVITE) 14424 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 14425 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 14426 sip_alreadygone(p); 14427 if (!p->owner) 14428 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14429 } else if ((resp >= 100) && (resp < 200)) { 14430 if (sipmethod == SIP_INVITE) { 14431 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 14432 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14433 if (find_sdp(req)) 14434 process_sdp(p, req); 14435 if (p->owner) { 14436 /* Queue a progress frame */ 14437 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 14438 } 14439 } 14440 } else 14441 ast_log(LOG_NOTICE, "Don't 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)); 14442 } 14443 } else { 14444 /* Responses to OUTGOING SIP requests on INCOMING calls 14445 get handled here. As well as out-of-call message responses */ 14446 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14447 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 14448 14449 if (sipmethod == SIP_INVITE && resp == 200) { 14450 /* Tags in early session is replaced by the tag in 200 OK, which is 14451 the final reply to our INVITE */ 14452 char tag[128]; 14453 14454 gettag(req, "To", tag, sizeof(tag)); 14455 ast_string_field_set(p, theirtag, tag); 14456 } 14457 14458 switch(resp) { 14459 case 200: 14460 if (sipmethod == SIP_INVITE) { 14461 handle_response_invite(p, resp, rest, req, seqno); 14462 } else if (sipmethod == SIP_CANCEL) { 14463 if (option_debug) 14464 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 14465 14466 /* Wait for 487, then destroy */ 14467 } else if (sipmethod == SIP_NOTIFY) { 14468 /* They got the notify, this is the end */ 14469 if (p->owner) { 14470 if (p->refer) { 14471 if (option_debug) 14472 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 14473 } else 14474 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 14475 /* ast_queue_hangup(p->owner); Disabled */ 14476 } else { 14477 if (!p->subscribed && !p->refer) 14478 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14479 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 14480 /* Ready to send the next state we have on queue */ 14481 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 14482 notify_extenstate_update((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 14483 } 14484 } 14485 } else if (sipmethod == SIP_BYE) 14486 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14487 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 14488 /* We successfully transmitted a message or 14489 a video update request in INFO */ 14490 ; 14491 else if (sipmethod == SIP_BYE) 14492 /* Ok, we're ready to go */ 14493 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14494 break; 14495 case 202: /* Transfer accepted */ 14496 if (sipmethod == SIP_REFER) 14497 handle_response_refer(p, resp, rest, req, seqno); 14498 break; 14499 case 401: /* www-auth */ 14500 case 407: 14501 if (sipmethod == SIP_REFER) 14502 handle_response_refer(p, resp, rest, req, seqno); 14503 else if (sipmethod == SIP_INVITE) 14504 handle_response_invite(p, resp, rest, req, seqno); 14505 else if (sipmethod == SIP_BYE) { 14506 char *auth, *auth2; 14507 14508 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 14509 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 14510 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 14511 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 14512 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14513 } 14514 } 14515 break; 14516 case 481: /* Call leg does not exist */ 14517 if (sipmethod == SIP_INVITE) { 14518 /* Re-invite failed */ 14519 handle_response_invite(p, resp, rest, req, seqno); 14520 } else if (sipmethod == SIP_BYE) { 14521 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14522 } else if (sipmethod == SIP_NOTIFY) { 14523 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14524 } else if (sipdebug) { 14525 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 14526 } 14527 break; 14528 case 501: /* Not Implemented */ 14529 if (sipmethod == SIP_INVITE) 14530 handle_response_invite(p, resp, rest, req, seqno); 14531 else if (sipmethod == SIP_REFER) 14532 handle_response_refer(p, resp, rest, req, seqno); 14533 break; 14534 case 603: /* Declined transfer */ 14535 if (sipmethod == SIP_REFER) { 14536 handle_response_refer(p, resp, rest, req, seqno); 14537 break; 14538 } 14539 /* Fallthrough */ 14540 default: /* Errors without handlers */ 14541 if ((resp >= 100) && (resp < 200)) { 14542 if (sipmethod == SIP_INVITE) { /* re-invite */ 14543 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 14544 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14545 } 14546 } 14547 if ((resp >= 300) && (resp < 700)) { 14548 if ((option_verbose > 2) && (resp != 487)) 14549 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)); 14550 switch(resp) { 14551 case 488: /* Not acceptable here - codec error */ 14552 case 603: /* Decline */ 14553 case 500: /* Server error */ 14554 case 502: /* Bad gateway */ 14555 case 503: /* Service Unavailable */ 14556 case 504: /* Server timeout */ 14557 14558 /* re-invite failed */ 14559 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 14560 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14561 break; 14562 } 14563 } 14564 break; 14565 } 14566 } 14567 }
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 13518 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_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_reinvite_with_sdp(), 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().
13519 { 13520 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 13521 int res = 0; 13522 int xmitres = 0; 13523 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 13524 struct ast_channel *bridgepeer = NULL; 13525 13526 if (option_debug > 3) { 13527 if (reinvite) 13528 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 13529 else 13530 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 13531 } 13532 13533 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 13534 if (option_debug) 13535 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 13536 return; 13537 } 13538 13539 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 13540 /* Don't auto congest anymore since we've gotten something useful back */ 13541 AST_SCHED_DEL(sched, p->initid); 13542 13543 /* RFC3261 says we must treat every 1xx response (but not 100) 13544 that we don't recognize as if it was 183. 13545 */ 13546 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 13547 resp = 183; 13548 13549 /* Any response between 100 and 199 is PROCEEDING */ 13550 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 13551 p->invitestate = INV_PROCEEDING; 13552 13553 /* Final response, not 200 ? */ 13554 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 13555 p->invitestate = INV_COMPLETED; 13556 13557 13558 switch (resp) { 13559 case 100: /* Trying */ 13560 case 101: /* Dialog establishment */ 13561 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13562 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13563 check_pendings(p); 13564 break; 13565 13566 case 180: /* 180 Ringing */ 13567 case 182: /* 182 Queued */ 13568 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13569 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13570 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13571 ast_queue_control(p->owner, AST_CONTROL_RINGING); 13572 if (p->owner->_state != AST_STATE_UP) { 13573 ast_setstate(p->owner, AST_STATE_RINGING); 13574 } 13575 } 13576 if (find_sdp(req)) { 13577 if (p->invitestate != INV_CANCELLED) 13578 p->invitestate = INV_EARLY_MEDIA; 13579 res = process_sdp(p, req); 13580 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13581 /* Queue a progress frame only if we have SDP in 180 or 182 */ 13582 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13583 } 13584 } 13585 check_pendings(p); 13586 break; 13587 13588 case 183: /* Session progress */ 13589 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13590 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13591 if (find_sdp(req)) { 13592 if (p->invitestate != INV_CANCELLED) 13593 p->invitestate = INV_EARLY_MEDIA; 13594 res = process_sdp(p, req); 13595 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13596 /* Queue a progress frame */ 13597 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13598 } 13599 } else { 13600 /* Alcatel PBXs are known to send 183s with no SDP after sending 13601 * a 100 Trying response. We're just going to treat this sort of thing 13602 * the same as we would treat a 180 Ringing 13603 */ 13604 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13605 ast_queue_control(p->owner, AST_CONTROL_RINGING); 13606 } 13607 } 13608 check_pendings(p); 13609 break; 13610 13611 case 200: /* 200 OK on invite - someone's answering our call */ 13612 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 13613 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13614 p->authtries = 0; 13615 if (find_sdp(req)) { 13616 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 13617 if (!reinvite) 13618 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 13619 /* For re-invites, we try to recover */ 13620 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13621 } 13622 13623 /* Parse contact header for continued conversation */ 13624 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 13625 /* This is important when we have a SIP proxy between us and the phone */ 13626 if (outgoing) { 13627 update_call_counter(p, DEC_CALL_RINGING); 13628 parse_ok_contact(p, req); 13629 /* Save Record-Route for any later requests we make on this dialogue */ 13630 if (!reinvite) 13631 build_route(p, req, 1); 13632 13633 if(set_address_from_contact(p)) { 13634 /* Bad contact - we don't know how to reach this device */ 13635 /* We need to ACK, but then send a bye */ 13636 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 13637 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13638 } 13639 13640 } 13641 13642 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13643 struct sip_pvt *bridgepvt = NULL; 13644 13645 if (!bridgepeer->tech) { 13646 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 13647 break; 13648 } 13649 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13650 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13651 if (bridgepvt->udptl) { 13652 if (p->t38.state == T38_PEER_REINVITE) { 13653 sip_handle_t38_reinvite(bridgepeer, p, 0); 13654 ast_rtp_set_rtptimers_onhold(p->rtp); 13655 if (p->vrtp) 13656 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 13657 } 13658 } else { 13659 if (option_debug > 1) 13660 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 13661 ast_mutex_lock(&bridgepvt->lock); 13662 bridgepvt->t38.state = T38_DISABLED; 13663 ast_mutex_unlock(&bridgepvt->lock); 13664 if (option_debug) 13665 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 13666 p->t38.state = T38_DISABLED; 13667 if (option_debug > 1) 13668 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13669 } 13670 } else { 13671 /* Other side is not a SIP channel */ 13672 if (option_debug > 1) 13673 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 13674 p->t38.state = T38_DISABLED; 13675 if (option_debug > 1) 13676 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13677 } 13678 } 13679 if (p->t38.state == T38_LOCAL_REINVITE) { 13680 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 13681 p->t38.state = T38_ENABLED; 13682 if (option_debug) 13683 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13684 } 13685 13686 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 13687 if (!reinvite) { 13688 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 13689 } else { /* RE-invite */ 13690 ast_queue_frame(p->owner, &ast_null_frame); 13691 } 13692 } else { 13693 /* It's possible we're getting an 200 OK after we've tried to disconnect 13694 by sending CANCEL */ 13695 /* First send ACK, then send bye */ 13696 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13697 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 13698 } 13699 /* If I understand this right, the branch is different for a non-200 ACK only */ 13700 p->invitestate = INV_TERMINATED; 13701 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13702 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 13703 check_pendings(p); 13704 break; 13705 case 407: /* Proxy authentication */ 13706 case 401: /* Www auth */ 13707 /* First we ACK */ 13708 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13709 if (p->options) 13710 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 13711 13712 /* Then we AUTH */ 13713 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 13714 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13715 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 13716 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 13717 if (p->authtries < MAX_AUTHTRIES) 13718 p->invitestate = INV_CALLING; 13719 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 13720 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 13721 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13722 sip_alreadygone(p); 13723 if (p->owner) 13724 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13725 } 13726 } 13727 break; 13728 13729 case 403: /* Forbidden */ 13730 /* First we ACK */ 13731 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13732 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 13733 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 13734 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13735 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13736 sip_alreadygone(p); 13737 break; 13738 13739 case 404: /* Not found */ 13740 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13741 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13742 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13743 sip_alreadygone(p); 13744 break; 13745 13746 case 408: /* Request timeout */ 13747 case 481: /* Call leg does not exist */ 13748 /* Could be REFER caused INVITE with replaces */ 13749 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 13750 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13751 if (p->owner) 13752 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13753 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13754 break; 13755 case 487: /* Cancelled transaction */ 13756 /* We have sent CANCEL on an outbound INVITE 13757 This transaction is already scheduled to be killed by sip_hangup(). 13758 */ 13759 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13760 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13761 ast_queue_hangup(p->owner); 13762 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 13763 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13764 update_call_counter(p, DEC_CALL_LIMIT); 13765 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 13766 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13767 sip_alreadygone(p); 13768 } 13769 break; 13770 case 488: /* Not acceptable here */ 13771 case 606: /* Not Acceptable */ 13772 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13773 if (reinvite && p->udptl) { 13774 p->t38.state = T38_DISABLED; 13775 /* Try to reset RTP timers */ 13776 ast_rtp_set_rtptimers_onhold(p->rtp); 13777 /* Trigger a reinvite back to audio */ 13778 transmit_reinvite_with_sdp(p); 13779 13780 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 13781 struct sip_pvt *bridgepvt = NULL; 13782 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13783 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 13784 if (bridgepvt->udptl) { 13785 sip_handle_t38_reinvite(bridgepeer, p, 0); 13786 } 13787 } 13788 } 13789 } else { 13790 /* We can't set up this call, so give up */ 13791 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 13792 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13793 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13794 /* If there's no dialog to end, then mark p as already gone */ 13795 if (!reinvite) 13796 sip_alreadygone(p); 13797 } 13798 break; 13799 case 491: /* Pending */ 13800 /* we really should have to wait a while, then retransmit 13801 * We should support the retry-after at some point 13802 * At this point, we treat this as a congestion if the call is not in UP state 13803 */ 13804 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13805 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 13806 if (p->owner->_state != AST_STATE_UP) { 13807 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13808 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13809 } else { 13810 /* This is a re-invite that failed. 13811 * Reset the flag after a while 13812 */ 13813 int wait; 13814 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 13815 * if not owner of call, wait 0 to 2 seconds */ 13816 if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 13817 wait = 2100 + ast_random() % 2000; 13818 } else { 13819 wait = ast_random() % 2000; 13820 } 13821 13822 if (p->waitid != -1) { 13823 if (option_debug > 2) 13824 ast_log(LOG_DEBUG, "Reinvite race during existing reinvite race. Abandoning previous reinvite retry.\n"); 13825 AST_SCHED_DEL(sched, p->waitid); 13826 p->waitid = -1; 13827 } 13828 13829 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 13830 if (option_debug > 2) 13831 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 13832 } 13833 } 13834 break; 13835 13836 case 501: /* Not implemented */ 13837 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13838 if (p->owner) 13839 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13840 break; 13841 } 13842 if (xmitres == XMIT_ERROR) 13843 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 13844 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 14042 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().
14043 { 14044 struct sip_peer *peer = p->relatedpeer; 14045 int statechanged, is_reachable, was_reachable; 14046 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 14047 14048 /* 14049 * Compute the response time to a ping (goes in peer->lastms.) 14050 * -1 means did not respond, 0 means unknown, 14051 * 1..maxms is a valid response, >maxms means late response. 14052 */ 14053 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 14054 pingtime = 1; 14055 14056 /* Now determine new state and whether it has changed. 14057 * Use some helper variables to simplify the writing 14058 * of the expressions. 14059 */ 14060 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 14061 is_reachable = pingtime <= peer->maxms; 14062 statechanged = peer->lastms == 0 /* yes, unknown before */ 14063 || was_reachable != is_reachable; 14064 14065 peer->lastms = pingtime; 14066 peer->call = NULL; 14067 if (statechanged) { 14068 const char *s = is_reachable ? "Reachable" : "Lagged"; 14069 char str_lastms[20]; 14070 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 14071 14072 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 14073 peer->name, s, pingtime, peer->maxms); 14074 ast_device_state_changed("SIP/%s", peer->name); 14075 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 14076 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 14077 } 14078 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 14079 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 14080 peer->name, s, pingtime); 14081 } 14082 14083 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 14084 struct sip_peer *peer_ptr = peer; 14085 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 14086 } 14087 14088 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14089 14090 /* Try again eventually */ 14091 peer->pokeexpire = ast_sched_add(sched, 14092 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 14093 sip_poke_peer_s, ASTOBJ_REF(peer)); 14094 14095 if (peer->pokeexpire == -1) { 14096 ASTOBJ_UNREF(peer, sip_destroy_peer); 14097 } 14098 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 13849 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().
13850 { 13851 char *auth = "Proxy-Authenticate"; 13852 char *auth2 = "Proxy-Authorization"; 13853 13854 /* If no refer structure exists, then do nothing */ 13855 if (!p->refer) 13856 return; 13857 13858 switch (resp) { 13859 case 202: /* Transfer accepted */ 13860 /* We need to do something here */ 13861 /* The transferee is now sending INVITE to target */ 13862 p->refer->status = REFER_ACCEPTED; 13863 /* Now wait for next message */ 13864 if (option_debug > 2) 13865 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 13866 /* We should hang along, waiting for NOTIFY's here */ 13867 break; 13868 13869 case 401: /* Not www-authorized on SIP method */ 13870 case 407: /* Proxy auth */ 13871 if (ast_strlen_zero(p->authname)) { 13872 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 13873 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13874 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13875 } 13876 if (resp == 401) { 13877 auth = "WWW-Authenticate"; 13878 auth2 = "Authorization"; 13879 } 13880 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 13881 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 13882 p->refer->status = REFER_NOAUTH; 13883 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13884 } 13885 break; 13886 case 481: /* Call leg does not exist */ 13887 13888 /* A transfer with Replaces did not work */ 13889 /* OEJ: We should Set flag, cancel the REFER, go back 13890 to original call - but right now we can't */ 13891 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 13892 if (p->owner) 13893 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13894 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13895 break; 13896 13897 case 500: /* Server error */ 13898 case 501: /* Method not implemented */ 13899 /* Return to the current call onhold */ 13900 /* Status flag needed to be reset */ 13901 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 13902 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13903 p->refer->status = REFER_FAILED; 13904 break; 13905 case 603: /* Transfer declined */ 13906 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 13907 p->refer->status = REFER_FAILED; 13908 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13909 break; 13910 } 13911 }
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 13914 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().
13915 { 13916 int expires, expires_ms; 13917 struct sip_registry *r; 13918 r=p->registry; 13919 13920 switch (resp) { 13921 case 401: /* Unauthorized */ 13922 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 13923 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 13924 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13925 } 13926 break; 13927 case 403: /* Forbidden */ 13928 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 13929 if (global_regattempts_max) 13930 p->registry->regattempts = global_regattempts_max+1; 13931 AST_SCHED_DEL(sched, r->timeout); 13932 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13933 break; 13934 case 404: /* Not found */ 13935 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 13936 if (global_regattempts_max) 13937 p->registry->regattempts = global_regattempts_max+1; 13938 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13939 r->call = NULL; 13940 AST_SCHED_DEL(sched, r->timeout); 13941 break; 13942 case 407: /* Proxy auth */ 13943 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 13944 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 13945 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13946 } 13947 break; 13948 case 408: /* Request timeout */ 13949 /* Got a timeout response, so reset the counter of failed responses */ 13950 if (r) { 13951 r->regattempts = 0; 13952 } else { 13953 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 13954 } 13955 break; 13956 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 13957 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 13958 if (global_regattempts_max) 13959 p->registry->regattempts = global_regattempts_max+1; 13960 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13961 r->call = NULL; 13962 AST_SCHED_DEL(sched, r->timeout); 13963 break; 13964 case 200: /* 200 OK */ 13965 if (!r) { 13966 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)); 13967 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13968 return 0; 13969 } 13970 13971 r->regstate = REG_STATE_REGISTERED; 13972 r->regtime = time(NULL); /* Reset time of last succesful registration */ 13973 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 13974 r->regattempts = 0; 13975 if (option_debug) 13976 ast_log(LOG_DEBUG, "Registration successful\n"); 13977 if (r->timeout > -1) { 13978 if (option_debug) 13979 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 13980 } 13981 AST_SCHED_DEL(sched, r->timeout); 13982 r->call = NULL; 13983 p->registry = NULL; 13984 /* Let this one hang around until we have all the responses */ 13985 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13986 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 13987 13988 /* set us up for re-registering */ 13989 /* figure out how long we got registered for */ 13990 AST_SCHED_DEL(sched, r->expire); 13991 /* according to section 6.13 of RFC, contact headers override 13992 expires headers, so check those first */ 13993 expires = 0; 13994 13995 /* XXX todo: try to save the extra call */ 13996 if (!ast_strlen_zero(get_header(req, "Contact"))) { 13997 const char *contact = NULL; 13998 const char *tmptmp = NULL; 13999 int start = 0; 14000 for(;;) { 14001 contact = __get_header(req, "Contact", &start); 14002 /* this loop ensures we get a contact header about our register request */ 14003 if(!ast_strlen_zero(contact)) { 14004 if( (tmptmp=strstr(contact, p->our_contact))) { 14005 contact=tmptmp; 14006 break; 14007 } 14008 } else 14009 break; 14010 } 14011 tmptmp = strcasestr(contact, "expires="); 14012 if (tmptmp) { 14013 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 14014 expires = 0; 14015 } 14016 14017 } 14018 if (!expires) 14019 expires=atoi(get_header(req, "expires")); 14020 if (!expires) 14021 expires=default_expiry; 14022 14023 expires_ms = expires * 1000; 14024 if (expires <= EXPIRY_GUARD_LIMIT) 14025 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 14026 else 14027 expires_ms -= EXPIRY_GUARD_SECS * 1000; 14028 if (sipdebug) 14029 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 14030 14031 r->refresh= (int) expires_ms / 1000; 14032 14033 /* Schedule re-registration before we expire */ 14034 AST_SCHED_DEL(sched, r->expire); 14035 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 14036 ASTOBJ_UNREF(r, sip_registry_destroy); 14037 } 14038 return 1; 14039 }
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 3781 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().
03782 { 03783 switch (cause) { 03784 case AST_CAUSE_UNALLOCATED: /* 1 */ 03785 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03786 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03787 return "404 Not Found"; 03788 case AST_CAUSE_CONGESTION: /* 34 */ 03789 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03790 return "503 Service Unavailable"; 03791 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03792 return "408 Request Timeout"; 03793 case AST_CAUSE_NO_ANSWER: /* 19 */ 03794 case AST_CAUSE_UNREGISTERED: /* 20 */ 03795 return "480 Temporarily unavailable"; 03796 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03797 return "403 Forbidden"; 03798 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03799 return "410 Gone"; 03800 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03801 return "480 Temporarily unavailable"; 03802 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03803 return "484 Address incomplete"; 03804 case AST_CAUSE_USER_BUSY: 03805 return "486 Busy here"; 03806 case AST_CAUSE_FAILURE: 03807 return "500 Server internal failure"; 03808 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03809 return "501 Not Implemented"; 03810 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03811 return "503 Service Unavailable"; 03812 /* Used in chan_iax2 */ 03813 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03814 return "502 Bad Gateway"; 03815 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03816 return "488 Not Acceptable Here"; 03817 03818 case AST_CAUSE_NOTDEFINED: 03819 default: 03820 if (option_debug) 03821 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03822 return NULL; 03823 } 03824 03825 /* Never reached */ 03826 return 0; 03827 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3669 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().
03670 { 03671 /* Possible values taken from causes.h */ 03672 03673 switch(cause) { 03674 case 401: /* Unauthorized */ 03675 return AST_CAUSE_CALL_REJECTED; 03676 case 403: /* Not found */ 03677 return AST_CAUSE_CALL_REJECTED; 03678 case 404: /* Not found */ 03679 return AST_CAUSE_UNALLOCATED; 03680 case 405: /* Method not allowed */ 03681 return AST_CAUSE_INTERWORKING; 03682 case 407: /* Proxy authentication required */ 03683 return AST_CAUSE_CALL_REJECTED; 03684 case 408: /* No reaction */ 03685 return AST_CAUSE_NO_USER_RESPONSE; 03686 case 409: /* Conflict */ 03687 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03688 case 410: /* Gone */ 03689 return AST_CAUSE_NUMBER_CHANGED; 03690 case 411: /* Length required */ 03691 return AST_CAUSE_INTERWORKING; 03692 case 413: /* Request entity too large */ 03693 return AST_CAUSE_INTERWORKING; 03694 case 414: /* Request URI too large */ 03695 return AST_CAUSE_INTERWORKING; 03696 case 415: /* Unsupported media type */ 03697 return AST_CAUSE_INTERWORKING; 03698 case 420: /* Bad extension */ 03699 return AST_CAUSE_NO_ROUTE_DESTINATION; 03700 case 480: /* No answer */ 03701 return AST_CAUSE_NO_ANSWER; 03702 case 481: /* No answer */ 03703 return AST_CAUSE_INTERWORKING; 03704 case 482: /* Loop detected */ 03705 return AST_CAUSE_INTERWORKING; 03706 case 483: /* Too many hops */ 03707 return AST_CAUSE_NO_ANSWER; 03708 case 484: /* Address incomplete */ 03709 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03710 case 485: /* Ambigous */ 03711 return AST_CAUSE_UNALLOCATED; 03712 case 486: /* Busy everywhere */ 03713 return AST_CAUSE_BUSY; 03714 case 487: /* Request terminated */ 03715 return AST_CAUSE_INTERWORKING; 03716 case 488: /* No codecs approved */ 03717 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03718 case 491: /* Request pending */ 03719 return AST_CAUSE_INTERWORKING; 03720 case 493: /* Undecipherable */ 03721 return AST_CAUSE_INTERWORKING; 03722 case 500: /* Server internal failure */ 03723 return AST_CAUSE_FAILURE; 03724 case 501: /* Call rejected */ 03725 return AST_CAUSE_FACILITY_REJECTED; 03726 case 502: 03727 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03728 case 503: /* Service unavailable */ 03729 return AST_CAUSE_CONGESTION; 03730 case 504: /* Gateway timeout */ 03731 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03732 case 505: /* SIP version not supported */ 03733 return AST_CAUSE_INTERWORKING; 03734 case 600: /* Busy everywhere */ 03735 return AST_CAUSE_USER_BUSY; 03736 case 603: /* Decline */ 03737 return AST_CAUSE_CALL_REJECTED; 03738 case 604: /* Does not exist anywhere */ 03739 return AST_CAUSE_UNALLOCATED; 03740 case 606: /* Not acceptable */ 03741 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03742 default: 03743 return AST_CAUSE_NORMAL; 03744 } 03745 /* Never reached */ 03746 return 0; 03747 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6711 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06712 { 06713 /* Initialize a request */ 06714 memset(req, 0, sizeof(*req)); 06715 req->method = sipmethod; 06716 req->header[0] = req->data; 06717 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06718 req->len = strlen(req->header[0]); 06719 req->headers++; 06720 return 0; 06721 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6698 of file chan_sip.c.
References SIP_RESPONSE.
06699 { 06700 /* Initialize a response */ 06701 memset(resp, 0, sizeof(*resp)); 06702 resp->method = SIP_RESPONSE; 06703 resp->header[0] = resp->data; 06704 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06705 resp->len = strlen(resp->header[0]); 06706 resp->headers++; 06707 return 0; 06708 }
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 1759 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().
01760 { 01761 if (p->initreq.headers && option_debug) { 01762 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01763 } 01764 /* Use this as the basis */ 01765 copy_request(&p->initreq, req); 01766 parse_request(&p->initreq); 01767 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01768 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01769 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7866 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().
07867 { 07868 char invite_buf[256] = ""; 07869 char *invite = invite_buf; 07870 size_t invite_max = sizeof(invite_buf); 07871 char from[256]; 07872 char to[256]; 07873 char tmp[SIPBUFSIZE/2]; 07874 char tmp2[SIPBUFSIZE/2]; 07875 const char *l = NULL, *n = NULL, *d = NULL; 07876 const char *urioptions = ""; 07877 07878 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07879 const char *s = p->username; /* being a string field, cannot be NULL */ 07880 07881 /* Test p->username against allowed characters in AST_DIGIT_ANY 07882 If it matches the allowed characters list, then sipuser = ";user=phone" 07883 If not, then sipuser = "" 07884 */ 07885 /* + is allowed in first position in a tel: uri */ 07886 if (*s == '+') 07887 s++; 07888 for (; *s; s++) { 07889 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07890 break; 07891 } 07892 /* If we have only digits, add ;user=phone to the uri */ 07893 if (!*s) 07894 urioptions = ";user=phone"; 07895 } 07896 07897 07898 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07899 07900 d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07901 if (p->owner) { 07902 l = p->owner->cid.cid_num; 07903 n = p->owner->cid.cid_name; 07904 } 07905 /* if we are not sending RPID and user wants his callerid restricted */ 07906 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07907 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07908 l = CALLERID_UNKNOWN; 07909 n = l; 07910 d = FROMDOMAIN_INVALID; 07911 } 07912 if (ast_strlen_zero(l)) 07913 l = default_callerid; 07914 if (ast_strlen_zero(n)) 07915 n = l; 07916 /* Allow user to be overridden */ 07917 if (!ast_strlen_zero(p->fromuser)) 07918 l = p->fromuser; 07919 else /* Save for any further attempts */ 07920 ast_string_field_set(p, fromuser, l); 07921 07922 /* Allow user to be overridden */ 07923 if (!ast_strlen_zero(p->fromname)) 07924 n = p->fromname; 07925 else /* Save for any further attempts */ 07926 ast_string_field_set(p, fromname, n); 07927 07928 if (pedanticsipchecking) { 07929 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07930 n = tmp; 07931 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07932 l = tmp2; 07933 } 07934 07935 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07936 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag); 07937 else 07938 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag); 07939 07940 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07941 if (!ast_strlen_zero(p->fullcontact)) { 07942 /* If we have full contact, trust it */ 07943 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07944 } else { 07945 /* Otherwise, use the username while waiting for registration */ 07946 ast_build_string(&invite, &invite_max, "sip:"); 07947 if (!ast_strlen_zero(p->username)) { 07948 n = p->username; 07949 if (pedanticsipchecking) { 07950 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07951 n = tmp; 07952 } 07953 ast_build_string(&invite, &invite_max, "%s@", n); 07954 } 07955 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07956 if (p->portinuri) 07957 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07958 ast_build_string(&invite, &invite_max, "%s", urioptions); 07959 } 07960 07961 /* If custom URI options have been provided, append them */ 07962 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07963 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07964 07965 ast_string_field_set(p, uri, invite_buf); 07966 07967 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07968 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07969 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07970 } else if (p->options && p->options->vxml_url) { 07971 /* If there is a VXML URL append it to the SIP URL */ 07972 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07973 } else 07974 snprintf(to, sizeof(to), "<%s>", p->uri); 07975 07976 init_req(req, sipmethod, p->uri); 07977 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07978 07979 add_header(req, "Via", p->via); 07980 /* This will be a no-op most of the time. However, under certain circumstances, 07981 * NOTIFY messages will use this function for preparing the request and should 07982 * have Route headers present. 07983 */ 07984 add_route(req, p->route); 07985 /* Build Remote Party-ID and From */ 07986 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07987 build_rpid(p); 07988 add_header(req, "From", p->rpid_from); 07989 } else 07990 add_header(req, "From", from); 07991 add_header(req, "To", to); 07992 ast_string_field_set(p, exten, l); 07993 build_contact(p); 07994 add_header(req, "Contact", p->our_contact); 07995 add_header(req, "Call-ID", p->callid); 07996 add_header(req, "CSeq", tmp); 07997 if (!ast_strlen_zero(global_useragent)) 07998 add_header(req, "User-Agent", global_useragent); 07999 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08000 if (!ast_strlen_zero(p->rpid)) 08001 add_header(req, "Remote-Party-ID", p->rpid); 08002 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 11474 of file chan_sip.c.
Referenced by _sip_show_peer().
11475 { 11476 if (port && invite) 11477 return "port,invite"; 11478 else if (port) 11479 return "port"; 11480 else if (invite) 11481 return "invite"; 11482 else 11483 return "no"; 11484 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 9268 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
09269 { 09270 if (!route) 09271 ast_verbose("list_route: no route\n"); 09272 else { 09273 for (;route; route = route->next) 09274 ast_verbose("list_route: hop: <%s>\n", route->hop); 09275 } 09276 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 20297 of file chan_sip.c.
References app_dtmfmode, app_sipaddheader, 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, descrip_dtmfmode, descrip_sipaddheader, 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, synopsis_dtmfmode, synopsis_sipaddheader, and userl.
20298 { 20299 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 20300 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 20301 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 20302 20303 if (!(sched = sched_context_create())) { 20304 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 20305 return AST_MODULE_LOAD_FAILURE; 20306 } 20307 20308 if (!(io = io_context_create())) { 20309 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 20310 sched_context_destroy(sched); 20311 return AST_MODULE_LOAD_FAILURE; 20312 } 20313 20314 sip_reloadreason = CHANNEL_MODULE_LOAD; 20315 20316 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 20317 return AST_MODULE_LOAD_DECLINE; 20318 20319 /* Make sure we can register our sip channel type */ 20320 if (ast_channel_register(&sip_tech)) { 20321 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 20322 io_context_destroy(io); 20323 sched_context_destroy(sched); 20324 return AST_MODULE_LOAD_FAILURE; 20325 } 20326 20327 /* Register all CLI functions for SIP */ 20328 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 20329 20330 /* Tell the RTP subdriver that we're here */ 20331 ast_rtp_proto_register(&sip_rtp); 20332 20333 /* Tell the UDPTL subdriver that we're here */ 20334 ast_udptl_proto_register(&sip_udptl); 20335 20336 /* Register dialplan applications */ 20337 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 20338 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 20339 20340 /* Register dialplan functions */ 20341 ast_custom_function_register(&sip_header_function); 20342 ast_custom_function_register(&sippeer_function); 20343 ast_custom_function_register(&sipchaninfo_function); 20344 ast_custom_function_register(&checksipdomain_function); 20345 20346 /* Register manager commands */ 20347 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 20348 "List SIP peers (text format)", mandescr_show_peers); 20349 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 20350 "Show SIP peer (text format)", mandescr_show_peer); 20351 20352 sip_poke_all_peers(); 20353 sip_send_all_registers(); 20354 20355 /* And start the monitor for the first time */ 20356 restart_monitor(); 20357 20358 return AST_MODULE_LOAD_SUCCESS; 20359 }
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 16071 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_hangup(), ast_indicate(), 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(), and TRUE.
Referenced by handle_request_refer().
16072 { 16073 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 16074 /* Chan 2: Call from Asterisk to target */ 16075 int res = 0; 16076 struct sip_pvt *targetcall_pvt; 16077 16078 /* Check if the call ID of the replaces header does exist locally */ 16079 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 16080 transferer->refer->replaces_callid_fromtag))) { 16081 if (transferer->refer->localtransfer) { 16082 /* We did not find the refered call. Sorry, can't accept then */ 16083 /* Let's fake a response from someone else in order 16084 to follow the standard */ 16085 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 16086 append_history(transferer, "Xfer", "Refer failed"); 16087 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 16088 transferer->refer->status = REFER_FAILED; 16089 return -1; 16090 } 16091 /* Fall through for remote transfers that we did not find locally */ 16092 if (option_debug > 2) 16093 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 16094 return 0; 16095 } 16096 16097 /* Ok, we can accept this transfer */ 16098 append_history(transferer, "Xfer", "Refer accepted"); 16099 if (!targetcall_pvt->owner) { /* No active channel */ 16100 if (option_debug > 3) 16101 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 16102 /* Cancel transfer */ 16103 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 16104 append_history(transferer, "Xfer", "Refer failed"); 16105 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 16106 transferer->refer->status = REFER_FAILED; 16107 ast_mutex_unlock(&targetcall_pvt->lock); 16108 return -1; 16109 } 16110 16111 /* We have a channel, find the bridge */ 16112 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 16113 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 16114 16115 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 16116 /* Wrong state of new channel */ 16117 if (option_debug > 3) { 16118 if (target.chan2) 16119 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 16120 else if (target.chan1->_state != AST_STATE_RING) 16121 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 16122 else 16123 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 16124 } 16125 } 16126 16127 /* Transfer */ 16128 if (option_debug > 3 && sipdebug) { 16129 if (current->chan2) /* We have two bridges */ 16130 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 16131 else /* One bridge, propably transfer of IVR/voicemail etc */ 16132 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 16133 } 16134 16135 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 16136 16137 /* Perform the transfer */ 16138 res = attempt_transfer(current, &target); 16139 ast_mutex_unlock(&targetcall_pvt->lock); 16140 if (res) { 16141 /* Failed transfer */ 16142 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 16143 append_history(transferer, "Xfer", "Refer failed"); 16144 transferer->refer->status = REFER_FAILED; 16145 if (targetcall_pvt->owner) 16146 ast_channel_unlock(targetcall_pvt->owner); 16147 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 16148 if (res != -2) 16149 ast_hangup(transferer->owner); 16150 else 16151 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 16152 } else { 16153 /* Transfer succeeded! */ 16154 16155 /* Tell transferer that we're done. */ 16156 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 16157 append_history(transferer, "Xfer", "Refer succeeded"); 16158 transferer->refer->status = REFER_200OK; 16159 if (targetcall_pvt->owner) { 16160 if (option_debug) 16161 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 16162 ast_channel_unlock(targetcall_pvt->owner); 16163 } 16164 ast_indicate(target.chan1, AST_CONTROL_UNHOLD); 16165 if (target.chan2) { 16166 ast_indicate(target.chan2, AST_CONTROL_UNHOLD); 16167 } 16168 } 16169 return 1; 16170 }
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 5387 of file chan_sip.c.
References t.
Referenced by sipsock_read().
05388 { 05389 int h = 0, t = 0; 05390 int lws = 0; 05391 05392 for (; h < len;) { 05393 /* Eliminate all CRs */ 05394 if (msgbuf[h] == '\r') { 05395 h++; 05396 continue; 05397 } 05398 /* Check for end-of-line */ 05399 if (msgbuf[h] == '\n') { 05400 /* Check for end-of-message */ 05401 if (h + 1 == len) 05402 break; 05403 /* Check for a continuation line */ 05404 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 05405 /* Merge continuation line */ 05406 h++; 05407 continue; 05408 } 05409 /* Propagate LF and start new line */ 05410 msgbuf[t++] = msgbuf[h++]; 05411 lws = 0; 05412 continue; 05413 } 05414 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 05415 if (lws) { 05416 h++; 05417 continue; 05418 } 05419 msgbuf[t++] = msgbuf[h++]; 05420 lws = 1; 05421 continue; 05422 } 05423 msgbuf[t++] = msgbuf[h++]; 05424 if (lws) 05425 lws = 0; 05426 } 05427 msgbuf[t] = '\0'; 05428 return t; 05429 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4864 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().
04865 { 04866 snprintf(tagbuf, len, "as%08lx", ast_random()); 04867 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11726 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().
11727 { 11728 const char *a[4]; 11729 const char *peer; 11730 int ret; 11731 11732 peer = astman_get_header(m,"Peer"); 11733 if (ast_strlen_zero(peer)) { 11734 astman_send_error(s, m, "Peer: <name> missing."); 11735 return 0; 11736 } 11737 a[0] = "sip"; 11738 a[1] = "show"; 11739 a[2] = "peer"; 11740 a[3] = peer; 11741 11742 ret = _sip_show_peer(1, -1, s, m, 4, a); 11743 astman_append(s, "\r\n\r\n" ); 11744 return ret; 11745 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 11270 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().
11271 { 11272 const char *id = astman_get_header(m,"ActionID"); 11273 const char *a[] = {"sip", "show", "peers"}; 11274 char idtext[256] = ""; 11275 int total = 0; 11276 11277 if (!ast_strlen_zero(id)) 11278 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 11279 11280 astman_send_ack(s, m, "Peer status list will follow"); 11281 /* List the peers in separate manager events */ 11282 _sip_show_peers(-1, &total, s, m, 3, a); 11283 /* Send final confirmation */ 11284 astman_append(s, 11285 "Event: PeerlistComplete\r\n" 11286 "ListItems: %d\r\n" 11287 "%s" 11288 "\r\n", total, idtext); 11289 return 0; 11290 }
static void markall_extenstate_updates | ( | void | ) | [static] |
Definition at line 9717 of file chan_sip.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::list, and update().
Referenced by do_monitor().
09718 { 09719 struct sip_extenstate_update *update = NULL; 09720 09721 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09722 /* avoid holding the lock if possible */ 09723 return; 09724 } 09725 09726 AST_LIST_LOCK(&sip_extenstate_updates); 09727 AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) { 09728 update->marked = 1; 09729 } 09730 AST_LIST_UNLOCK(&sip_extenstate_updates); 09731 }
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 1785 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
01786 { 01787 int len = strlen(sip_methods[id].text); 01788 int l_name = name ? strlen(name) : 0; 01789 /* true if the string is long enough, and ends with whitespace, and matches */ 01790 return (l_name >= len && name[len] < 33 && 01791 !strncasecmp(sip_methods[id].text, name, len)); 01792 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 11173 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().
11174 { 11175 switch(nat) { 11176 case SIP_NAT_NEVER: 11177 return "No"; 11178 case SIP_NAT_ROUTE: 11179 return "Route"; 11180 case SIP_NAT_ALWAYS: 11181 return "Always"; 11182 case SIP_NAT_RFC3581: 11183 return "RFC3581"; 11184 default: 11185 return "Unknown"; 11186 } 11187 }
static int notify_extenstate_update | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 9760 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 check_extenstate_updates(), and handle_response().
09761 { 09762 struct sip_pvt *p = data; 09763 09764 ast_mutex_lock(&p->lock); 09765 09766 switch(state) { 09767 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 09768 case AST_EXTENSION_REMOVED: /* Extension is gone */ 09769 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 09770 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09771 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 09772 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); 09773 p->stateid = -1; 09774 p->subscribed = NONE; 09775 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 09776 break; 09777 default: /* Tell user */ 09778 p->laststate = state; 09779 break; 09780 } 09781 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 09782 if (!p->pendinginvite) { 09783 transmit_state_notify(p, state, 1, FALSE); 09784 } else { 09785 /* We already have a NOTIFY sent that is not answered. Queue the state up. 09786 if many state changes happen meanwhile, we will only send a notification of the last one */ 09787 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 09788 } 09789 } 09790 if (option_verbose > 1) 09791 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, 09792 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 09793 09794 09795 ast_mutex_unlock(&p->lock); 09796 09797 return 0; 09798 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2387 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02388 { 02389 memset(dst, 0, sizeof(*dst)); 02390 memcpy(dst->data, src->data, sizeof(dst->data)); 02391 dst->len = src->len; 02392 parse_request(dst); 02393 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 13397 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, ast_uri_decode(), 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().
13398 { 13399 char tmp[SIPBUFSIZE]; 13400 char *s, *e, *uri, *t; 13401 char *domain; 13402 13403 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 13404 if ((t = strchr(tmp, ','))) 13405 *t = '\0'; 13406 s = get_in_brackets(tmp); 13407 uri = ast_strdupa(s); 13408 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 13409 if (!strncasecmp(s, "sip:", 4)) 13410 s += 4; 13411 e = strchr(s, ';'); 13412 if (e) 13413 *e = '\0'; 13414 if (option_debug) 13415 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 13416 if (p->owner) 13417 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 13418 } else { 13419 e = strchr(tmp, '@'); 13420 if (e) { 13421 *e++ = '\0'; 13422 domain = e; 13423 } else { 13424 /* No username part */ 13425 domain = tmp; 13426 } 13427 e = strchr(s, ';'); /* Strip of parameters in the username part */ 13428 if (e) 13429 *e = '\0'; 13430 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 13431 if (e) 13432 *e = '\0'; 13433 13434 if (!strncasecmp(s, "sip:", 4)) 13435 s += 4; 13436 ast_uri_decode(s); 13437 if (option_debug > 1) 13438 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 13439 if (p->owner) { 13440 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 13441 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 13442 ast_string_field_set(p->owner, call_forward, s); 13443 } 13444 } 13445 }
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 8977 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().
08978 { 08979 char contact[SIPBUFSIZE]; 08980 char *c; 08981 08982 /* Look for brackets */ 08983 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08984 c = get_in_brackets(contact); 08985 08986 /* Save full contact to call pvt for later bye or re-invite */ 08987 ast_string_field_set(pvt, fullcontact, c); 08988 08989 /* Save URI for later ACKs, BYE or RE-invites */ 08990 ast_string_field_set(pvt, okcontacturi, c); 08991 08992 /* We should return false for URI:s we can't handle, 08993 like sips:, tel:, mailto:,ldap: etc */ 08994 return TRUE; 08995 }
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 9066 of file chan_sip.c.
References __get_header(), 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_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, 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(), 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().
09067 { 09068 char contact[SIPBUFSIZE]; 09069 char data[SIPBUFSIZE]; 09070 const char *expires = get_header(req, "Expires"); 09071 int expiry = atoi(expires); 09072 char *curi, *n, *pt; 09073 int port; 09074 const char *useragent; 09075 struct hostent *hp; 09076 struct ast_hostent ahp; 09077 struct sockaddr_in oldsin, testsin; 09078 char *firstcuri = NULL; 09079 int start = 0; 09080 int wildcard_found = 0; 09081 int single_binding_found = 0; 09082 09083 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 09084 09085 if (ast_strlen_zero(expires)) { /* No expires header */ 09086 expires = strcasestr(contact, ";expires="); 09087 if (expires) { 09088 /* XXX bug here, we overwrite the string */ 09089 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 09090 if (sscanf(expires + 9, "%30d", &expiry) != 1) 09091 expiry = default_expiry; 09092 } else { 09093 /* Nothing has been specified */ 09094 expiry = default_expiry; 09095 } 09096 } 09097 09098 do { 09099 /* Look for brackets */ 09100 curi = contact; 09101 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 09102 strsep(&curi, ";"); /* This is Header options, not URI options */ 09103 curi = get_in_brackets(contact); 09104 if (!firstcuri) { 09105 firstcuri = ast_strdupa(curi); 09106 } 09107 09108 if (!strcasecmp(curi, "*")) { 09109 wildcard_found = 1; 09110 } else { 09111 single_binding_found = 1; 09112 } 09113 09114 if (wildcard_found && (ast_strlen_zero(expires) || expiry != 0 || single_binding_found)) { 09115 /* Contact header parameter "*" detected, so punt if: Expires header is missing, 09116 * Expires value is not zero, or another Contact header is present. */ 09117 return PARSE_REGISTER_FAILED; 09118 } 09119 09120 ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); 09121 } while (!ast_strlen_zero(contact)); 09122 curi = firstcuri; 09123 09124 /* if they did not specify Contact: or Expires:, they are querying 09125 what we currently have stored as their contact address, so return 09126 it 09127 */ 09128 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 09129 /* If we have an active registration, tell them when the registration is going to expire */ 09130 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 09131 pvt->expiry = ast_sched_when(sched, peer->expire); 09132 return PARSE_REGISTER_QUERY; 09133 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 09134 /* This means remove all registrations and return OK */ 09135 if (!AST_SCHED_DEL(sched, peer->expire)) { 09136 struct sip_peer *peer_ptr = peer; 09137 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09138 } 09139 09140 expire_register(ASTOBJ_REF(peer)); 09141 09142 if (option_verbose > 2) 09143 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 09144 09145 return PARSE_REGISTER_UPDATE; 09146 } 09147 09148 /* Store whatever we got as a contact from the client */ 09149 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 09150 09151 /* For the 200 OK, we should use the received contact */ 09152 ast_string_field_build(pvt, our_contact, "<%s>", curi); 09153 09154 /* Make sure it's a SIP URL */ 09155 if (strncasecmp(curi, "sip:", 4)) { 09156 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 09157 } else 09158 curi += 4; 09159 /* Ditch q */ 09160 curi = strsep(&curi, ";"); 09161 /* Grab host */ 09162 n = strchr(curi, '@'); 09163 if (!n) { 09164 n = curi; 09165 curi = NULL; 09166 } else 09167 *n++ = '\0'; 09168 pt = strchr(n, ':'); 09169 if (pt) { 09170 *pt++ = '\0'; 09171 port = atoi(pt); 09172 peer->portinuri = 1; 09173 } else { 09174 port = STANDARD_SIP_PORT; 09175 peer->portinuri = 0; 09176 } 09177 oldsin = peer->addr; 09178 09179 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 09180 /* use the data provided in the Contact header for call routing */ 09181 /* XXX This could block for a long time XXX */ 09182 hp = ast_gethostbyname(n, &ahp); 09183 if (!hp) { 09184 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 09185 *peer->fullcontact = '\0'; 09186 ast_string_field_set(pvt, our_contact, ""); 09187 return PARSE_REGISTER_FAILED; 09188 } 09189 09190 peer->addr.sin_family = AF_INET; 09191 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 09192 peer->addr.sin_port = htons(port); 09193 } else { 09194 /* Don't trust the contact field. Just use what they came to us 09195 with */ 09196 peer->addr = pvt->recv; 09197 } 09198 09199 /* Check that they're allowed to register at this IP */ 09200 memcpy(&testsin.sin_addr, &peer->addr.sin_addr, sizeof(testsin.sin_addr)); 09201 if (ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 09202 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 09203 ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", n, ast_inet_ntoa(testsin.sin_addr)); 09204 *peer->fullcontact = '\0'; 09205 ast_string_field_set(pvt, our_contact, ""); 09206 return PARSE_REGISTER_DENIED; 09207 } 09208 09209 /* Save SIP options profile */ 09210 peer->sipoptions = pvt->sipoptions; 09211 09212 if (curi && ast_strlen_zero(peer->username)) 09213 ast_copy_string(peer->username, curi, sizeof(peer->username)); 09214 09215 if (!AST_SCHED_DEL(sched, peer->expire)) { 09216 struct sip_peer *peer_ptr = peer; 09217 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09218 } 09219 if (expiry > max_expiry) 09220 expiry = max_expiry; 09221 if (expiry < min_expiry) 09222 expiry = min_expiry; 09223 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09224 peer->expire = -1; 09225 } else { 09226 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 09227 if (peer->expire == -1) { 09228 struct sip_peer *peer_ptr = peer; 09229 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 09230 } 09231 } 09232 pvt->expiry = expiry; 09233 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); 09234 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 09235 ast_db_put("SIP/Registry", peer->name, data); 09236 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09237 09238 /* Is this a new IP address for us? */ 09239 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 09240 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)); 09241 } 09242 sip_poke_peer(peer); 09243 register_peer_exten(peer, 1); 09244 09245 /* Save User agent */ 09246 useragent = get_header(req, "User-Agent"); 09247 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 09248 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 09249 if (option_verbose > 3) 09250 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 09251 } 09252 return PARSE_REGISTER_UPDATE; 09253 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 5434 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().
05435 { 05436 /* Divide fields by NULL's */ 05437 char *c; 05438 int f = 0; 05439 05440 c = req->data; 05441 05442 /* First header starts immediately */ 05443 req->header[f] = c; 05444 while(*c) { 05445 if (*c == '\n') { 05446 /* We've got a new header */ 05447 *c = 0; 05448 05449 if (sipdebug && option_debug > 3) 05450 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05451 if (ast_strlen_zero(req->header[f])) { 05452 /* Line by itself means we're now in content */ 05453 c++; 05454 break; 05455 } 05456 if (f >= SIP_MAX_HEADERS - 1) { 05457 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 05458 } else { 05459 f++; 05460 req->header[f] = c + 1; 05461 } 05462 } else if (*c == '\r') { 05463 /* Ignore but eliminate \r's */ 05464 *c = 0; 05465 } 05466 c++; 05467 } 05468 05469 req->headers = f; 05470 05471 /* Check a non-newline-terminated last header */ 05472 if (!ast_strlen_zero(req->header[f])) { 05473 if (sipdebug && option_debug > 3) 05474 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05475 req->headers++; 05476 } 05477 05478 /* Now we process any body content */ 05479 f = 0; 05480 req->line[f] = c; 05481 while (*c) { 05482 if (*c == '\n') { 05483 /* We've got a new line */ 05484 *c = 0; 05485 if (sipdebug && option_debug > 3) 05486 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05487 if (f == SIP_MAX_LINES - 1) { 05488 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 05489 break; 05490 } else { 05491 f++; 05492 req->line[f] = c + 1; 05493 } 05494 } else if (*c == '\r') { 05495 /* Ignore and eliminate \r's */ 05496 *c = 0; 05497 } 05498 c++; 05499 } 05500 05501 req->lines = f; 05502 05503 /* Check a non-newline-terminated last line */ 05504 if (!ast_strlen_zero(req->line[f])) { 05505 if (sipdebug && option_debug > 3) 05506 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05507 req->lines++; 05508 } 05509 05510 if (*c) 05511 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05512 05513 /* Split up the first line parts */ 05514 return determine_firstline_parts(req); 05515 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1809 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().
01810 { 01811 char *next, *sep; 01812 char *temp; 01813 unsigned int profile = 0; 01814 int i, found; 01815 01816 if (ast_strlen_zero(supported) ) 01817 return 0; 01818 temp = ast_strdupa(supported); 01819 01820 if (option_debug > 2 && sipdebug) 01821 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01822 01823 for (next = temp; next; next = sep) { 01824 found = FALSE; 01825 if ( (sep = strchr(next, ',')) != NULL) 01826 *sep++ = '\0'; 01827 next = ast_skip_blanks(next); 01828 if (option_debug > 2 && sipdebug) 01829 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01830 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01831 if (!strcasecmp(next, sip_options[i].text)) { 01832 profile |= sip_options[i].id; 01833 found = TRUE; 01834 if (option_debug > 2 && sipdebug) 01835 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01836 break; 01837 } 01838 } 01839 if (!found && option_debug > 2 && sipdebug) { 01840 if (!strncasecmp(next, "x-", 2)) 01841 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01842 else 01843 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01844 } 01845 } 01846 01847 if (pvt) 01848 pvt->sipoptions = profile; 01849 return profile; 01850 }
static struct sip_via * parse_via | ( | const char * | header | ) | [static] |
Parse a Via header.
This function parses the Via header and processes it according to section 18.2 of RFC 3261 and RFC 3581. Since we don't have a transport layer, we only care about the maddr and ttl parms. The received and rport params are not parsed.
VIA syntax. RFC 3261 section 25.1 Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm) via-parm = sent-protocol LWS sent-by *( SEMI via-params ) via-params = via-ttl / via-maddr / via-received / via-branch / via-extension via-ttl = "ttl" EQUAL ttl via-maddr = "maddr" EQUAL host via-received = "received" EQUAL (IPv4address / IPv6address) via-branch = "branch" EQUAL token via-extension = generic-param sent-protocol = protocol-name SLASH protocol-version SLASH transport protocol-name = "SIP" / token protocol-version = token transport = "UDP" / "TCP" / "TLS" / "SCTP" / other-transport sent-by = host [ COLON port ] ttl = 1*3DIGIT ; 0 to 255
Definition at line 5051 of file chan_sip.c.
References ast_calloc, ast_log(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), free_via(), LOG_ERROR, and sip_via::via.
Referenced by process_via().
05052 { 05053 struct sip_via *v = ast_calloc(1, sizeof(*v)); 05054 char *via, *parm; 05055 05056 if (!v) { 05057 return NULL; 05058 } 05059 05060 v->via = ast_strdup(header); 05061 v->ttl = 1; 05062 05063 via = v->via; 05064 05065 if (ast_strlen_zero(via)) { 05066 ast_log(LOG_ERROR, "received request without a Via header\n"); 05067 free_via(v); 05068 return NULL; 05069 } 05070 05071 /* seperate the first via-parm */ 05072 via = strsep(&via, ","); 05073 05074 /* chop off sent-protocol */ 05075 v->protocol = strsep(&via, " \t\r\n"); 05076 if (ast_strlen_zero(v->protocol)) { 05077 ast_log(LOG_ERROR, "missing sent-protocol in Via header\n"); 05078 free_via(v); 05079 return NULL; 05080 } 05081 v->protocol = ast_skip_blanks(v->protocol); 05082 05083 if (via) { 05084 via = ast_skip_blanks(via); 05085 } 05086 05087 /* chop off sent-by */ 05088 v->sent_by = strsep(&via, "; \t\r\n"); 05089 if (ast_strlen_zero(v->sent_by)) { 05090 ast_log(LOG_ERROR, "missing sent-by in Via header\n"); 05091 free_via(v); 05092 return NULL; 05093 } 05094 v->sent_by = ast_skip_blanks(v->sent_by); 05095 05096 /* store the port */ 05097 if ((parm = strchr(v->sent_by, ':'))) { 05098 char *endptr; 05099 05100 v->port = strtol(++parm, &endptr, 10); 05101 } 05102 05103 /* evaluate any via-parms */ 05104 while ((parm = strsep(&via, "; \t\r\n"))) { 05105 char *c; 05106 if ((c = strstr(parm, "maddr="))) { 05107 v->maddr = ast_skip_blanks(c + sizeof("maddr=") - 1); 05108 } else if ((c = strstr(parm, "branch="))) { 05109 v->branch = ast_skip_blanks(c + sizeof("branch=") - 1); 05110 } else if ((c = strstr(parm, "ttl="))) { 05111 char *endptr; 05112 c = ast_skip_blanks(c + sizeof("ttl=") - 1); 05113 v->ttl = strtol(c, &endptr, 10); 05114 05115 /* make sure we got a valid ttl value */ 05116 if (c == endptr) { 05117 v->ttl = 1; 05118 } 05119 } 05120 } 05121 05122 return v; 05123 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 11192 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
11193 { 11194 int res = 0; 11195 if (peer->maxms) { 11196 if (peer->lastms < 0) { 11197 ast_copy_string(status, "UNREACHABLE", statuslen); 11198 } else if (peer->lastms > peer->maxms) { 11199 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 11200 res = 1; 11201 } else if (peer->lastms) { 11202 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 11203 res = 1; 11204 } else { 11205 ast_copy_string(status, "UNKNOWN", statuslen); 11206 } 11207 } else { 11208 ast_copy_string(status, "Unmonitored", statuslen); 11209 /* Checking if port is 0 */ 11210 res = -1; 11211 } 11212 return res; 11213 }
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 11667 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().
11668 { 11669 int x, codec; 11670 11671 for(x = 0; x < 32 ; x++) { 11672 codec = ast_codec_pref_index(pref, x); 11673 if (!codec) 11674 break; 11675 ast_cli(fd, "%s", ast_getformatname(codec)); 11676 ast_cli(fd, ":%d", pref->framing[x]); 11677 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 11678 ast_cli(fd, ","); 11679 } 11680 if (!x) 11681 ast_cli(fd, "none"); 11682 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 11451 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
11452 { 11453 char buf[256]; 11454 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 11455 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 17359 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().
17360 { 17361 struct sip_request *req; 17362 17363 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 17364 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 17365 /* Request failed */ 17366 if (option_debug) { 17367 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 17368 } 17369 } 17370 ast_free(req); 17371 } 17372 }
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
< UDPTL 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 5706 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_error_correction_scheme(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::callid, t38properties::capability, 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, t38properties::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, T38FAX_UDP_EC_NONE, TRUE, type, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_NONE, sip_pvt::vrtp, and ast_channel::writeformat.
05707 { 05708 /* Iterators for SDP parsing */ 05709 int start = req->sdp_start; 05710 int next = start; 05711 int iterator = start; 05712 05713 /* Temporary vars for SDP parsing */ 05714 char type = '\0'; 05715 const char *value = NULL; 05716 const char *m = NULL; /* SDP media offer */ 05717 const char *nextm = NULL; 05718 int len = -1; 05719 05720 /* Host information */ 05721 struct ast_hostent audiohp; 05722 struct ast_hostent videohp; 05723 struct ast_hostent imagehp; 05724 struct ast_hostent sessionhp; 05725 struct hostent *hp = NULL; /*!< RTP Audio host IP */ 05726 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05727 struct hostent *ihp = NULL; /*!< UDPTL host IP */ 05728 int portno = -1; /*!< RTP Audio port number */ 05729 int vportno = -1; /*!< RTP Video port number */ 05730 int udptlportno = -1; /*!< UDPTL Image port number */ 05731 struct sockaddr_in sin = { 0, }; /*!< media socket address */ 05732 struct sockaddr_in vsin = { 0, }; /*!< video socket address */ 05733 struct sockaddr_in isin = { 0, }; /*!< image socket address */ 05734 05735 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05736 int peercapability = 0, peernoncodeccapability = 0; 05737 int vpeercapability = 0, vpeernoncodeccapability = 0; 05738 struct ast_rtp *newaudiortp, *newvideortp; /*!< Buffers for codec handling */ 05739 int newjointcapability; /*!< Negotiated capability */ 05740 int newpeercapability; 05741 int newnoncodeccapability; 05742 const char *codecs; 05743 int codec; 05744 05745 /* Others */ 05746 int sendonly = -1; 05747 int vsendonly = -1; 05748 int numberofports; 05749 int numberofmediastreams = 0; 05750 int last_rtpmap_codec = 0; 05751 int debug = sip_debug_test_pvt(p); 05752 05753 /* Initial check */ 05754 if (!p->rtp) { 05755 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05756 return -1; 05757 } 05758 05759 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05760 #ifdef LOW_MEMORY 05761 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05762 #else 05763 newaudiortp = alloca(ast_rtp_alloc_size()); 05764 #endif 05765 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05766 ast_rtp_new_init(newaudiortp); 05767 ast_rtp_pt_clear(newaudiortp); 05768 05769 #ifdef LOW_MEMORY 05770 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05771 #else 05772 newvideortp = alloca(ast_rtp_alloc_size()); 05773 #endif 05774 memset(newvideortp, 0, ast_rtp_alloc_size()); 05775 ast_rtp_new_init(newvideortp); 05776 ast_rtp_pt_clear(newvideortp); 05777 05778 05779 /* Update our last rtprx when we receive an SDP, too */ 05780 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05781 05782 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05783 05784 memset(p->offered_media, 0, sizeof(p->offered_media)); 05785 05786 05787 /* Scan for the first media stream (m=) line to limit scanning of globals */ 05788 nextm = get_sdp_iterate(&next, req, "m"); 05789 if (ast_strlen_zero(nextm)) { 05790 ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n"); 05791 return -1; 05792 } 05793 05794 /* Scan session level SDP parameters (lines before first media stream) */ 05795 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05796 int processed = FALSE; 05797 switch (type) { 05798 case 'c': 05799 if (process_sdp_c(value, &sessionhp)) { 05800 processed = TRUE; 05801 hp = &sessionhp.hp; 05802 vhp = hp; 05803 ihp = hp; 05804 } 05805 break; 05806 case 'a': 05807 if (process_sdp_a_sendonly(value, &sendonly)) { 05808 processed = TRUE; 05809 vsendonly = sendonly; 05810 } 05811 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05812 processed = TRUE; 05813 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05814 processed = TRUE; 05815 else if (process_sdp_a_image(value, p)) 05816 processed = TRUE; 05817 break; 05818 } 05819 05820 if (option_debug > 2) 05821 ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED."); 05822 } 05823 05824 05825 /* Scan media stream (m=) specific parameters loop */ 05826 while (!ast_strlen_zero(nextm)) { 05827 int audio = FALSE; 05828 int video = FALSE; 05829 int image = FALSE; 05830 int x; 05831 05832 numberofports = 1; 05833 len = -1; 05834 start = next; 05835 m = nextm; 05836 iterator = next; 05837 nextm = get_sdp_iterate(&next, req, "m"); 05838 05839 /* Search for audio media definition */ 05840 if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05841 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05842 /* Found audio stream in this media definition */ 05843 audio = TRUE; 05844 p->offered_media[SDP_AUDIO].offered = TRUE; 05845 numberofmediastreams++; 05846 portno = x; 05847 05848 /* Scan through the RTP payload types specified in a "m=" line: */ 05849 codecs = m + len; 05850 ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text)); 05851 for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05852 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05853 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05854 return -1; 05855 } 05856 if (debug) 05857 ast_verbose("Found RTP audio format %d\n", codec); 05858 ast_rtp_set_m_type(newaudiortp, codec); 05859 } 05860 /* Search for video media definition */ 05861 } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05862 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05863 /* Found video stream in this media definition */ 05864 video = TRUE; 05865 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05866 p->offered_media[SDP_VIDEO].offered = TRUE; 05867 numberofmediastreams++; 05868 vportno = x; 05869 05870 /* Scan through the RTP payload types specified in a "m=" line: */ 05871 codecs = m + len; 05872 ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text)); 05873 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05874 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05875 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05876 return -1; 05877 } 05878 if (debug) 05879 ast_verbose("Found RTP video format %d\n", codec); 05880 ast_rtp_set_m_type(newvideortp, codec); 05881 } 05882 /* Search for image media definition */ 05883 } else if (p->udptl && ((sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 05884 (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0))) { 05885 /* Found image stream in this media definition */ 05886 image = TRUE; 05887 if (debug) 05888 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05889 p->offered_media[SDP_IMAGE].offered = TRUE; 05890 udptlportno = x; 05891 numberofmediastreams++; 05892 05893 if (p->owner && p->lastinvite) { 05894 if (p->t38.state != T38_LOCAL_REINVITE) { 05895 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05896 if (option_debug > 1) 05897 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05898 } 05899 } else { 05900 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05901 p->t38.direct = 1; 05902 if (option_debug > 1) 05903 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05904 } 05905 05906 /* default EC to none, the remote end should respond 05907 * with the EC they want to use */ 05908 p->t38.peercapability &= ~T38FAX_UDP_EC_NONE; 05909 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05910 } else { 05911 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05912 continue; 05913 } 05914 05915 /* Check for number of ports */ 05916 if (numberofports > 1) 05917 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05918 05919 05920 05921 /* Media stream specific parameters */ 05922 while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') { 05923 int processed = FALSE; 05924 05925 switch (type) { 05926 case 'c': 05927 if (audio) { 05928 if (process_sdp_c(value, &audiohp)) { 05929 processed = TRUE; 05930 hp = &audiohp.hp; 05931 } 05932 } 05933 else if (video) { 05934 if (process_sdp_c(value, &videohp)) { 05935 processed = TRUE; 05936 vhp = &videohp.hp; 05937 } 05938 } else if (image) { 05939 if (process_sdp_c(value, &imagehp)) { 05940 processed = TRUE; 05941 ihp = &imagehp.hp; 05942 } 05943 } 05944 break; 05945 case 'a': 05946 /* Audio specific scanning */ 05947 if (audio) { 05948 if (process_sdp_a_sendonly(value, &sendonly)) 05949 processed = TRUE; 05950 else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec)) 05951 processed = TRUE; 05952 } 05953 /* Video specific scanning */ 05954 else if (video) { 05955 if (process_sdp_a_sendonly(value, &vsendonly)) 05956 processed = TRUE; 05957 else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec)) 05958 processed = TRUE; 05959 } 05960 /* Image (T.38 FAX) specific scanning */ 05961 else if (image) { 05962 if (process_sdp_a_image(value, p)) 05963 processed = TRUE; 05964 } 05965 break; 05966 } 05967 05968 if (option_debug > 2) 05969 ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n", 05970 (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image", 05971 type, value, 05972 (processed == TRUE)? "OK." : "UNSUPPORTED."); 05973 } 05974 } 05975 05976 /* Sanity checks */ 05977 if (!hp && !vhp && !ihp) { 05978 ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n"); 05979 return -1; 05980 } 05981 05982 if (portno == -1 && vportno == -1 && udptlportno == -1) 05983 /* No acceptable offer found in SDP - we have no ports */ 05984 /* Do not change RTP or VRTP if this is a re-invite */ 05985 return -2; 05986 05987 if (numberofmediastreams > 2) 05988 /* We have too many fax, audio and/or video media streams, fail this offer */ 05989 return -3; 05990 05991 if (udptlportno == -1) { 05992 p->t38.state = T38_DISABLED; 05993 if (option_debug > 2) 05994 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05995 } 05996 05997 05998 /* Now gather all of the codecs that we are asked for: */ 05999 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 06000 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 06001 06002 newjointcapability = p->capability & (peercapability | vpeercapability); 06003 newpeercapability = (peercapability | vpeercapability); 06004 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 06005 06006 06007 if (debug) { 06008 /* shame on whoever coded this.... */ 06009 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 06010 06011 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 06012 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 06013 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 06014 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 06015 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 06016 06017 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 06018 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 06019 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 06020 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 06021 06022 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 06023 p->t38.capability, 06024 p->t38.peercapability, 06025 p->t38.jointcapability); 06026 06027 } 06028 if (!newjointcapability) { 06029 /* If T.38 was not negotiated either, totally bail out... */ 06030 if (!p->t38.jointcapability || !udptlportno) { 06031 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 06032 /* Do NOT Change current setting */ 06033 return -1; 06034 } else { 06035 if (option_debug > 2) 06036 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 06037 } 06038 } 06039 06040 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 06041 they are acceptable */ 06042 p->jointcapability = newjointcapability; /* Our joint codec profile */ 06043 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 06044 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 06045 06046 ast_rtp_pt_copy(p->rtp, newaudiortp); 06047 if (p->vrtp) 06048 ast_rtp_pt_copy(p->vrtp, newvideortp); 06049 06050 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 06051 ast_clear_flag(&p->flags[0], SIP_DTMF); 06052 if (newnoncodeccapability & AST_RTP_DTMF) { 06053 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 06054 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 06055 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 06056 ast_rtp_setdtmf(p->rtp, 1); 06057 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 06058 } else { 06059 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 06060 } 06061 } 06062 06063 /* Setup audio port number */ 06064 if (p->rtp) { 06065 if (portno > 0) { 06066 sin.sin_family = AF_INET; 06067 sin.sin_port = htons(portno); 06068 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 06069 ast_rtp_set_peer(p->rtp, &sin); 06070 if (debug) 06071 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06072 } else if (udptlportno > 0) { 06073 if (debug) 06074 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n"); 06075 } else { 06076 ast_rtp_stop(p->rtp); 06077 if (debug) 06078 ast_verbose("Peer doesn't provide audio\n"); 06079 } 06080 } 06081 06082 /* Setup video port number */ 06083 if (p->vrtp) { 06084 if (vportno > 0) { 06085 vsin.sin_family = AF_INET; 06086 vsin.sin_port = htons(vportno); 06087 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 06088 ast_rtp_set_peer(p->vrtp, &vsin); 06089 if (debug) 06090 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 06091 } else { 06092 ast_rtp_stop(p->vrtp); 06093 if (debug) 06094 ast_verbose("Peer doesn't provide video\n"); 06095 } 06096 } 06097 06098 /* Setup image port number */ 06099 if (p->udptl) { 06100 if (udptlportno > 0) { 06101 isin.sin_family = AF_INET; 06102 isin.sin_port = htons(udptlportno); 06103 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 06104 struct sockaddr_in peer = { 0, }; 06105 ast_rtp_get_peer(p->rtp, &peer); 06106 if (peer.sin_addr.s_addr) { 06107 memcpy(&isin.sin_addr, &peer.sin_addr, sizeof(isin.sin_addr)); 06108 if (debug) 06109 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)); 06110 } 06111 } else 06112 memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr)); 06113 ast_udptl_set_peer(p->udptl, &isin); 06114 if (debug) 06115 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port)); 06116 } else { 06117 ast_udptl_stop(p->udptl); 06118 if (debug) 06119 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 06120 } 06121 } 06122 06123 06124 /* Ok, we're going with this offer */ 06125 if (option_debug > 1) { 06126 char buf[SIPBUFSIZE]; 06127 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 06128 } 06129 06130 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 06131 return 0; 06132 06133 if (option_debug > 3) 06134 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 06135 06136 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 06137 if (debug) { 06138 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 06139 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 06140 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 06141 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 06142 } 06143 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 06144 ast_set_read_format(p->owner, p->owner->readformat); 06145 ast_set_write_format(p->owner, p->owner->writeformat); 06146 } 06147 06148 /* sendonly processing */ 06149 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1)) { 06150 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 06151 /* Activate a re-invite */ 06152 ast_queue_frame(p->owner, &ast_null_frame); 06153 } else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1)) { 06154 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 06155 S_OR(p->mohsuggest, NULL), 06156 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06157 if (sendonly) 06158 ast_rtp_stop(p->rtp); 06159 /* RTCP needs to go ahead, even if we're on hold!!! */ 06160 /* Activate a re-invite */ 06161 ast_queue_frame(p->owner, &ast_null_frame); 06162 } 06163 06164 /* Manager Hold and Unhold events must be generated, if necessary */ 06165 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) && (!sendonly || sendonly == -1)) 06166 change_hold_state(p, req, FALSE, sendonly); 06167 else if (!(sin.sin_addr.s_addr || vsin.sin_addr.s_addr || isin.sin_addr.s_addr) || (sendonly && sendonly != -1)) 06168 change_hold_state(p, req, TRUE, sendonly); 06169 06170 return 0; 06171 }
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 6213 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().
06214 { 06215 int found = FALSE; 06216 int codec; 06217 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 06218 int debug = sip_debug_test_pvt(p); 06219 06220 if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 06221 char *tmp = strrchr(a, ':'); 06222 long int framing = 0; 06223 if (tmp) { 06224 tmp++; 06225 framing = strtol(tmp, NULL, 10); 06226 if (framing == LONG_MIN || framing == LONG_MAX) { 06227 framing = 0; 06228 if (option_debug) 06229 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 06230 } 06231 } 06232 if (framing && p->autoframing) { 06233 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06234 int codec_n; 06235 int format = 0; 06236 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 06237 format = ast_rtp_codec_getformat(codec_n); 06238 if (!format) /* non-codec or not found */ 06239 continue; 06240 if (option_debug) 06241 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 06242 ast_codec_pref_setsize(pref, format, framing); 06243 } 06244 ast_rtp_codec_setpref(p->rtp, pref); 06245 } 06246 found = TRUE; 06247 } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 06248 /* We have a rtpmap to handle */ 06249 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 06250 /* Note: should really look at the 'freq' and '#chans' params too */ 06251 if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 06252 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 06253 if (debug) 06254 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 06255 (*last_rtpmap_codec)++; 06256 found = TRUE; 06257 } 06258 } else { 06259 if (debug) 06260 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 06261 } 06262 06263 if (!found) { 06264 /* Remove this codec since it's an unknown media type for us */ 06265 ast_rtp_unset_m_type(newaudiortp, codec); 06266 if (debug) 06267 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 06268 } 06269 } 06270 06271 return found; 06272 }
static int process_sdp_a_image | ( | const char * | a, | |
struct sip_pvt * | p | |||
) | [static] |
Definition at line 6307 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, FALSE, t38properties::jointcapability, LOG_DEBUG, option_debug, t38properties::peercapability, s, 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().
06308 { 06309 int found = FALSE; 06310 char s[256]; 06311 int x; 06312 06313 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 06314 if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) { 06315 found = TRUE; 06316 if (option_debug > 2) 06317 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 06318 } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) { 06319 found = TRUE; 06320 if (option_debug > 2) 06321 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 06322 switch (x) { 06323 case 14400: 06324 p->t38.peercapability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06325 break; 06326 case 12000: 06327 p->t38.peercapability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06328 break; 06329 case 9600: 06330 p->t38.peercapability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06331 break; 06332 case 7200: 06333 p->t38.peercapability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 06334 break; 06335 case 4800: 06336 p->t38.peercapability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 06337 break; 06338 case 2400: 06339 p->t38.peercapability |= T38FAX_RATE_2400; 06340 break; 06341 } 06342 } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) { 06343 found = TRUE; 06344 if (option_debug > 2) 06345 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 06346 if (x == 0) 06347 p->t38.peercapability |= T38FAX_VERSION_0; 06348 else if (x == 1) 06349 p->t38.peercapability |= T38FAX_VERSION_1; 06350 } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) { 06351 found = TRUE; 06352 if (option_debug > 2) 06353 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 06354 ast_udptl_set_far_max_datagram(p->udptl, x); 06355 ast_udptl_set_local_max_datagram(p->udptl, x); 06356 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 06357 found = TRUE; 06358 if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) { 06359 if (option_debug > 2) 06360 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 06361 if (x == 1) 06362 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06363 } else { 06364 if (option_debug > 2) 06365 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 06366 p->t38.peercapability |= T38FAX_FILL_BIT_REMOVAL; 06367 } 06368 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 06369 found = TRUE; 06370 if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) { 06371 if (option_debug > 2) 06372 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 06373 if (x == 1) 06374 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06375 } else { 06376 if (option_debug > 2) 06377 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 06378 p->t38.peercapability |= T38FAX_TRANSCODING_MMR; 06379 } 06380 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 06381 found = TRUE; 06382 if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) { 06383 if (option_debug > 2) 06384 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 06385 if (x == 1) 06386 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06387 } else { 06388 if (option_debug > 2) 06389 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 06390 p->t38.peercapability |= T38FAX_TRANSCODING_JBIG; 06391 } 06392 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 06393 found = TRUE; 06394 if (option_debug > 2) 06395 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 06396 if (!strcasecmp(s, "localTCF")) 06397 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 06398 else if (!strcasecmp(s, "transferredTCF")) 06399 p->t38.peercapability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 06400 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 06401 found = TRUE; 06402 if (option_debug > 2) 06403 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 06404 if (!strcasecmp(s, "t38UDPRedundancy")) { 06405 p->t38.peercapability |= T38FAX_UDP_EC_REDUNDANCY; 06406 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 06407 } else if (!strcasecmp(s, "t38UDPFEC")) { 06408 p->t38.peercapability |= T38FAX_UDP_EC_FEC; 06409 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 06410 } else { 06411 p->t38.peercapability |= T38FAX_UDP_EC_NONE; 06412 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 06413 } 06414 } 06415 06416 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 06417 int t38speed = p->t38.peercapability & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 06418 06419 p->t38.jointcapability = (p->t38.peercapability & 255); /* Put everything beside supported speeds settings */ 06420 p->t38.jointcapability |= (t38speed & p->t38.capability); /* Put the lower of our's and peer's speed */ 06421 } 06422 06423 return found; 06424 }
static int process_sdp_a_sendonly | ( | const char * | a, | |
int * | sendonly | |||
) | [static] |
Definition at line 6193 of file chan_sip.c.
Referenced by process_sdp().
06194 { 06195 int found = FALSE; 06196 06197 if (!strcasecmp(a, "sendonly")) { 06198 if (*sendonly == -1) 06199 *sendonly = 1; 06200 found = TRUE; 06201 } else if (!strcasecmp(a, "inactive")) { 06202 if (*sendonly == -1) 06203 *sendonly = 2; 06204 found = TRUE; 06205 } else if (!strcasecmp(a, "sendrecv")) { 06206 if (*sendonly == -1) 06207 *sendonly = 0; 06208 found = TRUE; 06209 } 06210 return found; 06211 }
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 6274 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().
06275 { 06276 int found = FALSE; 06277 int codec; 06278 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 06279 int debug = sip_debug_test_pvt(p); 06280 06281 if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 06282 /* We have a rtpmap to handle */ 06283 if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 06284 /* Note: should really look at the 'freq' and '#chans' params too */ 06285 if (p->vrtp && ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 06286 if (debug) 06287 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 06288 (*last_rtpmap_codec)++; 06289 found = TRUE; 06290 } 06291 } else { 06292 if (debug) 06293 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 06294 } 06295 06296 if (!found) { 06297 /* Remove this codec since it's an unknown media type for us */ 06298 ast_rtp_unset_m_type(newvideortp, codec); 06299 if (debug) 06300 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 06301 } 06302 } 06303 06304 return found; 06305 }
static int process_sdp_c | ( | const char * | c, | |
struct ast_hostent * | hp | |||
) | [static] |
Definition at line 6174 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), FALSE, hp, and TRUE.
Referenced by process_sdp().
06175 { 06176 char host[258]; 06177 struct hostent *hp; 06178 06179 /* Check for Media-description-level-address */ 06180 if (sscanf(c, "IN IP4 %255s", host) != 1) { 06181 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 06182 return FALSE; 06183 } else { 06184 if (!(hp = ast_gethostbyname(host, ast_hp))) { 06185 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c); 06186 return FALSE; 06187 } 06188 return TRUE; 06189 } 06190 return FALSE; 06191 }
static int process_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Process the Via header according to RFC 3261 section 18.2.2.
p | a sip_pvt structure that will be modified according to the received header | |
req | a sip request with a Via header to process |
-1 | error | |
0 | success |
Definition at line 5152 of file chan_sip.c.
References addr_is_multicast(), ahp, ast_gethostbyname(), ast_log(), free_via(), get_header(), hp, LOG_ERROR, sip_via::maddr, parse_via(), sip_via::port, sip_pvt::sa, sipsock, STANDARD_SIP_PORT, sip_via::ttl, and sip_via::via.
Referenced by respprep().
05153 { 05154 struct sip_via *via = parse_via(get_header(req, "Via")); 05155 05156 if (!via) { 05157 ast_log(LOG_ERROR, "error processing via header\n"); 05158 return -1; 05159 } 05160 05161 if (via->maddr) { 05162 struct hostent *hp; 05163 struct ast_hostent ahp; 05164 05165 hp = ast_gethostbyname(via->maddr, &ahp); 05166 if (hp == NULL) { 05167 ast_log(LOG_WARNING, "Can't find address for maddr '%s'\n", via->maddr); 05168 ast_log(LOG_ERROR, "error processing via header\n"); 05169 free_via(via); 05170 return -1; 05171 } 05172 05173 p->sa.sin_family = AF_INET; 05174 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05175 05176 if (addr_is_multicast(&p->sa.sin_addr)) { 05177 setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); 05178 } 05179 } 05180 05181 p->sa.sin_port = htons(via->port ? via->port : STANDARD_SIP_PORT); 05182 05183 free_via(via); 05184 return 0; 05185 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 17424 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().
17425 { 17426 struct sip_request *newreq; 17427 17428 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 17429 return -1; 17430 } 17431 17432 copy_request(newreq, req); 17433 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 17434 if (p->request_queue_sched_id == -1) { 17435 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 17436 } 17437 17438 return 0; 17439 }
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 2798 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.
02799 { 02800 struct sip_peer *peer=NULL; 02801 struct ast_variable *var = NULL; 02802 struct ast_config *peerlist = NULL; 02803 struct ast_variable *tmp; 02804 struct ast_flags flags = {0}; 02805 const char *iabuf = NULL; 02806 char portstring[6]; /*up to five digits plus null terminator*/ 02807 const char *insecure; 02808 char *cat = NULL; 02809 unsigned short portnum; 02810 02811 /* First check on peer name */ 02812 if (newpeername) { 02813 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02814 if (!var && sin) 02815 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02816 if (!var) { 02817 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02818 /*!\note 02819 * If this one loaded something, then we need to ensure that the host 02820 * field matched. The only reason why we can't have this as a criteria 02821 * is because we only have the IP address and the host field might be 02822 * set as a name (and the reverse PTR might not match). 02823 */ 02824 if (var && sin) { 02825 for (tmp = var; tmp; tmp = tmp->next) { 02826 if (!strcasecmp(tmp->name, "host")) { 02827 struct hostent *hp; 02828 struct ast_hostent ahp; 02829 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02830 /* No match */ 02831 ast_variables_destroy(var); 02832 var = NULL; 02833 } 02834 break; 02835 } 02836 } 02837 } 02838 } 02839 } 02840 02841 if (!var && sin) { /* Then check on IP address */ 02842 iabuf = ast_inet_ntoa(sin->sin_addr); 02843 portnum = ntohs(sin->sin_port); 02844 sprintf(portstring, "%d", portnum); 02845 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02846 if (!var) 02847 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02848 if (!var) { 02849 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02850 if(peerlist){ 02851 while((cat = ast_category_browse(peerlist, cat))) 02852 { 02853 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02854 set_insecure_flags(&flags, insecure, -1); 02855 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02856 var = ast_category_root(peerlist, cat); 02857 break; 02858 } 02859 } 02860 } 02861 if(!var) { 02862 ast_config_destroy(peerlist); 02863 peerlist = NULL; /*for safety's sake*/ 02864 cat = NULL; 02865 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02866 if(peerlist) { 02867 while((cat = ast_category_browse(peerlist, cat))) 02868 { 02869 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02870 set_insecure_flags(&flags, insecure, -1); 02871 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02872 var = ast_category_root(peerlist, cat); 02873 break; 02874 } 02875 } 02876 } 02877 } 02878 } 02879 } 02880 02881 if (!var) { 02882 if(peerlist) 02883 ast_config_destroy(peerlist); 02884 return NULL; 02885 } 02886 02887 for (tmp = var; tmp; tmp = tmp->next) { 02888 /* If this is type=user, then skip this object. */ 02889 if (!strcasecmp(tmp->name, "type") && 02890 !strcasecmp(tmp->value, "user")) { 02891 ast_variables_destroy(var); 02892 return NULL; 02893 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02894 newpeername = tmp->value; 02895 } else if (!strcasecmp(tmp->name, "lastms")) { 02896 seen_lastms = 1; 02897 } 02898 } 02899 02900 if (!newpeername) { /* Did not find peer in realtime */ 02901 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02902 if(peerlist) 02903 ast_config_destroy(peerlist); 02904 else 02905 ast_variables_destroy(var); 02906 return NULL; 02907 } 02908 02909 /* Peer found in realtime, now build it in memory */ 02910 peer = build_peer(newpeername, var, NULL, 1, devstate_only); 02911 if (!peer) { 02912 if(peerlist) 02913 ast_config_destroy(peerlist); 02914 else 02915 ast_variables_destroy(var); 02916 return NULL; 02917 } 02918 02919 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02920 /* Cache peer */ 02921 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02922 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02923 if (!AST_SCHED_DEL(sched, peer->expire)) { 02924 struct sip_peer *peer_ptr = peer; 02925 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02926 } 02927 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02928 if (peer->expire == -1) { 02929 struct sip_peer *peer_ptr = peer; 02930 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02931 } 02932 } 02933 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02934 } 02935 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02936 if(peerlist) 02937 ast_config_destroy(peerlist); 02938 else 02939 ast_variables_destroy(var); 02940 return peer; 02941 }
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 2677 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.
02678 { 02679 char port[10]; 02680 char ipaddr[INET_ADDRSTRLEN]; 02681 char regseconds[20]; 02682 char str_lastms[20]; 02683 02684 char *sysname = ast_config_AST_SYSTEM_NAME; 02685 char *syslabel = NULL; 02686 02687 time_t nowtime = time(NULL) + expirey; 02688 const char *fc = fullcontact ? "fullcontact" : NULL; 02689 02690 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02691 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02692 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02693 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02694 02695 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02696 sysname = NULL; 02697 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02698 syslabel = "regserver"; 02699 02700 if (fc) 02701 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02702 "port", port, "regseconds", regseconds, 02703 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02704 else 02705 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02706 "port", port, "regseconds", regseconds, 02707 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02708 if (seen_lastms) { 02709 /* We cannot do this in the same statement as above, because the lack of 02710 * this field could cause the whole statement to fail. */ 02711 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02712 } 02713 }
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 2991 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02992 { 02993 struct ast_variable *var; 02994 struct ast_variable *tmp; 02995 struct sip_user *user = NULL; 02996 02997 var = ast_load_realtime("sipusers", "name", username, NULL); 02998 02999 if (!var) 03000 return NULL; 03001 03002 for (tmp = var; tmp; tmp = tmp->next) { 03003 if (!strcasecmp(tmp->name, "type") && 03004 !strcasecmp(tmp->value, "peer")) { 03005 ast_variables_destroy(var); 03006 return NULL; 03007 } 03008 } 03009 03010 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 03011 03012 if (!user) { /* No user found */ 03013 ast_variables_destroy(var); 03014 return NULL; 03015 } 03016 03017 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 03018 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 03019 suserobjs++; 03020 ASTOBJ_CONTAINER_LINK(&userl,user); 03021 } else { 03022 /* Move counter from s to r... */ 03023 suserobjs--; 03024 ruserobjs++; 03025 } 03026 ast_set_flag(&user->flags[0], SIP_REALTIME); 03027 ast_variables_destroy(var); 03028 return user; 03029 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 11075 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().
11076 { 11077 char buf[1024]; 11078 struct ast_frame f; 11079 const char *content_type = get_header(req, "Content-Type"); 11080 11081 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 11082 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 11083 if (!p->owner) 11084 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11085 return; 11086 } 11087 11088 if (get_msg_text(buf, sizeof(buf), req)) { 11089 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 11090 transmit_response(p, "202 Accepted", req); 11091 if (!p->owner) 11092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11093 return; 11094 } 11095 11096 if (p->owner) { 11097 if (sip_debug_test_pvt(p)) 11098 ast_verbose("Message received: '%s'\n", buf); 11099 memset(&f, 0, sizeof(f)); 11100 f.frametype = AST_FRAME_TEXT; 11101 f.subclass = 0; 11102 f.offset = 0; 11103 f.data = buf; 11104 f.datalen = strlen(buf) + 1; 11105 ast_queue_frame(p->owner, &f); 11106 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 11107 } else { /* Message outside of a call, we do not support that */ 11108 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); 11109 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 11110 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11111 } 11112 return; 11113 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1744 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01745 { 01746 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01747 int x; 01748 01749 for (x = 0; x < i; x++) { 01750 if (referstatusstrings[x].status == rstatus) 01751 return (char *) referstatusstrings[x].text; 01752 } 01753 return ""; 01754 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8905 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.
08906 { 08907 char data[256]; 08908 struct in_addr in; 08909 int expiry; 08910 int port; 08911 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08912 08913 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08914 return; 08915 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08916 return; 08917 08918 scan = data; 08919 addr = strsep(&scan, ":"); 08920 port_str = strsep(&scan, ":"); 08921 expiry_str = strsep(&scan, ":"); 08922 username = strsep(&scan, ":"); 08923 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08924 08925 if (!inet_aton(addr, &in)) 08926 return; 08927 08928 if (port_str) 08929 port = atoi(port_str); 08930 else 08931 return; 08932 08933 if (expiry_str) 08934 expiry = atoi(expiry_str); 08935 else 08936 return; 08937 08938 if (username) 08939 ast_copy_string(peer->username, username, sizeof(peer->username)); 08940 if (contact) 08941 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08942 08943 if (option_debug > 1) 08944 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08945 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08946 08947 memset(&peer->addr, 0, sizeof(peer->addr)); 08948 peer->addr.sin_family = AF_INET; 08949 peer->addr.sin_addr = in; 08950 peer->addr.sin_port = htons(port); 08951 if (sipsock < 0) { 08952 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08953 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08954 struct sip_peer *peer_ptr = peer; 08955 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08956 } 08957 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08958 if (peer->pokeexpire == -1) { 08959 struct sip_peer *peer_ptr = peer; 08960 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08961 } 08962 } else 08963 sip_poke_peer(peer); 08964 if (!AST_SCHED_DEL(sched, peer->expire)) { 08965 struct sip_peer *peer_ptr = peer; 08966 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08967 } 08968 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08969 if (peer->expire == -1) { 08970 struct sip_peer *peer_ptr = peer; 08971 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08972 } 08973 register_peer_exten(peer, TRUE); 08974 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2716 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.
02717 { 02718 char multi[256]; 02719 char *stringp, *ext, *context; 02720 02721 /* XXX note that global_regcontext is both a global 'enable' flag and 02722 * the name of the global regexten context, if not specified 02723 * individually. 02724 */ 02725 if (ast_strlen_zero(global_regcontext)) 02726 return; 02727 02728 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02729 stringp = multi; 02730 while ((ext = strsep(&stringp, "&"))) { 02731 if ((context = strchr(ext, '@'))) { 02732 *context++ = '\0'; /* split ext@context */ 02733 if (!ast_context_find(context)) { 02734 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02735 continue; 02736 } 02737 } else { 02738 context = global_regcontext; 02739 } 02740 if (onoff) { 02741 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02742 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02743 ast_strdup(peer->name), ast_free_ptr, "SIP"); 02744 } 02745 } else { 02746 ast_context_remove_extension(context, ext, 1, NULL); 02747 } 02748 } 02749 }
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 9900 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_strlen_zero(), ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_peer::expire, 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.
09902 { 09903 enum check_auth_result res = AUTH_NOT_FOUND; 09904 struct sip_peer *peer; 09905 char tmp[256]; 09906 char *name, *c; 09907 char *t; 09908 char *domain; 09909 09910 /* Terminate URI */ 09911 t = uri; 09912 while(*t && (*t > 32) && (*t != ';')) 09913 t++; 09914 *t = '\0'; 09915 09916 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09917 if (pedanticsipchecking) 09918 ast_uri_decode(tmp); 09919 09920 c = get_in_brackets(tmp); 09921 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09922 09923 if (!strncasecmp(c, "sip:", 4)) { 09924 name = c + 4; 09925 } else { 09926 name = c; 09927 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09928 } 09929 09930 /* Strip off the domain name */ 09931 if ((c = strchr(name, '@'))) { 09932 *c++ = '\0'; 09933 domain = c; 09934 if ((c = strchr(domain, ':'))) /* Remove :port */ 09935 *c = '\0'; 09936 if (!AST_LIST_EMPTY(&domain_list)) { 09937 if (!check_sip_domain(domain, NULL, 0)) { 09938 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09939 return AUTH_UNKNOWN_DOMAIN; 09940 } 09941 } 09942 } 09943 09944 ast_string_field_set(p, exten, name); 09945 build_contact(p); 09946 if (ast_test_flag(req, SIP_PKT_IGNORE)) { 09947 /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */ 09948 const char *expires = get_header(req, "Expires"); 09949 int expire = atoi(expires); 09950 09951 if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */ 09952 if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) { 09953 expire = atoi(expires + 9); 09954 } 09955 } 09956 if (!ast_strlen_zero(expires) && expire == 0) { 09957 transmit_response_with_date(p, "200 OK", req); 09958 return 0; 09959 } 09960 } 09961 peer = find_peer(name, NULL, 1, 0); 09962 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09963 /* Peer fails ACL check */ 09964 if (peer) { 09965 ASTOBJ_UNREF(peer, sip_destroy_peer); 09966 res = AUTH_ACL_FAILED; 09967 } else 09968 res = AUTH_NOT_FOUND; 09969 } 09970 if (peer) { 09971 /* Set Frame packetization */ 09972 if (p->rtp) { 09973 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09974 p->autoframing = peer->autoframing; 09975 } 09976 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09977 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09978 res = AUTH_PEER_NOT_DYNAMIC; 09979 } else { 09980 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09981 transmit_response(p, "100 Trying", req); 09982 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09983 if (sip_cancel_destroy(p)) 09984 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09985 09986 /* We have a succesful registration attemp with proper authentication, 09987 now, update the peer */ 09988 switch (parse_register_contact(p, peer, req)) { 09989 case PARSE_REGISTER_DENIED: 09990 transmit_response_with_date(p, "603 Denied", req); 09991 peer->lastmsgssent = -1; 09992 res = 0; 09993 break; 09994 case PARSE_REGISTER_FAILED: 09995 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09996 transmit_response_with_date(p, "400 Bad Request", req); 09997 peer->lastmsgssent = -1; 09998 res = 0; 09999 break; 10000 case PARSE_REGISTER_QUERY: 10001 ast_string_field_set(p, fullcontact, peer->fullcontact); 10002 transmit_response_with_date(p, "200 OK", req); 10003 peer->lastmsgssent = -1; 10004 res = 0; 10005 break; 10006 case PARSE_REGISTER_UPDATE: 10007 ast_string_field_set(p, fullcontact, peer->fullcontact); 10008 update_peer(peer, p->expiry); 10009 /* Say OK and ask subsystem to retransmit msg counter */ 10010 transmit_response_with_date(p, "200 OK", req); 10011 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 10012 peer->lastmsgssent = -1; 10013 res = 0; 10014 break; 10015 } 10016 } 10017 } 10018 } 10019 if (!peer && autocreatepeer) { 10020 /* Create peer if we have autocreate mode enabled */ 10021 peer = temp_peer(name); 10022 if (peer) { 10023 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10024 if (sip_cancel_destroy(p)) 10025 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 10026 switch (parse_register_contact(p, peer, req)) { 10027 case PARSE_REGISTER_DENIED: 10028 ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); 10029 transmit_response_with_date(p, "403 Forbidden (ACL)", req); 10030 peer->lastmsgssent = -1; 10031 res = 0; 10032 break; 10033 case PARSE_REGISTER_FAILED: 10034 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 10035 transmit_response_with_date(p, "400 Bad Request", req); 10036 peer->lastmsgssent = -1; 10037 res = 0; 10038 break; 10039 case PARSE_REGISTER_QUERY: 10040 ast_string_field_set(p, fullcontact, peer->fullcontact); 10041 transmit_response_with_date(p, "200 OK", req); 10042 peer->lastmsgssent = -1; 10043 res = 0; 10044 break; 10045 case PARSE_REGISTER_UPDATE: 10046 ast_string_field_set(p, fullcontact, peer->fullcontact); 10047 /* Say OK and ask subsystem to retransmit msg counter */ 10048 transmit_response_with_date(p, "200 OK", req); 10049 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 10050 peer->lastmsgssent = -1; 10051 res = 0; 10052 break; 10053 } 10054 } 10055 } 10056 if (!peer && global_alwaysauthreject) { 10057 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 10058 * trying to avoid leaking information, we MUST also transmit the same 10059 * response when we DON'T find a peer. */ 10060 transmit_response(p, "100 Trying", req); 10061 /* Insert a fake delay between the 100 and the subsequent failure. */ 10062 sched_yield(); 10063 } 10064 if (!res) { 10065 ast_device_state_changed("SIP/%s", peer->name); 10066 } 10067 if (res < 0) { 10068 switch (res) { 10069 case AUTH_SECRET_FAILED: 10070 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 10071 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 10072 break; 10073 case AUTH_USERNAME_MISMATCH: 10074 /* Username and digest username does not match. 10075 Asterisk uses the From: username for authentication. We need the 10076 users to use the same authentication user name until we support 10077 proper authentication by digest auth name */ 10078 case AUTH_NOT_FOUND: 10079 case AUTH_PEER_NOT_DYNAMIC: 10080 case AUTH_ACL_FAILED: 10081 if (global_alwaysauthreject) { 10082 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 10083 } else { 10084 /* URI not found */ 10085 if (res == AUTH_PEER_NOT_DYNAMIC) 10086 transmit_response(p, "403 Forbidden", &p->initreq); 10087 else 10088 transmit_response(p, "404 Not found", &p->initreq); 10089 } 10090 break; 10091 default: 10092 break; 10093 } 10094 } 10095 if (peer) 10096 ASTOBJ_UNREF(peer, sip_destroy_peer); 10097 10098 return res; 10099 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 8366 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.
08367 { 08368 switch(regstate) { 08369 case REG_STATE_FAILED: 08370 return "Failed"; 08371 case REG_STATE_UNREGISTERED: 08372 return "Unregistered"; 08373 case REG_STATE_REGSENT: 08374 return "Request Sent"; 08375 case REG_STATE_AUTHSENT: 08376 return "Auth. Sent"; 08377 case REG_STATE_REGISTERED: 08378 return "Registered"; 08379 case REG_STATE_REJECTED: 08380 return "Rejected"; 08381 case REG_STATE_TIMEOUT: 08382 return "Timeout"; 08383 case REG_STATE_NOAUTH: 08384 return "No Authentication"; 08385 default: 08386 return "Unknown"; 08387 } 08388 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 20183 of file chan_sip.c.
References sip_reload().
20184 { 20185 return sip_reload(0, 0, NULL); 20186 }
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
< Set up call forward on 482 Loop Detected
Definition at line 19016 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().
19017 { 19018 struct ast_config *cfg, *ucfg; 19019 struct ast_variable *v; 19020 struct sip_peer *peer; 19021 struct sip_user *user; 19022 struct ast_hostent ahp; 19023 char *cat, *stringp, *context, *oldregcontext; 19024 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 19025 struct hostent *hp; 19026 int format; 19027 struct ast_flags dummy[2]; 19028 int auto_sip_domains = FALSE; 19029 struct sockaddr_in old_bindaddr = bindaddr; 19030 int registry_count = 0, peer_count = 0, user_count = 0; 19031 unsigned int temp_tos = 0; 19032 struct ast_flags debugflag = {0}; 19033 19034 cfg = ast_config_load(config); 19035 19036 /* We *must* have a config file otherwise stop immediately */ 19037 if (!cfg) { 19038 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 19039 return -1; 19040 } 19041 19042 if (option_debug > 3) 19043 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 19044 19045 clear_realm_authentication(authl); 19046 clear_sip_domains(); 19047 authl = NULL; 19048 19049 ast_free_ha(global_contact_ha); 19050 global_contact_ha = NULL; 19051 19052 /* First, destroy all outstanding registry calls */ 19053 /* This is needed, since otherwise active registry entries will not be destroyed */ 19054 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 19055 ASTOBJ_RDLOCK(iterator); 19056 if (iterator->call) { 19057 if (option_debug > 2) 19058 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 19059 /* This will also remove references to the registry */ 19060 sip_destroy(iterator->call); 19061 } 19062 ASTOBJ_UNLOCK(iterator); 19063 19064 } while(0)); 19065 19066 /* Then, actually destroy users and registry */ 19067 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19068 if (option_debug > 3) 19069 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 19070 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19071 if (option_debug > 3) 19072 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 19073 ASTOBJ_CONTAINER_MARKALL(&peerl); 19074 19075 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 19076 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 19077 oldregcontext = oldcontexts; 19078 19079 /* Clear all flags before setting default values */ 19080 /* Preserve debugging settings for console */ 19081 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 19082 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 19083 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 19084 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 19085 19086 /* Reset IP addresses */ 19087 memset(&bindaddr, 0, sizeof(bindaddr)); 19088 ast_free_ha(localaddr); 19089 memset(&localaddr, 0, sizeof(localaddr)); 19090 memset(&externip, 0, sizeof(externip)); 19091 memset(&default_prefs, 0 , sizeof(default_prefs)); 19092 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 19093 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 19094 ourport = STANDARD_SIP_PORT; 19095 srvlookup = DEFAULT_SRVLOOKUP; 19096 global_tos_sip = DEFAULT_TOS_SIP; 19097 global_tos_audio = DEFAULT_TOS_AUDIO; 19098 global_tos_video = DEFAULT_TOS_VIDEO; 19099 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 19100 externexpire = 0; /* Expiration for DNS re-issuing */ 19101 externrefresh = 10; 19102 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 19103 19104 /* Reset channel settings to default before re-configuring */ 19105 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 19106 global_regcontext[0] = '\0'; 19107 expiry = DEFAULT_EXPIRY; 19108 global_notifyringing = DEFAULT_NOTIFYRINGING; 19109 global_limitonpeers = FALSE; 19110 global_prematuremediafilter = FALSE; 19111 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 19112 global_notifyhold = FALSE; 19113 global_alwaysauthreject = 0; 19114 global_allowsubscribe = FALSE; 19115 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 19116 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 19117 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 19118 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 19119 else 19120 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 19121 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 19122 compactheaders = DEFAULT_COMPACTHEADERS; 19123 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 19124 global_regattempts_max = 0; 19125 pedanticsipchecking = DEFAULT_PEDANTIC; 19126 global_mwitime = DEFAULT_MWITIME; 19127 autocreatepeer = DEFAULT_AUTOCREATEPEER; 19128 global_autoframing = 0; 19129 global_allowguest = DEFAULT_ALLOWGUEST; 19130 global_rtptimeout = 0; 19131 global_rtpholdtimeout = 0; 19132 global_rtpkeepalive = 0; 19133 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 19134 global_rtautoclear = 120; 19135 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 19136 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 19137 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 19138 19139 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 19140 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 19141 default_subscribecontext[0] = '\0'; 19142 default_language[0] = '\0'; 19143 default_fromdomain[0] = '\0'; 19144 default_qualify = DEFAULT_QUALIFY; 19145 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 19146 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 19147 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 19148 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 19149 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 19150 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 19151 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 19152 ast_set_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); /*!< Set up call forward on 482 Loop Detected */ 19153 19154 /* Debugging settings, always default to off */ 19155 dumphistory = FALSE; 19156 recordhistory = FALSE; 19157 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 19158 19159 /* Misc settings for the channel */ 19160 global_relaxdtmf = FALSE; 19161 global_callevents = FALSE; 19162 global_t1min = DEFAULT_T1MIN; 19163 global_shrinkcallerid = 1; 19164 19165 global_matchexterniplocally = FALSE; 19166 19167 /* Copy the default jb config over global_jbconf */ 19168 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 19169 19170 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 19171 19172 /* Read the [general] config section of sip.conf (or from realtime config) */ 19173 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 19174 if (handle_common_options(&global_flags[0], &dummy[0], v)) 19175 continue; 19176 /* handle jb conf */ 19177 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 19178 continue; 19179 19180 /* Create the interface list */ 19181 if (!strcasecmp(v->name, "context")) { 19182 ast_copy_string(default_context, v->value, sizeof(default_context)); 19183 } else if (!strcasecmp(v->name, "subscribecontext")) { 19184 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 19185 } else if (!strcasecmp(v->name, "allowguest")) { 19186 global_allowguest = ast_true(v->value) ? 1 : 0; 19187 } else if (!strcasecmp(v->name, "realm")) { 19188 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 19189 } else if (!strcasecmp(v->name, "useragent")) { 19190 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 19191 if (option_debug) 19192 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 19193 } else if (!strcasecmp(v->name, "allowtransfer")) { 19194 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 19195 } else if (!strcasecmp(v->name, "rtcachefriends")) { 19196 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 19197 } else if (!strcasecmp(v->name, "rtsavesysname")) { 19198 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 19199 } else if (!strcasecmp(v->name, "rtupdate")) { 19200 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 19201 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 19202 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 19203 } else if (!strcasecmp(v->name, "t1min")) { 19204 global_t1min = atoi(v->value); 19205 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 19206 global_dynamic_exclude_static = ast_true(v->value); 19207 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 19208 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 19209 } else if (!strcasecmp(v->name, "rtautoclear")) { 19210 int i = atoi(v->value); 19211 if (i > 0) 19212 global_rtautoclear = i; 19213 else 19214 i = 0; 19215 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 19216 } else if (!strcasecmp(v->name, "usereqphone")) { 19217 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 19218 } else if (!strcasecmp(v->name, "prematuremedia")) { 19219 global_prematuremediafilter = ast_true(v->value); 19220 } else if (!strcasecmp(v->name, "relaxdtmf")) { 19221 global_relaxdtmf = ast_true(v->value); 19222 } else if (!strcasecmp(v->name, "checkmwi")) { 19223 if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) { 19224 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 19225 global_mwitime = DEFAULT_MWITIME; 19226 } 19227 } else if (!strcasecmp(v->name, "vmexten")) { 19228 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 19229 } else if (!strcasecmp(v->name, "rtptimeout")) { 19230 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 19231 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 19232 global_rtptimeout = 0; 19233 } 19234 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 19235 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 19236 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 19237 global_rtpholdtimeout = 0; 19238 } 19239 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 19240 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 19241 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 19242 global_rtpkeepalive = 0; 19243 } 19244 } else if (!strcasecmp(v->name, "compactheaders")) { 19245 compactheaders = ast_true(v->value); 19246 } else if (!strcasecmp(v->name, "notifymimetype")) { 19247 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 19248 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 19249 global_limitonpeers = ast_true(v->value); 19250 } else if (!strcasecmp(v->name, "directrtpsetup")) { 19251 global_directrtpsetup = ast_true(v->value); 19252 } else if (!strcasecmp(v->name, "notifyringing")) { 19253 global_notifyringing = ast_true(v->value); 19254 } else if (!strcasecmp(v->name, "notifyhold")) { 19255 global_notifyhold = ast_true(v->value); 19256 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 19257 global_alwaysauthreject = ast_true(v->value); 19258 } else if (!strcasecmp(v->name, "mohinterpret") 19259 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 19260 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 19261 } else if (!strcasecmp(v->name, "mohsuggest")) { 19262 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 19263 } else if (!strcasecmp(v->name, "language")) { 19264 ast_copy_string(default_language, v->value, sizeof(default_language)); 19265 } else if (!strcasecmp(v->name, "regcontext")) { 19266 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 19267 stringp = newcontexts; 19268 /* Let's remove any contexts that are no longer defined in regcontext */ 19269 cleanup_stale_contexts(stringp, oldregcontext); 19270 /* Create contexts if they don't exist already */ 19271 while ((context = strsep(&stringp, "&"))) { 19272 if (!ast_context_find(context)) 19273 ast_context_create(NULL, context,"SIP"); 19274 } 19275 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 19276 } else if (!strcasecmp(v->name, "callerid")) { 19277 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 19278 } else if (!strcasecmp(v->name, "fromdomain")) { 19279 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 19280 } else if (!strcasecmp(v->name, "outboundproxy")) { 19281 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 19282 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 19283 } else if (!strcasecmp(v->name, "outboundproxyport")) { 19284 /* Port needs to be after IP */ 19285 sscanf(v->value, "%30d", &format); 19286 outboundproxyip.sin_port = htons(format); 19287 } else if (!strcasecmp(v->name, "autocreatepeer")) { 19288 autocreatepeer = ast_true(v->value); 19289 } else if (!strcasecmp(v->name, "srvlookup")) { 19290 srvlookup = ast_true(v->value); 19291 } else if (!strcasecmp(v->name, "pedantic")) { 19292 pedanticsipchecking = ast_true(v->value); 19293 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 19294 max_expiry = atoi(v->value); 19295 if (max_expiry < 1) 19296 max_expiry = DEFAULT_MAX_EXPIRY; 19297 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 19298 min_expiry = atoi(v->value); 19299 if (min_expiry < 1) 19300 min_expiry = DEFAULT_MIN_EXPIRY; 19301 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 19302 default_expiry = atoi(v->value); 19303 if (default_expiry < 1) 19304 default_expiry = DEFAULT_DEFAULT_EXPIRY; 19305 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 19306 if (ast_true(v->value)) 19307 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 19308 } else if (!strcasecmp(v->name, "dumphistory")) { 19309 dumphistory = ast_true(v->value); 19310 } else if (!strcasecmp(v->name, "recordhistory")) { 19311 recordhistory = ast_true(v->value); 19312 } else if (!strcasecmp(v->name, "registertimeout")) { 19313 global_reg_timeout = atoi(v->value); 19314 if (global_reg_timeout < 1) 19315 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 19316 } else if (!strcasecmp(v->name, "registerattempts")) { 19317 global_regattempts_max = atoi(v->value); 19318 } else if (!strcasecmp(v->name, "bindaddr")) { 19319 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 19320 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 19321 } else { 19322 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 19323 } 19324 } else if (!strcasecmp(v->name, "localnet")) { 19325 struct ast_ha *na; 19326 if (!(na = ast_append_ha("d", v->value, localaddr))) 19327 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 19328 else 19329 localaddr = na; 19330 } else if (!strcasecmp(v->name, "localmask")) { 19331 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 19332 } else if (!strcasecmp(v->name, "externip")) { 19333 if (!(hp = ast_gethostbyname(v->value, &ahp))) 19334 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 19335 else 19336 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 19337 externexpire = 0; 19338 } else if (!strcasecmp(v->name, "externhost")) { 19339 ast_copy_string(externhost, v->value, sizeof(externhost)); 19340 if (!(hp = ast_gethostbyname(externhost, &ahp))) 19341 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 19342 else 19343 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 19344 externexpire = time(NULL); 19345 } else if (!strcasecmp(v->name, "externrefresh")) { 19346 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 19347 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 19348 externrefresh = 10; 19349 } 19350 } else if (!strcasecmp(v->name, "allow")) { 19351 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 19352 } else if (!strcasecmp(v->name, "disallow")) { 19353 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 19354 } else if (!strcasecmp(v->name, "autoframing")) { 19355 global_autoframing = ast_true(v->value); 19356 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 19357 allow_external_domains = ast_true(v->value); 19358 } else if (!strcasecmp(v->name, "autodomain")) { 19359 auto_sip_domains = ast_true(v->value); 19360 } else if (!strcasecmp(v->name, "domain")) { 19361 char *domain = ast_strdupa(v->value); 19362 char *context = strchr(domain, ','); 19363 19364 if (context) 19365 *context++ = '\0'; 19366 19367 if (option_debug && ast_strlen_zero(context)) 19368 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 19369 if (ast_strlen_zero(domain)) 19370 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 19371 else 19372 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 19373 } else if (!strcasecmp(v->name, "register")) { 19374 if (sip_register(v->value, v->lineno) == 0) 19375 registry_count++; 19376 } else if (!strcasecmp(v->name, "tos")) { 19377 if (!ast_str2tos(v->value, &temp_tos)) { 19378 global_tos_sip = temp_tos; 19379 global_tos_audio = temp_tos; 19380 global_tos_video = temp_tos; 19381 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 19382 } else 19383 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 19384 } else if (!strcasecmp(v->name, "tos_sip")) { 19385 if (ast_str2tos(v->value, &global_tos_sip)) 19386 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 19387 } else if (!strcasecmp(v->name, "tos_audio")) { 19388 if (ast_str2tos(v->value, &global_tos_audio)) 19389 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 19390 } else if (!strcasecmp(v->name, "tos_video")) { 19391 if (ast_str2tos(v->value, &global_tos_video)) 19392 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 19393 } else if (!strcasecmp(v->name, "bindport")) { 19394 if (sscanf(v->value, "%5d", &ourport) == 1) { 19395 bindaddr.sin_port = htons(ourport); 19396 } else { 19397 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 19398 } 19399 } else if (!strcasecmp(v->name, "qualify")) { 19400 if (!strcasecmp(v->value, "no")) { 19401 default_qualify = 0; 19402 } else if (!strcasecmp(v->value, "yes")) { 19403 default_qualify = DEFAULT_MAXMS; 19404 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 19405 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 19406 default_qualify = 0; 19407 } 19408 } else if (!strcasecmp(v->name, "callevents")) { 19409 global_callevents = ast_true(v->value); 19410 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 19411 default_maxcallbitrate = atoi(v->value); 19412 if (default_maxcallbitrate < 0) 19413 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 19414 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 19415 global_matchexterniplocally = ast_true(v->value); 19416 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 19417 if (ast_true(v->value)) { 19418 global_shrinkcallerid = 1; 19419 } else if (ast_false(v->value)) { 19420 global_shrinkcallerid = 0; 19421 } else { 19422 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 19423 } 19424 } 19425 } 19426 19427 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 19428 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 19429 allow_external_domains = 1; 19430 } 19431 19432 /* Build list of authentication to various SIP realms, i.e. service providers */ 19433 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 19434 /* Format for authentication is auth = username:password@realm */ 19435 if (!strcasecmp(v->name, "auth")) 19436 authl = add_realm_authentication(authl, v->value, v->lineno); 19437 } 19438 19439 ucfg = ast_config_load("users.conf"); 19440 if (ucfg) { 19441 struct ast_variable *gen; 19442 int genhassip, genregistersip; 19443 const char *hassip, *registersip; 19444 19445 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 19446 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 19447 gen = ast_variable_browse(ucfg, "general"); 19448 cat = ast_category_browse(ucfg, NULL); 19449 while (cat) { 19450 if (strcasecmp(cat, "general")) { 19451 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 19452 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 19453 if (ast_true(hassip) || (!hassip && genhassip)) { 19454 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 19455 if (user) { 19456 ASTOBJ_CONTAINER_LINK(&userl,user); 19457 ASTOBJ_UNREF(user, sip_destroy_user); 19458 user_count++; 19459 } 19460 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0); 19461 if (peer) { 19462 ast_device_state_changed("SIP/%s", peer->name); 19463 ASTOBJ_CONTAINER_LINK(&peerl,peer); 19464 ASTOBJ_UNREF(peer, sip_destroy_peer); 19465 peer_count++; 19466 } 19467 } 19468 if (ast_true(registersip) || (!registersip && genregistersip)) { 19469 char tmp[256]; 19470 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 19471 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 19472 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 19473 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 19474 const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser"); 19475 if (!host) 19476 host = ast_variable_retrieve(ucfg, "general", "host"); 19477 if (!username) 19478 username = ast_variable_retrieve(ucfg, "general", "username"); 19479 if (!secret) 19480 secret = ast_variable_retrieve(ucfg, "general", "secret"); 19481 if (!contact) 19482 contact = "s"; 19483 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 19484 if (!ast_strlen_zero(secret)) { 19485 if (!ast_strlen_zero(authuser)) { 19486 snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact); 19487 } else { 19488 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 19489 } 19490 } else if (!ast_strlen_zero(authuser)) { 19491 snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact); 19492 } else { 19493 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 19494 } 19495 if (sip_register(tmp, 0) == 0) 19496 registry_count++; 19497 } 19498 } 19499 } 19500 cat = ast_category_browse(ucfg, cat); 19501 } 19502 ast_config_destroy(ucfg); 19503 } 19504 19505 19506 /* Load peers, users and friends */ 19507 cat = NULL; 19508 while ( (cat = ast_category_browse(cfg, cat)) ) { 19509 const char *utype; 19510 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 19511 continue; 19512 utype = ast_variable_retrieve(cfg, cat, "type"); 19513 if (!utype) { 19514 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 19515 continue; 19516 } else { 19517 int is_user = 0, is_peer = 0; 19518 if (!strcasecmp(utype, "user")) 19519 is_user = 1; 19520 else if (!strcasecmp(utype, "friend")) 19521 is_user = is_peer = 1; 19522 else if (!strcasecmp(utype, "peer")) 19523 is_peer = 1; 19524 else { 19525 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 19526 continue; 19527 } 19528 if (is_user) { 19529 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 19530 if (user) { 19531 ASTOBJ_CONTAINER_LINK(&userl,user); 19532 ASTOBJ_UNREF(user, sip_destroy_user); 19533 user_count++; 19534 } 19535 } 19536 if (is_peer) { 19537 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0); 19538 if (peer) { 19539 ASTOBJ_CONTAINER_LINK(&peerl,peer); 19540 ASTOBJ_UNREF(peer, sip_destroy_peer); 19541 peer_count++; 19542 } 19543 } 19544 } 19545 } 19546 if (ast_find_ourip(&__ourip, bindaddr)) { 19547 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 19548 ast_config_destroy(cfg); 19549 return 0; 19550 } 19551 if (!ntohs(bindaddr.sin_port)) 19552 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 19553 bindaddr.sin_family = AF_INET; 19554 ast_mutex_lock(&netlock); 19555 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 19556 close(sipsock); 19557 sipsock = -1; 19558 } 19559 if (sipsock < 0) { 19560 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 19561 if (sipsock < 0) { 19562 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 19563 ast_config_destroy(cfg); 19564 ast_mutex_unlock(&netlock); 19565 return -1; 19566 } else { 19567 /* Allow SIP clients on the same host to access us: */ 19568 const int reuseFlag = 1; 19569 19570 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 19571 (const char*)&reuseFlag, 19572 sizeof reuseFlag); 19573 19574 ast_enable_packet_fragmentation(sipsock); 19575 19576 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 19577 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 19578 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 19579 strerror(errno)); 19580 close(sipsock); 19581 sipsock = -1; 19582 } else { 19583 if (option_verbose > 1) { 19584 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 19585 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 19586 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 19587 } 19588 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 19589 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 19590 } 19591 } 19592 } else if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) { 19593 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 19594 } 19595 ast_mutex_unlock(&netlock); 19596 19597 /* Add default domains - host name, IP address and IP:port */ 19598 /* Only do this if user added any sip domain with "localdomains" */ 19599 /* In order to *not* break backwards compatibility */ 19600 /* Some phones address us at IP only, some with additional port number */ 19601 if (auto_sip_domains) { 19602 char temp[MAXHOSTNAMELEN]; 19603 19604 /* First our default IP address */ 19605 if (bindaddr.sin_addr.s_addr) 19606 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 19607 else 19608 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 19609 19610 /* Our extern IP address, if configured */ 19611 if (externip.sin_addr.s_addr) 19612 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 19613 19614 /* Extern host name (NAT traversal support) */ 19615 if (!ast_strlen_zero(externhost)) 19616 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 19617 19618 /* Our host name */ 19619 if (!gethostname(temp, sizeof(temp))) 19620 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 19621 } 19622 19623 /* Release configuration from memory */ 19624 ast_config_destroy(cfg); 19625 19626 /* Load the list of manual NOTIFY types to support */ 19627 if (notify_types) 19628 ast_config_destroy(notify_types); 19629 notify_types = ast_config_load(notify_config); 19630 19631 /* Done, tell the manager */ 19632 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); 19633 19634 return 0; 19635 }
static void remove_provisional_keepalive_sched | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 2483 of file chan_sip.c.
References ao2_ref(), AST_SCHED_DEL, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::pvt, sched, provisional_keepalive_data::sched_id, and unref_provisional_keepalive().
Referenced by __sip_destroy(), send_response(), sip_hangup(), and update_provisional_keepalive().
02484 { 02485 int res; 02486 if (!pvt->provisional_keepalive_data) { 02487 return; 02488 } 02489 res = AST_SCHED_DEL(sched, pvt->provisional_keepalive_data->sched_id); 02490 if (res == -1) { 02491 /* If we could not remove this item. remove pvt's reference 02492 * this data and mark it for removal for the next time the 02493 * scheduler uses it. The scheduler has it's own ref to this 02494 * data and will detect it should not reschedule the event 02495 * since the sched_id is -1 and pvt == NULL */ 02496 pvt->provisional_keepalive_data = unref_provisional_keepalive(pvt->provisional_keepalive_data); 02497 } else { 02498 /* If we successfully canceled the scheduler entry, we need to 02499 * remove its reference to the data. */ 02500 ao2_ref(pvt->provisional_keepalive_data, -1); 02501 } 02502 }
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 12897 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().
12898 { 12899 char tmp[512]; 12900 char *c; 12901 char oldnonce[256]; 12902 12903 /* table of recognised keywords, and places where they should be copied */ 12904 const struct x { 12905 const char *key; 12906 int field_index; 12907 } *i, keys[] = { 12908 { "realm=", ast_string_field_index(p, realm) }, 12909 { "nonce=", ast_string_field_index(p, nonce) }, 12910 { "opaque=", ast_string_field_index(p, opaque) }, 12911 { "qop=", ast_string_field_index(p, qop) }, 12912 { "domain=", ast_string_field_index(p, domain) }, 12913 { NULL, 0 }, 12914 }; 12915 12916 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 12917 if (ast_strlen_zero(tmp)) 12918 return -1; 12919 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 12920 ast_log(LOG_WARNING, "missing Digest.\n"); 12921 return -1; 12922 } 12923 c = tmp + strlen("Digest "); 12924 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 12925 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 12926 for (i = keys; i->key != NULL; i++) { 12927 char *src, *separator; 12928 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 12929 continue; 12930 /* Found. Skip keyword, take text in quotes or up to the separator. */ 12931 c += strlen(i->key); 12932 if (*c == '"') { 12933 src = ++c; 12934 separator = "\""; 12935 } else { 12936 src = c; 12937 separator = ","; 12938 } 12939 strsep(&c, separator); /* clear separator and move ptr */ 12940 ast_string_field_index_set(p, i->field_index, src); 12941 break; 12942 } 12943 if (i->key == NULL) /* not found, try ',' */ 12944 strsep(&c, ","); 12945 } 12946 /* Reset nonce count */ 12947 if (strcmp(p->nonce, oldnonce)) 12948 p->noncecount = 0; 12949 12950 /* Save auth data for following registrations */ 12951 if (p->registry) { 12952 struct sip_registry *r = p->registry; 12953 12954 if (strcmp(r->nonce, p->nonce)) { 12955 ast_string_field_set(r, realm, p->realm); 12956 ast_string_field_set(r, nonce, p->nonce); 12957 ast_string_field_set(r, domain, p->domain); 12958 ast_string_field_set(r, opaque, p->opaque); 12959 ast_string_field_set(r, qop, p->qop); 12960 r->noncecount = 0; 12961 } 12962 } 12963 return build_reply_digest(p, sipmethod, digest, digest_len); 12964 }
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 6848 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.
06849 { 06850 struct sip_request *orig = &p->initreq; 06851 char stripped[80]; 06852 char tmp[80]; 06853 char newto[256]; 06854 const char *c; 06855 const char *ot, *of; 06856 int is_strict = FALSE; /*!< Strict routing flag */ 06857 06858 memset(req, 0, sizeof(struct sip_request)); 06859 06860 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06861 06862 if (!seqno) { 06863 p->ocseq++; 06864 seqno = p->ocseq; 06865 } 06866 06867 /* A CANCEL must have the same branch as the INVITE that it is canceling. */ 06868 if (sipmethod == SIP_CANCEL) { 06869 p->branch = p->invite_branch; 06870 build_via(p); 06871 } else if (newbranch && (sipmethod == SIP_INVITE)) { 06872 p->branch ^= ast_random(); 06873 p->invite_branch = p->branch; 06874 build_via(p); 06875 } else if (newbranch) { 06876 p->branch ^= ast_random(); 06877 build_via(p); 06878 } 06879 06880 /* Check for strict or loose router */ 06881 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06882 is_strict = TRUE; 06883 if (sipdebug) 06884 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06885 } 06886 06887 if (sipmethod == SIP_CANCEL) 06888 c = p->initreq.rlPart2; /* Use original URI */ 06889 else if (sipmethod == SIP_ACK) { 06890 /* Use URI from Contact: in 200 OK (if INVITE) 06891 (we only have the contacturi on INVITEs) */ 06892 if (!ast_strlen_zero(p->okcontacturi)) 06893 c = is_strict ? p->route->hop : p->okcontacturi; 06894 else 06895 c = p->initreq.rlPart2; 06896 } else if (!ast_strlen_zero(p->okcontacturi)) 06897 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06898 else if (!ast_strlen_zero(p->uri)) 06899 c = p->uri; 06900 else { 06901 char *n; 06902 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06903 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06904 sizeof(stripped)); 06905 n = get_in_brackets(stripped); 06906 c = strsep(&n, ";"); /* trim ; and beyond */ 06907 } 06908 init_req(req, sipmethod, c); 06909 06910 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06911 06912 add_header(req, "Via", p->via); 06913 if (p->route) { 06914 set_destination(p, p->route->hop); 06915 add_route(req, is_strict ? p->route->next : p->route); 06916 } 06917 06918 ot = get_header(orig, "To"); 06919 of = get_header(orig, "From"); 06920 06921 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06922 as our original request, including tag (or presumably lack thereof) */ 06923 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06924 /* Add the proper tag if we don't have it already. If they have specified 06925 their tag, use it. Otherwise, use our own tag */ 06926 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06927 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06928 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06929 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06930 else 06931 snprintf(newto, sizeof(newto), "%s", ot); 06932 ot = newto; 06933 } 06934 06935 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06936 add_header(req, "From", of); 06937 add_header(req, "To", ot); 06938 } else { 06939 add_header(req, "From", ot); 06940 add_header(req, "To", of); 06941 } 06942 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06943 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06944 add_header(req, "Contact", p->our_contact); 06945 06946 copy_header(req, orig, "Call-ID"); 06947 add_header(req, "CSeq", tmp); 06948 06949 if (!ast_strlen_zero(global_useragent)) 06950 add_header(req, "User-Agent", global_useragent); 06951 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06952 06953 if (!ast_strlen_zero(p->rpid)) 06954 add_header(req, "Remote-Party-ID", p->rpid); 06955 06956 return 0; 06957 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6724 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().
06724 { 06725 /* Requirements for Contact header inclusion in responses generated 06726 * from the header tables found in the following RFCs. Where the 06727 * Contact header was marked mandatory (m) or optional (o) this 06728 * function returns 1. 06729 * 06730 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06731 * - RFC 2976 (INFO) 06732 * - RFC 3262 (PRACK) 06733 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06734 * - RFC 3311 (UPDATE) 06735 * - RFC 3428 (MESSAGE) 06736 * - RFC 3515 (REFER) 06737 * - RFC 3903 (PUBLISH) 06738 */ 06739 06740 switch (method) { 06741 /* 1xx, 2xx, 3xx, 485 */ 06742 case SIP_INVITE: 06743 case SIP_UPDATE: 06744 case SIP_SUBSCRIBE: 06745 case SIP_NOTIFY: 06746 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06747 return 1; 06748 break; 06749 06750 /* 2xx, 3xx, 485 */ 06751 case SIP_REGISTER: 06752 case SIP_OPTIONS: 06753 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06754 return 1; 06755 break; 06756 06757 /* 3xx, 485 */ 06758 case SIP_BYE: 06759 case SIP_PRACK: 06760 case SIP_MESSAGE: 06761 case SIP_PUBLISH: 06762 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06763 return 1; 06764 break; 06765 06766 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06767 case SIP_REFER: 06768 if (msg[0] >= '2' && msg[0] <= '6') 06769 return 1; 06770 break; 06771 06772 /* contact will not be included for everything else */ 06773 case SIP_ACK: 06774 case SIP_CANCEL: 06775 case SIP_INFO: 06776 case SIP_PING: 06777 default: 06778 return 0; 06779 } 06780 return 0; 06781 }
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 6785 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), 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, process_via(), sip_pvt::recv, resp_needs_contact(), sip_pvt::sa, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06786 { 06787 char newto[256]; 06788 const char *ot; 06789 06790 init_resp(resp, msg); 06791 copy_via_headers(p, resp, req, "Via"); 06792 if (msg[0] == '1' || msg[0] == '2') 06793 copy_all_header(resp, req, "Record-Route"); 06794 copy_header(resp, req, "From"); 06795 ot = get_header(req, "To"); 06796 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06797 /* Add the proper tag if we don't have it already. If they have specified 06798 their tag, use it. Otherwise, use our own tag */ 06799 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06800 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06801 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06802 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06803 else 06804 ast_copy_string(newto, ot, sizeof(newto)); 06805 ot = newto; 06806 } 06807 add_header(resp, "To", ot); 06808 copy_header(resp, req, "Call-ID"); 06809 copy_header(resp, req, "CSeq"); 06810 if (!ast_strlen_zero(global_useragent)) 06811 add_header(resp, "User-Agent", global_useragent); 06812 add_header(resp, "Allow", ALLOWED_METHODS); 06813 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06814 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06815 /* For registration responses, we also need expiry and 06816 contact info */ 06817 char tmp[256]; 06818 06819 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06820 add_header(resp, "Expires", tmp); 06821 if (p->expiry) { /* Only add contact if we have an expiry time */ 06822 char contact[SIPBUFSIZE]; 06823 const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact; 06824 char *brackets = strchr(contact_uri, '<'); 06825 snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry); 06826 add_header(resp, "Contact", contact); /* Not when we unregister */ 06827 } 06828 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06829 add_header(resp, "Contact", p->our_contact); 06830 } 06831 06832 /* default to routing the response to the address where the request 06833 * came from. Since we don't have a transport layer, we do this here. 06834 * The process_via() function will update the port to either the port 06835 * specified in the via header or the default port later on (per RFC 06836 * 3261 section 18.2.2). 06837 */ 06838 p->sa = p->recv; 06839 06840 if (process_via(p, req)) { 06841 ast_log(LOG_WARNING, "error processing via header, will send response to originating address\n"); 06842 } 06843 06844 return 0; 06845 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 17829 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.
17830 { 17831 /* If we're supposed to be stopped -- stay stopped */ 17832 if (monitor_thread == AST_PTHREADT_STOP) 17833 return 0; 17834 ast_mutex_lock(&monlock); 17835 if (monitor_thread == pthread_self()) { 17836 ast_mutex_unlock(&monlock); 17837 ast_log(LOG_WARNING, "Cannot kill myself\n"); 17838 return -1; 17839 } 17840 if (monitor_thread != AST_PTHREADT_NULL) { 17841 /* Wake up the thread */ 17842 pthread_kill(monitor_thread, SIGURG); 17843 } else { 17844 /* Start a new monitor */ 17845 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 17846 ast_mutex_unlock(&monlock); 17847 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 17848 return -1; 17849 } 17850 } 17851 ast_mutex_unlock(&monlock); 17852 return 0; 17853 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 2015 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.
02016 { 02017 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 02018 int reschedule = DEFAULT_RETRANS; 02019 int xmitres = 0; 02020 02021 /* Lock channel PVT */ 02022 ast_mutex_lock(&pkt->owner->lock); 02023 02024 if (pkt->retrans < MAX_RETRANS) { 02025 pkt->retrans++; 02026 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 02027 if (sipdebug && option_debug > 3) 02028 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); 02029 } else { 02030 int siptimer_a; 02031 02032 if (sipdebug && option_debug > 3) 02033 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 02034 if (!pkt->timer_a) 02035 pkt->timer_a = 2 ; 02036 else 02037 pkt->timer_a = 2 * pkt->timer_a; 02038 02039 /* For non-invites, a maximum of 4 secs */ 02040 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 02041 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 02042 siptimer_a = 4000; 02043 02044 /* Reschedule re-transmit */ 02045 reschedule = siptimer_a; 02046 if (option_debug > 3) 02047 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); 02048 } 02049 02050 if (sip_debug_test_pvt(pkt->owner)) { 02051 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 02052 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 02053 pkt->retrans, sip_nat_mode(pkt->owner), 02054 ast_inet_ntoa(dst->sin_addr), 02055 ntohs(dst->sin_port), pkt->data); 02056 } 02057 02058 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 02059 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 02060 if (xmitres == XMIT_ERROR) { 02061 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 02062 } else { 02063 ast_mutex_unlock(&pkt->owner->lock); 02064 return reschedule; 02065 } 02066 } 02067 /* Too many retries */ 02068 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 02069 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 02070 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); 02071 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 02072 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 02073 } 02074 if (xmitres == XMIT_ERROR) { 02075 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 02076 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02077 } else 02078 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02079 02080 pkt->retransid = -1; 02081 02082 if (ast_test_flag(pkt, FLAG_FATAL)) { 02083 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02084 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 02085 } 02086 02087 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02088 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02089 02090 if (pkt->owner->owner) { 02091 sip_alreadygone(pkt->owner); 02092 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); 02093 ast_queue_hangup(pkt->owner->owner); 02094 ast_channel_unlock(pkt->owner->owner); 02095 } else { 02096 /* If no channel owner, destroy now */ 02097 02098 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02099 if (pkt->method != SIP_OPTIONS) { 02100 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02101 sip_alreadygone(pkt->owner); 02102 if (option_debug) 02103 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02104 } 02105 } 02106 } 02107 02108 if (pkt->method == SIP_BYE) { 02109 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02110 sip_alreadygone(pkt->owner); 02111 if (pkt->owner->owner) 02112 ast_channel_unlock(pkt->owner->owner); 02113 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02114 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02115 } 02116 02117 /* In any case, go ahead and remove the packet */ 02118 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02119 if (cur == pkt) 02120 break; 02121 } 02122 if (cur) { 02123 if (prev) 02124 prev->next = cur->next; 02125 else 02126 pkt->owner->packets = cur->next; 02127 ast_mutex_unlock(&pkt->owner->lock); 02128 free(cur); 02129 pkt = NULL; 02130 } else 02131 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02132 if (pkt) 02133 ast_mutex_unlock(&pkt->owner->lock); 02134 return 0; 02135 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 17374 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().
17375 { 17376 struct sip_pvt *p = (struct sip_pvt *) data; 17377 int recount = 0; 17378 int nounlock = 0; 17379 int lockretry; 17380 17381 for (lockretry = 10; lockretry > 0; lockretry--) { 17382 ast_mutex_lock(&p->lock); 17383 17384 /* lock the owner if it has one -- we may need it */ 17385 /* because this is deadlock-prone, we need to try and unlock if failed */ 17386 if (!p->owner || !ast_channel_trylock(p->owner)) { 17387 break; /* locking succeeded */ 17388 } 17389 17390 if (lockretry != 1) { 17391 ast_mutex_unlock(&p->lock); 17392 /* Sleep for a very short amount of time */ 17393 usleep(1); 17394 } 17395 } 17396 17397 if (!lockretry) { 17398 int retry = !AST_LIST_EMPTY(&p->request_queue); 17399 17400 /* we couldn't get the owner lock, which is needed to process 17401 the queued requests, so return a non-zero value, which will 17402 cause the scheduler to run this request again later if there 17403 still requests to be processed 17404 */ 17405 ast_mutex_unlock(&p->lock); 17406 return retry; 17407 }; 17408 17409 process_request_queue(p, &recount, &nounlock); 17410 p->request_queue_sched_id = -1; 17411 17412 if (p->owner && !nounlock) { 17413 ast_channel_unlock(p->owner); 17414 } 17415 ast_mutex_unlock(&p->lock); 17416 17417 if (recount) { 17418 ast_update_use_count(); 17419 } 17420 17421 return 0; 17422 }
static int send_provisional_keepalive | ( | const void * | data | ) | [static] |
Definition at line 2459 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02460 { 02461 struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data; 02462 02463 return send_provisional_keepalive_full(d, 0); 02464 }
static int send_provisional_keepalive_full | ( | struct provisional_keepalive_data * | data, | |
int | with_sdp | |||
) | [static] |
This is called by the scheduler to resend the last provisional message in a dialog.
Definition at line 2406 of file chan_sip.c.
References ao2_ref(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), sip_request::data, sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, sip_pvt::lock, sip_pvt::owner, 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().
02407 { 02408 const char *msg = NULL; 02409 int res = 0; 02410 struct sip_pvt *pvt = data->pvt; 02411 02412 if (!pvt) { 02413 ao2_ref(data, -1); /* not rescheduling so drop ref. in this case the dialog has already dropped this ref */ 02414 return res; 02415 } 02416 02417 ast_mutex_lock(&pvt->lock); 02418 while (pvt->owner && ast_channel_trylock(pvt->owner)) { 02419 ast_mutex_unlock(&pvt->lock); 02420 sched_yield(); 02421 if ((pvt = data->pvt)) { 02422 ast_mutex_lock(&pvt->lock); 02423 } else { 02424 ao2_ref(data, -1); 02425 return res; 02426 } 02427 } 02428 02429 if (data->sched_id == -1 || pvt->invitestate >= INV_COMPLETED) { 02430 goto provisional_keepalive_cleanup; 02431 } 02432 02433 if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) { 02434 msg = "183 Session Progress"; 02435 } 02436 02437 if (with_sdp) { 02438 transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE); 02439 } else { 02440 transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq); 02441 } 02442 02443 res = PROVIS_KEEPALIVE_TIMEOUT; /* reschedule the keepalive event */ 02444 02445 provisional_keepalive_cleanup: 02446 if (!res) { /* not rescheduling, so drop ref */ 02447 data->sched_id = -1; /* if we don't re-schedule, make sure to remove the sched id */ 02448 ao2_ref(data, -1); /* release the scheduler's reference to this data */ 02449 } 02450 02451 if (pvt->owner) { 02452 ast_channel_unlock(pvt->owner); 02453 } 02454 ast_mutex_unlock(&pvt->lock); 02455 02456 return res; 02457 }
static int send_provisional_keepalive_with_sdp | ( | const void * | data | ) | [static] |
Definition at line 2466 of file chan_sip.c.
References send_provisional_keepalive_full().
Referenced by update_provisional_keepalive().
02467 { 02468 struct provisional_keepalive_data *d = (struct provisional_keepalive_data *) data; 02469 02470 return send_provisional_keepalive_full(d, 1); 02471 }
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 2567 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, finalize_content(), 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.
02568 { 02569 int res; 02570 02571 finalize_content(req); 02572 add_blank(req); 02573 if (sip_debug_test_pvt(p)) { 02574 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02575 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); 02576 else 02577 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); 02578 } 02579 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02580 struct sip_request tmp; 02581 parse_copy(&tmp, req); 02582 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02583 } 02584 res = (reliable) ? 02585 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02586 __sip_xmit(p, req->data, req->len); 02587 return res; 02588 }
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 2532 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, finalize_content(), sip_pvt::flags, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), remove_provisional_keepalive_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.
02533 { 02534 int res; 02535 02536 finalize_content(req); 02537 add_blank(req); 02538 if (sip_debug_test_pvt(p)) { 02539 const struct sockaddr_in *dst = sip_real_dst(p); 02540 02541 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02542 reliable ? "Reliably " : "", sip_nat_mode(p), 02543 ast_inet_ntoa(dst->sin_addr), 02544 ntohs(dst->sin_port), req->data); 02545 } 02546 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02547 struct sip_request tmp; 02548 parse_copy(&tmp, req); 02549 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02550 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02551 } 02552 02553 /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */ 02554 if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) { 02555 remove_provisional_keepalive_sched(p); 02556 } 02557 02558 res = (reliable) ? 02559 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02560 __sip_xmit(p, req->data, req->len); 02561 if (res > 0) 02562 return 0; 02563 return res; 02564 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 9052 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().
09053 { 09054 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 09055 /* NAT: Don't trust the contact field. Just use what they came to us 09056 with. */ 09057 pvt->sa = pvt->recv; 09058 return 0; 09059 } 09060 09061 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 09062 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 6634 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().
06635 { 06636 char *h, *maddr, hostname[256]; 06637 int port, hn; 06638 struct hostent *hp; 06639 struct ast_hostent ahp; 06640 int debug=sip_debug_test_pvt(p); 06641 06642 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 06643 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 06644 06645 if (debug) 06646 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 06647 06648 /* Find and parse hostname */ 06649 h = strchr(uri, '@'); 06650 if (h) 06651 ++h; 06652 else { 06653 h = uri; 06654 if (strncasecmp(h, "sip:", 4) == 0) 06655 h += 4; 06656 else if (strncasecmp(h, "sips:", 5) == 0) 06657 h += 5; 06658 } 06659 hn = strcspn(h, ":;>") + 1; 06660 if (hn > sizeof(hostname)) 06661 hn = sizeof(hostname); 06662 ast_copy_string(hostname, h, hn); 06663 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 06664 h += hn - 1; 06665 06666 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 06667 if (*h == ':') { 06668 /* Parse port */ 06669 ++h; 06670 port = strtol(h, &h, 10); 06671 } 06672 else 06673 port = STANDARD_SIP_PORT; 06674 06675 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06676 maddr = strstr(h, "maddr="); 06677 if (maddr) { 06678 maddr += 6; 06679 hn = strspn(maddr, "0123456789.") + 1; 06680 if (hn > sizeof(hostname)) 06681 hn = sizeof(hostname); 06682 ast_copy_string(hostname, maddr, hn); 06683 } 06684 06685 hp = ast_gethostbyname(hostname, &ahp); 06686 if (hp == NULL) { 06687 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06688 return; 06689 } 06690 p->sa.sin_family = AF_INET; 06691 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06692 p->sa.sin_port = htons(port); 06693 if (debug) 06694 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06695 }
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 18176 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().
18177 { 18178 static int dep_insecure_very = 0; 18179 static int dep_insecure_yes = 0; 18180 18181 if (ast_strlen_zero(value)) 18182 return; 18183 18184 if (!strcasecmp(value, "very")) { 18185 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 18186 if(!dep_insecure_very) { 18187 if(lineno != -1) 18188 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 18189 else 18190 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 18191 dep_insecure_very = 1; 18192 } 18193 } 18194 else if (ast_true(value)) { 18195 ast_set_flag(flags, SIP_INSECURE_PORT); 18196 if(!dep_insecure_yes) { 18197 if(lineno != -1) 18198 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 18199 else 18200 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 18201 dep_insecure_yes = 1; 18202 } 18203 } 18204 else if (!ast_false(value)) { 18205 char buf[64]; 18206 char *word, *next; 18207 ast_copy_string(buf, value, sizeof(buf)); 18208 next = buf; 18209 while ((word = strsep(&next, ","))) { 18210 if (!strcasecmp(word, "port")) 18211 ast_set_flag(flags, SIP_INSECURE_PORT); 18212 else if (!strcasecmp(word, "invite")) 18213 ast_set_flag(flags, SIP_INSECURE_INVITE); 18214 else 18215 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 18216 } 18217 } 18218 }
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 9390 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().
09391 { 09392 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 09393 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 09394 p->stalenonce = 0; 09395 } 09396 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 18611 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().
18612 { 18613 if (peer->expire == 0) { 18614 /* Don't reset expire or port time during reload 18615 if we have an active registration 18616 */ 18617 peer->expire = -1; 18618 peer->pokeexpire = -1; 18619 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 18620 } 18621 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 18622 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 18623 strcpy(peer->context, default_context); 18624 strcpy(peer->subscribecontext, default_subscribecontext); 18625 strcpy(peer->language, default_language); 18626 strcpy(peer->mohinterpret, default_mohinterpret); 18627 strcpy(peer->mohsuggest, default_mohsuggest); 18628 peer->addr.sin_family = AF_INET; 18629 peer->defaddr.sin_family = AF_INET; 18630 peer->capability = global_capability; 18631 peer->maxcallbitrate = default_maxcallbitrate; 18632 peer->rtptimeout = global_rtptimeout; 18633 peer->rtpholdtimeout = global_rtpholdtimeout; 18634 peer->rtpkeepalive = global_rtpkeepalive; 18635 peer->allowtransfer = global_allowtransfer; 18636 peer->autoframing = global_autoframing; 18637 strcpy(peer->vmexten, default_vmexten); 18638 peer->secret[0] = '\0'; 18639 peer->md5secret[0] = '\0'; 18640 peer->cid_num[0] = '\0'; 18641 peer->cid_name[0] = '\0'; 18642 peer->fromdomain[0] = '\0'; 18643 peer->fromuser[0] = '\0'; 18644 peer->regexten[0] = '\0'; 18645 peer->mailbox[0] = '\0'; 18646 peer->callgroup = 0; 18647 peer->pickupgroup = 0; 18648 peer->maxms = default_qualify; 18649 peer->prefs = default_prefs; 18650 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 19984 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().
19985 { 19986 int no = 0; 19987 int ok = FALSE; 19988 char varbuf[30]; 19989 char *inbuf = (char *) data; 19990 19991 if (ast_strlen_zero(inbuf)) { 19992 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 19993 return 0; 19994 } 19995 ast_channel_lock(chan); 19996 19997 /* Check for headers */ 19998 while (!ok && no <= 50) { 19999 no++; 20000 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 20001 20002 /* Compare without the leading underscores */ 20003 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 20004 ok = TRUE; 20005 } 20006 if (ok) { 20007 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 20008 if (sipdebug) 20009 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 20010 } else { 20011 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 20012 } 20013 ast_channel_unlock(chan); 20014 return 0; 20015 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2944 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02945 { 02946 /* We know name is the first field, so we can cast */ 02947 struct sip_peer *p = (struct sip_peer *) name; 02948 return !(!inaddrcmp(&p->addr, sin) || 02949 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02950 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02951 }
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 4870 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().
04872 { 04873 struct sip_pvt *p; 04874 04875 if (!(p = ast_calloc(1, sizeof(*p)))) 04876 return NULL; 04877 04878 if (ast_string_field_init(p, 512)) { 04879 free(p); 04880 return NULL; 04881 } 04882 04883 ast_mutex_init(&p->lock); 04884 04885 p->method = intended_method; 04886 p->initid = -1; 04887 p->waitid = -1; 04888 p->autokillid = -1; 04889 p->request_queue_sched_id = -1; 04890 p->subscribed = NONE; 04891 p->stateid = -1; 04892 p->prefs = default_prefs; /* Set default codecs for this call */ 04893 04894 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04895 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04896 04897 if (sin) { 04898 p->sa = *sin; 04899 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04900 p->ourip = __ourip; 04901 } else 04902 p->ourip = __ourip; 04903 04904 /* Copy global flags to this PVT at setup. */ 04905 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04906 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04907 04908 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04909 04910 p->branch = ast_random(); 04911 make_our_tag(p->tag, sizeof(p->tag)); 04912 p->ocseq = INITIAL_CSEQ; 04913 04914 if (sip_methods[intended_method].need_rtp) { 04915 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04916 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04917 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04918 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04919 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04920 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04921 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04922 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04923 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04924 /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */ 04925 if (p->rtp) { 04926 ast_rtp_destroy(p->rtp); 04927 } 04928 if (p->udptl) { 04929 ast_udptl_destroy(p->udptl); 04930 } 04931 ast_mutex_destroy(&p->lock); 04932 if (p->chanvars) { 04933 ast_variables_destroy(p->chanvars); 04934 p->chanvars = NULL; 04935 } 04936 ast_string_field_free_memory(p); 04937 free(p); 04938 return NULL; 04939 } 04940 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04941 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04942 ast_rtp_settos(p->rtp, global_tos_audio); 04943 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04944 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04945 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04946 if (p->vrtp) { 04947 ast_rtp_settos(p->vrtp, global_tos_video); 04948 ast_rtp_setdtmf(p->vrtp, 0); 04949 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04950 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04951 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04952 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04953 } 04954 if (p->udptl) 04955 ast_udptl_settos(p->udptl, global_tos_audio); 04956 p->maxcallbitrate = default_maxcallbitrate; 04957 p->autoframing = global_autoframing; 04958 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04959 } 04960 04961 if (useglobal_nat && sin) { 04962 /* Setup NAT structure according to global settings if we have an address */ 04963 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04964 p->recv = *sin; 04965 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04966 } 04967 04968 if (p->method != SIP_REGISTER) 04969 ast_string_field_set(p, fromdomain, default_fromdomain); 04970 build_via(p); 04971 if (!callid) 04972 build_callid_pvt(p); 04973 else 04974 ast_string_field_set(p, callid, callid); 04975 /* Assign default music on hold class */ 04976 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04977 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04978 p->capability = global_capability; 04979 p->allowtransfer = global_allowtransfer; 04980 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04981 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04982 p->noncodeccapability |= AST_RTP_DTMF; 04983 if (p->udptl) { 04984 p->t38.capability = global_t38_capability; 04985 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04986 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04987 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04988 p->t38.capability |= T38FAX_UDP_EC_FEC; 04989 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04990 p->t38.capability |= T38FAX_UDP_EC_NONE; 04991 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04992 p->t38.jointcapability = p->t38.capability; 04993 } 04994 ast_string_field_set(p, context, default_context); 04995 04996 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04997 04998 /* Add to active dialog list */ 04999 ast_mutex_lock(&iflock); 05000 p->next = iflist; 05001 iflist = p; 05002 ast_mutex_unlock(&iflock); 05003 if (option_debug) 05004 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"); 05005 return p; 05006 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1771 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().
01772 { 01773 if (option_debug > 2) 01774 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01775 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01776 }
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 4023 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), 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.
04024 { 04025 int res = 0; 04026 struct sip_pvt *p = ast->tech_pvt; 04027 04028 ast_mutex_lock(&p->lock); 04029 if (ast->_state != AST_STATE_UP) { 04030 try_suggested_sip_codec(p); 04031 04032 ast_setstate(ast, AST_STATE_UP); 04033 if (option_debug) 04034 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 04035 04036 ast_rtp_new_source(p->rtp); 04037 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 04038 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 04039 } 04040 ast_mutex_unlock(&p->lock); 04041 return res; 04042 }
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 3280 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.
03281 { 03282 int res, xmitres = 0; 03283 struct sip_pvt *p; 03284 struct varshead *headp; 03285 struct ast_var_t *current; 03286 const char *referer = NULL; /* SIP refererer */ 03287 03288 p = ast->tech_pvt; 03289 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03290 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03291 return -1; 03292 } 03293 03294 /* Check whether there is vxml_url, distinctive ring variables */ 03295 headp=&ast->varshead; 03296 AST_LIST_TRAVERSE(headp,current,entries) { 03297 /* Check whether there is a VXML_URL variable */ 03298 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03299 p->options->vxml_url = ast_var_value(current); 03300 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03301 p->options->uri_options = ast_var_value(current); 03302 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03303 /* Check whether there is a ALERT_INFO variable */ 03304 p->options->distinctive_ring = ast_var_value(current); 03305 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03306 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03307 p->options->addsipheaders = 1; 03308 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03309 /* This is a transfered call */ 03310 p->options->transfer = 1; 03311 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03312 /* This is the referer */ 03313 referer = ast_var_value(current); 03314 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03315 /* We're replacing a call. */ 03316 p->options->replaces = ast_var_value(current); 03317 } 03318 } 03319 03320 res = 0; 03321 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03322 03323 if (p->options->transfer) { 03324 char buf[SIPBUFSIZE/2]; 03325 03326 if (referer) { 03327 if (sipdebug && option_debug > 2) 03328 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03329 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03330 } else 03331 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03332 ast_string_field_set(p, cid_name, buf); 03333 } 03334 if (option_debug) 03335 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03336 03337 res = update_call_counter(p, INC_CALL_RINGING); 03338 if ( res != -1 ) { 03339 p->callingpres = ast->cid.cid_pres; 03340 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03341 p->jointnoncodeccapability = p->noncodeccapability; 03342 03343 /* If there are no audio formats left to offer, punt */ 03344 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03345 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03346 res = -1; 03347 } else { 03348 p->t38.jointcapability = p->t38.capability; 03349 if (option_debug > 1) 03350 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03351 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03352 if (xmitres == XMIT_ERROR) 03353 return -1; /* Transmission error */ 03354 03355 p->invitestate = INV_CALLING; 03356 03357 /* Initialize auto-congest time */ 03358 AST_SCHED_DEL(sched, p->initid); 03359 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03360 } 03361 } else { 03362 ast->hangupcause = AST_CAUSE_USER_BUSY; 03363 } 03364 return res; 03365 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2277 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), notify_extenstate_update(), register_verify(), and sip_hangup().
02278 { 02279 int res = 0; 02280 if (p->autokillid > -1) { 02281 if (!(res = ast_sched_del(sched, p->autokillid))) { 02282 append_history(p, "CancelDestroy", ""); 02283 p->autokillid = -1; 02284 } 02285 } 02286 return res; 02287 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1853 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01854 { 01855 if (!sipdebug) 01856 return 0; 01857 if (debugaddr.sin_addr.s_addr) { 01858 if (((ntohs(debugaddr.sin_port) != 0) 01859 && (debugaddr.sin_port != addr->sin_port)) 01860 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01861 return 0; 01862 } 01863 return 1; 01864 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1879 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_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01880 { 01881 if (!sipdebug) 01882 return 0; 01883 return sip_debug_test_addr(sip_real_dst(p)); 01884 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3659 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().
03660 { 03661 ast_mutex_lock(&iflock); 03662 if (option_debug > 2) 03663 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03664 __sip_destroy(p, 1); 03665 ast_mutex_unlock(&iflock); 03666 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2752 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, global_flags, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, sip_peer::name, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), 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().
02753 { 02754 if (option_debug > 2) 02755 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02756 02757 /* Delete it, it needs to disappear */ 02758 if (peer->call) 02759 sip_destroy(peer->call); 02760 02761 if (peer->mwipvt) /* We have an active subscription, delete it */ 02762 sip_destroy(peer->mwipvt); 02763 02764 if (peer->chanvars) { 02765 ast_variables_destroy(peer->chanvars); 02766 peer->chanvars = NULL; 02767 } 02768 02769 register_peer_exten(peer, FALSE); 02770 ast_free_ha(peer->ha); 02771 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02772 apeerobjs--; 02773 else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02774 rpeerobjs--; 02775 else 02776 speerobjs--; 02777 clear_realm_authentication(peer->auth); 02778 peer->auth = NULL; 02779 free(peer); 02780 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2972 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, global_flags, sip_user::ha, LOG_DEBUG, sip_user::name, option_debug, SIP_PAGE2_RTCACHEFRIENDS, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02973 { 02974 if (option_debug > 2) 02975 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02976 ast_free_ha(user->ha); 02977 if (user->chanvars) { 02978 ast_variables_destroy(user->chanvars); 02979 user->chanvars = NULL; 02980 } 02981 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && ast_test_flag(&user->flags[0], SIP_REALTIME)) 02982 ruserobjs--; 02983 else 02984 suserobjs--; 02985 free(user); 02986 }
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 18005 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().
18006 { 18007 char *host; 18008 char *tmp; 18009 18010 struct hostent *hp; 18011 struct ast_hostent ahp; 18012 struct sip_peer *p; 18013 18014 int res = AST_DEVICE_INVALID; 18015 18016 /* make sure data is not null. Maybe unnecessary, but better be safe */ 18017 host = ast_strdupa(data ? data : ""); 18018 if ((tmp = strchr(host, '@'))) 18019 host = tmp + 1; 18020 18021 if (option_debug > 2) 18022 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 18023 18024 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 18025 * is because when a peer tries to autoexpire, the last thing it does is to 18026 * queue up an event telling the system that the devicestate has changed 18027 * (presumably to unavailable). If we ask for a realtime peer here, this would 18028 * load it BACK into memory, thus defeating the point of trying to trying to 18029 * clear dead hosts out of memory. 18030 */ 18031 if ((p = find_peer(host, NULL, 0, 1))) { 18032 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 18033 /* we have an address for the peer */ 18034 18035 /* Check status in this order 18036 - Hold 18037 - Ringing 18038 - Busy (enforced only by call limit) 18039 - Inuse (we have a call) 18040 - Unreachable (qualify) 18041 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 18042 for registered devices */ 18043 18044 if (p->onHold) 18045 /* First check for hold or ring states */ 18046 res = AST_DEVICE_ONHOLD; 18047 else if (p->inRinging) { 18048 if (p->inRinging == p->inUse) 18049 res = AST_DEVICE_RINGING; 18050 else 18051 res = AST_DEVICE_RINGINUSE; 18052 } else if (p->call_limit && (p->inUse == p->call_limit)) 18053 /* check call limit */ 18054 res = AST_DEVICE_BUSY; 18055 else if (p->call_limit && p->inUse) 18056 /* Not busy, but we do have a call */ 18057 res = AST_DEVICE_INUSE; 18058 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 18059 /* We don't have a call. Are we reachable at all? Requires qualify= */ 18060 res = AST_DEVICE_UNAVAILABLE; 18061 else /* Default reply if we're registered and have no other data */ 18062 res = AST_DEVICE_NOT_INUSE; 18063 } else { 18064 /* there is no address, it's unavailable */ 18065 res = AST_DEVICE_UNAVAILABLE; 18066 } 18067 ASTOBJ_UNREF(p,sip_destroy_peer); 18068 } else { 18069 char *port = strchr(host, ':'); 18070 if (port) 18071 *port = '\0'; 18072 hp = ast_gethostbyname(host, &ahp); 18073 if (hp) 18074 res = AST_DEVICE_UNKNOWN; 18075 } 18076 18077 return res; 18078 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 12703 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.
12704 { 12705 int oldsipdebug = sipdebug_console; 12706 if (argc != 3) { 12707 if (argc != 5) 12708 return RESULT_SHOWUSAGE; 12709 else if (strcmp(argv[3], "ip") == 0) 12710 return sip_do_debug_ip(fd, argc, argv); 12711 else if (strcmp(argv[3], "peer") == 0) 12712 return sip_do_debug_peer(fd, argc, argv); 12713 else 12714 return RESULT_SHOWUSAGE; 12715 } 12716 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12717 memset(&debugaddr, 0, sizeof(debugaddr)); 12718 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12719 return RESULT_SUCCESS; 12720 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12722 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.
12723 { 12724 int oldsipdebug = sipdebug_console; 12725 char *newargv[6] = { "sip", "set", "debug", NULL }; 12726 if (argc != 2) { 12727 if (argc != 4) 12728 return RESULT_SHOWUSAGE; 12729 else if (strcmp(argv[2], "ip") == 0) { 12730 newargv[3] = argv[2]; 12731 newargv[4] = argv[3]; 12732 return sip_do_debug_ip(fd, argc + 1, newargv); 12733 } else if (strcmp(argv[2], "peer") == 0) { 12734 newargv[3] = argv[2]; 12735 newargv[4] = argv[3]; 12736 return sip_do_debug_peer(fd, argc + 1, newargv); 12737 } else 12738 return RESULT_SHOWUSAGE; 12739 } 12740 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12741 memset(&debugaddr, 0, sizeof(debugaddr)); 12742 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 12743 return RESULT_SUCCESS; 12744 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 12649 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().
12650 { 12651 struct hostent *hp; 12652 struct ast_hostent ahp; 12653 int port = 0; 12654 char *p, *arg; 12655 12656 /* sip set debug ip <ip> */ 12657 if (argc != 5) 12658 return RESULT_SHOWUSAGE; 12659 p = arg = argv[4]; 12660 strsep(&p, ":"); 12661 if (p) 12662 port = atoi(p); 12663 hp = ast_gethostbyname(arg, &ahp); 12664 if (hp == NULL) 12665 return RESULT_SHOWUSAGE; 12666 12667 debugaddr.sin_family = AF_INET; 12668 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 12669 debugaddr.sin_port = htons(port); 12670 if (port == 0) 12671 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 12672 else 12673 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 12674 12675 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12676 12677 return RESULT_SUCCESS; 12678 }
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 12681 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().
12682 { 12683 struct sip_peer *peer; 12684 if (argc != 5) 12685 return RESULT_SHOWUSAGE; 12686 peer = find_peer(argv[4], NULL, 1, 0); 12687 if (peer) { 12688 if (peer->addr.sin_addr.s_addr) { 12689 debugaddr.sin_family = AF_INET; 12690 debugaddr.sin_addr = peer->addr.sin_addr; 12691 debugaddr.sin_port = peer->addr.sin_port; 12692 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 12693 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12694 } else 12695 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 12696 ASTOBJ_UNREF(peer,sip_destroy_peer); 12697 } else 12698 ast_cli(fd, "No such peer '%s'\n", argv[4]); 12699 return RESULT_SUCCESS; 12700 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 12829 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
12830 { 12831 if (argc != 2) { 12832 return RESULT_SHOWUSAGE; 12833 } 12834 recordhistory = TRUE; 12835 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 12836 return RESULT_SUCCESS; 12837 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 20130 of file chan_sip.c.
References AST_SCHED_DEL, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNREF, peerl, reload_config(), sched, sip_destroy_peer(), and SIP_REALTIME.
Referenced by do_monitor().
20131 { 20132 reload_config(reason); 20133 20134 /* before peers are removed from the peer container, cancel any scheduled pokes */ 20135 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 20136 ASTOBJ_RDLOCK(iterator); 20137 if (ast_test_flag(&iterator->flags[0], SIP_REALTIME)) { 20138 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 20139 struct sip_peer *peer_ptr = iterator; 20140 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20141 } 20142 } 20143 ASTOBJ_UNLOCK(iterator); 20144 } while (0) ); 20145 20146 /* Prune peers who still are supposed to be deleted */ 20147 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 20148 if (option_debug > 3) 20149 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 20150 20151 /* Send qualify (OPTIONS) to all peers */ 20152 sip_poke_all_peers(); 20153 20154 /* Register with all services */ 20155 sip_send_all_registers(); 20156 20157 if (option_debug > 3) 20158 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 20159 20160 return 0; 20161 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 19929 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().
19930 { 19931 struct sip_pvt *p; 19932 char *mode; 19933 if (data) 19934 mode = (char *)data; 19935 else { 19936 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 19937 return 0; 19938 } 19939 ast_channel_lock(chan); 19940 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 19941 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 19942 ast_channel_unlock(chan); 19943 return 0; 19944 } 19945 p = chan->tech_pvt; 19946 if (!p) { 19947 ast_channel_unlock(chan); 19948 return 0; 19949 } 19950 ast_mutex_lock(&p->lock); 19951 if (!strcasecmp(mode,"info")) { 19952 ast_clear_flag(&p->flags[0], SIP_DTMF); 19953 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 19954 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19955 } else if (!strcasecmp(mode,"rfc2833")) { 19956 ast_clear_flag(&p->flags[0], SIP_DTMF); 19957 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 19958 p->jointnoncodeccapability |= AST_RTP_DTMF; 19959 } else if (!strcasecmp(mode,"inband")) { 19960 ast_clear_flag(&p->flags[0], SIP_DTMF); 19961 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 19962 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 19963 } else 19964 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 19965 if (p->rtp) 19966 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 19967 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 19968 if (!p->vad) { 19969 p->vad = ast_dsp_new(); 19970 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 19971 } 19972 } else { 19973 if (p->vad) { 19974 ast_dsp_free(p->vad); 19975 p->vad = NULL; 19976 } 19977 } 19978 ast_mutex_unlock(&p->lock); 19979 ast_channel_unlock(chan); 19980 return 0; 19981 }
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 12507 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().
12508 { 12509 int x = 0; 12510 struct sip_history *hist; 12511 static int errmsg = 0; 12512 12513 if (!dialog) 12514 return; 12515 12516 if (!option_debug && !sipdebug) { 12517 if (!errmsg) { 12518 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 12519 errmsg = 1; 12520 } 12521 return; 12522 } 12523 12524 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 12525 if (dialog->subscribed) 12526 ast_log(LOG_DEBUG, " * Subscription\n"); 12527 else 12528 ast_log(LOG_DEBUG, " * SIP Call\n"); 12529 if (dialog->history) 12530 AST_LIST_TRAVERSE(dialog->history, hist, list) 12531 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 12532 if (!x) 12533 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 12534 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 12535 }
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 4139 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.
04140 { 04141 int ret = -1; 04142 struct sip_pvt *p; 04143 04144 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 04145 ast_log(LOG_DEBUG, "New channel is zombie\n"); 04146 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 04147 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 04148 04149 if (!newchan || !newchan->tech_pvt) { 04150 if (!newchan) 04151 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 04152 else 04153 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 04154 return -1; 04155 } 04156 p = newchan->tech_pvt; 04157 04158 if (!p) { 04159 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 04160 return -1; 04161 } 04162 04163 ast_mutex_lock(&p->lock); 04164 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 04165 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 04166 if (p->owner != oldchan) 04167 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 04168 else { 04169 p->owner = newchan; 04170 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 04171 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 04172 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 04173 redirect of both channels). Note that a channel can not be masqueraded *into* 04174 a native bridge. So there is no danger that this breaks a native bridge that 04175 should stay up. */ 04176 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 04177 ret = 0; 04178 } 04179 if (option_debug > 2) 04180 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 04181 04182 ast_mutex_unlock(&p->lock); 04183 return ret; 04184 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 20074 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
20075 { 20076 struct sip_pvt *p = chan->tech_pvt; 20077 return p->jointcapability ? p->jointcapability : p->capability; 20078 }
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 19785 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.
19786 { 19787 struct sip_pvt *p = NULL; 19788 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19789 19790 if (!(p = chan->tech_pvt)) 19791 return AST_RTP_GET_FAILED; 19792 19793 ast_mutex_lock(&p->lock); 19794 if (!(p->rtp)) { 19795 ast_mutex_unlock(&p->lock); 19796 return AST_RTP_GET_FAILED; 19797 } 19798 19799 *rtp = p->rtp; 19800 19801 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 19802 res = AST_RTP_TRY_PARTIAL; 19803 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19804 res = AST_RTP_TRY_NATIVE; 19805 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 19806 res = AST_RTP_GET_FAILED; 19807 19808 ast_mutex_unlock(&p->lock); 19809 19810 return res; 19811 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 19637 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.
19638 { 19639 struct sip_pvt *p; 19640 struct ast_udptl *udptl = NULL; 19641 19642 p = chan->tech_pvt; 19643 if (!p) 19644 return NULL; 19645 19646 ast_mutex_lock(&p->lock); 19647 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19648 udptl = p->udptl; 19649 ast_mutex_unlock(&p->lock); 19650 return udptl; 19651 }
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 19814 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.
19815 { 19816 struct sip_pvt *p = NULL; 19817 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 19818 19819 if (!(p = chan->tech_pvt)) 19820 return AST_RTP_GET_FAILED; 19821 19822 ast_mutex_lock(&p->lock); 19823 if (!(p->vrtp)) { 19824 ast_mutex_unlock(&p->lock); 19825 return AST_RTP_GET_FAILED; 19826 } 19827 19828 *rtp = p->vrtp; 19829 19830 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 19831 res = AST_RTP_TRY_NATIVE; 19832 19833 ast_mutex_unlock(&p->lock); 19834 19835 return res; 19836 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 19689 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, LOG_ERROR, 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_DISABLED, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
19690 { 19691 struct sip_pvt *p; 19692 int flag = 0; 19693 19694 p = chan->tech_pvt; 19695 if (!p || !pvt->udptl) 19696 return -1; 19697 19698 /* Setup everything on the other side like offered/responded from first side */ 19699 ast_mutex_lock(&p->lock); 19700 19701 /*! \todo check if this is not set earlier when setting up the PVT. If not 19702 maybe it should move there. */ 19703 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 19704 19705 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 19706 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 19707 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 19708 19709 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 19710 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 19711 not really T38 re-invites which are different. In this 19712 case it's used properly, to see if we can reinvite over 19713 NAT 19714 */ 19715 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 19716 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 19717 flag =1; 19718 } else { 19719 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19720 } 19721 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 19722 if (!p->pendinginvite) { 19723 if (option_debug > 2) { 19724 if (flag) 19725 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)); 19726 else 19727 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)); 19728 } 19729 transmit_reinvite_with_t38_sdp(p); 19730 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19731 if (option_debug > 2) { 19732 if (flag) 19733 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)); 19734 else 19735 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)); 19736 } 19737 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19738 } 19739 } 19740 /* Reset lastrtprx timer */ 19741 p->lastrtprx = p->lastrtptx = time(NULL); 19742 ast_mutex_unlock(&p->lock); 19743 return 0; 19744 } else if (pvt->t38.state != T38_DISABLED) { /* If we are handling sending 200 OK to the other side of the bridge */ 19745 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 19746 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 19747 flag = 1; 19748 } else { 19749 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19750 } 19751 if (option_debug > 2) { 19752 if (flag) 19753 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)); 19754 else 19755 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)); 19756 } 19757 pvt->t38.state = T38_ENABLED; 19758 p->t38.state = T38_ENABLED; 19759 if (option_debug > 1) { 19760 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 19761 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 19762 } 19763 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 19764 p->lastrtprx = p->lastrtptx = time(NULL); 19765 ast_mutex_unlock(&p->lock); 19766 return 0; 19767 } else if (pvt->t38.state == T38_DISABLED) { /* The other side can not talk T.38 with us. We tell it to the the originating T.38 party with a 488 */ 19768 p->t38.state = T38_DISABLED; 19769 if (option_debug > 1) { 19770 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 19771 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 19772 } 19773 transmit_response_reliable(p, "488 Not acceptable here", &p->initreq); 19774 p->lastrtprx = p->lastrtptx = time(NULL); 19775 ast_mutex_unlock(&p->lock); 19776 return 0; 19777 } else { 19778 ast_log(LOG_ERROR, "Something went wrong with T.38. State is:%d on channel %s and %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>", p->t38.state, chan ? chan->name : "<none>"); 19779 ast_mutex_unlock(&p->lock); 19780 return 0; 19781 } 19782 }
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 3832 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, remove_provisional_keepalive_sched(), 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.
03833 { 03834 struct sip_pvt *p = ast->tech_pvt; 03835 int needcancel = FALSE; 03836 int needdestroy = 0; 03837 struct ast_channel *oldowner = ast; 03838 03839 if (!p) { 03840 if (option_debug) 03841 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03842 return 0; 03843 } 03844 03845 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03846 if (p->owner) 03847 p->hangupcause = p->owner->hangupcause; 03848 03849 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03850 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03851 if (option_debug && sipdebug) 03852 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03853 update_call_counter(p, DEC_CALL_LIMIT); 03854 } 03855 if (option_debug >3) 03856 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03857 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03858 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03859 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03860 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03861 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03862 p->owner->tech_pvt = NULL; 03863 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03864 ast_module_unref(ast_module_info->self); 03865 return 0; 03866 } 03867 if (option_debug) { 03868 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03869 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03870 else { 03871 if (option_debug) 03872 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03873 } 03874 } 03875 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03876 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03877 03878 ast_mutex_lock(&p->lock); 03879 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03880 if (option_debug && sipdebug) 03881 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03882 update_call_counter(p, DEC_CALL_LIMIT); 03883 } 03884 03885 /* Determine how to disconnect */ 03886 if (p->owner != ast) { 03887 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03888 ast_mutex_unlock(&p->lock); 03889 return 0; 03890 } 03891 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03892 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03893 needcancel = TRUE; 03894 if (option_debug > 3) 03895 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03896 } 03897 03898 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03899 03900 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03901 03902 /* Disconnect */ 03903 if (p->vad) 03904 ast_dsp_free(p->vad); 03905 03906 p->owner = NULL; 03907 ast->tech_pvt = NULL; 03908 03909 ast_module_unref(ast_module_info->self); 03910 03911 /* Do not destroy this pvt until we have timeout or 03912 get an answer to the BYE or INVITE/CANCEL 03913 If we get no answer during retransmit period, drop the call anyway. 03914 (Sorry, mother-in-law, you can't deny a hangup by sending 03915 603 declined to BYE...) 03916 */ 03917 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03918 needdestroy = 1; /* Set destroy flag at end of this function */ 03919 else if (p->invitestate != INV_CALLING) 03920 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03921 03922 /* Start the process if it's not already started */ 03923 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03924 if (needcancel) { /* Outgoing call, not up */ 03925 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03926 /* stop retransmitting an INVITE that has not received a response */ 03927 struct sip_pkt *cur; 03928 03929 /* if we can't send right now, mark it pending */ 03930 if (p->invitestate == INV_CALLING) { 03931 /* We can't send anything in CALLING state */ 03932 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03933 /* 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. */ 03934 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03935 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03936 } else { 03937 for (cur = p->packets; cur; cur = cur->next) { 03938 __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data)); 03939 } 03940 p->invitestate = INV_CANCELLED; 03941 /* Send a new request: CANCEL */ 03942 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03943 /* Actually don't destroy us yet, wait for the 487 on our original 03944 INVITE, but do set an autodestruct just in case we never get it. */ 03945 needdestroy = 0; 03946 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03947 } 03948 } else { /* Incoming call, not up */ 03949 const char *res; 03950 remove_provisional_keepalive_sched(p); 03951 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03952 transmit_response_reliable(p, res, &p->initreq); 03953 else 03954 transmit_response_reliable(p, "603 Declined", &p->initreq); 03955 p->invitestate = INV_TERMINATED; 03956 } 03957 } else { /* Call is in UP state, send BYE */ 03958 if (!p->pendinginvite) { 03959 char *audioqos = ""; 03960 char *videoqos = ""; 03961 if (p->rtp) 03962 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03963 if (p->vrtp) 03964 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03965 /* Send a hangup */ 03966 if (oldowner->_state == AST_STATE_UP) { 03967 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03968 } 03969 03970 /* Get RTCP quality before end of call */ 03971 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03972 if (p->rtp) 03973 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03974 if (p->vrtp) 03975 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03976 } 03977 if (p->rtp && oldowner) 03978 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03979 if (p->vrtp && oldowner) 03980 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03981 } else { 03982 /* Note we will need a BYE when this all settles out 03983 but we can't send one while we have "INVITE" outstanding. */ 03984 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03985 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03986 AST_SCHED_DEL(sched, p->waitid); 03987 if (sip_cancel_destroy(p)) 03988 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03989 } 03990 } 03991 } 03992 if (needdestroy) 03993 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03994 ast_mutex_unlock(&p->lock); 03995 return 0; 03996 }
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 4255 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_SRCCHANGE, 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_change_source(), 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.
04256 { 04257 struct sip_pvt *p = ast->tech_pvt; 04258 int res = 0; 04259 04260 ast_mutex_lock(&p->lock); 04261 switch(condition) { 04262 case AST_CONTROL_RINGING: 04263 if (ast->_state == AST_STATE_RING) { 04264 p->invitestate = INV_EARLY_MEDIA; 04265 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 04266 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 04267 /* Send 180 ringing if out-of-band seems reasonable */ 04268 transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); 04269 ast_set_flag(&p->flags[0], SIP_RINGING); 04270 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 04271 break; 04272 } else { 04273 /* Well, if it's not reasonable, just send in-band */ 04274 } 04275 } 04276 res = -1; 04277 break; 04278 case AST_CONTROL_BUSY: 04279 if (ast->_state != AST_STATE_UP) { 04280 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04281 p->invitestate = INV_COMPLETED; 04282 sip_alreadygone(p); 04283 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04284 break; 04285 } 04286 res = -1; 04287 break; 04288 case AST_CONTROL_CONGESTION: 04289 if (ast->_state != AST_STATE_UP) { 04290 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04291 p->invitestate = INV_COMPLETED; 04292 sip_alreadygone(p); 04293 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04294 break; 04295 } 04296 res = -1; 04297 break; 04298 case AST_CONTROL_PROCEEDING: 04299 if ((ast->_state != AST_STATE_UP) && 04300 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04301 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04302 transmit_response(p, "100 Trying", &p->initreq); 04303 p->invitestate = INV_PROCEEDING; 04304 break; 04305 } 04306 res = -1; 04307 break; 04308 case AST_CONTROL_PROGRESS: 04309 if ((ast->_state != AST_STATE_UP) && 04310 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04311 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04312 p->invitestate = INV_EARLY_MEDIA; 04313 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04314 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04315 break; 04316 } 04317 res = -1; 04318 break; 04319 case AST_CONTROL_HOLD: 04320 ast_rtp_new_source(p->rtp); 04321 ast_moh_start(ast, data, p->mohinterpret); 04322 break; 04323 case AST_CONTROL_UNHOLD: 04324 ast_rtp_new_source(p->rtp); 04325 ast_moh_stop(ast); 04326 break; 04327 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04328 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04329 transmit_info_with_vidupdate(p); 04330 /* ast_rtcp_send_h261fur(p->vrtp); */ 04331 } else 04332 res = -1; 04333 break; 04334 case AST_CONTROL_SRCUPDATE: 04335 ast_rtp_new_source(p->rtp); 04336 break; 04337 case AST_CONTROL_SRCCHANGE: 04338 ast_rtp_change_source(p->rtp); 04339 break; 04340 case -1: 04341 res = -1; 04342 break; 04343 default: 04344 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04345 res = -1; 04346 break; 04347 } 04348 ast_mutex_unlock(&p->lock); 04349 return res; 04350 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1873 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().
01874 { 01875 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01876 }
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 4358 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_exists_extension(), 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().
04359 { 04360 struct ast_channel *tmp; 04361 struct ast_variable *v = NULL; 04362 int fmt; 04363 int what; 04364 int needvideo = 0, video = 0; 04365 char *decoded_exten; 04366 04367 if (option_debug != 0) { 04368 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04369 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04370 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04371 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04372 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04373 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04374 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04375 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04376 } 04377 04378 { 04379 char my_name[128]; /* pick a good name */ 04380 const char *f, *fromdomain = NULL; 04381 04382 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04383 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04384 else 04385 fromdomain = i->fromdomain; 04386 04387 if (!ast_strlen_zero(i->username)) { 04388 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04389 /* title not empty and different from username */ 04390 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04391 } else { 04392 /* username not empty, title is empty or equal to username */ 04393 snprintf(my_name, sizeof(my_name), "%s", i->username); 04394 } 04395 } else { /* username empty */ 04396 if (!ast_strlen_zero(i->peername)) { 04397 /* call from unregisted peer */ 04398 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04399 } else { /* username and peername empty */ 04400 if (!ast_strlen_zero(title)) { /* title not empty */ 04401 snprintf(my_name, sizeof(my_name), "%s", title); 04402 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04403 f = i->from; 04404 if (!strncmp(f, "sip:", 4)) 04405 f += 4; 04406 snprintf(my_name, sizeof(my_name), "%s", f); 04407 } else { /* fallback to fromdomain */ 04408 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04409 } 04410 } 04411 } 04412 ast_mutex_unlock(&i->lock); 04413 /* Don't hold a sip pvt lock while we allocate a channel */ 04414 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)); 04415 04416 } 04417 if (!tmp) { 04418 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04419 ast_mutex_lock(&i->lock); 04420 return NULL; 04421 } 04422 ast_mutex_lock(&i->lock); 04423 04424 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04425 tmp->tech = &sip_tech_info; 04426 else 04427 tmp->tech = &sip_tech; 04428 04429 /* Select our native format based on codec preference until we receive 04430 something from another device to the contrary. */ 04431 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04432 what = i->jointcapability; 04433 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04434 } else if (i->capability) { /* Our configured capability for this peer */ 04435 what = i->capability; 04436 video = i->capability & AST_FORMAT_VIDEO_MASK; 04437 } else { 04438 what = global_capability; /* Global codec support */ 04439 video = global_capability & AST_FORMAT_VIDEO_MASK; 04440 } 04441 04442 /* Set the native formats for audio and merge in video */ 04443 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04444 if (option_debug > 2) { 04445 char buf[SIPBUFSIZE]; 04446 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04447 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04448 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04449 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04450 if (i->prefcodec) 04451 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04452 } 04453 04454 /* XXX Why are we choosing a codec from the native formats?? */ 04455 fmt = ast_best_codec(tmp->nativeformats); 04456 04457 /* If we have a prefcodec setting, we have an inbound channel that set a 04458 preferred format for this call. Otherwise, we check the jointcapability 04459 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04460 */ 04461 if (i->vrtp) { 04462 if (i->prefcodec) 04463 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04464 else 04465 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04466 } 04467 04468 if (option_debug > 2) { 04469 if (needvideo) 04470 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04471 else 04472 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04473 } 04474 04475 04476 04477 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04478 i->vad = ast_dsp_new(); 04479 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04480 if (global_relaxdtmf) 04481 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04482 } 04483 if (i->rtp) { 04484 tmp->fds[0] = ast_rtp_fd(i->rtp); 04485 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04486 } 04487 if (needvideo && i->vrtp) { 04488 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04489 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04490 } 04491 if (i->udptl) { 04492 tmp->fds[5] = ast_udptl_fd(i->udptl); 04493 } 04494 if (state == AST_STATE_RING) 04495 tmp->rings = 1; 04496 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04497 tmp->writeformat = fmt; 04498 tmp->rawwriteformat = fmt; 04499 tmp->readformat = fmt; 04500 tmp->rawreadformat = fmt; 04501 tmp->tech_pvt = i; 04502 04503 tmp->callgroup = i->callgroup; 04504 tmp->pickupgroup = i->pickupgroup; 04505 tmp->cid.cid_pres = i->callingpres; 04506 if (!ast_strlen_zero(i->accountcode)) 04507 ast_string_field_set(tmp, accountcode, i->accountcode); 04508 if (i->amaflags) 04509 tmp->amaflags = i->amaflags; 04510 if (!ast_strlen_zero(i->language)) 04511 ast_string_field_set(tmp, language, i->language); 04512 i->owner = tmp; 04513 ast_module_ref(ast_module_info->self); 04514 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04515 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04516 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04517 * structure so that there aren't issues when forming URI's 04518 */ 04519 if (ast_exists_extension(NULL, i->context, i->exten, 1, i->cid_num)) { 04520 /* encoded in dialplan, so keep extension encoded */ 04521 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04522 } else { 04523 decoded_exten = ast_strdupa(i->exten); 04524 ast_uri_decode(decoded_exten); 04525 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04526 } 04527 04528 /* Don't use ast_set_callerid() here because it will 04529 * generate an unnecessary NewCallerID event */ 04530 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04531 if (!ast_strlen_zero(i->rdnis)) 04532 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04533 04534 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04535 tmp->cid.cid_dnid = ast_strdup(i->exten); 04536 04537 tmp->priority = 1; 04538 if (!ast_strlen_zero(i->uri)) 04539 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04540 if (!ast_strlen_zero(i->domain)) 04541 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04542 if (!ast_strlen_zero(i->useragent)) 04543 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04544 if (!ast_strlen_zero(i->callid)) 04545 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04546 if (i->rtp) 04547 ast_jb_configure(tmp, &global_jbconf); 04548 04549 /* Set channel variables for this call from configuration */ 04550 for (v = i->chanvars ; v ; v = v->next) 04551 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04552 04553 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04554 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04555 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04556 ast_hangup(tmp); 04557 tmp = NULL; 04558 } 04559 04560 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04561 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04562 04563 return tmp; 04564 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 12810 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12811 { 12812 if (argc != 4) 12813 return RESULT_SHOWUSAGE; 12814 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12815 ast_cli(fd, "SIP Debugging Disabled\n"); 12816 return RESULT_SUCCESS; 12817 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 12819 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
12820 { 12821 if (argc != 3) 12822 return RESULT_SHOWUSAGE; 12823 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 12824 ast_cli(fd, "SIP Debugging Disabled\n"); 12825 return RESULT_SUCCESS; 12826 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 12840 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
12841 { 12842 if (argc != 3) { 12843 return RESULT_SHOWUSAGE; 12844 } 12845 recordhistory = FALSE; 12846 ast_cli(fd, "SIP History Recording Disabled\n"); 12847 return RESULT_SUCCESS; 12848 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 12747 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_DEBUG, notify_types, option_debug, RESULT_FAILURE, RESULT_SHOWUSAGE, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
12748 { 12749 struct ast_variable *varlist; 12750 int i; 12751 12752 if (argc < 4) 12753 return RESULT_SHOWUSAGE; 12754 12755 if (!notify_types) { 12756 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 12757 return RESULT_FAILURE; 12758 } 12759 12760 varlist = ast_variable_browse(notify_types, argv[2]); 12761 12762 if (!varlist) { 12763 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 12764 return RESULT_FAILURE; 12765 } 12766 12767 for (i = 3; i < argc; i++) { 12768 struct sip_pvt *p; 12769 struct sip_request req; 12770 struct ast_variable *var; 12771 12772 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 12773 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 12774 return RESULT_FAILURE; 12775 } 12776 12777 if (create_addr(p, argv[i], NULL)) { 12778 /* Maybe they're not registered, etc. */ 12779 sip_destroy(p); 12780 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 12781 continue; 12782 } 12783 12784 initreqprep(&req, p, SIP_NOTIFY); 12785 12786 for (var = varlist; var; var = var->next) { 12787 if (!strcasecmp(var->name, "Content-Length")) { 12788 if (option_debug >= 2) { 12789 ast_log(LOG_DEBUG, "Ignoring pair %s=%s\n", var->name, var->value); 12790 } 12791 continue; /* ignore content-length, it is calculated automatically */ 12792 } 12793 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 12794 } 12795 12796 /* Recalculate our side, and recalculate Call ID */ 12797 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 12798 p->ourip = __ourip; 12799 build_via(p); 12800 build_callid_pvt(p); 12801 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 12802 transmit_sip_request(p, &req); 12803 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12804 } 12805 12806 return RESULT_SUCCESS; 12807 }
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 14643 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_free, ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, 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().
14644 { 14645 struct sip_dual *d; 14646 struct ast_channel *transferee, *transferer; 14647 /* Chan2m: The transferer, chan1m: The transferee */ 14648 pthread_t th; 14649 pthread_attr_t attr; 14650 14651 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 14652 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 14653 if ((!transferer) || (!transferee)) { 14654 if (transferee) { 14655 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14656 ast_hangup(transferee); 14657 } 14658 if (transferer) { 14659 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14660 ast_hangup(transferer); 14661 } 14662 return -1; 14663 } 14664 14665 /* Make formats okay */ 14666 transferee->readformat = chan1->readformat; 14667 transferee->writeformat = chan1->writeformat; 14668 14669 /* Prepare for taking over the channel */ 14670 ast_channel_masquerade(transferee, chan1); 14671 14672 /* Setup the extensions and such */ 14673 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 14674 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 14675 transferee->priority = chan1->priority; 14676 14677 /* We make a clone of the peer channel too, so we can play 14678 back the announcement */ 14679 14680 /* Make formats okay */ 14681 transferer->readformat = chan2->readformat; 14682 transferer->writeformat = chan2->writeformat; 14683 14684 /* Prepare for taking over the channel. Go ahead and grab this channel 14685 * lock here to avoid a deadlock with callbacks into the channel driver 14686 * that hold the channel lock and want the pvt lock. */ 14687 while (ast_channel_trylock(chan2)) { 14688 struct sip_pvt *pvt = chan2->tech_pvt; 14689 DEADLOCK_AVOIDANCE(&pvt->lock); 14690 } 14691 ast_channel_masquerade(transferer, chan2); 14692 ast_channel_unlock(chan2); 14693 14694 /* Setup the extensions and such */ 14695 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 14696 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 14697 transferer->priority = chan2->priority; 14698 14699 ast_channel_lock(transferer); 14700 if (ast_do_masquerade(transferer)) { 14701 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 14702 ast_channel_unlock(transferer); 14703 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14704 ast_hangup(transferer); 14705 return -1; 14706 } 14707 ast_channel_unlock(transferer); 14708 if (!transferer || !transferee) { 14709 if (!transferer) { 14710 if (option_debug) 14711 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 14712 } 14713 if (!transferee) { 14714 if (option_debug) 14715 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 14716 } 14717 return -1; 14718 } 14719 if (!(d = ast_calloc(1, sizeof(*d)))) { 14720 return -1; 14721 } 14722 14723 pthread_attr_init(&attr); 14724 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 14725 14726 /* Save original request for followup */ 14727 copy_request(&d->req, req); 14728 d->chan1 = transferee; /* Transferee */ 14729 d->chan2 = transferer; /* Transferer */ 14730 d->seqno = seqno; 14731 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 14732 /* Could not start thread */ 14733 ast_free(d); /* We don't need it anymore. If thread is created, d will be free'd 14734 by sip_park_thread() */ 14735 pthread_attr_destroy(&attr); 14736 return -1; 14737 } 14738 pthread_attr_destroy(&attr); 14739 14740 return 0; 14741 }
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 14575 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, 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().
14576 { 14577 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 14578 struct sip_dual *d; 14579 struct sip_request req; 14580 int ext; 14581 int res; 14582 14583 d = stuff; 14584 transferee = d->chan1; 14585 transferer = d->chan2; 14586 copy_request(&req, &d->req); 14587 14588 if (!transferee || !transferer) { 14589 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 14590 ast_free(d); 14591 return NULL; 14592 } 14593 if (option_debug > 3) 14594 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 14595 14596 ast_channel_lock(transferee); 14597 if (ast_do_masquerade(transferee)) { 14598 ast_log(LOG_WARNING, "Masquerade failed.\n"); 14599 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 14600 ast_channel_unlock(transferee); 14601 ast_free(d); 14602 return NULL; 14603 } 14604 ast_channel_unlock(transferee); 14605 14606 res = ast_park_call(transferee, transferer, 0, &ext); 14607 14608 14609 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 14610 if (!res) { 14611 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 14612 } else { 14613 /* Then tell the transferer what happened */ 14614 sprintf(buf, "Call parked on extension '%d'", ext); 14615 transmit_message_with_text(transferer->tech_pvt, buf); 14616 } 14617 #endif 14618 14619 /* Any way back to the current call??? */ 14620 /* Transmit response to the REFER request */ 14621 if (!res) { 14622 /* Transfer succeeded */ 14623 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 14624 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 14625 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14626 ast_hangup(transferer); /* This will cause a BYE */ 14627 if (option_debug) 14628 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 14629 } else { 14630 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 14631 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 14632 if (option_debug) 14633 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 14634 /* Do not hangup call */ 14635 } 14636 ast_free(d); 14637 return NULL; 14638 }
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 9582 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().
09583 { 09584 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 09585 09586 if (!peer) 09587 return; 09588 09589 /* If they put someone on hold, increment the value... otherwise decrement it */ 09590 if (hold) 09591 peer->onHold++; 09592 else 09593 peer->onHold--; 09594 09595 /* Request device state update */ 09596 ast_device_state_changed("SIP/%s", peer->name); 09597 09598 return; 09599 }
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 20084 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().
20085 { 20086 int ms = 0; 20087 20088 if (!speerobjs) /* No peers, just give up */ 20089 return; 20090 20091 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 20092 ASTOBJ_WRLOCK(iterator); 20093 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 20094 struct sip_peer *peer_ptr = iterator; 20095 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20096 } 20097 ms += 100; 20098 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 20099 if (iterator->pokeexpire == -1) { 20100 struct sip_peer *peer_ptr = iterator; 20101 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 20102 } 20103 ASTOBJ_UNLOCK(iterator); 20104 } while (0) 20105 ); 20106 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 17856 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().
17857 { 17858 struct sip_peer *peer = (struct sip_peer *)data; 17859 17860 peer->pokeexpire = -1; 17861 if (peer->lastms > -1) { 17862 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 17863 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 17864 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 17865 } 17866 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 17867 } 17868 if (peer->call) 17869 sip_destroy(peer->call); 17870 peer->call = NULL; 17871 17872 /* Don't send a devstate change if nothing changed. */ 17873 if (peer->lastms > -1) { 17874 peer->lastms = -1; 17875 ast_device_state_changed("SIP/%s", peer->name); 17876 } 17877 17878 /* This function gets called one place outside of the scheduler ... */ 17879 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17880 struct sip_peer *peer_ptr = peer; 17881 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17882 } 17883 17884 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 17885 * inherit the reference that the current callback already has. */ 17886 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 17887 if (peer->pokeexpire == -1) { 17888 ASTOBJ_UNREF(peer, sip_destroy_peer); 17889 } 17890 17891 return 0; 17892 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 17897 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().
17898 { 17899 struct sip_pvt *p; 17900 int xmitres = 0; 17901 17902 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 17903 /* IF we have no IP, or this isn't to be monitored, return 17904 imeediately after clearing things out */ 17905 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17906 struct sip_peer *peer_ptr = peer; 17907 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17908 } 17909 peer->lastms = 0; 17910 peer->call = NULL; 17911 return 0; 17912 } 17913 if (peer->call) { 17914 if (sipdebug) 17915 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 17916 sip_destroy(peer->call); 17917 } 17918 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 17919 return -1; 17920 17921 p->sa = peer->addr; 17922 p->recv = peer->addr; 17923 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 17924 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17925 17926 /* Send OPTIONs to peer's fullcontact */ 17927 if (!ast_strlen_zero(peer->fullcontact)) 17928 ast_string_field_set(p, fullcontact, peer->fullcontact); 17929 17930 if (!ast_strlen_zero(peer->tohost)) 17931 ast_string_field_set(p, tohost, peer->tohost); 17932 else 17933 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 17934 17935 /* Recalculate our side, and recalculate Call ID */ 17936 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17937 p->ourip = __ourip; 17938 build_via(p); 17939 build_callid_pvt(p); 17940 17941 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17942 struct sip_peer *peer_ptr = peer; 17943 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17944 } 17945 17946 p->relatedpeer = ASTOBJ_REF(peer); 17947 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17948 #ifdef VOCAL_DATA_HACK 17949 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 17950 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 17951 #else 17952 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 17953 #endif 17954 gettimeofday(&peer->ps, NULL); 17955 if (xmitres == XMIT_ERROR) { 17956 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 17957 } else { 17958 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 17959 struct sip_peer *peer_ptr = peer; 17960 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17961 } 17962 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 17963 if (peer->pokeexpire == -1) { 17964 struct sip_peer *peer_ptr = peer; 17965 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17966 } 17967 } 17968 17969 return 0; 17970 }
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 8880 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, sip_peer::name, peerl, 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().
08881 { 08882 struct sip_peer *peer = (struct sip_peer *) data; 08883 struct sip_peer *foundpeer; 08884 08885 peer->pokeexpire = -1; 08886 08887 foundpeer = ASTOBJ_CONTAINER_FIND(&peerl, peer->name); 08888 if (!foundpeer) { 08889 ASTOBJ_UNREF(peer, sip_destroy_peer); 08890 return 0; 08891 } else if (foundpeer->name != peer->name) { 08892 ASTOBJ_UNREF(foundpeer, sip_destroy_peer); 08893 ASTOBJ_UNREF(peer, sip_destroy_peer); 08894 return 0; 08895 } 08896 08897 ASTOBJ_UNREF(foundpeer, sip_destroy_peer); 08898 sip_poke_peer(peer); 08899 ASTOBJ_UNREF(peer, sip_destroy_peer); 08900 08901 return 0; 08902 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 11513 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.
11514 { 11515 struct sip_peer *peer; 11516 struct sip_user *user; 11517 int pruneuser = FALSE; 11518 int prunepeer = FALSE; 11519 int multi = FALSE; 11520 char *name = NULL; 11521 regex_t regexbuf; 11522 int havepattern = 0; 11523 11524 switch (argc) { 11525 case 4: 11526 if (!strcasecmp(argv[3], "user")) 11527 return RESULT_SHOWUSAGE; 11528 if (!strcasecmp(argv[3], "peer")) 11529 return RESULT_SHOWUSAGE; 11530 if (!strcasecmp(argv[3], "like")) 11531 return RESULT_SHOWUSAGE; 11532 if (!strcasecmp(argv[3], "all")) { 11533 multi = TRUE; 11534 pruneuser = prunepeer = TRUE; 11535 } else { 11536 pruneuser = prunepeer = TRUE; 11537 name = argv[3]; 11538 } 11539 break; 11540 case 5: 11541 if (!strcasecmp(argv[4], "like")) 11542 return RESULT_SHOWUSAGE; 11543 if (!strcasecmp(argv[3], "all")) 11544 return RESULT_SHOWUSAGE; 11545 if (!strcasecmp(argv[3], "like")) { 11546 multi = TRUE; 11547 name = argv[4]; 11548 pruneuser = prunepeer = TRUE; 11549 } else if (!strcasecmp(argv[3], "user")) { 11550 pruneuser = TRUE; 11551 if (!strcasecmp(argv[4], "all")) 11552 multi = TRUE; 11553 else 11554 name = argv[4]; 11555 } else if (!strcasecmp(argv[3], "peer")) { 11556 prunepeer = TRUE; 11557 if (!strcasecmp(argv[4], "all")) 11558 multi = TRUE; 11559 else 11560 name = argv[4]; 11561 } else 11562 return RESULT_SHOWUSAGE; 11563 break; 11564 case 6: 11565 if (strcasecmp(argv[4], "like")) 11566 return RESULT_SHOWUSAGE; 11567 if (!strcasecmp(argv[3], "user")) { 11568 pruneuser = TRUE; 11569 name = argv[5]; 11570 } else if (!strcasecmp(argv[3], "peer")) { 11571 prunepeer = TRUE; 11572 name = argv[5]; 11573 } else 11574 return RESULT_SHOWUSAGE; 11575 break; 11576 default: 11577 return RESULT_SHOWUSAGE; 11578 } 11579 11580 if (multi && name) { 11581 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) { 11582 return RESULT_SHOWUSAGE; 11583 } 11584 havepattern = 1; 11585 } 11586 11587 if (multi) { 11588 if (prunepeer) { 11589 int pruned = 0; 11590 11591 ASTOBJ_CONTAINER_WRLOCK(&peerl); 11592 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11593 ASTOBJ_RDLOCK(iterator); 11594 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11595 ASTOBJ_UNLOCK(iterator); 11596 continue; 11597 }; 11598 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11599 ASTOBJ_MARK(iterator); 11600 pruned++; 11601 } 11602 ASTOBJ_UNLOCK(iterator); 11603 } while (0) ); 11604 if (pruned) { 11605 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 11606 ast_cli(fd, "%d peers pruned.\n", pruned); 11607 } else 11608 ast_cli(fd, "No peers found to prune.\n"); 11609 ASTOBJ_CONTAINER_UNLOCK(&peerl); 11610 } 11611 if (pruneuser) { 11612 int pruned = 0; 11613 11614 ASTOBJ_CONTAINER_WRLOCK(&userl); 11615 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11616 ASTOBJ_RDLOCK(iterator); 11617 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11618 ASTOBJ_UNLOCK(iterator); 11619 continue; 11620 }; 11621 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11622 ASTOBJ_MARK(iterator); 11623 pruned++; 11624 } 11625 ASTOBJ_UNLOCK(iterator); 11626 } while (0) ); 11627 if (pruned) { 11628 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 11629 ast_cli(fd, "%d users pruned.\n", pruned); 11630 } else 11631 ast_cli(fd, "No users found to prune.\n"); 11632 ASTOBJ_CONTAINER_UNLOCK(&userl); 11633 } 11634 } else { 11635 if (prunepeer) { 11636 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 11637 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11638 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 11639 ASTOBJ_CONTAINER_LINK(&peerl, peer); 11640 } else 11641 ast_cli(fd, "Peer '%s' pruned.\n", name); 11642 ASTOBJ_UNREF(peer, sip_destroy_peer); 11643 } else 11644 ast_cli(fd, "Peer '%s' not found.\n", name); 11645 } 11646 if (pruneuser) { 11647 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 11648 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 11649 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 11650 ASTOBJ_CONTAINER_LINK(&userl, user); 11651 } else 11652 ast_cli(fd, "User '%s' pruned.\n", name); 11653 ASTOBJ_UNREF(user, sip_destroy_user); 11654 } else 11655 ast_cli(fd, "User '%s' not found.\n", name); 11656 } 11657 } 11658 11659 if (havepattern) { 11660 regfree(®exbuf); 11661 } 11662 11663 return RESULT_SUCCESS; 11664 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4790 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().
04791 { 04792 struct ast_frame *fr; 04793 struct sip_pvt *p = ast->tech_pvt; 04794 int faxdetected = FALSE; 04795 04796 ast_mutex_lock(&p->lock); 04797 fr = sip_rtp_read(ast, p, &faxdetected); 04798 p->lastrtprx = time(NULL); 04799 04800 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04801 /* 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 */ 04802 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04803 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04804 if (!p->pendinginvite) { 04805 if (option_debug > 2) 04806 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04807 p->t38.state = T38_LOCAL_REINVITE; 04808 transmit_reinvite_with_t38_sdp(p); 04809 if (option_debug > 1) 04810 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04811 } 04812 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04813 if (option_debug > 2) 04814 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04815 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04816 } 04817 } 04818 04819 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04820 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04821 fr = &ast_null_frame; 04822 } 04823 04824 ast_mutex_unlock(&p->lock); 04825 return fr; 04826 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1867 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().
01868 { 01869 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01870 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8685 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().
08686 { 08687 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08688 return p->refer ? 1 : 0; 08689 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 8423 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().
08424 { 08425 08426 /* if we are here, our registration timed out, so we'll just do it over */ 08427 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 08428 struct sip_pvt *p; 08429 int res; 08430 08431 /* if we couldn't get a reference to the registry object, punt */ 08432 if (!r) 08433 return 0; 08434 08435 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 08436 if (r->call) { 08437 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 08438 in the single SIP manager thread. */ 08439 p = r->call; 08440 ast_mutex_lock(&p->lock); 08441 if (p->registry) 08442 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 08443 r->call = NULL; 08444 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 08445 /* Pretend to ACK anything just in case */ 08446 __sip_pretend_ack(p); 08447 ast_mutex_unlock(&p->lock); 08448 } 08449 /* If we have a limit, stop registration and give up */ 08450 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 08451 /* Ok, enough is enough. Don't try any more */ 08452 /* We could add an external notification here... 08453 steal it from app_voicemail :-) */ 08454 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 08455 r->regstate = REG_STATE_FAILED; 08456 } else { 08457 r->regstate = REG_STATE_UNREGISTERED; 08458 r->timeout = -1; 08459 r->needdns = TRUE; 08460 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 08461 } 08462 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)); 08463 ASTOBJ_UNREF(r, sip_registry_destroy); 08464 return 0; 08465 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 5308 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.
05309 { 05310 struct sip_registry *reg; 05311 int portnum = 0; 05312 char username[256] = ""; 05313 char *hostname=NULL, *secret=NULL, *authuser=NULL; 05314 char *porta=NULL; 05315 char *contact=NULL; 05316 05317 if (!value) 05318 return -1; 05319 ast_copy_string(username, value, sizeof(username)); 05320 /* First split around the last '@' then parse the two components. */ 05321 hostname = strrchr(username, '@'); /* allow @ in the first part */ 05322 if (hostname) 05323 *hostname++ = '\0'; 05324 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 05325 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 05326 return -1; 05327 } 05328 /* split user[:secret[:authuser]] */ 05329 secret = strchr(username, ':'); 05330 if (secret) { 05331 *secret++ = '\0'; 05332 authuser = strchr(secret, ':'); 05333 if (authuser) 05334 *authuser++ = '\0'; 05335 } 05336 /* split host[:port][/contact] */ 05337 contact = strchr(hostname, '/'); 05338 if (contact) 05339 *contact++ = '\0'; 05340 if (ast_strlen_zero(contact)) 05341 contact = "s"; 05342 porta = strchr(hostname, ':'); 05343 if (porta) { 05344 *porta++ = '\0'; 05345 portnum = atoi(porta); 05346 if (portnum == 0) { 05347 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05348 return -1; 05349 } 05350 } 05351 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 05352 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 05353 return -1; 05354 } 05355 05356 if (ast_string_field_init(reg, 256)) { 05357 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 05358 free(reg); 05359 return -1; 05360 } 05361 05362 regobjs++; 05363 ASTOBJ_INIT(reg); 05364 ast_string_field_set(reg, contact, contact); 05365 if (!ast_strlen_zero(username)) 05366 ast_string_field_set(reg, username, username); 05367 if (hostname) 05368 ast_string_field_set(reg, hostname, hostname); 05369 if (authuser) 05370 ast_string_field_set(reg, authuser, authuser); 05371 if (secret) 05372 ast_string_field_set(reg, secret, secret); 05373 reg->expire = -1; 05374 reg->timeout = -1; 05375 reg->refresh = default_expiry; 05376 reg->portno = portnum; 05377 reg->callid_valid = FALSE; 05378 reg->ocseq = INITIAL_CSEQ; 05379 reg->needdns = TRUE; 05380 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 05381 ASTOBJ_UNREF(reg,sip_registry_destroy); 05382 return 0; 05383 }
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 3369 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().
03370 { 03371 /* Really delete */ 03372 if (option_debug > 2) 03373 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03374 03375 if (reg->call) { 03376 /* Clear registry before destroying to ensure 03377 we don't get reentered trying to grab the registry lock */ 03378 reg->call->registry = NULL; 03379 if (option_debug > 2) 03380 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03381 sip_destroy(reg->call); 03382 } 03383 AST_SCHED_DEL(sched, reg->expire); 03384 AST_SCHED_DEL(sched, reg->timeout); 03385 ast_string_field_free_memory(reg); 03386 regobjs--; 03387 free(reg); 03388 03389 }
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 13494 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, sip_pvt::owner, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
13495 { 13496 struct sip_pvt *p = (struct sip_pvt *) data; 13497 struct ast_channel *owner; 13498 13499 ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ 13500 while ((owner = p->owner) && ast_channel_trylock(owner)) { 13501 ast_mutex_unlock(&p->lock); 13502 usleep(1); 13503 ast_mutex_lock(&p->lock); 13504 } 13505 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 13506 p->waitid = -1; 13507 check_pendings(p); 13508 ast_mutex_unlock(&p->lock); 13509 if (owner) { 13510 ast_channel_unlock(owner); 13511 } 13512 13513 return 0; 13514 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 20164 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().
20165 { 20166 ast_mutex_lock(&sip_reload_lock); 20167 if (sip_reloading) 20168 ast_verbose("Previous SIP reload not yet done\n"); 20169 else { 20170 sip_reloading = TRUE; 20171 if (fd) 20172 sip_reloadreason = CHANNEL_CLI_RELOAD; 20173 else 20174 sip_reloadreason = CHANNEL_MODULE_RELOAD; 20175 } 20176 ast_mutex_unlock(&sip_reload_lock); 20177 restart_monitor(); 20178 20179 return 0; 20180 }
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 18082 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CHANNEL_UNACCEPTABLE, 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.
18083 { 18084 int oldformat; 18085 struct sip_pvt *p; 18086 struct ast_channel *tmpc = NULL; 18087 char *ext, *host; 18088 char tmp[256]; 18089 char *dest = data; 18090 18091 oldformat = format; 18092 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 18093 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)); 18094 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 18095 return NULL; 18096 } 18097 if (option_debug) 18098 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 18099 18100 if (ast_strlen_zero(dest)) { 18101 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n"); 18102 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE; 18103 return NULL; 18104 } 18105 18106 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 18107 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 18108 *cause = AST_CAUSE_SWITCH_CONGESTION; 18109 return NULL; 18110 } 18111 18112 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 18113 18114 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 18115 sip_destroy(p); 18116 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 18117 *cause = AST_CAUSE_SWITCH_CONGESTION; 18118 return NULL; 18119 } 18120 18121 ast_copy_string(tmp, dest, sizeof(tmp)); 18122 host = strchr(tmp, '@'); 18123 if (host) { 18124 *host++ = '\0'; 18125 ext = tmp; 18126 } else { 18127 ext = strchr(tmp, '/'); 18128 if (ext) 18129 *ext++ = '\0'; 18130 host = tmp; 18131 } 18132 18133 if (create_addr(p, host, NULL)) { 18134 *cause = AST_CAUSE_UNREGISTERED; 18135 if (option_debug > 2) 18136 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 18137 sip_destroy(p); 18138 return NULL; 18139 } 18140 if (ast_strlen_zero(p->peername) && ext) 18141 ast_string_field_set(p, peername, ext); 18142 /* Recalculate our side, and recalculate Call ID */ 18143 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 18144 p->ourip = __ourip; 18145 build_via(p); 18146 build_callid_pvt(p); 18147 18148 /* We have an extension to call, don't use the full contact here */ 18149 /* This to enable dialing registered peers with extension dialling, 18150 like SIP/peername/extension 18151 SIP/peername will still use the full contact */ 18152 if (ext) { 18153 ast_string_field_set(p, username, ext); 18154 ast_string_field_free(p, fullcontact); 18155 } 18156 #if 0 18157 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 18158 #endif 18159 p->prefcodec = oldformat; /* Format for this call */ 18160 ast_mutex_lock(&p->lock); 18161 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 18162 ast_mutex_unlock(&p->lock); 18163 if (!tmpc) 18164 sip_destroy(p); 18165 ast_update_use_count(); 18166 restart_monitor(); 18167 return tmpc; 18168 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 8391 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().
08392 { 08393 /* if we are here, we know that we need to reregister. */ 08394 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 08395 08396 /* if we couldn't get a reference to the registry object, punt */ 08397 if (!r) 08398 return 0; 08399 08400 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 08401 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 08402 /* Since registry's are only added/removed by the the monitor thread, this 08403 may be overkill to reference/dereference at all here */ 08404 if (sipdebug) 08405 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 08406 08407 r->expire = -1; 08408 __sip_do_register(r); 08409 ASTOBJ_UNREF(r, sip_registry_destroy); 08410 return 0; 08411 }
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 4718 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().
04719 { 04720 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04721 struct ast_frame *f; 04722 04723 if (!p->rtp) { 04724 /* We have no RTP allocated for this channel */ 04725 return &ast_null_frame; 04726 } 04727 04728 switch(ast->fdno) { 04729 case 0: 04730 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04731 break; 04732 case 1: 04733 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04734 break; 04735 case 2: 04736 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04737 break; 04738 case 3: 04739 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04740 break; 04741 case 5: 04742 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04743 break; 04744 default: 04745 f = &ast_null_frame; 04746 } 04747 /* Don't forward RFC2833 if we're not supposed to */ 04748 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 04749 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 04750 ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 04751 return &ast_null_frame; 04752 } 04753 04754 /* We already hold the channel lock */ 04755 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04756 return f; 04757 04758 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04759 if (!(f->subclass & p->jointcapability)) { 04760 if (option_debug) { 04761 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04762 ast_getformatname(f->subclass), p->owner->name); 04763 } 04764 return &ast_null_frame; 04765 } 04766 if (option_debug) 04767 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04768 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04769 ast_set_read_format(p->owner, p->owner->readformat); 04770 ast_set_write_format(p->owner, p->owner->writeformat); 04771 } 04772 04773 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04774 f = ast_dsp_process(p->owner, p->vad, f); 04775 if (f && f->frametype == AST_FRAME_DTMF) { 04776 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04777 if (option_debug) 04778 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04779 *faxdetect = 1; 04780 } else if (option_debug) { 04781 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04782 } 04783 } 04784 } 04785 04786 return f; 04787 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2260 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(), auto_congest(), 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(), notify_extenstate_update(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().
02261 { 02262 if (ms < 0) { 02263 if (p->timer_t1 == 0) 02264 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02265 ms = p->timer_t1 * 64; 02266 } 02267 if (sip_debug_test_pvt(p)) 02268 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02269 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02270 append_history(p, "SchedDestroy", "%d ms", ms); 02271 02272 AST_SCHED_DEL(sched, p->autokillid); 02273 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02274 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 20109 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().
20110 { 20111 int ms; 20112 int regspacing; 20113 if (!regobjs) 20114 return; 20115 regspacing = default_expiry * 1000/regobjs; 20116 if (regspacing > 100) 20117 regspacing = 100; 20118 ms = regspacing; 20119 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 20120 ASTOBJ_WRLOCK(iterator); 20121 AST_SCHED_DEL(sched, iterator->expire); 20122 ms += regspacing; 20123 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 20124 ASTOBJ_UNLOCK(iterator); 20125 } while (0) 20126 ); 20127 }
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 17566 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by do_monitor(), and handle_request_subscribe().
17567 { 17568 /* Called with peerl lock, but releases it */ 17569 struct sip_pvt *p; 17570 int newmsgs, oldmsgs; 17571 17572 /* Do we have an IP address? If not, skip this peer */ 17573 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 17574 return 0; 17575 17576 /* Check for messages */ 17577 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 17578 17579 peer->lastmsgcheck = time(NULL); 17580 17581 /* Return now if it's the same thing we told them last time */ 17582 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 17583 return 0; 17584 } 17585 17586 17587 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 17588 17589 if (peer->mwipvt) { 17590 /* Base message on subscription */ 17591 p = peer->mwipvt; 17592 } else { 17593 /* Build temporary dialog for this message */ 17594 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 17595 return -1; 17596 if (create_addr_from_peer(p, peer)) { 17597 /* Maybe they're not registered, etc. */ 17598 sip_destroy(p); 17599 return 0; 17600 } 17601 /* Recalculate our side, and recalculate Call ID */ 17602 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17603 p->ourip = __ourip; 17604 build_via(p); 17605 build_callid_pvt(p); 17606 /* Destroy this session after 32 secs */ 17607 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 17608 } 17609 /* Send MWI */ 17610 ast_set_flag(&p->flags[0], SIP_OUTGOING); 17611 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 17612 return 0; 17613 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4186 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.
04187 { 04188 struct sip_pvt *p = ast->tech_pvt; 04189 int res = 0; 04190 04191 ast_mutex_lock(&p->lock); 04192 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04193 case SIP_DTMF_INBAND: 04194 res = -1; /* Tell Asterisk to generate inband indications */ 04195 break; 04196 case SIP_DTMF_RFC2833: 04197 if (p->rtp) 04198 ast_rtp_senddigit_begin(p->rtp, digit); 04199 break; 04200 default: 04201 break; 04202 } 04203 ast_mutex_unlock(&p->lock); 04204 04205 return res; 04206 }
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 4210 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end_with_duration(), 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().
04211 { 04212 struct sip_pvt *p = ast->tech_pvt; 04213 int res = 0; 04214 04215 ast_mutex_lock(&p->lock); 04216 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 04217 case SIP_DTMF_INFO: 04218 transmit_info_with_digit(p, digit, duration); 04219 break; 04220 case SIP_DTMF_RFC2833: 04221 if (p->rtp) 04222 ast_rtp_senddigit_end_with_duration(p->rtp, digit, duration); 04223 break; 04224 case SIP_DTMF_INBAND: 04225 res = -1; /* Tell Asterisk to stop inband indications */ 04226 break; 04227 } 04228 ast_mutex_unlock(&p->lock); 04229 04230 return res; 04231 }
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 2653 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().
02654 { 02655 struct sip_pvt *p = ast->tech_pvt; 02656 int debug = sip_debug_test_pvt(p); 02657 02658 if (debug) 02659 ast_verbose("Sending text %s on %s\n", text, ast->name); 02660 if (!p) 02661 return -1; 02662 /* NOT ast_strlen_zero, because a zero-length message is specifically 02663 * allowed by RFC 3428 (See section 10, Examples) */ 02664 if (!text) 02665 return 0; 02666 if (debug) 02667 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02668 transmit_message_with_text(p, text); 02669 return 0; 02670 }
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 19839 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().
19840 { 19841 struct sip_pvt *p; 19842 int changed = 0; 19843 19844 p = chan->tech_pvt; 19845 if (!p) 19846 return -1; 19847 19848 /* Disable early RTP bridge */ 19849 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 19850 return 0; 19851 19852 ast_mutex_lock(&p->lock); 19853 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 19854 /* If we're destroyed, don't bother */ 19855 ast_mutex_unlock(&p->lock); 19856 return 0; 19857 } 19858 19859 /* if this peer cannot handle reinvites of the media stream to devices 19860 that are known to be behind a NAT, then stop the process now 19861 */ 19862 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 19863 ast_mutex_unlock(&p->lock); 19864 return 0; 19865 } 19866 19867 if (rtp) { 19868 changed |= ast_rtp_get_peer(rtp, &p->redirip); 19869 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 19870 memset(&p->redirip, 0, sizeof(p->redirip)); 19871 changed = 1; 19872 } 19873 if (vrtp) { 19874 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 19875 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 19876 memset(&p->vredirip, 0, sizeof(p->vredirip)); 19877 changed = 1; 19878 } 19879 if (codecs) { 19880 if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) { 19881 p->redircodecs = codecs; 19882 p->jointcapability &= codecs; 19883 p->capability &= codecs; 19884 changed = 1; 19885 } 19886 } 19887 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 19888 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 19889 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 19890 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 19891 if (option_debug) 19892 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)); 19893 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 19894 if (option_debug > 2) { 19895 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)); 19896 } 19897 transmit_reinvite_with_sdp(p); 19898 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19899 if (option_debug > 2) { 19900 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)); 19901 } 19902 /* We have a pending Invite. Send re-invite when we're done with the invite */ 19903 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19904 } 19905 } 19906 /* Reset lastrtprx timer */ 19907 p->lastrtprx = p->lastrtptx = time(NULL); 19908 ast_mutex_unlock(&p->lock); 19909 return 0; 19910 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 19653 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.
19654 { 19655 struct sip_pvt *p; 19656 19657 p = chan->tech_pvt; 19658 if (!p) 19659 return -1; 19660 ast_mutex_lock(&p->lock); 19661 if (udptl) 19662 ast_udptl_get_peer(udptl, &p->udptlredirip); 19663 else 19664 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 19665 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 19666 if (!p->pendinginvite) { 19667 if (option_debug > 2) { 19668 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); 19669 } 19670 transmit_reinvite_with_t38_sdp(p); 19671 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 19672 if (option_debug > 2) { 19673 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); 19674 } 19675 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 19676 } 19677 } 19678 /* Reset lastrtprx timer */ 19679 p->lastrtprx = p->lastrtptx = time(NULL); 19680 ast_mutex_unlock(&p->lock); 19681 return 0; 19682 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 12402 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.
12403 { 12404 struct sip_pvt *cur; 12405 size_t len; 12406 int found = 0; 12407 12408 if (argc != 4) 12409 return RESULT_SHOWUSAGE; 12410 len = strlen(argv[3]); 12411 ast_mutex_lock(&iflock); 12412 for (cur = iflist; cur; cur = cur->next) { 12413 if (!strncasecmp(cur->callid, argv[3], len)) { 12414 char formatbuf[SIPBUFSIZE/2]; 12415 ast_cli(fd,"\n"); 12416 if (cur->subscribed != NONE) 12417 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 12418 else 12419 ast_cli(fd, " * SIP Call\n"); 12420 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 12421 ast_cli(fd, " Call-ID: %s\n", cur->callid); 12422 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 12423 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 12424 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 12425 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 12426 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 12427 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 12428 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 12429 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 12430 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 12431 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 12432 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 12433 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)" ); 12434 ast_cli(fd, " Our Tag: %s\n", cur->tag); 12435 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 12436 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 12437 if (!ast_strlen_zero(cur->username)) 12438 ast_cli(fd, " Username: %s\n", cur->username); 12439 if (!ast_strlen_zero(cur->peername)) 12440 ast_cli(fd, " Peername: %s\n", cur->peername); 12441 if (!ast_strlen_zero(cur->uri)) 12442 ast_cli(fd, " Original uri: %s\n", cur->uri); 12443 if (!ast_strlen_zero(cur->cid_num)) 12444 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 12445 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 12446 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 12447 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 12448 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 12449 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 12450 ast_cli(fd, " SIP Options: "); 12451 if (cur->sipoptions) { 12452 int x; 12453 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 12454 if (cur->sipoptions & sip_options[x].id) 12455 ast_cli(fd, "%s ", sip_options[x].text); 12456 } 12457 } else 12458 ast_cli(fd, "(none)\n"); 12459 ast_cli(fd, "\n\n"); 12460 found++; 12461 } 12462 } 12463 ast_mutex_unlock(&iflock); 12464 if (!found) 12465 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 12466 return RESULT_SUCCESS; 12467 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 12188 of file chan_sip.c.
References __sip_show_channels().
12189 { 12190 return __sip_show_channels(fd, argc, argv, 0); 12191 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 11698 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.
11699 { 11700 struct domain *d; 11701 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 11702 11703 if (AST_LIST_EMPTY(&domain_list)) { 11704 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 11705 return RESULT_SUCCESS; 11706 } else { 11707 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 11708 AST_LIST_LOCK(&domain_list); 11709 AST_LIST_TRAVERSE(&domain_list, d, list) 11710 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 11711 domain_mode_to_text(d->mode)); 11712 AST_LIST_UNLOCK(&domain_list); 11713 ast_cli(fd, "\n"); 11714 return RESULT_SUCCESS; 11715 } 11716 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 12470 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.
12471 { 12472 struct sip_pvt *cur; 12473 size_t len; 12474 int found = 0; 12475 12476 if (argc != 4) 12477 return RESULT_SHOWUSAGE; 12478 if (!recordhistory) 12479 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 12480 len = strlen(argv[3]); 12481 ast_mutex_lock(&iflock); 12482 for (cur = iflist; cur; cur = cur->next) { 12483 if (!strncasecmp(cur->callid, argv[3], len)) { 12484 struct sip_history *hist; 12485 int x = 0; 12486 12487 ast_cli(fd,"\n"); 12488 if (cur->subscribed != NONE) 12489 ast_cli(fd, " * Subscription\n"); 12490 else 12491 ast_cli(fd, " * SIP Call\n"); 12492 if (cur->history) 12493 AST_LIST_TRAVERSE(cur->history, hist, list) 12494 ast_cli(fd, "%d. %s\n", ++x, hist->event); 12495 if (x == 0) 12496 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 12497 found++; 12498 } 12499 } 12500 ast_mutex_unlock(&iflock); 12501 if (!found) 12502 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 12503 return RESULT_SUCCESS; 12504 }
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 11116 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.
11117 { 11118 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 11119 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 11120 char ilimits[40]; 11121 char iused[40]; 11122 int showall = FALSE; 11123 11124 if (argc < 3) 11125 return RESULT_SHOWUSAGE; 11126 11127 if (argc == 4 && !strcmp(argv[3],"all")) 11128 showall = TRUE; 11129 11130 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 11131 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11132 ASTOBJ_RDLOCK(iterator); 11133 if (iterator->call_limit) 11134 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 11135 else 11136 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 11137 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 11138 if (showall || iterator->call_limit) 11139 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 11140 ASTOBJ_UNLOCK(iterator); 11141 } while (0) ); 11142 11143 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 11144 11145 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 11146 ASTOBJ_RDLOCK(iterator); 11147 if (iterator->call_limit) 11148 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 11149 else 11150 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 11151 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 11152 if (showall || iterator->call_limit) 11153 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 11154 ASTOBJ_UNLOCK(iterator); 11155 } while (0) ); 11156 11157 return RESULT_SUCCESS; 11158 #undef FORMAT 11159 #undef FORMAT2 11160 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 11437 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
11438 { 11439 char tmp[256]; 11440 if (argc != 3) 11441 return RESULT_SHOWUSAGE; 11442 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 11443 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 11444 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 11445 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 11446 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 11447 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 11448 return RESULT_SUCCESS; 11449 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 11750 of file chan_sip.c.
References _sip_show_peer().
11751 { 11752 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 11753 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 11293 of file chan_sip.c.
References _sip_show_peers().
11294 { 11295 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 11296 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 12024 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.
12025 { 12026 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 12027 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 12028 char host[80]; 12029 char tmpdat[256]; 12030 struct tm tm; 12031 12032 12033 if (argc != 3) 12034 return RESULT_SHOWUSAGE; 12035 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 12036 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 12037 ASTOBJ_RDLOCK(iterator); 12038 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 12039 if (iterator->regtime) { 12040 ast_localtime(&iterator->regtime, &tm, NULL); 12041 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 12042 } else { 12043 tmpdat[0] = 0; 12044 } 12045 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 12046 ASTOBJ_UNLOCK(iterator); 12047 } while(0)); 12048 return RESULT_SUCCESS; 12049 #undef FORMAT 12050 #undef FORMAT2 12051 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 12054 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_FORWARD_LOOP_DETECTED, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTAUTOCLEAR, 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().
12055 { 12056 int realtimepeers; 12057 int realtimeusers; 12058 char codec_buf[SIPBUFSIZE]; 12059 12060 realtimepeers = ast_check_realtime("sippeers"); 12061 realtimeusers = ast_check_realtime("sipusers"); 12062 12063 if (argc != 3) 12064 return RESULT_SHOWUSAGE; 12065 ast_cli(fd, "\n\nGlobal Settings:\n"); 12066 ast_cli(fd, "----------------\n"); 12067 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 12068 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 12069 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 12070 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 12071 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 12072 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 12073 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 12074 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 12075 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 12076 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 12077 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 12078 ast_cli(fd, " Our auth realm %s\n", global_realm); 12079 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 12080 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 12081 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 12082 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 12083 ast_cli(fd, " User Agent: %s\n", global_useragent); 12084 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 12085 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 12086 ast_cli(fd, " Caller ID: %s\n", default_callerid); 12087 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 12088 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 12089 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 12090 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 12091 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 12092 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 12093 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 12094 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 12095 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 12096 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 12097 #endif 12098 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 12099 if (!realtimepeers && !realtimeusers) 12100 ast_cli(fd, " SIP realtime: Disabled\n" ); 12101 else 12102 ast_cli(fd, " SIP realtime: Enabled\n" ); 12103 12104 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 12105 ast_cli(fd, "---------------------------\n"); 12106 ast_cli(fd, " Codecs: "); 12107 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 12108 ast_cli(fd, "%s\n", codec_buf); 12109 ast_cli(fd, " Codec Order: "); 12110 print_codec_to_cli(fd, &default_prefs); 12111 ast_cli(fd, "\n"); 12112 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 12113 ast_cli(fd, " No premature media: %s\n", global_prematuremediafilter ? "Yes" : "No"); 12114 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 12115 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 12116 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 12117 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 12118 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 12119 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 12120 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 12121 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 12122 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 12123 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 12124 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 12125 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 12126 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 12127 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 12128 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 12129 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 12130 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 12131 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 12132 ast_cli(fd, "\nDefault Settings:\n"); 12133 ast_cli(fd, "-----------------\n"); 12134 ast_cli(fd, " Context: %s\n", default_context); 12135 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 12136 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 12137 ast_cli(fd, " Qualify: %d\n", default_qualify); 12138 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 12139 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" ); 12140 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 12141 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 12142 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 12143 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 12144 ast_cli(fd, " Forward Detected Loops: %s\n", (ast_test_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No")); 12145 12146 if (realtimepeers || realtimeusers) { 12147 ast_cli(fd, "\nRealtime SIP Settings:\n"); 12148 ast_cli(fd, "----------------------\n"); 12149 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 12150 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 12151 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 12152 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 12153 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 12154 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 12155 ast_cli(fd, " Auto Clear: %d (%s)", global_rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled"); 12156 } 12157 ast_cli(fd, "\n----\n"); 12158 return RESULT_SUCCESS; 12159 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 12194 of file chan_sip.c.
References __sip_show_channels().
12195 { 12196 return __sip_show_channels(fd, argc, argv, 1); 12197 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11969 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.
11970 { 11971 char cbuf[256]; 11972 struct sip_user *user; 11973 struct ast_variable *v; 11974 int load_realtime; 11975 11976 if (argc < 4) 11977 return RESULT_SHOWUSAGE; 11978 11979 /* Load from realtime storage? */ 11980 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11981 11982 user = find_user(argv[3], load_realtime); 11983 if (user) { 11984 ast_cli(fd,"\n\n"); 11985 ast_cli(fd, " * Name : %s\n", user->name); 11986 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11987 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11988 ast_cli(fd, " Context : %s\n", user->context); 11989 ast_cli(fd, " Language : %s\n", user->language); 11990 if (!ast_strlen_zero(user->accountcode)) 11991 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11992 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11993 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11994 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11995 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11996 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11997 ast_cli(fd, " Callgroup : "); 11998 print_group(fd, user->callgroup, 0); 11999 ast_cli(fd, " Pickupgroup : "); 12000 print_group(fd, user->pickupgroup, 0); 12001 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 12002 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 12003 ast_cli(fd, " Codec Order : ("); 12004 print_codec_to_cli(fd, &user->prefs); 12005 ast_cli(fd, ")\n"); 12006 12007 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 12008 if (user->chanvars) { 12009 ast_cli(fd, " Variables :\n"); 12010 for (v = user->chanvars ; v ; v = v->next) 12011 ast_cli(fd, " %s = %s\n", v->name, v->value); 12012 } 12013 ast_cli(fd,"\n"); 12014 ASTOBJ_UNREF(user,sip_destroy_user); 12015 } else { 12016 ast_cli(fd,"User %s not found.\n", argv[3]); 12017 ast_cli(fd,"\n"); 12018 } 12019 12020 return RESULT_SUCCESS; 12021 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 11216 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.
11217 { 11218 regex_t regexbuf; 11219 int havepattern = FALSE; 11220 11221 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 11222 11223 switch (argc) { 11224 case 5: 11225 if (!strcasecmp(argv[3], "like")) { 11226 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 11227 return RESULT_SHOWUSAGE; 11228 havepattern = TRUE; 11229 } else 11230 return RESULT_SHOWUSAGE; 11231 case 3: 11232 break; 11233 default: 11234 return RESULT_SHOWUSAGE; 11235 } 11236 11237 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 11238 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 11239 ASTOBJ_RDLOCK(iterator); 11240 11241 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 11242 ASTOBJ_UNLOCK(iterator); 11243 continue; 11244 } 11245 11246 ast_cli(fd, FORMAT, iterator->name, 11247 iterator->secret, 11248 iterator->accountcode, 11249 iterator->context, 11250 iterator->ha ? "Yes" : "No", 11251 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 11252 ASTOBJ_UNLOCK(iterator); 11253 } while (0) 11254 ); 11255 11256 if (havepattern) 11257 regfree(®exbuf); 11258 11259 return RESULT_SUCCESS; 11260 #undef FORMAT 11261 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 20023 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().
20024 { 20025 char *cdest; 20026 char *extension, *host, *port; 20027 char tmp[80]; 20028 20029 cdest = ast_strdupa(dest); 20030 20031 extension = strsep(&cdest, "@"); 20032 host = strsep(&cdest, ":"); 20033 port = strsep(&cdest, ":"); 20034 if (ast_strlen_zero(extension)) { 20035 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 20036 return 0; 20037 } 20038 20039 /* we'll issue the redirect message here */ 20040 if (!host) { 20041 char *localtmp; 20042 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 20043 if (ast_strlen_zero(tmp)) { 20044 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 20045 return 0; 20046 } 20047 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 20048 char lhost[80], lport[80]; 20049 memset(lhost, 0, sizeof(lhost)); 20050 memset(lport, 0, sizeof(lport)); 20051 localtmp++; 20052 /* This is okey because lhost and lport are as big as tmp */ 20053 sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport); 20054 if (ast_strlen_zero(lhost)) { 20055 ast_log(LOG_ERROR, "Can't find the host address\n"); 20056 return 0; 20057 } 20058 host = ast_strdupa(lhost); 20059 if (!ast_strlen_zero(lport)) { 20060 port = ast_strdupa(lport); 20061 } 20062 } 20063 } 20064 20065 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 20066 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 20067 20068 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 20069 sip_alreadygone(p); 20070 return 0; 20071 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 4234 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().
04235 { 04236 struct sip_pvt *p = ast->tech_pvt; 04237 int res; 04238 04239 if (dest == NULL) /* functions below do not take a NULL */ 04240 dest = ""; 04241 ast_mutex_lock(&p->lock); 04242 if (ast->_state == AST_STATE_RING) 04243 res = sip_sipredirect(p, dest); 04244 else 04245 res = transmit_refer(p, dest); 04246 ast_mutex_unlock(&p->lock); 04247 return res; 04248 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 15353 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
15354 { 15355 char *uri1 = ast_strdupa(input1); 15356 char *uri2 = ast_strdupa(input2); 15357 char *host1; 15358 char *host2; 15359 char *params1; 15360 char *params2; 15361 char *headers1; 15362 char *headers2; 15363 15364 /* Strip off "sip:" from the URI. We know this is present 15365 * because it was checked back in parse_request() 15366 */ 15367 strsep(&uri1, ":"); 15368 strsep(&uri2, ":"); 15369 15370 if ((host1 = strchr(uri1, '@'))) { 15371 *host1++ = '\0'; 15372 } 15373 if ((host2 = strchr(uri2, '@'))) { 15374 *host2++ = '\0'; 15375 } 15376 15377 /* Check for mismatched username and passwords. This is the 15378 * only case-sensitive comparison of a SIP URI 15379 */ 15380 if ((host1 && !host2) || 15381 (host2 && !host1) || 15382 (host1 && host2 && strcmp(uri1, uri2))) { 15383 return 1; 15384 } 15385 15386 if (!host1) 15387 host1 = uri1; 15388 if (!host2) 15389 host2 = uri2; 15390 15391 /* Strip off the parameters and headers so we can compare 15392 * host and port 15393 */ 15394 15395 if ((params1 = strchr(host1, ';'))) { 15396 *params1++ = '\0'; 15397 } 15398 if ((params2 = strchr(host2, ';'))) { 15399 *params2++ = '\0'; 15400 } 15401 15402 /* Headers come after parameters, but there may be headers without 15403 * parameters, thus the S_OR 15404 */ 15405 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 15406 *headers1++ = '\0'; 15407 } 15408 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 15409 *headers2++ = '\0'; 15410 } 15411 15412 /* Now the host/port are properly isolated. We can get by with a string comparison 15413 * because the SIP URI checking rules have some interesting exceptions that make 15414 * this possible. I will note 2 in particular 15415 * 1. hostnames which resolve to the same IP address as well as a hostname and its 15416 * IP address are not considered a match with SIP URI's. 15417 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 15418 * This includes if one URI explicitly contains port 5060 and the other implies it 15419 * by not having a port specified. 15420 */ 15421 15422 if (strcasecmp(host1, host2)) { 15423 return 1; 15424 } 15425 15426 /* Headers have easier rules to follow, so do those first */ 15427 if (sip_uri_headers_cmp(headers1, headers2)) { 15428 return 1; 15429 } 15430 15431 /* And now the parameters. Ugh */ 15432 return sip_uri_params_cmp(params1, params2); 15433 }
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 15307 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
15308 { 15309 char *headers1 = NULL; 15310 char *headers2 = NULL; 15311 int zerolength1 = 0; 15312 int zerolength2 = 0; 15313 int different = 0; 15314 char *header1; 15315 15316 if (ast_strlen_zero(input1)) { 15317 zerolength1 = 1; 15318 } else { 15319 headers1 = ast_strdupa(input1); 15320 } 15321 15322 if (ast_strlen_zero(input2)) { 15323 zerolength2 = 1; 15324 } else { 15325 headers2 = ast_strdupa(input2); 15326 } 15327 15328 if ((zerolength1 && !zerolength2) || 15329 (zerolength2 && !zerolength1)) 15330 return 1; 15331 15332 if (zerolength1 && zerolength2) 15333 return 0; 15334 15335 /* At this point, we can definitively state that both inputs are 15336 * not zero-length. First, one more optimization. If the length 15337 * of the headers is not equal, then we definitely have no match 15338 */ 15339 if (strlen(headers1) != strlen(headers2)) { 15340 return 1; 15341 } 15342 15343 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 15344 if (!strcasestr(headers2, header1)) { 15345 different = 1; 15346 break; 15347 } 15348 } 15349 15350 return different; 15351 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp to compare URI parameters
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 |
0 | URIs' parameters match | |
nonzero | URIs' parameters do not match |
Definition at line 15182 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
15183 { 15184 char *params1 = NULL; 15185 char *params2 = NULL; 15186 char *pos1; 15187 char *pos2; 15188 int zerolength1 = 0; 15189 int zerolength2 = 0; 15190 int maddrmatch = 0; 15191 int ttlmatch = 0; 15192 int usermatch = 0; 15193 int methodmatch = 0; 15194 15195 if (ast_strlen_zero(input1)) { 15196 zerolength1 = 1; 15197 } else { 15198 params1 = ast_strdupa(input1); 15199 } 15200 if (ast_strlen_zero(input2)) { 15201 zerolength2 = 1; 15202 } else { 15203 params2 = ast_strdupa(input2); 15204 } 15205 15206 /* Quick optimization. If both params are zero-length, then 15207 * they match 15208 */ 15209 if (zerolength1 && zerolength2) { 15210 return 0; 15211 } 15212 15213 for (pos1 = strsep(¶ms1, ";"); pos1; pos1 = strsep(¶ms1, ";")) { 15214 char *value1 = pos1; 15215 char *name1 = strsep(&value1, "="); 15216 char *params2dup = NULL; 15217 int matched = 0; 15218 if (!value1) { 15219 value1 = ""; 15220 } 15221 /* Checkpoint reached. We have the name and value parsed for param1 15222 * We have to duplicate params2 each time through this loop 15223 * or else the inner loop below will not work properly. 15224 */ 15225 if (!zerolength2) { 15226 params2dup = ast_strdupa(params2); 15227 } 15228 for (pos2 = strsep(¶ms2dup, ";"); pos2; pos2 = strsep(¶ms2dup, ";")) { 15229 char *name2 = pos2; 15230 char *value2 = strchr(pos2, '='); 15231 if (!value2) { 15232 value2 = ""; 15233 } else { 15234 *value2++ = '\0'; 15235 } 15236 if (!strcasecmp(name1, name2)) { 15237 if (strcasecmp(value1, value2)) { 15238 goto fail; 15239 } else { 15240 matched = 1; 15241 break; 15242 } 15243 } 15244 } 15245 /* Check to see if the parameter is one of the 'must-match' parameters */ 15246 if (!strcasecmp(name1, "maddr")) { 15247 if (matched) { 15248 maddrmatch = 1; 15249 } else { 15250 goto fail; 15251 } 15252 } else if (!strcasecmp(name1, "ttl")) { 15253 if (matched) { 15254 ttlmatch = 1; 15255 } else { 15256 goto fail; 15257 } 15258 } else if (!strcasecmp(name1, "user")) { 15259 if (matched) { 15260 usermatch = 1; 15261 } else { 15262 goto fail; 15263 } 15264 } else if (!strcasecmp(name1, "method")) { 15265 if (matched) { 15266 methodmatch = 1; 15267 } else { 15268 goto fail; 15269 } 15270 } 15271 } 15272 15273 /* We've made it out of that horrible O(m*n) construct and there are no 15274 * failures yet. We're not done yet, though, because params2 could have 15275 * an maddr, ttl, user, or method header and params1 did not. 15276 */ 15277 for (pos2 = strsep(¶ms2, ";"); pos2; pos2 = strsep(¶ms2, ";")) { 15278 char *value2 = pos2; 15279 char *name2 = strsep(&value2, "="); 15280 if (!value2) { 15281 value2 = ""; 15282 } 15283 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 15284 (!strcasecmp(name2, "ttl") && !ttlmatch) || 15285 (!strcasecmp(name2, "user") && !usermatch) || 15286 (!strcasecmp(name2, "method") && !methodmatch)) { 15287 goto fail; 15288 } 15289 } 15290 return 0; 15291 15292 fail: 15293 return 1; 15294 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 4045 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.
04046 { 04047 struct sip_pvt *p = ast->tech_pvt; 04048 int res = 0; 04049 04050 switch (frame->frametype) { 04051 case AST_FRAME_VOICE: 04052 if (!(frame->subclass & ast->nativeformats)) { 04053 char s1[512], s2[512], s3[512]; 04054 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 04055 frame->subclass, 04056 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 04057 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 04058 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 04059 ast->readformat, 04060 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 04061 ast->writeformat); 04062 return 0; 04063 } 04064 if (p) { 04065 ast_mutex_lock(&p->lock); 04066 if (p->t38.state == T38_ENABLED && !p->t38.direct) { 04067 /* drop frame, can't sent VOICE frames while in T.38 mode */ 04068 ast_mutex_unlock(&p->lock); 04069 break; 04070 } else if (p->rtp) { 04071 /* If channel is not up, activate early media session */ 04072 if ((ast->_state != AST_STATE_UP) && 04073 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04074 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04075 ast_rtp_new_source(p->rtp); 04076 if (!global_prematuremediafilter) { 04077 p->invitestate = INV_EARLY_MEDIA; 04078 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04079 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04080 } 04081 } 04082 p->lastrtptx = time(NULL); 04083 res = ast_rtp_write(p->rtp, frame); 04084 } 04085 ast_mutex_unlock(&p->lock); 04086 } 04087 break; 04088 case AST_FRAME_VIDEO: 04089 if (p) { 04090 ast_mutex_lock(&p->lock); 04091 if (p->vrtp) { 04092 /* Activate video early media */ 04093 if ((ast->_state != AST_STATE_UP) && 04094 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04095 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04096 p->invitestate = INV_EARLY_MEDIA; 04097 transmit_provisional_response(p, "183 Session Progress", &p->initreq, 1); 04098 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04099 } 04100 p->lastrtptx = time(NULL); 04101 res = ast_rtp_write(p->vrtp, frame); 04102 } 04103 ast_mutex_unlock(&p->lock); 04104 } 04105 break; 04106 case AST_FRAME_IMAGE: 04107 return 0; 04108 break; 04109 case AST_FRAME_MODEM: 04110 if (p) { 04111 ast_mutex_lock(&p->lock); 04112 /* UDPTL requires two-way communication, so early media is not needed here. 04113 we simply forget the frames if we get modem frames before the bridge is up. 04114 Fax will re-transmit. 04115 */ 04116 if (ast->_state == AST_STATE_UP) { 04117 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 04118 if (!p->pendinginvite) { 04119 p->t38.state = T38_LOCAL_REINVITE; 04120 transmit_reinvite_with_t38_sdp(p); 04121 } 04122 } else if (p->t38.state == T38_ENABLED) { 04123 res = ast_udptl_write(p->udptl, frame); 04124 } 04125 } 04126 ast_mutex_unlock(&p->lock); 04127 } 04128 break; 04129 default: 04130 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 04131 return 0; 04132 } 04133 04134 return res; 04135 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 17446 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().
17447 { 17448 struct sip_request req; 17449 struct sockaddr_in sin = { 0, }; 17450 struct sip_pvt *p; 17451 int res; 17452 socklen_t len = sizeof(sin); 17453 int nounlock = 0; 17454 int recount = 0; 17455 int lockretry; 17456 17457 memset(&req, 0, sizeof(req)); 17458 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 17459 if (res < 0) { 17460 #if !defined(__FreeBSD__) 17461 if (errno == EAGAIN) 17462 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 17463 else 17464 #endif 17465 if (errno != ECONNREFUSED) 17466 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 17467 return 1; 17468 } 17469 if (option_debug && res == sizeof(req.data) - 1) 17470 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 17471 17472 req.data[res] = '\0'; 17473 req.len = res; 17474 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 17475 ast_set_flag(&req, SIP_PKT_DEBUG); 17476 if (pedanticsipchecking) 17477 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 17478 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 17479 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 17480 17481 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 17482 return 1; 17483 17484 req.method = find_sip_method(req.rlPart1); 17485 17486 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 17487 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 17488 17489 if (req.headers < 2) /* Must have at least two headers */ 17490 return 1; 17491 17492 /* Process request, with netlock held, and with usual deadlock avoidance */ 17493 for (lockretry = 10; lockretry > 0; lockretry--) { 17494 ast_mutex_lock(&netlock); 17495 17496 /* Find the active SIP dialog or create a new one */ 17497 p = find_call(&req, &sin, req.method); /* returns p locked */ 17498 if (p == NULL) { 17499 if (option_debug) 17500 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 17501 ast_mutex_unlock(&netlock); 17502 return 1; 17503 } 17504 /* Go ahead and lock the owner if it has one -- we may need it */ 17505 /* because this is deadlock-prone, we need to try and unlock if failed */ 17506 if (!p->owner || !ast_channel_trylock(p->owner)) 17507 break; /* locking succeeded */ 17508 if (lockretry != 1) { 17509 ast_mutex_unlock(&p->lock); 17510 ast_mutex_unlock(&netlock); 17511 /* Sleep for a very short amount of time */ 17512 usleep(1); 17513 } 17514 } 17515 p->recv = sin; 17516 17517 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 17518 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 17519 17520 if (!lockretry) { 17521 if (!queue_request(p, &req)) { 17522 /* the request has been queued for later handling */ 17523 ast_mutex_unlock(&p->lock); 17524 ast_mutex_unlock(&netlock); 17525 return 1; 17526 } 17527 17528 /* This is unsafe, since p->owner is not locked. */ 17529 if (p->owner) 17530 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 ??? - ")); 17531 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 17532 if (req.method != SIP_ACK) 17533 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 17534 /* XXX We could add retry-after to make sure they come back */ 17535 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 17536 ast_mutex_unlock(&p->lock); 17537 ast_mutex_unlock(&netlock); 17538 return 1; 17539 } 17540 17541 /* if there are queued requests on this sip_pvt, process them first, so that everything is 17542 handled in order 17543 */ 17544 if (!AST_LIST_EMPTY(&p->request_queue)) { 17545 AST_SCHED_DEL(sched, p->request_queue_sched_id); 17546 process_request_queue(p, &recount, &nounlock); 17547 } 17548 17549 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 17550 /* Request failed */ 17551 if (option_debug) 17552 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 17553 } 17554 17555 if (p->owner && !nounlock) 17556 ast_channel_unlock(p->owner); 17557 ast_mutex_unlock(&p->lock); 17558 ast_mutex_unlock(&netlock); 17559 if (recount) 17560 ast_update_use_count(); 17561 17562 return 1; 17563 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 14101 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().
14102 { 14103 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14104 if (p->rtp) 14105 ast_rtp_stop(p->rtp); 14106 if (p->vrtp) 14107 ast_rtp_stop(p->vrtp); 14108 if (p->udptl) 14109 ast_udptl_stop(p->udptl); 14110 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 12162 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
12163 { 12164 int i; 12165 12166 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 12167 if (subscription_types[i].type == subtype) { 12168 return subscription_types[i].text; 12169 } 12170 } 12171 return subscription_types[0].text; 12172 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 7213 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().
07214 { 07215 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 07216 07217 if (maxrate & T38FAX_RATE_14400) { 07218 if (option_debug > 1) 07219 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 07220 return 14400; 07221 } else if (maxrate & T38FAX_RATE_12000) { 07222 if (option_debug > 1) 07223 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 07224 return 12000; 07225 } else if (maxrate & T38FAX_RATE_9600) { 07226 if (option_debug > 1) 07227 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 07228 return 9600; 07229 } else if (maxrate & T38FAX_RATE_7200) { 07230 if (option_debug > 1) 07231 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 07232 return 7200; 07233 } else if (maxrate & T38FAX_RATE_4800) { 07234 if (option_debug > 1) 07235 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 07236 return 4800; 07237 } else if (maxrate & T38FAX_RATE_2400) { 07238 if (option_debug > 1) 07239 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 07240 return 2400; 07241 } else { 07242 if (option_debug > 1) 07243 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 07244 return 0; 07245 } 07246 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 18653 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().
18654 { 18655 struct sip_peer *peer; 18656 18657 if (!(peer = ast_calloc(1, sizeof(*peer)))) 18658 return NULL; 18659 18660 apeerobjs++; 18661 ASTOBJ_INIT(peer); 18662 set_peer_defaults(peer); 18663 18664 ast_copy_string(peer->name, name, sizeof(peer->name)); 18665 18666 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 18667 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 18668 peer->prefs = default_prefs; 18669 reg_source_db(peer); 18670 18671 return peer; 18672 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6982 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06983 { 06984 struct sip_pvt *p = data; 06985 06986 ast_string_field_free_memory(p); 06987 06988 free(data); 06989 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 11163 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().
11164 { 11165 if (mode == TRANSFER_OPENFORALL) 11166 return "open"; 11167 else if (mode == TRANSFER_CLOSED) 11168 return "closed"; 11169 return "strict"; 11170 }
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 9803 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().
09804 { 09805 /* We have to emulate EXACTLY what we'd get with a good peer 09806 * and a bad password, or else we leak information. */ 09807 const char *response = "407 Proxy Authentication Required"; 09808 const char *reqheader = "Proxy-Authorization"; 09809 const char *respheader = "Proxy-Authenticate"; 09810 const char *authtoken; 09811 struct ast_dynamic_str *buf; 09812 char *c; 09813 09814 /* table of recognised keywords, and their value in the digest */ 09815 enum keys { K_NONCE, K_LAST }; 09816 struct x { 09817 const char *key; 09818 const char *s; 09819 } *i, keys[] = { 09820 [K_NONCE] = { "nonce=", "" }, 09821 [K_LAST] = { NULL, NULL} 09822 }; 09823 09824 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09825 response = "401 Unauthorized"; 09826 reqheader = "Authorization"; 09827 respheader = "WWW-Authenticate"; 09828 } 09829 authtoken = get_header(req, reqheader); 09830 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09831 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09832 * information */ 09833 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09834 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09835 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09836 return; 09837 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09838 /* We have no auth, so issue challenge and request authentication */ 09839 set_nonce_randdata(p, 1); 09840 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 09841 /* Schedule auto destroy in 32 seconds */ 09842 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09843 return; 09844 } 09845 09846 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 09847 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09848 return; 09849 } 09850 09851 /* Make a copy of the response and parse it */ 09852 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 09853 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09854 return; 09855 } 09856 09857 c = buf->str; 09858 09859 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09860 for (i = keys; i->key != NULL; i++) { 09861 const char *separator = ","; /* default */ 09862 09863 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 09864 continue; 09865 } 09866 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09867 c += strlen(i->key); 09868 if (*c == '"') { /* in quotes. Skip first and look for last */ 09869 c++; 09870 separator = "\""; 09871 } 09872 i->s = c; 09873 strsep(&c, separator); 09874 break; 09875 } 09876 if (i->key == NULL) { /* not found, jump after space or comma */ 09877 strsep(&c, " ,"); 09878 } 09879 } 09880 09881 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 09882 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 09883 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09884 set_nonce_randdata(p, 1); 09885 } 09886 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09887 09888 /* Schedule auto destroy in 32 seconds */ 09889 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09890 } else { 09891 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09892 } 09893 }
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 8766 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08767 { 08768 struct sip_request req; 08769 08770 reqprep(&req, p, SIP_INFO, 0, 1); 08771 add_digit(&req, digit, duration); 08772 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08773 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8776 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08777 { 08778 struct sip_request req; 08779 08780 reqprep(&req, p, SIP_INFO, 0, 1); 08781 add_vidupdate(&req); 08782 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08783 }
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 8005 of file chan_sip.c.
References add_header(), 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().
08006 { 08007 struct sip_request req; 08008 08009 req.method = sipmethod; 08010 if (init) { /* Seems like init always is 2 */ 08011 /* Bump branch even on initial requests */ 08012 p->branch ^= ast_random(); 08013 p->invite_branch = p->branch; 08014 build_via(p); 08015 if (init > 1) 08016 initreqprep(&req, p, sipmethod); 08017 else 08018 reqprep(&req, p, sipmethod, 0, 0); 08019 } else 08020 reqprep(&req, p, sipmethod, 0, 1); 08021 08022 if (p->options && p->options->auth) 08023 add_header(&req, p->options->authheader, p->options->auth); 08024 append_date(&req); 08025 if (sipmethod == SIP_REFER) { /* Call transfer */ 08026 if (p->refer) { 08027 char buf[SIPBUFSIZE]; 08028 if (!ast_strlen_zero(p->refer->refer_to)) 08029 add_header(&req, "Refer-To", p->refer->refer_to); 08030 if (!ast_strlen_zero(p->refer->referred_by)) { 08031 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 08032 add_header(&req, "Referred-By", buf); 08033 } 08034 } 08035 } 08036 /* This new INVITE is part of an attended transfer. Make sure that the 08037 other end knows and replace the current call with this new call */ 08038 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 08039 add_header(&req, "Replaces", p->options->replaces); 08040 add_header(&req, "Require", "replaces"); 08041 } 08042 08043 add_header(&req, "Allow", ALLOWED_METHODS); 08044 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08045 if (p->options && p->options->addsipheaders && p->owner) { 08046 struct ast_channel *chan = p->owner; /* The owner channel */ 08047 struct varshead *headp; 08048 08049 ast_channel_lock(chan); 08050 08051 headp = &chan->varshead; 08052 08053 if (!headp) 08054 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 08055 else { 08056 const struct ast_var_t *current; 08057 AST_LIST_TRAVERSE(headp, current, entries) { 08058 /* SIPADDHEADER: Add SIP header to outgoing call */ 08059 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 08060 char *content, *end; 08061 const char *header = ast_var_value(current); 08062 char *headdup = ast_strdupa(header); 08063 08064 /* Strip of the starting " (if it's there) */ 08065 if (*headdup == '"') 08066 headdup++; 08067 if ((content = strchr(headdup, ':'))) { 08068 *content++ = '\0'; 08069 content = ast_skip_blanks(content); /* Skip white space */ 08070 /* Strip the ending " (if it's there) */ 08071 end = content + strlen(content) -1; 08072 if (*end == '"') 08073 *end = '\0'; 08074 08075 add_header(&req, headdup, content); 08076 if (sipdebug) 08077 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 08078 } 08079 } 08080 } 08081 } 08082 08083 ast_channel_unlock(chan); 08084 } 08085 if (sdp) { 08086 memset(p->offered_media, 0, sizeof(p->offered_media)); 08087 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 08088 ast_udptl_offered_from_local(p->udptl, 1); 08089 if (option_debug) 08090 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 08091 add_sdp(&req, p, 0, 1); 08092 } else if (p->rtp) 08093 add_sdp(&req, p, 1, 0); 08094 } 08095 08096 if (!p->initreq.headers || init > 2) 08097 initialize_initreq(p, &req); 08098 p->lastinvite = p->ocseq; 08099 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 08100 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 8675 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().
08676 { 08677 struct sip_request req; 08678 08679 reqprep(&req, p, SIP_MESSAGE, 0, 1); 08680 add_text(&req, text); 08681 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08682 }
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 8290 of file chan_sip.c.
References add_content(), add_header(), 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().
08291 { 08292 struct sip_request req; 08293 char tmp[500]; 08294 char *t = tmp; 08295 size_t maxbytes = sizeof(tmp); 08296 08297 initreqprep(&req, p, SIP_NOTIFY); 08298 add_header(&req, "Event", "message-summary"); 08299 add_header(&req, "Content-Type", default_notifymime); 08300 08301 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 08302 /* if we listen to non-standard SIP port we have to specify the SIP port 08303 in the URI, except domains are used - in this case the SRV records should be 08304 used to redirect the client to the non-standard SIP port */ 08305 if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) { 08306 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n", 08307 S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport); 08308 } else { 08309 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 08310 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 08311 } 08312 /* Cisco has a bug in the SIP stack where it can't accept the 08313 (0/0) notification. This can temporarily be disabled in 08314 sip.conf with the "buggymwi" option */ 08315 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)")); 08316 08317 if (p->subscribed) { 08318 if (p->expiry) 08319 add_header(&req, "Subscription-State", "active"); 08320 else /* Expired */ 08321 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08322 } 08323 08324 if (t > tmp + sizeof(tmp)) 08325 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 08326 08327 add_content(&req, tmp); 08328 08329 if (!p->initreq.headers) 08330 initialize_initreq(p, &req); 08331 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08332 }
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 8343 of file chan_sip.c.
References add_content(), add_header(), 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().
08344 { 08345 struct sip_request req; 08346 char tmp[SIPBUFSIZE/2]; 08347 08348 reqprep(&req, p, SIP_NOTIFY, 0, 1); 08349 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 08350 add_header(&req, "Event", tmp); 08351 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 08352 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 08353 add_header(&req, "Allow", ALLOWED_METHODS); 08354 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08355 08356 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 08357 add_content(&req, tmp); 08358 08359 if (!p->initreq.headers) 08360 initialize_initreq(p, &req); 08361 08362 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08363 }
static int transmit_provisional_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req, | |||
int | with_sdp | |||
) | [static] |
Definition at line 7117 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().
07118 { 07119 int res; 07120 07121 if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE) : transmit_response(p, msg, req))) { 07122 p->last_provisional = msg; 07123 update_provisional_keepalive(p, with_sdp); 07124 } 07125 07126 return res; 07127 }
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 8696 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().
08697 { 08698 struct sip_request req = { 08699 .headers = 0, 08700 }; 08701 char from[256]; 08702 const char *of; 08703 char *c; 08704 char referto[256]; 08705 char *ttag, *ftag; 08706 char *theirtag = ast_strdupa(p->theirtag); 08707 08708 if (option_debug || sipdebug) 08709 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08710 08711 /* Are we transfering an inbound or outbound call ? */ 08712 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08713 of = get_header(&p->initreq, "To"); 08714 ttag = theirtag; 08715 ftag = p->tag; 08716 } else { 08717 of = get_header(&p->initreq, "From"); 08718 ftag = theirtag; 08719 ttag = p->tag; 08720 } 08721 08722 ast_copy_string(from, of, sizeof(from)); 08723 of = get_in_brackets(from); 08724 ast_string_field_set(p, from, of); 08725 if (strncasecmp(of, "sip:", 4)) 08726 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08727 else 08728 of += 4; 08729 /* Get just the username part */ 08730 if ((c = strchr(dest, '@'))) 08731 c = NULL; 08732 else if ((c = strchr(of, '@'))) 08733 *c++ = '\0'; 08734 if (c) 08735 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08736 else 08737 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08738 08739 /* save in case we get 407 challenge */ 08740 sip_refer_allocate(p); 08741 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08742 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08743 p->refer->status = REFER_SENT; /* Set refer status */ 08744 08745 reqprep(&req, p, SIP_REFER, 0, 1); 08746 08747 add_header(&req, "Refer-To", referto); 08748 add_header(&req, "Allow", ALLOWED_METHODS); 08749 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08750 if (!ast_strlen_zero(p->our_contact)) 08751 add_header(&req, "Referred-By", p->our_contact); 08752 08753 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08754 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08755 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08756 08757 /*! \todo In theory, we should hang around and wait for a reply, before 08758 returning to the dial plan here. Don't know really how that would 08759 affect the transfer() app or the pbx, but, well, to make this 08760 useful we should have a STATUS code on transfer(). 08761 */ 08762 }
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 8468 of file chan_sip.c.
References __ourip, add_header(), 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().
08469 { 08470 struct sip_request req; 08471 char from[256]; 08472 char to[256]; 08473 char tmp[80]; 08474 char addr[80]; 08475 struct sip_pvt *p; 08476 char *fromdomain; 08477 08478 /* exit if we are already in process with this registrar ?*/ 08479 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 08480 if (r) { 08481 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 08482 } 08483 return 0; 08484 } 08485 08486 if (r->call) { /* We have a registration */ 08487 if (!auth) { 08488 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 08489 return 0; 08490 } else { 08491 p = r->call; 08492 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 08493 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 08494 } 08495 } else { 08496 /* Build callid for registration if we haven't registered before */ 08497 if (!r->callid_valid) { 08498 build_callid_registry(r, __ourip, default_fromdomain); 08499 r->callid_valid = TRUE; 08500 } 08501 /* Allocate SIP packet for registration */ 08502 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 08503 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 08504 return 0; 08505 } 08506 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 08507 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 08508 /* Find address to hostname if we haven't tried to connect 08509 * or a connection error has occurred */ 08510 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 08511 /* we have what we hope is a temporary network error, 08512 * probably DNS. We need to reschedule a registration try */ 08513 sip_destroy(p); 08514 08515 if (r->timeout > -1) 08516 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 08517 else 08518 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); 08519 08520 AST_SCHED_DEL(sched, r->timeout); 08521 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08522 r->regattempts++; 08523 return 0; 08524 } 08525 if (r->needdns) { 08526 memcpy(&r->us, &p->sa, sizeof(r->us)); 08527 } 08528 r->needdns = FALSE; 08529 /* Copy back Call-ID in case create_addr changed it */ 08530 ast_string_field_set(r, callid, p->callid); 08531 if (r->portno) { 08532 p->sa.sin_port = htons(r->portno); 08533 p->recv.sin_port = htons(r->portno); 08534 } else /* Set registry port to the port set from the peer definition/srv or default */ 08535 r->portno = ntohs(p->sa.sin_port); 08536 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 08537 r->call=p; /* Save pointer to SIP packet */ 08538 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 08539 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 08540 ast_string_field_set(p, peersecret, r->secret); 08541 if (!ast_strlen_zero(r->md5secret)) 08542 ast_string_field_set(p, peermd5secret, r->md5secret); 08543 /* User name in this realm 08544 - if authuser is set, use that, otherwise use username */ 08545 if (!ast_strlen_zero(r->authuser)) { 08546 ast_string_field_set(p, peername, r->authuser); 08547 ast_string_field_set(p, authname, r->authuser); 08548 } else if (!ast_strlen_zero(r->username)) { 08549 ast_string_field_set(p, peername, r->username); 08550 ast_string_field_set(p, authname, r->username); 08551 ast_string_field_set(p, fromuser, r->username); 08552 } 08553 if (!ast_strlen_zero(r->username)) 08554 ast_string_field_set(p, username, r->username); 08555 /* Save extension in packet */ 08556 ast_string_field_set(p, exten, r->contact); 08557 08558 /* 08559 check which address we should use in our contact header 08560 based on whether the remote host is on the external or 08561 internal network so we can register through nat 08562 */ 08563 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 08564 p->ourip = bindaddr.sin_addr; 08565 build_contact(p); 08566 } 08567 08568 /* set up a timeout */ 08569 if (auth == NULL) { 08570 if (r->timeout > -1) 08571 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 08572 AST_SCHED_DEL(sched, r->timeout); 08573 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 08574 if (option_debug) 08575 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 08576 } 08577 08578 if ((fromdomain = strchr(r->username, '@'))) { 08579 /* the domain name is just behind '@' */ 08580 fromdomain++ ; 08581 /* We have a domain in the username for registration */ 08582 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 08583 if (!ast_strlen_zero(p->theirtag)) 08584 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 08585 else 08586 snprintf(to, sizeof(to), "<sip:%s>", r->username); 08587 08588 /* If the registration username contains '@', then the domain should be used as 08589 the equivalent of "fromdomain" for the registration */ 08590 if (ast_strlen_zero(p->fromdomain)) { 08591 ast_string_field_set(p, fromdomain, fromdomain); 08592 } 08593 } else { 08594 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 08595 if (!ast_strlen_zero(p->theirtag)) 08596 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 08597 else 08598 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 08599 } 08600 08601 /* Fromdomain is what we are registering to, regardless of actual 08602 host name from SRV */ 08603 if (!ast_strlen_zero(p->fromdomain)) { 08604 if (r->portno && r->portno != STANDARD_SIP_PORT) 08605 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 08606 else 08607 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 08608 } else { 08609 if (r->portno && r->portno != STANDARD_SIP_PORT) 08610 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 08611 else 08612 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 08613 } 08614 ast_string_field_set(p, uri, addr); 08615 08616 p->branch ^= ast_random(); 08617 08618 init_req(&req, sipmethod, addr); 08619 08620 /* Add to CSEQ */ 08621 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 08622 p->ocseq = r->ocseq; 08623 08624 build_via(p); 08625 add_header(&req, "Via", p->via); 08626 add_header(&req, "From", from); 08627 add_header(&req, "To", to); 08628 add_header(&req, "Call-ID", p->callid); 08629 add_header(&req, "CSeq", tmp); 08630 if (!ast_strlen_zero(global_useragent)) 08631 add_header(&req, "User-Agent", global_useragent); 08632 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08633 08634 08635 if (auth) /* Add auth header */ 08636 add_header(&req, authheader, auth); 08637 else if (!ast_strlen_zero(r->nonce)) { 08638 char digest[1024]; 08639 08640 /* We have auth data to reuse, build a digest header! */ 08641 if (sipdebug) 08642 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 08643 ast_string_field_set(p, realm, r->realm); 08644 ast_string_field_set(p, nonce, r->nonce); 08645 ast_string_field_set(p, domain, r->domain); 08646 ast_string_field_set(p, opaque, r->opaque); 08647 ast_string_field_set(p, qop, r->qop); 08648 r->noncecount++; 08649 p->noncecount = r->noncecount; 08650 08651 memset(digest,0,sizeof(digest)); 08652 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 08653 add_header(&req, "Authorization", digest); 08654 else 08655 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 08656 08657 } 08658 08659 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 08660 add_header(&req, "Expires", tmp); 08661 add_header(&req, "Contact", p->our_contact); 08662 add_header(&req, "Event", "registration"); 08663 08664 initialize_initreq(p, &req); 08665 if (sip_debug_test_pvt(p)) 08666 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 08667 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 08668 r->regattempts++; /* Another attempt */ 08669 if (option_debug > 3) 08670 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 08671 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08672 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7713 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(), handle_response_invite(), and sip_set_rtp_peer().
07714 { 07715 struct sip_request req; 07716 07717 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07718 07719 add_header(&req, "Allow", ALLOWED_METHODS); 07720 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07721 if (sipdebug) 07722 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07723 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07724 append_history(p, "ReInv", "Re-invite sent"); 07725 memset(p->offered_media, 0, sizeof(p->offered_media)); 07726 add_sdp(&req, p, 1, 0); 07727 /* Use this as the basis */ 07728 initialize_initreq(p, &req); 07729 p->lastinvite = p->ocseq; 07730 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07731 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07732 }
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 7738 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().
07739 { 07740 struct sip_request req; 07741 07742 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07743 07744 add_header(&req, "Allow", ALLOWED_METHODS); 07745 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07746 if (sipdebug) 07747 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07748 memset(p->offered_media, 0, sizeof(p->offered_media)); 07749 add_sdp(&req, p, 0, 1); 07750 07751 /* Use this as the basis */ 07752 initialize_initreq(p, &req); 07753 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07754 p->lastinvite = p->ocseq; 07755 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07756 }
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 8788 of file chan_sip.c.
References 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().
08789 { 08790 struct sip_request resp; 08791 08792 if (sipmethod == SIP_ACK) 08793 p->invitestate = INV_CONFIRMED; 08794 08795 reqprep(&resp, p, sipmethod, seqno, newbranch); 08796 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08797 }
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 8800 of file chan_sip.c.
References add_header(), 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().
08801 { 08802 struct sip_request resp; 08803 08804 reqprep(&resp, p, sipmethod, seqno, newbranch); 08805 if (!ast_strlen_zero(p->realm)) { 08806 char digest[1024]; 08807 08808 memset(digest, 0, sizeof(digest)); 08809 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08810 if (p->options && p->options->auth_type == PROXY_AUTH) 08811 add_header(&resp, "Proxy-Authorization", digest); 08812 else if (p->options && p->options->auth_type == WWW_AUTH) 08813 add_header(&resp, "Authorization", digest); 08814 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08815 add_header(&resp, "Proxy-Authorization", digest); 08816 } else 08817 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08818 } 08819 /* If we are hanging up and know a cause for that, send it in clear text to make 08820 debugging easier. */ 08821 if (sipmethod == SIP_BYE) { 08822 char buf[10]; 08823 08824 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08825 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08826 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08827 } 08828 08829 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08830 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 7043 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
07044 { 07045 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 07046 }
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 7061 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_handle_t38_reinvite(), sip_hangup(), sip_indicate(), and sip_sipredirect().
07062 { 07063 return __transmit_response(p, msg, req, XMIT_CRITICAL); 07064 }
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 6992 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.
06993 { 06994 struct sip_pvt *p = NULL; 06995 06996 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06997 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06998 return -1; 06999 } 07000 07001 /* if the structure was just allocated, initialize it */ 07002 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 07003 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 07004 if (ast_string_field_init(p, 512)) 07005 return -1; 07006 } 07007 07008 /* Initialize the bare minimum */ 07009 p->method = intended_method; 07010 07011 if (sin) { 07012 p->sa = *sin; 07013 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07014 p->ourip = __ourip; 07015 } else 07016 p->ourip = __ourip; 07017 07018 p->branch = ast_random(); 07019 make_our_tag(p->tag, sizeof(p->tag)); 07020 p->ocseq = INITIAL_CSEQ; 07021 07022 if (useglobal_nat && sin) { 07023 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 07024 p->recv = *sin; 07025 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 07026 } 07027 check_via(p, req); 07028 07029 ast_string_field_set(p, fromdomain, default_fromdomain); 07030 build_via(p); 07031 ast_string_field_set(p, callid, callid); 07032 07033 /* Use this temporary pvt structure to send the message */ 07034 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 07035 07036 /* Free the string fields, but not the pool space */ 07037 ast_string_field_reset_all(p); 07038 07039 return 0; 07040 }
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 7088 of file chan_sip.c.
References add_header(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
07089 { 07090 struct sip_request resp; 07091 respprep(&resp, p, msg, req); 07092 add_header(&resp, "Accept", "application/sdp"); 07093 return send_response(p, &resp, reliable, 0); 07094 }
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 7097 of file chan_sip.c.
References add_header(), 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().
07098 { 07099 struct sip_request resp; 07100 char tmp[512]; 07101 int seqno = 0; 07102 07103 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 07104 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 07105 return -1; 07106 } 07107 /* Stale means that they sent us correct authentication, but 07108 based it on an old challenge (nonce) */ 07109 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 07110 respprep(&resp, p, msg, req); 07111 add_header(&resp, header, tmp); 07112 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 07113 return send_response(p, &resp, reliable, seqno); 07114 }
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 7079 of file chan_sip.c.
References append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
07080 { 07081 struct sip_request resp; 07082 respprep(&resp, p, msg, req); 07083 append_date(&resp); 07084 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 07085 }
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 7637 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().
07638 { 07639 struct sip_request resp; 07640 int seqno; 07641 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07642 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07643 return -1; 07644 } 07645 respprep(&resp, p, msg, req); 07646 if (p->rtp) { 07647 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07648 if (option_debug) 07649 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 07650 ast_rtp_codec_setpref(p->rtp, &p->prefs); 07651 } 07652 try_suggested_sip_codec(p); 07653 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 07654 p->t38.state = T38_ENABLED; 07655 add_sdp(&resp, p, 1, 1); 07656 } else { 07657 add_sdp(&resp, p, 1, 0); 07658 } 07659 } else 07660 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 07661 if (reliable && !p->pendinginvite) 07662 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07663 return send_response(p, &resp, reliable, seqno); 07664 }
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 7598 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().
07599 { 07600 struct sip_request resp; 07601 int seqno; 07602 07603 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07604 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07605 return -1; 07606 } 07607 respprep(&resp, p, msg, req); 07608 if (p->udptl) { 07609 add_sdp(&resp, p, 0, 1); 07610 } else 07611 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 07612 if (retrans && !p->pendinginvite) 07613 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07614 return send_response(p, &resp, retrans, seqno); 07615 }
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 7049 of file chan_sip.c.
References add_header(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
07050 { 07051 struct sip_request resp; 07052 respprep(&resp, p, msg, req); 07053 append_date(&resp); 07054 add_header(&resp, "Unsupported", unsupported); 07055 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 07056 }
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 8335 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().
08336 { 08337 if (!p->initreq.headers) /* Initialize first request before sending */ 08338 initialize_initreq(p, req); 08339 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 08340 }
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 8103 of file chan_sip.c.
References add_content(), add_header(), 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(), handle_request_subscribe(), and notify_extenstate_update().
08104 { 08105 char tmp[4000], from[256], to[256]; 08106 char *t = tmp, *c, *mfrom, *mto; 08107 size_t maxbytes = sizeof(tmp); 08108 struct sip_request req; 08109 char hint[AST_MAX_EXTENSION]; 08110 char *statestring = "terminated"; 08111 const struct cfsubscription_types *subscriptiontype; 08112 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 08113 char *pidfstate = "--"; 08114 char *pidfnote= "Ready"; 08115 08116 memset(from, 0, sizeof(from)); 08117 memset(to, 0, sizeof(to)); 08118 memset(tmp, 0, sizeof(tmp)); 08119 08120 switch (state) { 08121 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 08122 statestring = (global_notifyringing) ? "early" : "confirmed"; 08123 local_state = NOTIFY_INUSE; 08124 pidfstate = "busy"; 08125 pidfnote = "Ringing"; 08126 break; 08127 case AST_EXTENSION_RINGING: 08128 statestring = "early"; 08129 local_state = NOTIFY_INUSE; 08130 pidfstate = "busy"; 08131 pidfnote = "Ringing"; 08132 break; 08133 case AST_EXTENSION_INUSE: 08134 statestring = "confirmed"; 08135 local_state = NOTIFY_INUSE; 08136 pidfstate = "busy"; 08137 pidfnote = "On the phone"; 08138 break; 08139 case AST_EXTENSION_BUSY: 08140 statestring = "confirmed"; 08141 local_state = NOTIFY_CLOSED; 08142 pidfstate = "busy"; 08143 pidfnote = "On the phone"; 08144 break; 08145 case AST_EXTENSION_UNAVAILABLE: 08146 statestring = "terminated"; 08147 local_state = NOTIFY_CLOSED; 08148 pidfstate = "away"; 08149 pidfnote = "Unavailable"; 08150 break; 08151 case AST_EXTENSION_ONHOLD: 08152 statestring = "confirmed"; 08153 local_state = NOTIFY_CLOSED; 08154 pidfstate = "busy"; 08155 pidfnote = "On Hold"; 08156 break; 08157 case AST_EXTENSION_NOT_INUSE: 08158 default: 08159 /* Default setting */ 08160 break; 08161 } 08162 08163 subscriptiontype = find_subscription_type(p->subscribed); 08164 08165 /* Check which device/devices we are watching and if they are registered */ 08166 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 08167 char *hint2 = hint, *individual_hint = NULL; 08168 int hint_count = 0, unavailable_count = 0; 08169 08170 while ((individual_hint = strsep(&hint2, "&"))) { 08171 hint_count++; 08172 08173 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 08174 unavailable_count++; 08175 } 08176 08177 /* If none of the hinted devices are registered, we will 08178 * override notification and show no availability. 08179 */ 08180 if (hint_count > 0 && hint_count == unavailable_count) { 08181 local_state = NOTIFY_CLOSED; 08182 pidfstate = "away"; 08183 pidfnote = "Not online"; 08184 } 08185 } 08186 08187 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 08188 c = get_in_brackets(from); 08189 if (strncasecmp(c, "sip:", 4)) { 08190 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 08191 return -1; 08192 } 08193 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 08194 08195 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 08196 c = get_in_brackets(to); 08197 if (strncasecmp(c, "sip:", 4)) { 08198 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 08199 return -1; 08200 } 08201 mto = strsep(&c, ";"); /* trim ; and beyond */ 08202 08203 reqprep(&req, p, SIP_NOTIFY, 0, 1); 08204 08205 08206 add_header(&req, "Event", subscriptiontype->event); 08207 add_header(&req, "Content-Type", subscriptiontype->mediatype); 08208 switch(state) { 08209 case AST_EXTENSION_DEACTIVATED: 08210 if (timeout) 08211 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08212 else { 08213 add_header(&req, "Subscription-State", "terminated;reason=probation"); 08214 add_header(&req, "Retry-After", "60"); 08215 } 08216 break; 08217 case AST_EXTENSION_REMOVED: 08218 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 08219 break; 08220 default: 08221 if (p->expiry) 08222 add_header(&req, "Subscription-State", "active"); 08223 else /* Expired */ 08224 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 08225 } 08226 switch (p->subscribed) { 08227 case XPIDF_XML: 08228 case CPIM_PIDF_XML: 08229 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 08230 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 08231 ast_build_string(&t, &maxbytes, "<presence>\n"); 08232 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 08233 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 08234 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 08235 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 08236 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 08237 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 08238 break; 08239 case PIDF_XML: /* Eyebeam supports this format */ 08240 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 08241 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); 08242 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 08243 if (pidfstate[0] != '-') 08244 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 08245 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 08246 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 08247 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 08248 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 08249 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 08250 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 08251 else 08252 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 08253 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 08254 break; 08255 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 08256 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 08257 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); 08258 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 08259 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 08260 else 08261 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 08262 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 08263 if (state == AST_EXTENSION_ONHOLD) { 08264 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 08265 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 08266 "</target>\n</local>\n", mto); 08267 } 08268 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 08269 break; 08270 case NONE: 08271 default: 08272 break; 08273 } 08274 08275 if (t > tmp + sizeof(tmp)) 08276 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 08277 08278 add_content(&req, tmp); 08279 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 08280 08281 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08282 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3999 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().
04000 { 04001 int fmt; 04002 const char *codec; 04003 04004 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 04005 if (!codec) 04006 return; 04007 04008 fmt = ast_getformatbyname(codec); 04009 if (fmt) { 04010 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 04011 if (p->jointcapability & fmt) { 04012 p->jointcapability &= fmt; 04013 p->capability &= fmt; 04014 } else 04015 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 04016 } else 04017 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 04018 return; 04019 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 20362 of file chan_sip.c.
References __sip_destroy(), app_dtmfmode, app_sipaddheader, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, 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, global_contact_ha, iflist, iflock, sip_extenstate_update::list, 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, update(), and userl.
20363 { 20364 struct sip_pvt *p, *pl; 20365 struct sip_extenstate_update *update; 20366 20367 /* First, take us out of the channel type list */ 20368 ast_channel_unregister(&sip_tech); 20369 20370 /* Unregister dial plan functions */ 20371 ast_custom_function_unregister(&sipchaninfo_function); 20372 ast_custom_function_unregister(&sippeer_function); 20373 ast_custom_function_unregister(&sip_header_function); 20374 ast_custom_function_unregister(&checksipdomain_function); 20375 20376 /* Unregister dial plan applications */ 20377 ast_unregister_application(app_dtmfmode); 20378 ast_unregister_application(app_sipaddheader); 20379 20380 /* Unregister CLI commands */ 20381 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 20382 20383 /* Disconnect from the RTP subsystem */ 20384 ast_rtp_proto_unregister(&sip_rtp); 20385 20386 /* Disconnect from UDPTL */ 20387 ast_udptl_proto_unregister(&sip_udptl); 20388 20389 /* Unregister AMI actions */ 20390 ast_manager_unregister("SIPpeers"); 20391 ast_manager_unregister("SIPshowpeer"); 20392 20393 ast_mutex_lock(&iflock); 20394 /* Hangup all interfaces if they have an owner */ 20395 for (p = iflist; p ; p = p->next) { 20396 if (p->owner) 20397 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 20398 } 20399 ast_mutex_unlock(&iflock); 20400 20401 ast_mutex_lock(&monlock); 20402 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 20403 pthread_cancel(monitor_thread); 20404 pthread_kill(monitor_thread, SIGURG); 20405 pthread_join(monitor_thread, NULL); 20406 } 20407 monitor_thread = AST_PTHREADT_STOP; 20408 ast_mutex_unlock(&monlock); 20409 20410 restartdestroy: 20411 ast_mutex_lock(&iflock); 20412 /* Destroy all the interfaces and free their memory */ 20413 p = iflist; 20414 while (p) { 20415 pl = p; 20416 p = p->next; 20417 if (__sip_destroy(pl, TRUE) < 0) { 20418 /* Something is still bridged, let it react to getting a hangup */ 20419 iflist = p; 20420 ast_mutex_unlock(&iflock); 20421 usleep(1); 20422 goto restartdestroy; 20423 } 20424 } 20425 iflist = NULL; 20426 ast_mutex_unlock(&iflock); 20427 20428 /* Free memory for local network address mask */ 20429 ast_free_ha(localaddr); 20430 20431 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 20432 ASTOBJ_CONTAINER_DESTROY(&userl); 20433 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 20434 ASTOBJ_CONTAINER_DESTROY(&peerl); 20435 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 20436 ASTOBJ_CONTAINER_DESTROY(®l); 20437 20438 AST_LIST_LOCK(&sip_extenstate_updates); 20439 AST_LIST_TRAVERSE_SAFE_BEGIN(&sip_extenstate_updates, update, list) { 20440 AST_LIST_REMOVE_CURRENT(&sip_extenstate_updates, list); 20441 ast_free(update); 20442 } 20443 AST_LIST_TRAVERSE_SAFE_END 20444 AST_LIST_UNLOCK(&sip_extenstate_updates); 20445 20446 clear_realm_authentication(authl); 20447 clear_sip_domains(); 20448 ast_free_ha(global_contact_ha); 20449 close(sipsock); 20450 sched_context_destroy(sched); 20451 20452 return 0; 20453 }
static void unmark_extenstate_update | ( | struct sip_pvt * | pvt | ) | [static] |
Definition at line 9695 of file chan_sip.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, sip_extenstate_update::list, sip_extenstate_update::pvt, and update().
Referenced by do_monitor().
09696 { 09697 struct sip_extenstate_update *update = NULL; 09698 09699 if (AST_LIST_EMPTY(&sip_extenstate_updates)) { 09700 /* avoid holding the lock if possible */ 09701 return; 09702 } 09703 09704 AST_LIST_LOCK(&sip_extenstate_updates); 09705 AST_LIST_TRAVERSE(&sip_extenstate_updates, update, list) { 09706 if (update->pvt == pvt) { 09707 update->marked = 0; 09708 } 09709 } 09710 AST_LIST_UNLOCK(&sip_extenstate_updates); 09711 }
static void* unref_provisional_keepalive | ( | struct provisional_keepalive_data * | data | ) | [static] |
Definition at line 2473 of file chan_sip.c.
References ao2_ref(), and sip_request::data.
Referenced by __sip_destroy(), and remove_provisional_keepalive_sched().
02474 { 02475 if (data) { 02476 data->sched_id = -1; 02477 data->pvt = NULL; 02478 ao2_ref(data, -1); 02479 } 02480 return NULL; 02481 }
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 3544 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().
03545 { 03546 char name[256]; 03547 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03548 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03549 struct sip_user *u = NULL; 03550 struct sip_peer *p = NULL; 03551 03552 if (option_debug > 2) 03553 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03554 03555 /* Test if we need to check call limits, in order to avoid 03556 realtime lookups if we do not need it */ 03557 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03558 return 0; 03559 03560 ast_copy_string(name, fup->username, sizeof(name)); 03561 03562 /* Check the list of users only for incoming calls */ 03563 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03564 inuse = &u->inUse; 03565 call_limit = &u->call_limit; 03566 inringing = NULL; 03567 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03568 inuse = &p->inUse; 03569 call_limit = &p->call_limit; 03570 inringing = &p->inRinging; 03571 ast_copy_string(name, fup->peername, sizeof(name)); 03572 } 03573 if (!p && !u) { 03574 if (option_debug > 1) 03575 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03576 return 0; 03577 } 03578 03579 switch(event) { 03580 /* incoming and outgoing affects the inUse counter */ 03581 case DEC_CALL_LIMIT: 03582 if ( *inuse > 0 ) { 03583 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03584 (*inuse)--; 03585 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03586 } 03587 } else { 03588 *inuse = 0; 03589 } 03590 if (inringing) { 03591 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03592 if (*inringing > 0) 03593 (*inringing)--; 03594 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03595 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03596 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03597 } 03598 } 03599 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03600 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03601 sip_peer_hold(fup, 0); 03602 } 03603 if (option_debug > 1 || sipdebug) { 03604 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03605 } 03606 break; 03607 03608 case INC_CALL_RINGING: 03609 case INC_CALL_LIMIT: 03610 if (*call_limit > 0 ) { 03611 /* Let call limit affect only outgoing calls */ 03612 if (outgoing && (*inuse >= *call_limit)) { 03613 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); 03614 if (u) 03615 ASTOBJ_UNREF(u, sip_destroy_user); 03616 else 03617 ASTOBJ_UNREF(p, sip_destroy_peer); 03618 return -1; 03619 } 03620 } 03621 if (inringing && (event == INC_CALL_RINGING)) { 03622 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03623 (*inringing)++; 03624 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03625 } 03626 } 03627 /* Continue */ 03628 (*inuse)++; 03629 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03630 if (option_debug > 1 || sipdebug) { 03631 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03632 } 03633 break; 03634 03635 case DEC_CALL_RINGING: 03636 if (inringing) { 03637 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03638 if (*inringing > 0) 03639 (*inringing)--; 03640 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03641 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03642 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03643 } 03644 } 03645 break; 03646 03647 default: 03648 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03649 } 03650 if (p) { 03651 ast_device_state_changed("SIP/%s", p->name); 03652 ASTOBJ_UNREF(p, sip_destroy_peer); 03653 } else /* u must be set */ 03654 ASTOBJ_UNREF(u, sip_destroy_user); 03655 return 0; 03656 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2783 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().
02784 { 02785 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02786 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02787 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02788 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02789 } 02790 }
static void update_provisional_keepalive | ( | struct sip_pvt * | pvt, | |
int | with_sdp | |||
) | [static] |
Definition at line 2504 of file chan_sip.c.
References ao2_alloc(), ao2_ref(), ast_sched_add(), PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_data, provisional_keepalive_data::pvt, remove_provisional_keepalive_sched(), sched, provisional_keepalive_data::sched_id, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().
Referenced by transmit_provisional_response().
02505 { 02506 remove_provisional_keepalive_sched(pvt); 02507 02508 if (!pvt->provisional_keepalive_data) { 02509 if (!(pvt->provisional_keepalive_data = ao2_alloc(sizeof(*pvt->provisional_keepalive_data), NULL))) { 02510 return; /* alloc error, can not recover */ 02511 } 02512 pvt->provisional_keepalive_data->sched_id = -1; 02513 pvt->provisional_keepalive_data->pvt = pvt; 02514 } 02515 02516 /* give the scheduler a ref */ 02517 ao2_ref(pvt->provisional_keepalive_data, +1); 02518 02519 /* schedule the provisional keepalive */ 02520 pvt->provisional_keepalive_data->sched_id = ast_sched_add(sched, 02521 PROVIS_KEEPALIVE_TIMEOUT, 02522 with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, 02523 pvt->provisional_keepalive_data); 02524 02525 /* if schedule was unsuccessful, remove the scheduler's ref */ 02526 if (pvt->provisional_keepalive_data->sched_id == -1) { 02527 ao2_ref(pvt->provisional_keepalive_data, -1); 02528 } 02529 }
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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 20459 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1317 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 575 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 595 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
char* app_sipaddheader = "SIPAddHeader" [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 20459 of file chan_sip.c.
Definition at line 1306 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 554 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1311 of file chan_sip.c.
unsigned int chan_idx [static] |
Definition at line 403 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 9398 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 20188 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 20193 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 569 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 236 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 13105 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1320 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 533 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 530 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 194 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 534 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 227 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 532 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 541 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 538 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 539 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 535 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 542 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 536 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 531 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 537 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
char* descrip_sipaddheader [static] |
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 571 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 195 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 1314 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 1313 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 1312 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 562 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 563 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 579 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 551 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 578 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 576 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 587 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), reload_config(), and unload_module().
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 545 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 588 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 598 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_destroy_peer(), sip_destroy_user(), 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 234 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 547 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 581 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 565 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 550 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 549 of file chan_sip.c.
int global_prematuremediafilter [static] |
Enable/disable premature frames in a call (causing 183 early media)
Definition at line 546 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 572 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 559 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 560 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 573 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 555 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 557 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 558 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 556 of file chan_sip.c.
int global_shrinkcallerid [static] |
enable or disable shrinking of caller id
Definition at line 561 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 577 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 864 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 567 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 566 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 568 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 574 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 13122 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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct io_context* io [static] |
The IO context
Definition at line 619 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1316 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 11719 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 11263 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 193 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 192 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 613 of file chan_sip.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 607 of file chan_sip.c.
ast_mutex_t netlock = ((ast_mutex_t) 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 605 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 13114 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 13118 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 237 of file chan_sip.c.
struct ast_config* notify_types = NULL [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1322 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 13054 of file chan_sip.c.
int ourport [static] |
Definition at line 1319 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1318 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 553 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 13096 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 570 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 596 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 594 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 592 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 618 of file chan_sip.c.
char seen_lastms = 0 [static] |
Definition at line 196 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 13078 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 13074 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 13049 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 13082 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 13069 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 13135 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 13091 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 13086 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 13101 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 13139 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 13131 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 13064 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 13059 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 = ((ast_mutex_t) 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 13127 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 615 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 616 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 1728 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 1670 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 1696 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 1737 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 13381 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 13300 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 1310 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), process_via(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 620 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 593 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 552 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 591 of file chan_sip.c.
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 [static] |
The user list: Users and friends.