#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_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_TCP (1 << 30) |
#define | SIP_PAGE2_TCP_CONNECTED (1 << 31) |
#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_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static int | __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static 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 int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
Add realm authentication in list. | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add T.38 Session Description Protocol message. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the SIP dialog list (of sip_pvt's). | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
AST_THREADSTORAGE (check_auth_buf, check_auth_buf_init) | |
AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
A per-thread temporary pvt structure. | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime, int devstate_only) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock. | |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, 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) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static int | siptcpsock_accept (int *id, int fd, short events, void *ignore) |
Accept incoming TCP connections. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | siptcpsock = -1 |
static int * | siptcpsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
The user list: Users and friends. |
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" |
SIP Methods we support.
Definition at line 475 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1869 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 368 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 369 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 367 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
#define DEC_CALL_LIMIT 0 |
Definition at line 609 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 611 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 507 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 498 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 494 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 171 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 188 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 203 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 202 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 514 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 175 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 201 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 495 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 205 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 502 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 513 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 505 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 504 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 506 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 210 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 516 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 497 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 180 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 182 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 186 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 179 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 153 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1031 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define INC_CALL_LIMIT 1 |
Definition at line 610 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 219 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 166 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 196 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 211 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1029 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 206 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 235 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 408 of file chan_sip.c.
#define RTP 1 |
Definition at line 234 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 217 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6532 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 716 of file chan_sip.c.
Referenced by __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 757 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 745 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 746 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 731 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 732 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 736 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 734 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 735 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 733 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 762 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_FREE_BIT (1 << 14) |
----
Definition at line 730 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 760 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 723 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 759 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 750 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 749 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 213 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 214 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 215 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), 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 742 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 739 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 740 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 741 of file chan_sip.c.
Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 717 of file chan_sip.c.
Referenced by __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 721 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 756 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 718 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 411 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 412 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 729 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 784 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 783 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 796 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 791 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
23: Inactive hold
Definition at line 794 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 793 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 777 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 778 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 779 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
29: Has a dialog been established?
Definition at line 799 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 780 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_UDPTL_DESTINATION)
Definition at line 803 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 776 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 786 of file chan_sip.c.
Referenced by update_call_counter().
#define SIP_PAGE2_OUTGOING_CALL (1 << 27) |
27: Is this an outgoing call?
Definition at line 797 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 795 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 772 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 769 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 773 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 781 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 775 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 785 of file chan_sip.c.
Referenced by build_peer(), does_peer_need_mwi(), and register_verify().
#define SIP_PAGE2_T38SUPPORT (7 << 20) |
T38 Fax Passthrough Support
Definition at line 787 of file chan_sip.c.
Referenced by create_addr_from_peer(), and sip_alloc().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 789 of file chan_sip.c.
Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
22: T38 Fax Passthrough Support (not implemented)
Definition at line 790 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
20: T38 Fax Passthrough Support
Definition at line 788 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_TCP (1 << 30) |
30: Should we use TCP with this peer
Definition at line 800 of file chan_sip.c.
Referenced by __sip_xmit(), _sip_show_peer(), build_via(), create_addr_from_peer(), parse_register_contact(), sip_poke_peer(), and sipsock_read().
#define SIP_PAGE2_TCP_CONNECTED (1 << 31) |
31: Is this TCP peer connected
Definition at line 801 of file chan_sip.c.
Referenced by __sip_xmit(), create_addr_from_peer(), expire_register(), parse_register_contact(), and sip_poke_peer().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 798 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 782 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 722 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 808 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 810 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 809 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 754 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 755 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 720 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 724 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 727 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 747 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 758 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 207 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 725 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 728 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 726 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 160 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 840 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 841 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 842 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 481 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 407 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 478 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 815 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 834 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_14400 (1 << 13) |
14400 bps t38FaxRate This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate
Definition at line 835 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_2400 (1 << 8) |
2400 bps t38FaxRate
Definition at line 830 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_4800 (1 << 9) |
4800 bps t38FaxRate
Definition at line 831 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_7200 (1 << 10) |
7200 bps t38FaxRate
Definition at line 832 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_9600 (1 << 11) |
9600 bps t38FaxRate
Definition at line 833 of file chan_sip.c.
Referenced by process_sdp(), and t38_get_rate().
#define T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
Unset for transferredTCF (UDPTL), set for localTCF (TPKT)
Definition at line 820 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 819 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_TRANSCODING_JBIG (1 << 2) |
Default: 0 (unset)
Definition at line 817 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 816 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 823 of file chan_sip.c.
Referenced by create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_NONE (0 << 4) |
two bits, if unset NO t38UDPEC field in T38 SDP
Definition at line 822 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 824 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 826 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 827 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 828 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 157 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1616 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 164 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 162 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 343 of file chan_sip.c.
00343 { 00344 AUTH_SUCCESSFUL = 0, 00345 AUTH_CHALLENGE_SENT = 1, 00346 AUTH_SECRET_FAILED = -1, 00347 AUTH_USERNAME_MISMATCH = -2, 00348 AUTH_NOT_FOUND = -3, 00349 AUTH_FAKE_AUTH = -4, 00350 AUTH_UNKNOWN_DOMAIN = -5, 00351 AUTH_PEER_NOT_DYNAMIC = -6, 00352 AUTH_ACL_FAILED = -7, 00353 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 679 of file chan_sip.c.
00679 { 00680 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00681 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00682 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 254 of file chan_sip.c.
00254 { 00255 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00256 INV_CALLING = 1, /*!< Invite sent, no answer */ 00257 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00258 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00259 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00260 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00261 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00262 The only way out of this is a BYE from one side */ 00263 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00264 };
Definition at line 281 of file chan_sip.c.
00281 { 00282 PARSE_REGISTER_FAILED, 00283 PARSE_REGISTER_UPDATE, 00284 PARSE_REGISTER_QUERY, 00285 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 864 of file chan_sip.c.
00864 { 00865 REFER_IDLE, /*!< No REFER is in progress */ 00866 REFER_SENT, /*!< Sent REFER to transferee */ 00867 REFER_RECEIVED, /*!< Received REFER from transferer */ 00868 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00869 REFER_ACCEPTED, /*!< Accepted by transferee */ 00870 REFER_RINGING, /*!< Target Ringing */ 00871 REFER_200OK, /*!< Answered by transfer target */ 00872 REFER_FAILED, /*!< REFER declined - go on */ 00873 REFER_NOAUTH /*!< We had no auth for REFER */ 00874 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 337 of file chan_sip.c.
00337 { 00338 PROXY_AUTH, 00339 WWW_AUTH, 00340 };
enum sip_result |
Definition at line 246 of file chan_sip.c.
00246 { 00247 AST_SUCCESS = 0, 00248 AST_FAILURE = -1, 00249 };
enum sipmethod |
SIP Request methods known by Asterisk.
SIP_UNKNOWN | |
SIP_RESPONSE | |
SIP_REGISTER | |
SIP_OPTIONS | |
SIP_NOTIFY | |
SIP_INVITE | |
SIP_ACK | |
SIP_PRACK | |
SIP_BYE | |
SIP_REFER | |
SIP_SUBSCRIBE | |
SIP_MESSAGE | |
SIP_UPDATE | |
SIP_INFO | |
SIP_CANCEL | |
SIP_PUBLISH | |
SIP_PING |
Definition at line 312 of file chan_sip.c.
00312 { 00313 SIP_UNKNOWN, /* Unknown response */ 00314 SIP_RESPONSE, /* Not request, response to outbound request */ 00315 SIP_REGISTER, 00316 SIP_OPTIONS, 00317 SIP_NOTIFY, 00318 SIP_INVITE, 00319 SIP_ACK, 00320 SIP_PRACK, /* Not supported at all */ 00321 SIP_BYE, 00322 SIP_REFER, 00323 SIP_SUBSCRIBE, 00324 SIP_MESSAGE, 00325 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00326 SIP_INFO, 00327 SIP_CANCEL, 00328 SIP_PUBLISH, /* Not supported at all */ 00329 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00330 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 356 of file chan_sip.c.
00356 { 00357 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00358 REG_STATE_REGSENT, /*!< Registration request sent */ 00359 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00360 REG_STATE_REGISTERED, /*!< Registred and done */ 00361 REG_STATE_REJECTED, /*!< Registration rejected */ 00362 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00363 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00364 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00365 };
enum subscriptiontype |
Definition at line 287 of file chan_sip.c.
00287 { 00288 NONE = 0, 00289 XPIDF_XML, 00290 DIALOG_INFO_XML, 00291 CPIM_PIDF_XML, 00292 PIDF_XML, 00293 MWI_NOTIFICATION 00294 };
enum t38state |
T38 States for a call.
Definition at line 845 of file chan_sip.c.
00845 { 00846 T38_DISABLED = 0, /*!< Not enabled */ 00847 T38_LOCAL_DIRECT, /*!< Offered from local */ 00848 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00849 T38_PEER_DIRECT, /*!< Offered from peer */ 00850 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00851 T38_ENABLED /*!< Negotiated (enabled) */ 00852 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 240 of file chan_sip.c.
00240 { 00241 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00242 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00243 };
enum xmittype |
Definition at line 274 of file chan_sip.c.
00274 { 00275 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00276 If it fails, it's critical and will cause a teardown of the session */ 00277 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00278 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00279 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4325 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04326 { 04327 int pass; 04328 04329 /* 04330 * Technically you can place arbitrary whitespace both before and after the ':' in 04331 * a header, although RFC3261 clearly says you shouldn't before, and place just 04332 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04333 * a good idea to say you can do it, and if you can do it, why in the hell would. 04334 * you say you shouldn't. 04335 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04336 * and we always allow spaces after that for compatibility. 04337 */ 04338 for (pass = 0; name && pass < 2;pass++) { 04339 int x, len = strlen(name); 04340 for (x=*start; x<req->headers; x++) { 04341 if (!strncasecmp(req->header[x], name, len)) { 04342 char *r = req->header[x] + len; /* skip name */ 04343 if (pedanticsipchecking) 04344 r = ast_skip_blanks(r); 04345 04346 if (*r == ':') { 04347 *start = x+1; 04348 return ast_skip_blanks(r+1); 04349 } 04350 } 04351 } 04352 if (pass == 0) /* Try aliases */ 04353 name = find_alias(name, NULL); 04354 } 04355 04356 /* Don't return NULL, so get_header is always a valid pointer */ 04357 return ""; 04358 }
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8154 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, STANDARD_SIP_PORT, and strsep().
Referenced by build_peer(), and set_address_from_contact().
08155 { 08156 struct hostent *hp; 08157 struct ast_hostent ahp; 08158 int port; 08159 char *c, *host, *pt; 08160 char contact_buf[256]; 08161 char *contact; 08162 08163 /* Work on a copy */ 08164 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08165 contact = contact_buf; 08166 08167 /* Make sure it's a SIP URL */ 08168 if (strncasecmp(contact, "sip:", 4)) { 08169 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08170 } else 08171 contact += 4; 08172 08173 /* Ditch arguments */ 08174 /* XXX this code is replicated also shortly below */ 08175 08176 /* Grab host */ 08177 host = strchr(contact, '@'); 08178 if (!host) { /* No username part */ 08179 host = contact; 08180 c = NULL; 08181 } else { 08182 *host++ = '\0'; 08183 } 08184 pt = strchr(host, ':'); 08185 if (pt) { 08186 *pt++ = '\0'; 08187 port = atoi(pt); 08188 } else 08189 port = STANDARD_SIP_PORT; 08190 08191 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08192 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08193 08194 /* XXX This could block for a long time XXX */ 08195 /* We should only do this if it's a name, not an IP */ 08196 hp = ast_gethostbyname(host, &ahp); 08197 if (!hp) { 08198 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08199 return -1; 08200 } 08201 sin->sin_family = AF_INET; 08202 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08203 sin->sin_port = htons(port); 08204 08205 return 0; 08206 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2169 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, DEADLOCK_AVOIDANCE, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02170 { 02171 struct sip_pkt *cur, *prev = NULL; 02172 02173 /* Just in case... */ 02174 char *msg; 02175 int res = FALSE; 02176 02177 msg = sip_methods[sipmethod].text; 02178 02179 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02180 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02181 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02182 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02183 if (!resp && (seqno == p->pendinginvite)) { 02184 if (option_debug) 02185 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02186 p->pendinginvite = 0; 02187 } 02188 /* this is our baby */ 02189 res = TRUE; 02190 UNLINK(cur, p->packets, prev); 02191 if (cur->retransid > -1) { 02192 if (sipdebug && option_debug > 3) 02193 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02194 } 02195 /* This odd section is designed to thwart a 02196 * race condition in the packet scheduler. There are 02197 * two conditions under which deleting the packet from the 02198 * scheduler can fail. 02199 * 02200 * 1. The packet has been removed from the scheduler because retransmission 02201 * is being attempted. The problem is that if the packet is currently attempting 02202 * retransmission and we are at this point in the code, then that MUST mean 02203 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02204 * lock temporarily to allow retransmission. 02205 * 02206 * 2. The packet has reached its maximum number of retransmissions and has 02207 * been permanently removed from the packet scheduler. If this is the case, then 02208 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02209 * of the retransid to -1 is ensured since in both cases p's lock is held. 02210 */ 02211 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02212 DEADLOCK_AVOIDANCE(&p->lock); 02213 } 02214 free(cur); 02215 break; 02216 } 02217 } 02218 if (option_debug) 02219 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"); 02220 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2092 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ast_test_flag, ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_ALREADYGONE, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02093 { 02094 struct sip_pvt *p = (struct sip_pvt *)data; 02095 02096 /* If this is a subscription, tell the phone that we got a timeout */ 02097 if (p->subscribed) { 02098 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02099 p->subscribed = NONE; 02100 append_history(p, "Subscribestatus", "timeout"); 02101 if (option_debug > 2) 02102 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02103 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02104 } 02105 02106 /* If there are packets still waiting for delivery, delay the destruction */ 02107 if (p->packets) { 02108 if (option_debug > 2) 02109 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02110 append_history(p, "ReliableXmit", "timeout"); 02111 return 10000; 02112 } 02113 02114 /* If we're destroying a subscription, dereference peer object too */ 02115 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02116 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02117 02118 /* Reset schedule ID */ 02119 p->autokillid = -1; 02120 02121 if (option_debug) 02122 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02123 append_history(p, "AutoDestroy", "%s", p->callid); 02124 if (p->owner) { 02125 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02126 ast_queue_hangup(p->owner); 02127 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02128 if (option_debug > 2) 02129 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02130 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02131 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02132 } else 02133 sip_destroy(p); 02134 return 0; 02135 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3101 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03102 { 03103 struct sip_pvt *cur, *prev = NULL; 03104 struct sip_pkt *cp; 03105 03106 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03107 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03108 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03109 return -1; 03110 } 03111 03112 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03113 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03114 return -1; 03115 } 03116 03117 if (sip_debug_test_pvt(p) || option_debug > 2) 03118 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03119 03120 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03121 update_call_counter(p, DEC_CALL_LIMIT); 03122 if (option_debug > 1) 03123 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03124 } 03125 03126 /* Unlink us from the owner if we have one */ 03127 if (p->owner) { 03128 if (lockowner) 03129 ast_channel_lock(p->owner); 03130 if (option_debug) 03131 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03132 p->owner->tech_pvt = NULL; 03133 /* Make sure that the channel knows its backend is going away */ 03134 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03135 if (lockowner) 03136 ast_channel_unlock(p->owner); 03137 /* Give the channel a chance to react before deallocation */ 03138 usleep(1); 03139 } 03140 03141 /* Remove link from peer to subscription of MWI */ 03142 if (p->relatedpeer) { 03143 if (p->relatedpeer->mwipvt == p) { 03144 p->relatedpeer->mwipvt = NULL; 03145 } 03146 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03147 } 03148 03149 if (dumphistory) 03150 sip_dump_history(p); 03151 03152 if (p->options) 03153 free(p->options); 03154 03155 if (p->stateid > -1) 03156 ast_extension_state_del(p->stateid, NULL); 03157 AST_SCHED_DEL(sched, p->initid); 03158 AST_SCHED_DEL(sched, p->waitid); 03159 AST_SCHED_DEL(sched, p->autokillid); 03160 03161 if (p->rtp) { 03162 ast_rtp_destroy(p->rtp); 03163 } 03164 if (p->vrtp) { 03165 ast_rtp_destroy(p->vrtp); 03166 } 03167 if (p->udptl) 03168 ast_udptl_destroy(p->udptl); 03169 if (p->refer) 03170 free(p->refer); 03171 if (p->route) { 03172 free_old_route(p->route); 03173 p->route = NULL; 03174 } 03175 if (p->registry) { 03176 if (p->registry->call == p) 03177 p->registry->call = NULL; 03178 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03179 } 03180 03181 /* Clear history */ 03182 if (p->history) { 03183 struct sip_history *hist; 03184 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03185 free(hist); 03186 p->history_entries--; 03187 } 03188 free(p->history); 03189 p->history = NULL; 03190 } 03191 03192 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03193 if (cur == p) { 03194 UNLINK(cur, iflist, prev); 03195 break; 03196 } 03197 } 03198 if (!cur) { 03199 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03200 return 0; 03201 } 03202 03203 /* remove all current packets in this dialog */ 03204 while((cp = p->packets)) { 03205 p->packets = p->packets->next; 03206 AST_SCHED_DEL(sched, cp->retransid); 03207 free(cp); 03208 } 03209 if (p->chanvars) { 03210 ast_variables_destroy(p->chanvars); 03211 p->chanvars = NULL; 03212 } 03213 ast_mutex_destroy(&p->lock); 03214 03215 ast_string_field_free_memory(p); 03216 03217 free(p); 03218 return 0; 03219 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7587 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07588 { 07589 int res; 07590 07591 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07592 return res; 07593 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2224 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02225 { 02226 struct sip_pkt *cur = NULL; 02227 02228 while (p->packets) { 02229 int method; 02230 if (cur == p->packets) { 02231 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02232 return; 02233 } 02234 cur = p->packets; 02235 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02236 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02237 } 02238 }
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 2045 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().
02046 { 02047 struct sip_pkt *pkt; 02048 int siptimer_a = DEFAULT_RETRANS; 02049 int xmitres = 0; 02050 02051 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02052 return AST_FAILURE; 02053 memcpy(pkt->data, data, len); 02054 pkt->method = sipmethod; 02055 pkt->packetlen = len; 02056 pkt->next = p->packets; 02057 pkt->owner = p; 02058 pkt->seqno = seqno; 02059 if (resp) 02060 ast_set_flag(pkt, FLAG_RESPONSE); 02061 pkt->data[len] = '\0'; 02062 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02063 pkt->retransid = -1; 02064 if (fatal) 02065 ast_set_flag(pkt, FLAG_FATAL); 02066 if (pkt->timer_t1) 02067 siptimer_a = pkt->timer_t1 * 2; 02068 02069 if (option_debug > 3 && sipdebug) 02070 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02071 pkt->retransid = -1; 02072 pkt->next = p->packets; 02073 p->packets = pkt; 02074 if (sipmethod == SIP_INVITE) { 02075 /* Note this is a pending invite */ 02076 p->pendinginvite = seqno; 02077 } 02078 02079 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02080 02081 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02082 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02083 return AST_FAILURE; 02084 } else { 02085 /* Schedule retransmission */ 02086 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02087 return AST_SUCCESS; 02088 } 02089 }
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 2241 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02242 { 02243 struct sip_pkt *cur; 02244 int res = -1; 02245 02246 for (cur = p->packets; cur; cur = cur->next) { 02247 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02248 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02249 /* this is our baby */ 02250 if (cur->retransid > -1) { 02251 if (option_debug > 3 && sipdebug) 02252 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02253 } 02254 AST_SCHED_DEL(sched, cur->retransid); 02255 res = 0; 02256 break; 02257 } 02258 } 02259 if (option_debug) 02260 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"); 02261 return res; 02262 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10978 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10979 { 10980 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 10981 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 10982 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 10983 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10984 struct sip_pvt *cur; 10985 int numchans = 0; 10986 char *referstatus = NULL; 10987 10988 if (argc != 3) 10989 return RESULT_SHOWUSAGE; 10990 ast_mutex_lock(&iflock); 10991 cur = iflist; 10992 if (!subscriptions) 10993 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10994 else 10995 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 10996 for (; cur; cur = cur->next) { 10997 referstatus = ""; 10998 if (cur->refer) { /* SIP transfer in progress */ 10999 referstatus = referstatus2str(cur->refer->status); 11000 } 11001 if (cur->subscribed == NONE && !subscriptions) { 11002 char formatbuf[SIPBUFSIZE/2]; 11003 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11004 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11005 cur->callid, 11006 cur->ocseq, cur->icseq, 11007 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11008 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11009 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11010 cur->lastmsg , 11011 referstatus 11012 ); 11013 numchans++; 11014 } 11015 if (cur->subscribed != NONE && subscriptions) { 11016 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11017 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11018 cur->callid, 11019 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11020 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11021 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11022 subscription_type2str(cur->subscribed), 11023 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11024 cur->expiry 11025 ); 11026 numchans++; 11027 } 11028 } 11029 ast_mutex_unlock(&iflock); 11030 if (!subscriptions) 11031 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 11032 else 11033 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11034 return RESULT_SUCCESS; 11035 #undef FORMAT 11036 #undef FORMAT2 11037 #undef FORMAT3 11038 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1783 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, errno, sip_pvt::flags, LOG_ERROR, LOG_WARNING, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_real_dst(), sipsock, sip_pvt::sockfd, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01784 { 01785 int res; 01786 const struct sockaddr_in *dst = sip_real_dst(p); 01787 /* This is a TCP connection*/ 01788 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TCP)) { 01789 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED)) { 01790 if (connect(p->sockfd, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)) == 0) { 01791 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01792 } else if (errno == EISCONN) { 01793 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01794 } else { 01795 ast_log(LOG_ERROR, "Connect Failed Sock: %i %s:%d %s\n",p->sockfd,ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), strerror(errno)); 01796 } 01797 } 01798 res = write(p->sockfd, data, len); 01799 } else 01800 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01801 01802 if (res == -1) { 01803 switch (errno) { 01804 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01805 case EHOSTUNREACH: /* Host can't be reached */ 01806 case ENETDOWN: /* Inteface down */ 01807 case ENETUNREACH: /* Network failure */ 01808 case ECONNREFUSED: /* ICMP port unreachable */ 01809 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01810 } 01811 } 01812 if (res != len) 01813 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)); 01814 return res; 01815 }
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 6126 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06127 { 06128 struct sip_request resp; 06129 int seqno = 0; 06130 06131 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06132 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06133 return -1; 06134 } 06135 respprep(&resp, p, msg, req); 06136 add_header_contentLength(&resp, 0); 06137 /* If we are cancelling an incoming invite for some reason, add information 06138 about the reason why we are doing this in clear text */ 06139 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06140 char buf[10]; 06141 06142 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06143 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06144 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06145 } 06146 return send_response(p, &resp, reliable, seqno); 06147 }
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 10535 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_TCP, 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().
10536 { 10537 char status[30] = ""; 10538 char cbuf[256]; 10539 struct sip_peer *peer; 10540 char codec_buf[512]; 10541 struct ast_codec_pref *pref; 10542 struct ast_variable *v; 10543 struct sip_auth *auth; 10544 int x = 0, codec = 0, load_realtime; 10545 int realtimepeers; 10546 10547 realtimepeers = ast_check_realtime("sippeers"); 10548 10549 if (argc < 4) 10550 return RESULT_SHOWUSAGE; 10551 10552 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10553 peer = find_peer(argv[3], NULL, load_realtime, 0); 10554 if (s) { /* Manager */ 10555 if (peer) { 10556 const char *id = astman_get_header(m,"ActionID"); 10557 10558 astman_append(s, "Response: Success\r\n"); 10559 if (!ast_strlen_zero(id)) 10560 astman_append(s, "ActionID: %s\r\n",id); 10561 } else { 10562 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 10563 astman_send_error(s, m, cbuf); 10564 return 0; 10565 } 10566 } 10567 if (peer && type==0 ) { /* Normal listing */ 10568 ast_cli(fd,"\n\n"); 10569 ast_cli(fd, " * Name : %s\n", peer->name); 10570 if (realtimepeers) { /* Realtime is enabled */ 10571 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10572 } 10573 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10574 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10575 for (auth = peer->auth; auth; auth = auth->next) { 10576 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10577 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10578 } 10579 ast_cli(fd, " Context : %s\n", peer->context); 10580 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10581 ast_cli(fd, " Language : %s\n", peer->language); 10582 if (!ast_strlen_zero(peer->accountcode)) 10583 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10584 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10585 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10586 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10587 if (!ast_strlen_zero(peer->fromuser)) 10588 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10589 if (!ast_strlen_zero(peer->fromdomain)) 10590 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10591 ast_cli(fd, " Callgroup : "); 10592 print_group(fd, peer->callgroup, 0); 10593 ast_cli(fd, " Pickupgroup : "); 10594 print_group(fd, peer->pickupgroup, 0); 10595 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10596 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10597 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10598 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10599 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10600 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10601 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10602 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10603 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))); 10604 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10605 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10606 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10607 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10608 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10609 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10610 #endif 10611 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10612 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10613 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10614 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10615 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10616 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10617 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10618 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10619 10620 /* - is enumerated */ 10621 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10622 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10623 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10624 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)); 10625 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10626 ast_cli(fd, " Transport : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP"); 10627 if (!ast_strlen_zero(global_regcontext)) 10628 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10629 ast_cli(fd, " Def. Username: %s\n", peer->username); 10630 ast_cli(fd, " SIP Options : "); 10631 if (peer->sipoptions) { 10632 int lastoption = -1; 10633 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10634 if (sip_options[x].id != lastoption) { 10635 if (peer->sipoptions & sip_options[x].id) 10636 ast_cli(fd, "%s ", sip_options[x].text); 10637 lastoption = x; 10638 } 10639 } 10640 } else 10641 ast_cli(fd, "(none)"); 10642 10643 ast_cli(fd, "\n"); 10644 ast_cli(fd, " Codecs : "); 10645 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10646 ast_cli(fd, "%s\n", codec_buf); 10647 ast_cli(fd, " Codec Order : ("); 10648 print_codec_to_cli(fd, &peer->prefs); 10649 ast_cli(fd, ")\n"); 10650 10651 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10652 ast_cli(fd, " Status : "); 10653 peer_status(peer, status, sizeof(status)); 10654 ast_cli(fd, "%s\n",status); 10655 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10656 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10657 if (peer->chanvars) { 10658 ast_cli(fd, " Variables :\n"); 10659 for (v = peer->chanvars ; v ; v = v->next) 10660 ast_cli(fd, " %s = %s\n", v->name, v->value); 10661 } 10662 ast_cli(fd,"\n"); 10663 ASTOBJ_UNREF(peer,sip_destroy_peer); 10664 } else if (peer && type == 1) { /* manager listing */ 10665 char buf[256]; 10666 astman_append(s, "Channeltype: SIP\r\n"); 10667 astman_append(s, "ObjectName: %s\r\n", peer->name); 10668 astman_append(s, "ChanObjectType: peer\r\n"); 10669 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10670 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10671 astman_append(s, "Context: %s\r\n", peer->context); 10672 astman_append(s, "Language: %s\r\n", peer->language); 10673 if (!ast_strlen_zero(peer->accountcode)) 10674 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10675 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10676 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10677 if (!ast_strlen_zero(peer->fromuser)) 10678 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10679 if (!ast_strlen_zero(peer->fromdomain)) 10680 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10681 astman_append(s, "Callgroup: "); 10682 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10683 astman_append(s, "Pickupgroup: "); 10684 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10685 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10686 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10687 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10688 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10689 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10690 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10691 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10692 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10693 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))); 10694 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10695 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10696 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10697 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10698 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10699 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10700 10701 /* - is enumerated */ 10702 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10703 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10704 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10705 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)); 10706 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)); 10707 astman_append(s, "Default-Username: %s\r\n", peer->username); 10708 if (!ast_strlen_zero(global_regcontext)) 10709 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10710 astman_append(s, "Codecs: "); 10711 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10712 astman_append(s, "%s\r\n", codec_buf); 10713 astman_append(s, "CodecOrder: "); 10714 pref = &peer->prefs; 10715 for(x = 0; x < 32 ; x++) { 10716 codec = ast_codec_pref_index(pref,x); 10717 if (!codec) 10718 break; 10719 astman_append(s, "%s", ast_getformatname(codec)); 10720 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10721 astman_append(s, ","); 10722 } 10723 10724 astman_append(s, "\r\n"); 10725 astman_append(s, "Status: "); 10726 peer_status(peer, status, sizeof(status)); 10727 astman_append(s, "%s\r\n", status); 10728 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10729 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10730 if (peer->chanvars) { 10731 for (v = peer->chanvars ; v ; v = v->next) { 10732 astman_append(s, "ChanVariable:\n"); 10733 astman_append(s, " %s,%s\r\n", v->name, v->value); 10734 } 10735 } 10736 10737 ASTOBJ_UNREF(peer,sip_destroy_peer); 10738 10739 } else { 10740 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10741 ast_cli(fd,"\n"); 10742 } 10743 10744 return RESULT_SUCCESS; 10745 }
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 10085 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
10086 { 10087 regex_t regexbuf; 10088 int havepattern = FALSE; 10089 10090 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10091 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10092 10093 char name[256]; 10094 int total_peers = 0; 10095 int peers_mon_online = 0; 10096 int peers_mon_offline = 0; 10097 int peers_unmon_offline = 0; 10098 int peers_unmon_online = 0; 10099 const char *id; 10100 char idtext[256] = ""; 10101 int realtimepeers; 10102 10103 realtimepeers = ast_check_realtime("sippeers"); 10104 10105 if (s) { /* Manager - get ActionID */ 10106 id = astman_get_header(m,"ActionID"); 10107 if (!ast_strlen_zero(id)) 10108 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10109 } 10110 10111 switch (argc) { 10112 case 5: 10113 if (!strcasecmp(argv[3], "like")) { 10114 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10115 return RESULT_SHOWUSAGE; 10116 havepattern = TRUE; 10117 } else 10118 return RESULT_SHOWUSAGE; 10119 case 3: 10120 break; 10121 default: 10122 return RESULT_SHOWUSAGE; 10123 } 10124 10125 if (!s) /* Normal list */ 10126 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10127 10128 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10129 char status[20] = ""; 10130 char srch[2000]; 10131 char pstatus; 10132 10133 ASTOBJ_RDLOCK(iterator); 10134 10135 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10136 ASTOBJ_UNLOCK(iterator); 10137 continue; 10138 } 10139 10140 if (!ast_strlen_zero(iterator->username) && !s) 10141 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10142 else 10143 ast_copy_string(name, iterator->name, sizeof(name)); 10144 10145 pstatus = peer_status(iterator, status, sizeof(status)); 10146 if (pstatus == 1) 10147 peers_mon_online++; 10148 else if (pstatus == 0) 10149 peers_mon_offline++; 10150 else { 10151 if (iterator->addr.sin_port == 0) 10152 peers_unmon_offline++; 10153 else 10154 peers_unmon_online++; 10155 } 10156 10157 snprintf(srch, sizeof(srch), FORMAT, name, 10158 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10159 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10160 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10161 iterator->ha ? " A " : " ", /* permit/deny */ 10162 ntohs(iterator->addr.sin_port), status, 10163 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10164 10165 if (!s) {/* Normal CLI list */ 10166 ast_cli(fd, FORMAT, name, 10167 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10168 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10169 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10170 iterator->ha ? " A " : " ", /* permit/deny */ 10171 10172 ntohs(iterator->addr.sin_port), status, 10173 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10174 } else { /* Manager format */ 10175 /* The names here need to be the same as other channels */ 10176 astman_append(s, 10177 "Event: PeerEntry\r\n%s" 10178 "Channeltype: SIP\r\n" 10179 "ObjectName: %s\r\n" 10180 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10181 "IPaddress: %s\r\n" 10182 "IPport: %d\r\n" 10183 "Dynamic: %s\r\n" 10184 "Natsupport: %s\r\n" 10185 "VideoSupport: %s\r\n" 10186 "ACL: %s\r\n" 10187 "Status: %s\r\n" 10188 "RealtimeDevice: %s\r\n\r\n", 10189 idtext, 10190 iterator->name, 10191 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10192 ntohs(iterator->addr.sin_port), 10193 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10194 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10195 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10196 iterator->ha ? "yes" : "no", /* permit/deny */ 10197 status, 10198 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10199 } 10200 10201 ASTOBJ_UNLOCK(iterator); 10202 10203 total_peers++; 10204 } while(0) ); 10205 10206 if (!s) 10207 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10208 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10209 10210 if (havepattern) 10211 regfree(®exbuf); 10212 10213 if (total) 10214 *total = total_peers; 10215 10216 10217 return RESULT_SUCCESS; 10218 #undef FORMAT 10219 #undef FORMAT2 10220 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15187 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
15188 { 15189 struct ast_rtp_quality qos; 15190 struct sip_pvt *p = chan->tech_pvt; 15191 char *all = "", *parse = ast_strdupa(preparse); 15192 AST_DECLARE_APP_ARGS(args, 15193 AST_APP_ARG(param); 15194 AST_APP_ARG(type); 15195 AST_APP_ARG(field); 15196 ); 15197 AST_STANDARD_APP_ARGS(args, parse); 15198 15199 /* Sanity check */ 15200 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15201 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15202 return 0; 15203 } 15204 15205 if (strcasecmp(args.param, "rtpqos")) 15206 return 0; 15207 15208 /* Default arguments of audio,all */ 15209 if (ast_strlen_zero(args.type)) 15210 args.type = "audio"; 15211 if (ast_strlen_zero(args.field)) 15212 args.field = "all"; 15213 15214 memset(buf, 0, buflen); 15215 memset(&qos, 0, sizeof(qos)); 15216 15217 if (strcasecmp(args.type, "AUDIO") == 0) { 15218 all = ast_rtp_get_quality(p->rtp, &qos); 15219 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15220 all = ast_rtp_get_quality(p->vrtp, &qos); 15221 } 15222 15223 if (strcasecmp(args.field, "local_ssrc") == 0) 15224 snprintf(buf, buflen, "%u", qos.local_ssrc); 15225 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15226 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15227 else if (strcasecmp(args.field, "local_jitter") == 0) 15228 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15229 else if (strcasecmp(args.field, "local_count") == 0) 15230 snprintf(buf, buflen, "%u", qos.local_count); 15231 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15232 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15233 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15234 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15235 else if (strcasecmp(args.field, "remote_jitter") == 0) 15236 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15237 else if (strcasecmp(args.field, "remote_count") == 0) 15238 snprintf(buf, buflen, "%u", qos.remote_count); 15239 else if (strcasecmp(args.field, "rtt") == 0) 15240 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15241 else if (strcasecmp(args.field, "all") == 0) 15242 ast_copy_string(buf, all, buflen); 15243 else { 15244 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15245 return -1; 15246 } 15247 return 0; 15248 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2275 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02276 { 02277 if (!req->lines) { 02278 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02279 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02280 req->len += strlen(req->data + req->len); 02281 } 02282 }
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 6331 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), sip_pvt::flags, fmt, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06334 { 06335 int rtp_code; 06336 struct ast_format_list fmt; 06337 06338 06339 if (debug) 06340 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06341 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06342 return; 06343 06344 if (p->rtp) { 06345 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06346 fmt = ast_codec_pref_getsize(pref, codec); 06347 } 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 */ 06348 return; 06349 ast_build_string(m_buf, m_size, " %d", rtp_code); 06350 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06351 ast_rtp_lookup_mime_subtype(1, codec, 06352 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06353 sample_rate); 06354 if (codec == AST_FORMAT_G729A) { 06355 /* Indicate that we don't support VAD (G.729 annex B) */ 06356 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06357 } else if (codec == AST_FORMAT_G723_1) { 06358 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06359 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06360 } else if (codec == AST_FORMAT_ILBC) { 06361 /* Add information about us using only 20/30 ms packetization */ 06362 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06363 } 06364 06365 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06366 *min_packet_size = fmt.cur_ms; 06367 06368 /* Our first codec packetization processed cannot be less than zero */ 06369 if ((*min_packet_size) == 0 && fmt.cur_ms) 06370 *min_packet_size = fmt.cur_ms; 06371 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6299 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06300 { 06301 char tmp[256]; 06302 06303 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06304 add_header(req, "Content-Type", "application/dtmf-relay"); 06305 add_header_contentLength(req, strlen(tmp)); 06306 add_line(req, tmp); 06307 return 0; 06308 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5693 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and SIP_MAX_HEADERS.
05694 { 05695 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05696 05697 if (req->headers == SIP_MAX_HEADERS) { 05698 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05699 return -1; 05700 } 05701 05702 if (req->lines) { 05703 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05704 return -1; 05705 } 05706 05707 if (maxlen <= 0) { 05708 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05709 return -1; 05710 } 05711 05712 req->header[req->headers] = req->data + req->len; 05713 05714 if (compactheaders) 05715 var = find_alias(var, var); 05716 05717 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05718 req->len += strlen(req->header[req->headers]); 05719 req->headers++; 05720 05721 return 0; 05722 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5725 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_t38_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_unsupported(), and transmit_state_notify().
05726 { 05727 char clen[10]; 05728 05729 snprintf(clen, sizeof(clen), "%d", len); 05730 return add_header(req, "Content-Length", clen); 05731 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5734 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05735 { 05736 if (req->lines == SIP_MAX_LINES) { 05737 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05738 return -1; 05739 } 05740 if (!req->lines) { 05741 /* Add extra empty return */ 05742 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05743 req->len += strlen(req->data + req->len); 05744 } 05745 if (req->len >= sizeof(req->data) - 4) { 05746 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05747 return -1; 05748 } 05749 req->line[req->lines] = req->data + req->len; 05750 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05751 req->len += strlen(req->line[req->lines]); 05752 req->lines++; 05753 return 0; 05754 }
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 6507 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().
06510 { 06511 int rtp_code; 06512 06513 if (debug) 06514 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06515 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06516 return; 06517 06518 ast_build_string(m_buf, m_size, " %d", rtp_code); 06519 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06520 ast_rtp_lookup_mime_subtype(0, format, 0), 06521 sample_rate); 06522 if (format == AST_RTP_DTMF) 06523 /* Indicate we support DTMF and FLASH... */ 06524 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06525 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 16873 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, strsep(), and username.
Referenced by build_peer().
16874 { 16875 char authcopy[256]; 16876 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16877 char *stringp; 16878 struct sip_auth *a, *b, *auth; 16879 16880 if (ast_strlen_zero(configuration)) 16881 return authlist; 16882 16883 if (option_debug) 16884 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 16885 16886 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 16887 stringp = authcopy; 16888 16889 username = stringp; 16890 realm = strrchr(stringp, '@'); 16891 if (realm) 16892 *realm++ = '\0'; 16893 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 16894 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 16895 return authlist; 16896 } 16897 stringp = username; 16898 username = strsep(&stringp, ":"); 16899 if (username) { 16900 secret = strsep(&stringp, ":"); 16901 if (!secret) { 16902 stringp = username; 16903 md5secret = strsep(&stringp,"#"); 16904 } 16905 } 16906 if (!(auth = ast_calloc(1, sizeof(*auth)))) 16907 return authlist; 16908 16909 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 16910 ast_copy_string(auth->username, username, sizeof(auth->username)); 16911 if (secret) 16912 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 16913 if (md5secret) 16914 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 16915 16916 /* find the end of the list */ 16917 for (b = NULL, a = authlist; a ; b = a, a = a->next) 16918 ; 16919 if (b) 16920 b->next = auth; /* Add structure add end of list */ 16921 else 16922 authlist = auth; 16923 16924 if (option_verbose > 2) 16925 ast_verbose("Added authentication for realm %s\n", realm); 16926 16927 return authlist; 16928 16929 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5855 of file chan_sip.c.
References add_header(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05856 { 05857 char r[SIPBUFSIZE*2], *p; 05858 int n, rem = sizeof(r); 05859 05860 if (!route) 05861 return; 05862 05863 p = r; 05864 for (;route ; route = route->next) { 05865 n = strlen(route->hop); 05866 if (rem < n+3) /* we need room for ",<route>" */ 05867 break; 05868 if (p != r) { /* add a separator after fist route */ 05869 *p++ = ','; 05870 --rem; 05871 } 05872 *p++ = '<'; 05873 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05874 p += n; 05875 *p++ = '>'; 05876 rem -= (n+2); 05877 } 05878 *p = '\0'; 05879 add_header(req, "Route", r); 05880 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6535 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06536 { 06537 int len = 0; 06538 int alreadysent = 0; 06539 06540 struct sockaddr_in sin; 06541 struct sockaddr_in vsin; 06542 struct sockaddr_in dest; 06543 struct sockaddr_in vdest = { 0, }; 06544 06545 /* SDP fields */ 06546 char *version = "v=0\r\n"; /* Protocol version */ 06547 char *subject = "s=session\r\n"; /* Subject of the session */ 06548 char owner[256]; /* Session owner/creator */ 06549 char connection[256]; /* Connection data */ 06550 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06551 char bandwidth[256] = ""; /* Max bitrate */ 06552 char *hold; 06553 char m_audio[256]; /* Media declaration line for audio */ 06554 char m_video[256]; /* Media declaration line for video */ 06555 char a_audio[1024]; /* Attributes for audio */ 06556 char a_video[1024]; /* Attributes for video */ 06557 char *m_audio_next = m_audio; 06558 char *m_video_next = m_video; 06559 size_t m_audio_left = sizeof(m_audio); 06560 size_t m_video_left = sizeof(m_video); 06561 char *a_audio_next = a_audio; 06562 char *a_video_next = a_video; 06563 size_t a_audio_left = sizeof(a_audio); 06564 size_t a_video_left = sizeof(a_video); 06565 06566 int x; 06567 int capability; 06568 int needvideo = FALSE; 06569 int debug = sip_debug_test_pvt(p); 06570 int min_audio_packet_size = 0; 06571 int min_video_packet_size = 0; 06572 06573 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06574 06575 if (!p->rtp) { 06576 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06577 return AST_FAILURE; 06578 } 06579 06580 /* Set RTP Session ID and version */ 06581 if (!p->sessionid) { 06582 p->sessionid = getpid(); 06583 p->sessionversion = p->sessionid; 06584 } else 06585 p->sessionversion++; 06586 06587 /* Get our addresses */ 06588 ast_rtp_get_us(p->rtp, &sin); 06589 if (p->vrtp) 06590 ast_rtp_get_us(p->vrtp, &vsin); 06591 06592 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06593 if (p->redirip.sin_addr.s_addr) { 06594 dest.sin_port = p->redirip.sin_port; 06595 dest.sin_addr = p->redirip.sin_addr; 06596 } else { 06597 dest.sin_addr = p->ourip; 06598 dest.sin_port = sin.sin_port; 06599 } 06600 06601 capability = p->jointcapability; 06602 06603 06604 if (option_debug > 1) { 06605 char codecbuf[SIPBUFSIZE]; 06606 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"); 06607 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06608 } 06609 06610 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06611 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06612 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06613 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06614 } 06615 #endif 06616 06617 /* Check if we need video in this call */ 06618 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06619 if (p->vrtp) { 06620 needvideo = TRUE; 06621 if (option_debug > 1) 06622 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06623 } else if (option_debug > 1) 06624 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06625 } 06626 06627 06628 /* Ok, we need video. Let's add what we need for video and set codecs. 06629 Video is handled differently than audio since we can not transcode. */ 06630 if (needvideo) { 06631 /* Determine video destination */ 06632 if (p->vredirip.sin_addr.s_addr) { 06633 vdest.sin_addr = p->vredirip.sin_addr; 06634 vdest.sin_port = p->vredirip.sin_port; 06635 } else { 06636 vdest.sin_addr = p->ourip; 06637 vdest.sin_port = vsin.sin_port; 06638 } 06639 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06640 06641 /* Build max bitrate string */ 06642 if (p->maxcallbitrate) 06643 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06644 if (debug) 06645 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06646 } 06647 06648 if (debug) 06649 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06650 06651 /* Start building generic SDP headers */ 06652 06653 /* We break with the "recommendation" and send our IP, in order that our 06654 peer doesn't have to ast_gethostbyname() us */ 06655 06656 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06657 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06658 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06659 06660 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06661 hold = "a=recvonly\r\n"; 06662 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06663 hold = "a=inactive\r\n"; 06664 else 06665 hold = "a=sendrecv\r\n"; 06666 06667 /* Now, start adding audio codecs. These are added in this order: 06668 - First what was requested by the calling channel 06669 - Then preferences in order from sip.conf device config for this peer/user 06670 - Then other codecs in capabilities, including video 06671 */ 06672 06673 /* Prefer the audio codec we were requested to use, first, no matter what 06674 Note that p->prefcodec can include video codecs, so mask them out 06675 */ 06676 if (capability & p->prefcodec) { 06677 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06678 06679 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06680 &m_audio_next, &m_audio_left, 06681 &a_audio_next, &a_audio_left, 06682 debug, &min_audio_packet_size); 06683 alreadysent |= codec; 06684 } 06685 06686 /* Start by sending our preferred audio codecs */ 06687 for (x = 0; x < 32; x++) { 06688 int codec; 06689 06690 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06691 break; 06692 06693 if (!(capability & codec)) 06694 continue; 06695 06696 if (alreadysent & codec) 06697 continue; 06698 06699 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06700 &m_audio_next, &m_audio_left, 06701 &a_audio_next, &a_audio_left, 06702 debug, &min_audio_packet_size); 06703 alreadysent |= codec; 06704 } 06705 06706 /* Now send any other common audio and video codecs, and non-codec formats: */ 06707 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06708 if (!(capability & x)) /* Codec not requested */ 06709 continue; 06710 06711 if (alreadysent & x) /* Already added to SDP */ 06712 continue; 06713 06714 if (x <= AST_FORMAT_MAX_AUDIO) 06715 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06716 &m_audio_next, &m_audio_left, 06717 &a_audio_next, &a_audio_left, 06718 debug, &min_audio_packet_size); 06719 else 06720 add_codec_to_sdp(p, x, 90000, 06721 &m_video_next, &m_video_left, 06722 &a_video_next, &a_video_left, 06723 debug, &min_video_packet_size); 06724 } 06725 06726 /* Now add DTMF RFC2833 telephony-event as a codec */ 06727 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06728 if (!(p->jointnoncodeccapability & x)) 06729 continue; 06730 06731 add_noncodec_to_sdp(p, x, 8000, 06732 &m_audio_next, &m_audio_left, 06733 &a_audio_next, &a_audio_left, 06734 debug); 06735 } 06736 06737 if (option_debug > 2) 06738 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06739 06740 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06741 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06742 06743 if (min_audio_packet_size) 06744 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06745 06746 if (min_video_packet_size) 06747 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06748 06749 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06750 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06751 06752 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06753 if (needvideo) 06754 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06755 06756 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06757 if (needvideo) /* only if video response is appropriate */ 06758 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06759 06760 add_header(resp, "Content-Type", "application/sdp"); 06761 add_header_contentLength(resp, len); 06762 add_line(resp, version); 06763 add_line(resp, owner); 06764 add_line(resp, subject); 06765 add_line(resp, connection); 06766 if (needvideo) /* only if video response is appropriate */ 06767 add_line(resp, bandwidth); 06768 add_line(resp, stime); 06769 add_line(resp, m_audio); 06770 add_line(resp, a_audio); 06771 add_line(resp, hold); 06772 if (needvideo) { /* only if video response is appropriate */ 06773 add_line(resp, m_video); 06774 add_line(resp, a_video); 06775 add_line(resp, hold); /* Repeat hold for the video stream */ 06776 } 06777 06778 /* Update lastrtprx when we send our SDP */ 06779 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06780 06781 if (option_debug > 2) { 06782 char buf[SIPBUFSIZE]; 06783 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06784 } 06785 06786 return AST_SUCCESS; 06787 }
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 16809 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, and sipdebug.
16810 { 16811 struct domain *d; 16812 16813 if (ast_strlen_zero(domain)) { 16814 ast_log(LOG_WARNING, "Zero length domain.\n"); 16815 return 1; 16816 } 16817 16818 if (!(d = ast_calloc(1, sizeof(*d)))) 16819 return 0; 16820 16821 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16822 16823 if (!ast_strlen_zero(context)) 16824 ast_copy_string(d->context, context, sizeof(d->context)); 16825 16826 d->mode = mode; 16827 16828 AST_LIST_LOCK(&domain_list); 16829 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16830 AST_LIST_UNLOCK(&domain_list); 16831 16832 if (sipdebug) 16833 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16834 16835 return 1; 16836 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6410 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06411 { 06412 int len = 0; 06413 int x = 0; 06414 struct sockaddr_in udptlsin; 06415 char v[256] = ""; 06416 char s[256] = ""; 06417 char o[256] = ""; 06418 char c[256] = ""; 06419 char t[256] = ""; 06420 char m_modem[256]; 06421 char a_modem[1024]; 06422 char *m_modem_next = m_modem; 06423 size_t m_modem_left = sizeof(m_modem); 06424 char *a_modem_next = a_modem; 06425 size_t a_modem_left = sizeof(a_modem); 06426 struct sockaddr_in udptldest = { 0, }; 06427 int debug; 06428 06429 debug = sip_debug_test_pvt(p); 06430 len = 0; 06431 if (!p->udptl) { 06432 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06433 return -1; 06434 } 06435 06436 if (!p->sessionid) { 06437 p->sessionid = getpid(); 06438 p->sessionversion = p->sessionid; 06439 } else 06440 p->sessionversion++; 06441 06442 /* Our T.38 end is */ 06443 ast_udptl_get_us(p->udptl, &udptlsin); 06444 06445 /* Determine T.38 UDPTL destination */ 06446 if (p->udptlredirip.sin_addr.s_addr) { 06447 udptldest.sin_port = p->udptlredirip.sin_port; 06448 udptldest.sin_addr = p->udptlredirip.sin_addr; 06449 } else { 06450 udptldest.sin_addr = p->ourip; 06451 udptldest.sin_port = udptlsin.sin_port; 06452 } 06453 06454 if (debug) 06455 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06456 06457 /* We break with the "recommendation" and send our IP, in order that our 06458 peer doesn't have to ast_gethostbyname() us */ 06459 06460 if (debug) { 06461 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06462 p->t38.capability, 06463 p->t38.peercapability, 06464 p->t38.jointcapability); 06465 } 06466 snprintf(v, sizeof(v), "v=0\r\n"); 06467 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06468 snprintf(s, sizeof(s), "s=session\r\n"); 06469 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06470 snprintf(t, sizeof(t), "t=0 0\r\n"); 06471 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06472 06473 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06474 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06475 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06476 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06477 if ((x = t38_get_rate(p->t38.jointcapability))) 06478 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06479 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06480 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06481 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06482 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06483 x = ast_udptl_get_local_max_datagram(p->udptl); 06484 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06485 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06486 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06487 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06488 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06489 add_header(resp, "Content-Type", "application/sdp"); 06490 add_header_contentLength(resp, len); 06491 add_line(resp, v); 06492 add_line(resp, o); 06493 add_line(resp, s); 06494 add_line(resp, c); 06495 add_line(resp, t); 06496 add_line(resp, m_modem); 06497 add_line(resp, a_modem); 06498 06499 /* Update lastrtprx when we send our SDP */ 06500 p->lastrtprx = p->lastrtptx = time(NULL); 06501 06502 return 0; 06503 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6288 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06289 { 06290 /* XXX Convert \n's to \r\n's XXX */ 06291 add_header(req, "Content-Type", "text/plain"); 06292 add_header_contentLength(req, strlen(text)); 06293 add_line(req, text); 06294 return 0; 06295 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6312 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06313 { 06314 const char *xml_is_a_huge_waste_of_space = 06315 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06316 " <media_control>\r\n" 06317 " <vc_primitive>\r\n" 06318 " <to_encoder>\r\n" 06319 " <picture_fast_update>\r\n" 06320 " </picture_fast_update>\r\n" 06321 " </to_encoder>\r\n" 06322 " </vc_primitive>\r\n" 06323 " </media_control>\r\n"; 06324 add_header(req, "Content-Type", "application/media_control+xml"); 06325 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06326 add_line(req, xml_is_a_huge_waste_of_space); 06327 return 0; 06328 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6235 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().
06236 { 06237 char tmpdat[256]; 06238 struct tm tm; 06239 time_t t = time(NULL); 06240 06241 gmtime_r(&t, &tm); 06242 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06243 add_header(req, "Date", tmpdat); 06244 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1902 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01903 { 01904 va_list ap; 01905 01906 if (!p) 01907 return; 01908 01909 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01910 && !recordhistory && !dumphistory) { 01911 return; 01912 } 01913 01914 va_start(ap, fmt); 01915 append_history_va(p, fmt, ap); 01916 va_end(ap); 01917 01918 return; 01919 }
static void static void append_history_va | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1875 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, MAX_HISTORY_ENTRIES, and strsep().
Referenced by append_history_full().
01876 { 01877 char buf[80], *c = buf; /* max history length */ 01878 struct sip_history *hist; 01879 int l; 01880 01881 vsnprintf(buf, sizeof(buf), fmt, ap); 01882 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01883 l = strlen(buf) + 1; 01884 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01885 return; 01886 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01887 free(hist); 01888 return; 01889 } 01890 memcpy(hist->event, buf, l); 01891 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01892 struct sip_history *oldest; 01893 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01894 p->history_entries--; 01895 free(oldest); 01896 } 01897 AST_LIST_INSERT_TAIL(p->history, hist, list); 01898 p->history_entries++; 01899 }
AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
sip_history | ||||
) |
history list, entry in sip_pvt
static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
domain | ||||
) | [static] |
The SIP domain list
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Session Initiation Protocol (SIP)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 13440 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().
13441 { 13442 if (chan && chan->_state == AST_STATE_UP) { 13443 if (ast_test_flag(chan, AST_FLAG_MOH)) 13444 ast_moh_stop(chan); 13445 else if (chan->generatordata) 13446 ast_deactivate_generator(chan); 13447 } 13448 }
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 1835 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01836 { 01837 struct sockaddr_in theirs, ours; 01838 01839 /* Get our local information */ 01840 ast_ouraddrfor(them, us); 01841 theirs.sin_addr = *them; 01842 ours.sin_addr = *us; 01843 01844 if (localaddr && externip.sin_addr.s_addr && 01845 (ast_apply_ha(localaddr, &theirs)) && 01846 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01847 if (externexpire && time(NULL) >= externexpire) { 01848 struct ast_hostent ahp; 01849 struct hostent *hp; 01850 01851 externexpire = time(NULL) + externrefresh; 01852 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01853 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01854 } else 01855 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01856 } 01857 *us = externip.sin_addr; 01858 if (option_debug) { 01859 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01860 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01861 } 01862 } else if (bindaddr.sin_addr.s_addr) 01863 *us = bindaddr.sin_addr; 01864 return AST_SUCCESS; 01865 }
AST_THREADSTORAGE | ( | check_auth_buf | , | |
check_auth_buf_init | ||||
) |
AST_THREADSTORAGE_CUSTOM | ( | ts_temp_pvt | , | |
temp_pvt_init | , | |||
temp_pvt_cleanup | ||||
) |
A per-thread temporary pvt structure.
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13452 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, and option_debug.
13453 { 13454 int res = 0; 13455 struct ast_channel *peera = NULL, 13456 *peerb = NULL, 13457 *peerc = NULL, 13458 *peerd = NULL; 13459 13460 13461 /* We will try to connect the transferee with the target and hangup 13462 all channels to the transferer */ 13463 if (option_debug > 3) { 13464 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13465 if (transferer->chan1) 13466 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13467 else 13468 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13469 if (target->chan1) 13470 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13471 else 13472 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13473 if (transferer->chan2) 13474 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13475 else 13476 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13477 if (target->chan2) 13478 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)"); 13479 else 13480 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13481 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13482 } 13483 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13484 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13485 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13486 peerc = transferer->chan2; /* Asterisk to Transferee */ 13487 peerd = target->chan2; /* Asterisk to Target */ 13488 if (option_debug > 2) 13489 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13490 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13491 peera = target->chan1; /* Transferer to PBX -> target channel */ 13492 peerb = transferer->chan1; /* Transferer to IVR*/ 13493 peerc = target->chan2; /* Asterisk to Target */ 13494 peerd = transferer->chan2; /* Nothing */ 13495 if (option_debug > 2) 13496 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13497 } 13498 13499 if (peera && peerb && peerc && (peerb != peerc)) { 13500 ast_quiet_chan(peera); /* Stop generators */ 13501 ast_quiet_chan(peerb); 13502 ast_quiet_chan(peerc); 13503 if (peerd) 13504 ast_quiet_chan(peerd); 13505 13506 if (option_debug > 3) 13507 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13508 if (ast_channel_masquerade(peerb, peerc)) { 13509 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13510 res = -1; 13511 } else 13512 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13513 return res; 13514 } else { 13515 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13516 if (transferer->chan1) 13517 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13518 if (target->chan1) 13519 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13520 return -2; 13521 } 13522 return 0; 13523 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2964 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, and sip_pvt::owner.
02965 { 02966 struct sip_pvt *p = (struct sip_pvt *)nothing; 02967 02968 ast_mutex_lock(&p->lock); 02969 p->initid = -1; 02970 if (p->owner) { 02971 /* XXX fails on possible deadlock */ 02972 if (!ast_channel_trylock(p->owner)) { 02973 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02974 append_history(p, "Cong", "Auto-congesting (timer)"); 02975 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02976 ast_channel_unlock(p->owner); 02977 } 02978 } 02979 ast_mutex_unlock(&p->lock); 02980 return 0; 02981 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4491 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), sip_pvt::ourip, and S_OR.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
04492 { 04493 char buf[33]; 04494 04495 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04496 04497 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04498 04499 }
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 4502 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04503 { 04504 char buf[33]; 04505 04506 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04507 04508 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04509 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6958 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06959 { 06960 /* Construct Contact: header */ 06961 if (ourport != STANDARD_SIP_PORT) 06962 ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip), ourport); 06963 else 06964 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06965 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 17140 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_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, sip_peer::sockfd, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
17141 { 17142 struct sip_peer *peer = NULL; 17143 struct ast_ha *oldha = NULL; 17144 int obproxyfound=0; 17145 int found=0; 17146 int firstpass=1; 17147 int format=0; /* Ama flags */ 17148 time_t regseconds = 0; 17149 char *varname = NULL, *varval = NULL; 17150 struct ast_variable *tmpvar = NULL; 17151 struct ast_flags peerflags[2] = {{(0)}}; 17152 struct ast_flags mask[2] = {{(0)}}; 17153 char fullcontact[sizeof(peer->fullcontact)] = ""; 17154 17155 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17156 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17157 /* We also use a case-sensitive comparison (unlike find_peer) so 17158 that case changes made to the peer name will be properly handled 17159 during reload 17160 */ 17161 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17162 17163 if (peer) { 17164 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17165 found = 1; 17166 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17167 firstpass = 0; 17168 } else { 17169 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17170 return NULL; 17171 17172 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17173 rpeerobjs++; 17174 else 17175 speerobjs++; 17176 ASTOBJ_INIT(peer); 17177 } 17178 /* Note that our peer HAS had its reference count incrased */ 17179 if (firstpass) { 17180 peer->lastmsgssent = -1; 17181 oldha = peer->ha; 17182 peer->ha = NULL; 17183 set_peer_defaults(peer); /* Set peer defaults */ 17184 } 17185 if (!found && name) 17186 ast_copy_string(peer->name, name, sizeof(peer->name)); 17187 17188 /* If we have channel variables, remove them (reload) */ 17189 if (peer->chanvars) { 17190 ast_variables_destroy(peer->chanvars); 17191 peer->chanvars = NULL; 17192 /* XXX should unregister ? */ 17193 } 17194 17195 /* If we have realm authentication information, remove them (reload) */ 17196 clear_realm_authentication(peer->auth); 17197 peer->auth = NULL; 17198 peer->sockfd = -1; 17199 17200 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17201 if (handle_common_options(&peerflags[0], &mask[0], v)) 17202 continue; 17203 if (realtime && !strcasecmp(v->name, "regseconds")) { 17204 ast_get_time_t(v->value, ®seconds, 0, NULL); 17205 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17206 inet_aton(v->value, &(peer->addr.sin_addr)); 17207 } else if (realtime && !strcasecmp(v->name, "name")) 17208 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17209 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17210 /* Reconstruct field, because realtime separates our value at the ';' */ 17211 if (!ast_strlen_zero(fullcontact)) { 17212 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17213 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17214 } else { 17215 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17216 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17217 } 17218 } else if (!strcasecmp(v->name, "secret")) 17219 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17220 else if (!strcasecmp(v->name, "md5secret")) 17221 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17222 else if (!strcasecmp(v->name, "auth")) 17223 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17224 else if (!strcasecmp(v->name, "callerid")) { 17225 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17226 } else if (!strcasecmp(v->name, "fullname")) { 17227 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17228 } else if (!strcasecmp(v->name, "cid_number")) { 17229 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17230 } else if (!strcasecmp(v->name, "context")) { 17231 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17232 } else if (!strcasecmp(v->name, "subscribecontext")) { 17233 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17234 } else if (!strcasecmp(v->name, "fromdomain")) { 17235 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17236 } else if (!strcasecmp(v->name, "usereqphone")) { 17237 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17238 } else if (!strcasecmp(v->name, "fromuser")) { 17239 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17240 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17241 if (!strcasecmp(v->value, "dynamic")) { 17242 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17243 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17244 } else { 17245 /* They'll register with us */ 17246 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17247 /* Initialize stuff if this is a new peer, or if it used to be 17248 * non-dynamic before the reload. */ 17249 memset(&peer->addr.sin_addr, 0, 4); 17250 if (peer->addr.sin_port) { 17251 /* If we've already got a port, make it the default rather than absolute */ 17252 peer->defaddr.sin_port = peer->addr.sin_port; 17253 peer->addr.sin_port = 0; 17254 } 17255 } 17256 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17257 } 17258 } else { 17259 /* Non-dynamic. Make sure we become that way if we're not */ 17260 if (!AST_SCHED_DEL(sched, peer->expire)) { 17261 struct sip_peer *peer_ptr = peer; 17262 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17263 } 17264 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17265 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17266 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17267 ASTOBJ_UNREF(peer, sip_destroy_peer); 17268 return NULL; 17269 } 17270 } 17271 if (!strcasecmp(v->name, "outboundproxy")) 17272 obproxyfound=1; 17273 else { 17274 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17275 if (!peer->addr.sin_port) 17276 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17277 } 17278 } 17279 } else if (!strcasecmp(v->name, "defaultip")) { 17280 if (ast_get_ip(&peer->defaddr, v->value)) { 17281 ASTOBJ_UNREF(peer, sip_destroy_peer); 17282 return NULL; 17283 } 17284 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17285 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17286 } else if (!strcasecmp(v->name, "port")) { 17287 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17288 peer->defaddr.sin_port = htons(atoi(v->value)); 17289 else 17290 peer->addr.sin_port = htons(atoi(v->value)); 17291 } else if (!strcasecmp(v->name, "callingpres")) { 17292 peer->callingpres = ast_parse_caller_presentation(v->value); 17293 if (peer->callingpres == -1) 17294 peer->callingpres = atoi(v->value); 17295 } else if (!strcasecmp(v->name, "username")) { 17296 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17297 } else if (!strcasecmp(v->name, "language")) { 17298 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17299 } else if (!strcasecmp(v->name, "regexten")) { 17300 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17301 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17302 peer->call_limit = atoi(v->value); 17303 if (peer->call_limit < 0) 17304 peer->call_limit = 0; 17305 } else if (!strcasecmp(v->name, "amaflags")) { 17306 format = ast_cdr_amaflags2int(v->value); 17307 if (format < 0) { 17308 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17309 } else { 17310 peer->amaflags = format; 17311 } 17312 } else if (!strcasecmp(v->name, "accountcode")) { 17313 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17314 } else if (!strcasecmp(v->name, "mohinterpret") 17315 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17316 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17317 } else if (!strcasecmp(v->name, "mohsuggest")) { 17318 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17319 } else if (!strcasecmp(v->name, "mailbox")) { 17320 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17321 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17322 /* People expect that if 'hasvoicemail' is set, that the mailbox will 17323 * be also set, even if not explicitly specified. */ 17324 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 17325 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 17326 } 17327 } else if (!strcasecmp(v->name, "subscribemwi")) { 17328 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17329 } else if (!strcasecmp(v->name, "vmexten")) { 17330 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17331 } else if (!strcasecmp(v->name, "callgroup")) { 17332 peer->callgroup = ast_get_group(v->value); 17333 } else if (!strcasecmp(v->name, "allowtransfer")) { 17334 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17335 } else if (!strcasecmp(v->name, "pickupgroup")) { 17336 peer->pickupgroup = ast_get_group(v->value); 17337 } else if (!strcasecmp(v->name, "allow")) { 17338 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17339 } else if (!strcasecmp(v->name, "disallow")) { 17340 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17341 } else if (!strcasecmp(v->name, "autoframing")) { 17342 peer->autoframing = ast_true(v->value); 17343 } else if (!strcasecmp(v->name, "rtptimeout")) { 17344 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17345 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17346 peer->rtptimeout = global_rtptimeout; 17347 } 17348 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17349 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17350 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17351 peer->rtpholdtimeout = global_rtpholdtimeout; 17352 } 17353 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17354 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17355 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17356 peer->rtpkeepalive = global_rtpkeepalive; 17357 } 17358 } else if (!strcasecmp(v->name, "setvar")) { 17359 /* Set peer channel variable */ 17360 varname = ast_strdupa(v->value); 17361 if ((varval = strchr(varname, '='))) { 17362 *varval++ = '\0'; 17363 if ((tmpvar = ast_variable_new(varname, varval))) { 17364 tmpvar->next = peer->chanvars; 17365 peer->chanvars = tmpvar; 17366 } 17367 } 17368 } else if (!strcasecmp(v->name, "qualify")) { 17369 if (!strcasecmp(v->value, "no")) { 17370 peer->maxms = 0; 17371 } else if (!strcasecmp(v->value, "yes")) { 17372 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17373 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 17374 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); 17375 peer->maxms = 0; 17376 } 17377 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17378 peer->maxcallbitrate = atoi(v->value); 17379 if (peer->maxcallbitrate < 0) 17380 peer->maxcallbitrate = default_maxcallbitrate; 17381 } 17382 } 17383 if (!ast_strlen_zero(fullcontact)) { 17384 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17385 /* We have a hostname in the fullcontact, but if we don't have an 17386 * address listed on the entry (or if it's 'dynamic'), then we need to 17387 * parse the entry to obtain the IP address, so a dynamic host can be 17388 * contacted immediately after reload (as opposed to waiting for it to 17389 * register once again). */ 17390 __set_address_from_contact(fullcontact, &peer->addr); 17391 } 17392 17393 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17394 time_t nowtime = time(NULL); 17395 17396 if ((nowtime - regseconds) > 0) { 17397 destroy_association(peer); 17398 memset(&peer->addr, 0, sizeof(peer->addr)); 17399 if (option_debug) 17400 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17401 } 17402 } 17403 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17404 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17405 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17406 global_allowsubscribe = TRUE; /* No global ban any more */ 17407 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17408 reg_source_db(peer); 17409 ASTOBJ_UNMARK(peer); 17410 ast_free_ha(oldha); 17411 return peer; 17412 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11737 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::peerauth, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11738 { 11739 char a1[256]; 11740 char a2[256]; 11741 char a1_hash[256]; 11742 char a2_hash[256]; 11743 char resp[256]; 11744 char resp_hash[256]; 11745 char uri[256]; 11746 char opaque[256] = ""; 11747 char cnonce[80]; 11748 const char *username; 11749 const char *secret; 11750 const char *md5secret; 11751 struct sip_auth *auth = NULL; /* Realm authentication */ 11752 11753 if (!ast_strlen_zero(p->domain)) 11754 ast_copy_string(uri, p->domain, sizeof(uri)); 11755 else if (!ast_strlen_zero(p->uri)) 11756 ast_copy_string(uri, p->uri, sizeof(uri)); 11757 else 11758 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11759 11760 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11761 11762 /* Check if we have separate auth credentials */ 11763 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 11764 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 11765 11766 if (auth) { 11767 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 11768 username = auth->username; 11769 secret = auth->secret; 11770 md5secret = auth->md5secret; 11771 if (sipdebug) 11772 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11773 } else { 11774 /* No authentication, use peer or register= config */ 11775 username = p->authname; 11776 secret = p->peersecret; 11777 md5secret = p->peermd5secret; 11778 } 11779 if (ast_strlen_zero(username)) /* We have no authentication */ 11780 return -1; 11781 11782 /* Calculate SIP digest response */ 11783 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11784 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11785 if (!ast_strlen_zero(md5secret)) 11786 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11787 else 11788 ast_md5_hash(a1_hash,a1); 11789 ast_md5_hash(a2_hash,a2); 11790 11791 p->noncecount++; 11792 if (!ast_strlen_zero(p->qop)) 11793 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11794 else 11795 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11796 ast_md5_hash(resp_hash, resp); 11797 11798 /* only include the opaque string if it's set */ 11799 if (!ast_strlen_zero(p->opaque)) { 11800 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11801 } 11802 11803 /* XXX We hard code our qop to "auth" for now. XXX */ 11804 if (!ast_strlen_zero(p->qop)) 11805 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); 11806 else 11807 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); 11808 11809 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11810 11811 return 0; 11812 }
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 8409 of file chan_sip.c.
References __get_header(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len, list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
08410 { 08411 struct sip_route *thishop, *head, *tail; 08412 int start = 0; 08413 int len; 08414 const char *rr, *contact, *c; 08415 08416 /* Once a persistant route is set, don't fool with it */ 08417 if (p->route && p->route_persistant) { 08418 if (option_debug) 08419 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08420 return; 08421 } 08422 08423 if (p->route) { 08424 free_old_route(p->route); 08425 p->route = NULL; 08426 } 08427 08428 /* We only want to create the route set the first time this is called */ 08429 p->route_persistant = 1; 08430 08431 /* Build a tailq, then assign it to p->route when done. 08432 * If backwards, we add entries from the head so they end up 08433 * in reverse order. However, we do need to maintain a correct 08434 * tail pointer because the contact is always at the end. 08435 */ 08436 head = NULL; 08437 tail = head; 08438 /* 1st we pass through all the hops in any Record-Route headers */ 08439 for (;;) { 08440 /* Each Record-Route header */ 08441 rr = __get_header(req, "Record-Route", &start); 08442 if (*rr == '\0') 08443 break; 08444 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08445 ++rr; 08446 len = strcspn(rr, ">") + 1; 08447 /* Make a struct route */ 08448 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08449 /* ast_calloc is not needed because all fields are initialized in this block */ 08450 ast_copy_string(thishop->hop, rr, len); 08451 if (option_debug > 1) 08452 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08453 /* Link in */ 08454 if (backwards) { 08455 /* Link in at head so they end up in reverse order */ 08456 thishop->next = head; 08457 head = thishop; 08458 /* If this was the first then it'll be the tail */ 08459 if (!tail) 08460 tail = thishop; 08461 } else { 08462 thishop->next = NULL; 08463 /* Link in at the end */ 08464 if (tail) 08465 tail->next = thishop; 08466 else 08467 head = thishop; 08468 tail = thishop; 08469 } 08470 } 08471 } 08472 } 08473 08474 /* Only append the contact if we are dealing with a strict router */ 08475 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08476 /* 2nd append the Contact: if there is one */ 08477 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08478 contact = get_header(req, "Contact"); 08479 if (!ast_strlen_zero(contact)) { 08480 if (option_debug > 1) 08481 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08482 /* Look for <: delimited address */ 08483 c = strchr(contact, '<'); 08484 if (c) { 08485 /* Take to > */ 08486 ++c; 08487 len = strcspn(c, ">") + 1; 08488 } else { 08489 /* No <> - just take the lot */ 08490 c = contact; 08491 len = strlen(contact) + 1; 08492 } 08493 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08494 /* ast_calloc is not needed because all fields are initialized in this block */ 08495 ast_copy_string(thishop->hop, c, len); 08496 thishop->next = NULL; 08497 /* Goes at the end */ 08498 if (tail) 08499 tail->next = thishop; 08500 else 08501 head = thishop; 08502 } 08503 } 08504 } 08505 08506 /* Store as new route */ 08507 p->route = head; 08508 08509 /* For debugging dump what we ended up with */ 08510 if (sip_debug_test_pvt(p)) 08511 list_route(p->route); 08512 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6968 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06969 { 06970 int send_pres_tags = TRUE; 06971 const char *privacy=NULL; 06972 const char *screen=NULL; 06973 char buf[256]; 06974 const char *clid = default_callerid; 06975 const char *clin = NULL; 06976 const char *fromdomain; 06977 06978 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06979 return; 06980 06981 if (p->owner && p->owner->cid.cid_num) 06982 clid = p->owner->cid.cid_num; 06983 if (p->owner && p->owner->cid.cid_name) 06984 clin = p->owner->cid.cid_name; 06985 if (ast_strlen_zero(clin)) 06986 clin = clid; 06987 06988 switch (p->callingpres) { 06989 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06990 privacy = "off"; 06991 screen = "no"; 06992 break; 06993 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06994 privacy = "off"; 06995 screen = "yes"; 06996 break; 06997 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06998 privacy = "off"; 06999 screen = "no"; 07000 break; 07001 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07002 privacy = "off"; 07003 screen = "yes"; 07004 break; 07005 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07006 privacy = "full"; 07007 screen = "no"; 07008 break; 07009 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07010 privacy = "full"; 07011 screen = "yes"; 07012 break; 07013 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07014 privacy = "full"; 07015 screen = "no"; 07016 break; 07017 case AST_PRES_PROHIB_NETWORK_NUMBER: 07018 privacy = "full"; 07019 screen = "yes"; 07020 break; 07021 case AST_PRES_NUMBER_NOT_AVAILABLE: 07022 send_pres_tags = FALSE; 07023 break; 07024 default: 07025 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07026 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07027 privacy = "full"; 07028 else 07029 privacy = "off"; 07030 screen = "no"; 07031 break; 07032 } 07033 07034 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07035 07036 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07037 if (send_pres_tags) 07038 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07039 ast_string_field_set(p, rpid, buf); 07040 07041 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07042 S_OR(p->fromuser, clid), 07043 fromdomain, p->tag); 07044 }
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 16960 of file chan_sip.c.
References ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
16961 { 16962 struct sip_user *user; 16963 int format; 16964 struct ast_ha *oldha = NULL; 16965 char *varname = NULL, *varval = NULL; 16966 struct ast_variable *tmpvar = NULL; 16967 struct ast_flags userflags[2] = {{(0)}}; 16968 struct ast_flags mask[2] = {{(0)}}; 16969 16970 16971 if (!(user = ast_calloc(1, sizeof(*user)))) 16972 return NULL; 16973 16974 suserobjs++; 16975 ASTOBJ_INIT(user); 16976 ast_copy_string(user->name, name, sizeof(user->name)); 16977 oldha = user->ha; 16978 user->ha = NULL; 16979 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16980 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16981 user->capability = global_capability; 16982 user->allowtransfer = global_allowtransfer; 16983 user->maxcallbitrate = default_maxcallbitrate; 16984 user->autoframing = global_autoframing; 16985 user->prefs = default_prefs; 16986 /* set default context */ 16987 strcpy(user->context, default_context); 16988 strcpy(user->language, default_language); 16989 strcpy(user->mohinterpret, default_mohinterpret); 16990 strcpy(user->mohsuggest, default_mohsuggest); 16991 /* First we walk through the v parameters list and then the alt parameters list */ 16992 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16993 if (handle_common_options(&userflags[0], &mask[0], v)) 16994 continue; 16995 16996 if (!strcasecmp(v->name, "context")) { 16997 ast_copy_string(user->context, v->value, sizeof(user->context)); 16998 } else if (!strcasecmp(v->name, "subscribecontext")) { 16999 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17000 } else if (!strcasecmp(v->name, "setvar")) { 17001 varname = ast_strdupa(v->value); 17002 if ((varval = strchr(varname,'='))) { 17003 *varval++ = '\0'; 17004 if ((tmpvar = ast_variable_new(varname, varval))) { 17005 tmpvar->next = user->chanvars; 17006 user->chanvars = tmpvar; 17007 } 17008 } 17009 } else if (!strcasecmp(v->name, "permit") || 17010 !strcasecmp(v->name, "deny")) { 17011 user->ha = ast_append_ha(v->name, v->value, user->ha); 17012 } else if (!strcasecmp(v->name, "allowtransfer")) { 17013 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17014 } else if (!strcasecmp(v->name, "secret")) { 17015 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17016 } else if (!strcasecmp(v->name, "md5secret")) { 17017 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17018 } else if (!strcasecmp(v->name, "callerid")) { 17019 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17020 } else if (!strcasecmp(v->name, "fullname")) { 17021 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17022 } else if (!strcasecmp(v->name, "cid_number")) { 17023 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17024 } else if (!strcasecmp(v->name, "callgroup")) { 17025 user->callgroup = ast_get_group(v->value); 17026 } else if (!strcasecmp(v->name, "pickupgroup")) { 17027 user->pickupgroup = ast_get_group(v->value); 17028 } else if (!strcasecmp(v->name, "language")) { 17029 ast_copy_string(user->language, v->value, sizeof(user->language)); 17030 } else if (!strcasecmp(v->name, "mohinterpret") 17031 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17032 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17033 } else if (!strcasecmp(v->name, "mohsuggest")) { 17034 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17035 } else if (!strcasecmp(v->name, "accountcode")) { 17036 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17037 } else if (!strcasecmp(v->name, "call-limit")) { 17038 user->call_limit = atoi(v->value); 17039 if (user->call_limit < 0) 17040 user->call_limit = 0; 17041 } else if (!strcasecmp(v->name, "amaflags")) { 17042 format = ast_cdr_amaflags2int(v->value); 17043 if (format < 0) { 17044 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17045 } else { 17046 user->amaflags = format; 17047 } 17048 } else if (!strcasecmp(v->name, "allow")) { 17049 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17050 } else if (!strcasecmp(v->name, "disallow")) { 17051 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17052 } else if (!strcasecmp(v->name, "autoframing")) { 17053 user->autoframing = ast_true(v->value); 17054 } else if (!strcasecmp(v->name, "callingpres")) { 17055 user->callingpres = ast_parse_caller_presentation(v->value); 17056 if (user->callingpres == -1) 17057 user->callingpres = atoi(v->value); 17058 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17059 user->maxcallbitrate = atoi(v->value); 17060 if (user->maxcallbitrate < 0) 17061 user->maxcallbitrate = default_maxcallbitrate; 17062 } 17063 /* We can't just report unknown options here because this may be a 17064 * type=friend entry. All user options are valid for a peer, but not 17065 * the other way around. */ 17066 } 17067 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17068 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17069 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17070 global_allowsubscribe = TRUE; /* No global ban any more */ 17071 ast_free_ha(oldha); 17072 return user; 17073 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1819 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, SIP_NAT_RFC3581, and SIP_PAGE2_TCP.
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().
01820 { 01821 /* Work around buggy UNIDEN UIP200 firmware */ 01822 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01823 01824 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01825 ast_string_field_build(p, via, "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s", 01826 ast_test_flag(&p->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP", ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01827 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8717 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe(), and handle_response().
08718 { 08719 struct sip_pvt *p = data; 08720 08721 ast_mutex_lock(&p->lock); 08722 08723 switch(state) { 08724 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08725 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08726 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08727 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08728 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08729 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); 08730 p->stateid = -1; 08731 p->subscribed = NONE; 08732 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08733 break; 08734 default: /* Tell user */ 08735 p->laststate = state; 08736 break; 08737 } 08738 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08739 if (!p->pendinginvite) { 08740 transmit_state_notify(p, state, 1, FALSE); 08741 } else { 08742 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08743 if many state changes happen meanwhile, we will only send a notification of the last one */ 08744 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08745 } 08746 } 08747 if (option_verbose > 1) 08748 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, 08749 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08750 08751 08752 ast_mutex_unlock(&p->lock); 08753 08754 return 0; 08755 }
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 5062 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().
05063 { 05064 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05065 sip_peer_hold(dialog, holdstate); 05066 if (global_callevents) 05067 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05068 "Channel: %s\r\n" 05069 "Uniqueid: %s\r\n", 05070 dialog->owner->name, 05071 dialog->owner->uniqueid); 05072 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05073 if (!holdstate) { /* Put off remote hold */ 05074 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05075 return; 05076 } 05077 /* No address for RTP, we're on hold */ 05078 05079 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05080 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05081 else if (sendonly == 2) /* Inactive stream */ 05082 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05083 else 05084 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05085 return; 05086 }
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 8522 of file chan_sip.c.
References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, s, S_OR, sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08525 { 08526 const char *response = "407 Proxy Authentication Required"; 08527 const char *reqheader = "Proxy-Authorization"; 08528 const char *respheader = "Proxy-Authenticate"; 08529 const char *authtoken; 08530 char a1_hash[256]; 08531 char resp_hash[256]=""; 08532 char *c; 08533 int wrongnonce = FALSE; 08534 int good_response; 08535 const char *usednonce = p->randdata; 08536 struct ast_dynamic_str *buf; 08537 int res; 08538 08539 /* table of recognised keywords, and their value in the digest */ 08540 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08541 struct x { 08542 const char *key; 08543 const char *s; 08544 } *i, keys[] = { 08545 [K_RESP] = { "response=", "" }, 08546 [K_URI] = { "uri=", "" }, 08547 [K_USER] = { "username=", "" }, 08548 [K_NONCE] = { "nonce=", "" }, 08549 [K_LAST] = { NULL, NULL} 08550 }; 08551 08552 /* Always OK if no secret */ 08553 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08554 return AUTH_SUCCESSFUL; 08555 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08556 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08557 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08558 different circumstances! What a surprise. */ 08559 response = "401 Unauthorized"; 08560 reqheader = "Authorization"; 08561 respheader = "WWW-Authenticate"; 08562 } 08563 authtoken = get_header(req, reqheader); 08564 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08565 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08566 information */ 08567 if (!reliable) { 08568 /* Resend message if this was NOT a reliable delivery. Otherwise the 08569 retransmission should get it */ 08570 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08571 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08572 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08573 } 08574 return AUTH_CHALLENGE_SENT; 08575 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08576 /* We have no auth, so issue challenge and request authentication */ 08577 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08578 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08579 /* Schedule auto destroy in 32 seconds */ 08580 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08581 return AUTH_CHALLENGE_SENT; 08582 } 08583 08584 /* --- We have auth, so check it */ 08585 08586 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08587 an example in the spec of just what it is you're doing a hash on. */ 08588 08589 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08590 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08591 08592 /* Make a copy of the response and parse it */ 08593 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08594 08595 if (res == AST_DYNSTR_BUILD_FAILED) 08596 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08597 08598 c = buf->str; 08599 08600 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08601 for (i = keys; i->key != NULL; i++) { 08602 const char *separator = ","; /* default */ 08603 08604 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08605 continue; 08606 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08607 c += strlen(i->key); 08608 if (*c == '"') { /* in quotes. Skip first and look for last */ 08609 c++; 08610 separator = "\""; 08611 } 08612 i->s = c; 08613 strsep(&c, separator); 08614 break; 08615 } 08616 if (i->key == NULL) /* not found, jump after space or comma */ 08617 strsep(&c, " ,"); 08618 } 08619 08620 /* Verify that digest username matches the username we auth as */ 08621 if (strcmp(username, keys[K_USER].s)) { 08622 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08623 username, keys[K_USER].s); 08624 /* Oops, we're trying something here */ 08625 return AUTH_USERNAME_MISMATCH; 08626 } 08627 08628 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08629 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08630 wrongnonce = TRUE; 08631 usednonce = keys[K_NONCE].s; 08632 } 08633 08634 if (!ast_strlen_zero(md5secret)) 08635 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08636 else { 08637 char a1[256]; 08638 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08639 ast_md5_hash(a1_hash, a1); 08640 } 08641 08642 /* compute the expected response to compare with what we received */ 08643 { 08644 char a2[256]; 08645 char a2_hash[256]; 08646 char resp[256]; 08647 08648 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08649 S_OR(keys[K_URI].s, uri)); 08650 ast_md5_hash(a2_hash, a2); 08651 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08652 ast_md5_hash(resp_hash, resp); 08653 } 08654 08655 good_response = keys[K_RESP].s && 08656 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08657 if (wrongnonce) { 08658 if (good_response) { 08659 if (sipdebug) 08660 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08661 /* We got working auth token, based on stale nonce . */ 08662 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08663 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08664 } else { 08665 /* Everything was wrong, so give the device one more try with a new challenge */ 08666 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08667 if (sipdebug) 08668 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08669 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08670 } else { 08671 if (sipdebug) 08672 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08673 } 08674 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08675 } 08676 08677 /* Schedule auto destroy in 32 seconds */ 08678 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08679 return AUTH_CHALLENGE_SENT; 08680 } 08681 if (good_response) { 08682 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08683 return AUTH_SUCCESSFUL; 08684 } 08685 08686 /* Ok, we have a bad username/secret pair */ 08687 /* Tell the UAS not to re-send this authentication data, because 08688 it will continue to fail 08689 */ 08690 08691 return AUTH_SECRET_FAILED; 08692 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12207 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
12208 { 12209 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12210 /* if we can't BYE, then this is really a pending CANCEL */ 12211 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12212 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12213 /* Actually don't destroy us yet, wait for the 487 on our original 12214 INVITE, but do set an autodestruct just in case we never get it. */ 12215 else { 12216 /* We have a pending outbound invite, don't send someting 12217 new in-transaction */ 12218 if (p->pendinginvite) 12219 return; 12220 12221 /* Perhaps there is an SD change INVITE outstanding */ 12222 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12223 } 12224 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12225 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12226 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12227 /* if we can't REINVITE, hold it for later */ 12228 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12229 if (option_debug) 12230 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12231 } else { 12232 if (option_debug) 12233 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12234 /* Didn't get to reinvite yet, so do it now */ 12235 transmit_reinvite_with_sdp(p); 12236 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12237 } 12238 } 12239 }
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 16839 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
16840 { 16841 struct domain *d; 16842 int result = 0; 16843 16844 AST_LIST_LOCK(&domain_list); 16845 AST_LIST_TRAVERSE(&domain_list, d, list) { 16846 if (strcasecmp(d->domain, domain)) 16847 continue; 16848 16849 if (len && !ast_strlen_zero(d->context)) 16850 ast_copy_string(context, d->context, len); 16851 16852 result = 1; 16853 break; 16854 } 16855 AST_LIST_UNLOCK(&domain_list); 16856 16857 return result; 16858 }
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 9831 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09832 { 09833 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09834 }
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 9511 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
09514 { 09515 struct sip_user *user = NULL; 09516 struct sip_peer *peer; 09517 char from[256], *c; 09518 char *of; 09519 char rpid_num[50]; 09520 const char *rpid; 09521 enum check_auth_result res = AUTH_SUCCESSFUL; 09522 char *t; 09523 char calleridname[50]; 09524 int debug=sip_debug_test_addr(sin); 09525 struct ast_variable *tmpvar = NULL, *v = NULL; 09526 char *uri2 = ast_strdupa(uri); 09527 09528 /* Terminate URI */ 09529 t = uri2; 09530 while (*t && *t > 32 && *t != ';') 09531 t++; 09532 *t = '\0'; 09533 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09534 if (pedanticsipchecking) 09535 ast_uri_decode(from); 09536 /* XXX here tries to map the username for invite things */ 09537 memset(calleridname, 0, sizeof(calleridname)); 09538 get_calleridname(from, calleridname, sizeof(calleridname)); 09539 if (calleridname[0]) 09540 ast_string_field_set(p, cid_name, calleridname); 09541 09542 rpid = get_header(req, "Remote-Party-ID"); 09543 memset(rpid_num, 0, sizeof(rpid_num)); 09544 if (!ast_strlen_zero(rpid)) 09545 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09546 09547 of = get_in_brackets(from); 09548 if (ast_strlen_zero(p->exten)) { 09549 t = uri2; 09550 if (!strncasecmp(t, "sip:", 4)) 09551 t+= 4; 09552 ast_string_field_set(p, exten, t); 09553 t = strchr(p->exten, '@'); 09554 if (t) 09555 *t = '\0'; 09556 if (ast_strlen_zero(p->our_contact)) 09557 build_contact(p); 09558 } 09559 /* save the URI part of the From header */ 09560 ast_string_field_set(p, from, of); 09561 if (strncasecmp(of, "sip:", 4)) { 09562 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09563 } else 09564 of += 4; 09565 /* Get just the username part */ 09566 if ((c = strchr(of, '@'))) { 09567 char *tmp; 09568 *c = '\0'; 09569 if ((c = strchr(of, ':'))) 09570 *c = '\0'; 09571 tmp = ast_strdupa(of); 09572 /* We need to be able to handle auth-headers looking like 09573 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09574 */ 09575 tmp = strsep(&tmp, ";"); 09576 if (ast_is_shrinkable_phonenumber(tmp)) 09577 ast_shrink_phone_number(tmp); 09578 ast_string_field_set(p, cid_num, tmp); 09579 } 09580 09581 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09582 user = find_user(of, 1); 09583 09584 /* Find user based on user name in the from header */ 09585 if (user && ast_apply_ha(user->ha, sin)) { 09586 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09587 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09588 /* copy channel vars */ 09589 for (v = user->chanvars ; v ; v = v->next) { 09590 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09591 tmpvar->next = p->chanvars; 09592 p->chanvars = tmpvar; 09593 } 09594 } 09595 p->prefs = user->prefs; 09596 /* Set Frame packetization */ 09597 if (p->rtp) { 09598 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09599 p->autoframing = user->autoframing; 09600 } 09601 /* replace callerid if rpid found, and not restricted */ 09602 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09603 char *tmp; 09604 if (*calleridname) 09605 ast_string_field_set(p, cid_name, calleridname); 09606 tmp = ast_strdupa(rpid_num); 09607 if (ast_is_shrinkable_phonenumber(tmp)) 09608 ast_shrink_phone_number(tmp); 09609 ast_string_field_set(p, cid_num, tmp); 09610 } 09611 09612 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09613 09614 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09615 if (sip_cancel_destroy(p)) 09616 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09617 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09618 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09619 /* Copy SIP extensions profile from INVITE */ 09620 if (p->sipoptions) 09621 user->sipoptions = p->sipoptions; 09622 09623 /* If we have a call limit, set flag */ 09624 if (user->call_limit) 09625 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09626 if (!ast_strlen_zero(user->context)) 09627 ast_string_field_set(p, context, user->context); 09628 if (!ast_strlen_zero(user->cid_num)) { 09629 char *tmp = ast_strdupa(user->cid_num); 09630 if (ast_is_shrinkable_phonenumber(tmp)) 09631 ast_shrink_phone_number(tmp); 09632 ast_string_field_set(p, cid_num, tmp); 09633 } 09634 if (!ast_strlen_zero(user->cid_name)) 09635 ast_string_field_set(p, cid_name, user->cid_name); 09636 ast_string_field_set(p, username, user->name); 09637 ast_string_field_set(p, peername, user->name); 09638 ast_string_field_set(p, peersecret, user->secret); 09639 ast_string_field_set(p, peermd5secret, user->md5secret); 09640 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09641 ast_string_field_set(p, accountcode, user->accountcode); 09642 ast_string_field_set(p, language, user->language); 09643 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09644 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09645 p->allowtransfer = user->allowtransfer; 09646 p->amaflags = user->amaflags; 09647 p->callgroup = user->callgroup; 09648 p->pickupgroup = user->pickupgroup; 09649 if (user->callingpres) /* User callingpres setting will override RPID header */ 09650 p->callingpres = user->callingpres; 09651 09652 /* Set default codec settings for this call */ 09653 p->capability = user->capability; /* User codec choice */ 09654 p->jointcapability = user->capability; /* Our codecs */ 09655 if (p->peercapability) /* AND with peer's codecs */ 09656 p->jointcapability &= p->peercapability; 09657 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09658 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09659 p->noncodeccapability |= AST_RTP_DTMF; 09660 else 09661 p->noncodeccapability &= ~AST_RTP_DTMF; 09662 p->jointnoncodeccapability = p->noncodeccapability; 09663 if (p->t38.peercapability) 09664 p->t38.jointcapability &= p->t38.peercapability; 09665 p->maxcallbitrate = user->maxcallbitrate; 09666 /* If we do not support video, remove video from call structure */ 09667 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09668 ast_rtp_destroy(p->vrtp); 09669 p->vrtp = NULL; 09670 } 09671 } 09672 if (user && debug) 09673 ast_verbose("Found user '%s'\n", user->name); 09674 } else { 09675 if (user) { 09676 if (!authpeer && debug) 09677 ast_verbose("Found user '%s', but fails host access\n", user->name); 09678 ASTOBJ_UNREF(user,sip_destroy_user); 09679 } 09680 user = NULL; 09681 } 09682 09683 if (!user) { 09684 /* If we didn't find a user match, check for peers */ 09685 if (sipmethod == SIP_SUBSCRIBE) 09686 /* For subscribes, match on peer name only */ 09687 peer = find_peer(of, NULL, 1, 0); 09688 else 09689 /* Look for peer based on the IP address we received data from */ 09690 /* If peer is registered from this IP address or have this as a default 09691 IP address, this call is from the peer 09692 */ 09693 peer = find_peer(NULL, &p->recv, 1, 0); 09694 09695 if (peer) { 09696 /* Set Frame packetization */ 09697 if (p->rtp) { 09698 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09699 p->autoframing = peer->autoframing; 09700 } 09701 if (debug) 09702 ast_verbose("Found peer '%s'\n", peer->name); 09703 09704 /* Take the peer */ 09705 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09706 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09707 09708 /* Copy SIP extensions profile to peer */ 09709 if (p->sipoptions) 09710 peer->sipoptions = p->sipoptions; 09711 09712 /* replace callerid if rpid found, and not restricted */ 09713 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09714 char *tmp = ast_strdupa(rpid_num); 09715 if (*calleridname) 09716 ast_string_field_set(p, cid_name, calleridname); 09717 if (ast_is_shrinkable_phonenumber(tmp)) 09718 ast_shrink_phone_number(tmp); 09719 ast_string_field_set(p, cid_num, tmp); 09720 } 09721 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09722 09723 ast_string_field_set(p, peersecret, peer->secret); 09724 ast_string_field_set(p, peermd5secret, peer->md5secret); 09725 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09726 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09727 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09728 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09729 p->callingpres = peer->callingpres; 09730 if (peer->maxms && peer->lastms) 09731 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09732 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09733 /* Pretend there is no required authentication */ 09734 ast_string_field_free(p, peersecret); 09735 ast_string_field_free(p, peermd5secret); 09736 } 09737 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09738 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09739 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09740 /* If we have a call limit, set flag */ 09741 if (peer->call_limit) 09742 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09743 ast_string_field_set(p, peername, peer->name); 09744 ast_string_field_set(p, authname, peer->name); 09745 09746 /* copy channel vars */ 09747 for (v = peer->chanvars ; v ; v = v->next) { 09748 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09749 tmpvar->next = p->chanvars; 09750 p->chanvars = tmpvar; 09751 } 09752 } 09753 if (authpeer) { 09754 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09755 } 09756 09757 if (!ast_strlen_zero(peer->username)) { 09758 ast_string_field_set(p, username, peer->username); 09759 /* Use the default username for authentication on outbound calls */ 09760 /* XXX this takes the name from the caller... can we override ? */ 09761 ast_string_field_set(p, authname, peer->username); 09762 } 09763 if (!ast_strlen_zero(peer->cid_num)) { 09764 char *tmp = ast_strdupa(peer->cid_num); 09765 if (ast_is_shrinkable_phonenumber(tmp)) 09766 ast_shrink_phone_number(tmp); 09767 ast_string_field_set(p, cid_num, tmp); 09768 } 09769 if (!ast_strlen_zero(peer->cid_name)) 09770 ast_string_field_set(p, cid_name, peer->cid_name); 09771 ast_string_field_set(p, fullcontact, peer->fullcontact); 09772 if (!ast_strlen_zero(peer->context)) 09773 ast_string_field_set(p, context, peer->context); 09774 ast_string_field_set(p, peersecret, peer->secret); 09775 ast_string_field_set(p, peermd5secret, peer->md5secret); 09776 ast_string_field_set(p, language, peer->language); 09777 ast_string_field_set(p, accountcode, peer->accountcode); 09778 p->amaflags = peer->amaflags; 09779 p->callgroup = peer->callgroup; 09780 p->pickupgroup = peer->pickupgroup; 09781 p->capability = peer->capability; 09782 p->prefs = peer->prefs; 09783 p->jointcapability = peer->capability; 09784 if (p->peercapability) 09785 p->jointcapability &= p->peercapability; 09786 p->maxcallbitrate = peer->maxcallbitrate; 09787 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09788 ast_rtp_destroy(p->vrtp); 09789 p->vrtp = NULL; 09790 } 09791 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09792 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09793 p->noncodeccapability |= AST_RTP_DTMF; 09794 else 09795 p->noncodeccapability &= ~AST_RTP_DTMF; 09796 p->jointnoncodeccapability = p->noncodeccapability; 09797 if (p->t38.peercapability) 09798 p->t38.jointcapability &= p->t38.peercapability; 09799 } 09800 ASTOBJ_UNREF(peer, sip_destroy_peer); 09801 } else { 09802 if (debug) 09803 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09804 09805 /* do we allow guests? */ 09806 if (!global_allowguest) { 09807 if (global_alwaysauthreject) 09808 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09809 else 09810 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09811 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09812 char *tmp = ast_strdupa(rpid_num); 09813 if (*calleridname) 09814 ast_string_field_set(p, cid_name, calleridname); 09815 if (ast_is_shrinkable_phonenumber(tmp)) 09816 ast_shrink_phone_number(tmp); 09817 ast_string_field_set(p, cid_num, tmp); 09818 } 09819 } 09820 09821 } 09822 09823 if (user) 09824 ASTOBJ_UNREF(user, sip_destroy_user); 09825 return res; 09826 }
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 9379 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().
09380 { 09381 char via[512]; 09382 char *c, *pt; 09383 struct hostent *hp; 09384 struct ast_hostent ahp; 09385 09386 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09387 09388 /* Work on the leftmost value of the topmost Via header */ 09389 c = strchr(via, ','); 09390 if (c) 09391 *c = '\0'; 09392 09393 /* Check for rport */ 09394 c = strstr(via, ";rport"); 09395 if (c && (c[6] != '=')) /* rport query, not answer */ 09396 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09397 09398 c = strchr(via, ';'); 09399 if (c) 09400 *c = '\0'; 09401 09402 c = strchr(via, ' '); 09403 if (c) { 09404 *c = '\0'; 09405 c = ast_skip_blanks(c+1); 09406 if ((strcasecmp(via, "SIP/2.0/UDP")) && (strcasecmp(via, "SIP/2.0/TCP"))) { 09407 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09408 return; 09409 } 09410 pt = strchr(c, ':'); 09411 if (pt) 09412 *pt++ = '\0'; /* remember port pointer */ 09413 hp = ast_gethostbyname(c, &ahp); 09414 if (!hp) { 09415 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09416 return; 09417 } 09418 memset(&p->sa, 0, sizeof(p->sa)); 09419 p->sa.sin_family = AF_INET; 09420 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09421 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09422 09423 if (sip_debug_test_pvt(p)) { 09424 const struct sockaddr_in *dst = sip_real_dst(p); 09425 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09426 } 09427 } 09428 }
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 10275 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
10276 { 10277 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10278 10279 while ((oldcontext = strsep(&old, "&"))) { 10280 stalecontext = '\0'; 10281 ast_copy_string(newlist, new, sizeof(newlist)); 10282 stringp = newlist; 10283 while ((newcontext = strsep(&stringp, "&"))) { 10284 if (strcmp(newcontext, oldcontext) == 0) { 10285 /* This is not the context you're looking for */ 10286 stalecontext = '\0'; 10287 break; 10288 } else if (strcmp(newcontext, oldcontext)) { 10289 stalecontext = oldcontext; 10290 } 10291 10292 } 10293 if (stalecontext) 10294 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10295 } 10296 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16932 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
16933 { 16934 struct sip_auth *a = authlist; 16935 struct sip_auth *b; 16936 16937 while (a) { 16938 b = a; 16939 a = a->next; 16940 free(b); 16941 } 16942 16943 return 1; 16944 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16861 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by reload_config(), and unload_module().
16862 { 16863 struct domain *d; 16864 16865 AST_LIST_LOCK(&domain_list); 16866 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16867 free(d); 16868 AST_LIST_UNLOCK(&domain_list); 16869 }
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 11090 of file chan_sip.c.
References complete_sip_peer().
11091 { 11092 if (pos == 3) 11093 return complete_sip_peer(word, state, 0); 11094 11095 return NULL; 11096 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11064 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().
11065 { 11066 char *result = NULL; 11067 int wordlen = strlen(word); 11068 int which = 0; 11069 11070 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11071 /* locking of the object is not required because only the name and flags are being compared */ 11072 if (!strncasecmp(word, iterator->name, wordlen) && 11073 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11074 ++which > state) 11075 result = ast_strdup(iterator->name); 11076 } while(0) ); 11077 return result; 11078 }
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 11158 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11159 { 11160 if (pos == 4) 11161 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11162 return NULL; 11163 }
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 11166 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11167 { 11168 if (pos == 4) 11169 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11170 11171 return NULL; 11172 }
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 11081 of file chan_sip.c.
References complete_sip_peer().
11082 { 11083 if (pos == 3) 11084 return complete_sip_peer(word, state, 0); 11085 11086 return NULL; 11087 }
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 11119 of file chan_sip.c.
References complete_sip_user().
11120 { 11121 if (pos == 3) 11122 return complete_sip_user(word, state, 0); 11123 11124 return NULL; 11125 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11099 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().
11100 { 11101 char *result = NULL; 11102 int wordlen = strlen(word); 11103 int which = 0; 11104 11105 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11106 /* locking of the object is not required because only the name and flags are being compared */ 11107 if (!strncasecmp(word, iterator->name, wordlen)) { 11108 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11109 continue; 11110 if (++which > state) { 11111 result = ast_strdup(iterator->name); 11112 } 11113 } 11114 } while(0) ); 11115 return result; 11116 }
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 11041 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
11042 { 11043 int which=0; 11044 struct sip_pvt *cur; 11045 char *c = NULL; 11046 int wordlen = strlen(word); 11047 11048 if (pos != 3) { 11049 return NULL; 11050 } 11051 11052 ast_mutex_lock(&iflock); 11053 for (cur = iflist; cur; cur = cur->next) { 11054 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11055 c = ast_strdup(cur->callid); 11056 break; 11057 } 11058 } 11059 ast_mutex_unlock(&iflock); 11060 return c; 11061 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11128 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11129 { 11130 char *c = NULL; 11131 11132 if (pos == 2) { 11133 int which = 0; 11134 char *cat = NULL; 11135 int wordlen = strlen(word); 11136 11137 /* do completion for notify type */ 11138 11139 if (!notify_types) 11140 return NULL; 11141 11142 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11143 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11144 c = ast_strdup(cat); 11145 break; 11146 } 11147 } 11148 return c; 11149 } 11150 11151 if (pos > 2) 11152 return complete_sip_peer(word, state, 0); 11153 11154 return NULL; 11155 }
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 5768 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05769 { 05770 int start = 0; 05771 int copied = 0; 05772 for (;;) { 05773 const char *tmp = __get_header(orig, field, &start); 05774 05775 if (ast_strlen_zero(tmp)) 05776 break; 05777 /* Add what we're responding to */ 05778 add_header(req, field, tmp); 05779 copied++; 05780 } 05781 return copied ? 0 : -1; 05782 }
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 5757 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05758 { 05759 const char *tmp = get_header(orig, field); 05760 05761 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05762 return add_header(req, field, tmp); 05763 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05764 return -1; 05765 }
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 6811 of file chan_sip.c.
References offset.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06812 { 06813 long offset; 06814 int x; 06815 offset = ((void *)dst) - ((void *)src); 06816 /* First copy stuff */ 06817 memcpy(dst, src, sizeof(*dst)); 06818 /* Now fix pointer arithmetic */ 06819 for (x=0; x < src->headers; x++) 06820 dst->header[x] += offset; 06821 for (x=0; x < src->lines; x++) 06822 dst->line[x] += offset; 06823 dst->rlPart1 += offset; 06824 dst->rlPart2 += offset; 06825 }
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 5790 of file chan_sip.c.
References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.
Referenced by respprep().
05791 { 05792 int copied = 0; 05793 int start = 0; 05794 05795 for (;;) { 05796 char new[512]; 05797 const char *oh = __get_header(orig, field, &start); 05798 05799 if (ast_strlen_zero(oh)) 05800 break; 05801 05802 if (!copied) { /* Only check for empty rport in topmost via header */ 05803 char leftmost[512], *others, *rport; 05804 05805 /* Only work on leftmost value */ 05806 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05807 others = strchr(leftmost, ','); 05808 if (others) 05809 *others++ = '\0'; 05810 05811 /* Find ;rport; (empty request) */ 05812 rport = strstr(leftmost, ";rport"); 05813 if (rport && *(rport+6) == '=') 05814 rport = NULL; /* We already have a parameter to rport */ 05815 05816 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05817 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05818 /* We need to add received port - rport */ 05819 char *end; 05820 05821 rport = strstr(leftmost, ";rport"); 05822 05823 if (rport) { 05824 end = strchr(rport + 1, ';'); 05825 if (end) 05826 memmove(rport, end, strlen(end) + 1); 05827 else 05828 *rport = '\0'; 05829 } 05830 05831 /* Add rport to first VIA header if requested */ 05832 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05833 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05834 ntohs(p->recv.sin_port), 05835 others ? "," : "", others ? others : ""); 05836 } else { 05837 /* We should *always* add a received to the topmost via */ 05838 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05839 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05840 others ? "," : "", others ? others : ""); 05841 } 05842 oh = new; /* the header to copy */ 05843 } /* else add the following via headers untouched */ 05844 add_header(req, field, oh); 05845 copied++; 05846 } 05847 if (!copied) { 05848 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05849 return -1; 05850 } 05851 return 0; 05852 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer | |||
) | [static] |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 2910 of file chan_sip.c.
References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02911 { 02912 struct hostent *hp; 02913 struct ast_hostent ahp; 02914 struct sip_peer *p; 02915 char *port; 02916 int portno; 02917 char host[MAXHOSTNAMELEN], *hostn; 02918 char peer[256]; 02919 02920 ast_copy_string(peer, opeer, sizeof(peer)); 02921 port = strchr(peer, ':'); 02922 if (port) 02923 *port++ = '\0'; 02924 dialog->sa.sin_family = AF_INET; 02925 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02926 p = find_peer(peer, NULL, 1, 0); 02927 02928 if (p) { 02929 int res = create_addr_from_peer(dialog, p); 02930 if (port) { 02931 portno = atoi(port); 02932 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 02933 } 02934 ASTOBJ_UNREF(p, sip_destroy_peer); 02935 return res; 02936 } 02937 hostn = peer; 02938 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02939 if (srvlookup) { 02940 char service[MAXHOSTNAMELEN]; 02941 int tportno; 02942 int ret; 02943 02944 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02945 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02946 if (ret > 0) { 02947 hostn = host; 02948 portno = tportno; 02949 } 02950 } 02951 hp = ast_gethostbyname(hostn, &ahp); 02952 if (!hp) { 02953 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02954 return -1; 02955 } 02956 ast_string_field_set(dialog, tohost, peer); 02957 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02958 dialog->sa.sin_port = htons(portno); 02959 dialog->recv = dialog->sa; 02960 return 0; 02961 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2799 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, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, SIP_PAGE2_VIDEOSUPPORT, sip_peer::sockfd, sip_pvt::sockfd, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02800 { 02801 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02802 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02803 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02804 dialog->recv = dialog->sa; 02805 } else 02806 return -1; 02807 02808 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02809 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02810 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 02811 dialog->sockfd = peer->sockfd; 02812 dialog->capability = peer->capability; 02813 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02814 ast_rtp_destroy(dialog->vrtp); 02815 dialog->vrtp = NULL; 02816 } 02817 dialog->prefs = peer->prefs; 02818 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02819 dialog->t38.capability = global_t38_capability; 02820 if (dialog->udptl) { 02821 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02822 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02823 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02824 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02825 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02826 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02827 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02828 if (option_debug > 1) 02829 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02830 } 02831 dialog->t38.jointcapability = dialog->t38.capability; 02832 } else if (dialog->udptl) { 02833 ast_udptl_destroy(dialog->udptl); 02834 dialog->udptl = NULL; 02835 } 02836 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02837 02838 if (dialog->rtp) { 02839 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02840 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02841 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02842 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02843 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02844 /* Set Frame packetization */ 02845 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02846 dialog->autoframing = peer->autoframing; 02847 } 02848 if (dialog->vrtp) { 02849 ast_rtp_setdtmf(dialog->vrtp, 0); 02850 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02851 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02852 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02853 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02854 } 02855 02856 ast_string_field_set(dialog, peername, peer->name); 02857 ast_string_field_set(dialog, authname, peer->username); 02858 ast_string_field_set(dialog, username, peer->username); 02859 ast_string_field_set(dialog, peersecret, peer->secret); 02860 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02861 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02862 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02863 ast_string_field_set(dialog, tohost, peer->tohost); 02864 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02865 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02866 char *tmpcall; 02867 char *c; 02868 tmpcall = ast_strdupa(dialog->callid); 02869 c = strchr(tmpcall, '@'); 02870 if (c) { 02871 *c = '\0'; 02872 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02873 } 02874 } 02875 if (ast_strlen_zero(dialog->tohost)) 02876 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02877 if (!ast_strlen_zero(peer->fromdomain)) 02878 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02879 if (!ast_strlen_zero(peer->fromuser)) 02880 ast_string_field_set(dialog, fromuser, peer->fromuser); 02881 if (!ast_strlen_zero(peer->language)) 02882 ast_string_field_set(dialog, language, peer->language); 02883 dialog->maxtime = peer->maxms; 02884 dialog->callgroup = peer->callgroup; 02885 dialog->pickupgroup = peer->pickupgroup; 02886 dialog->peerauth = peer->auth; 02887 dialog->allowtransfer = peer->allowtransfer; 02888 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02889 /* Minimum is settable or default to 100 ms */ 02890 if (peer->maxms && peer->lastms) 02891 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02892 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02893 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02894 dialog->noncodeccapability |= AST_RTP_DTMF; 02895 else 02896 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02897 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02898 ast_string_field_set(dialog, context, peer->context); 02899 dialog->rtptimeout = peer->rtptimeout; 02900 if (peer->call_limit) 02901 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02902 dialog->maxcallbitrate = peer->maxcallbitrate; 02903 02904 return 0; 02905 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7999 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08000 { 08001 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08002 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08003 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08004 else 08005 ast_db_del("SIP/Registry", peer->name); 08006 } 08007 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6855 of file chan_sip.c.
References ast_log(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06856 { 06857 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06858 06859 if (!*e) 06860 return -1; 06861 req->rlPart1 = e; /* method or protocol */ 06862 e = ast_skip_nonblanks(e); 06863 if (*e) 06864 *e++ = '\0'; 06865 /* Get URI or status code */ 06866 e = ast_skip_blanks(e); 06867 if ( !*e ) 06868 return -1; 06869 ast_trim_blanks(e); 06870 06871 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06872 if (strlen(e) < 3) /* status code is 3 digits */ 06873 return -1; 06874 req->rlPart2 = e; 06875 } else { /* We have a request */ 06876 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06877 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06878 e++; 06879 if (!*e) 06880 return -1; 06881 } 06882 req->rlPart2 = e; /* URI */ 06883 e = ast_skip_nonblanks(e); 06884 if (*e) 06885 *e++ = '\0'; 06886 e = ast_skip_blanks(e); 06887 if (strcasecmp(e, "SIP/2.0") ) { 06888 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06889 return -1; 06890 } 06891 } 06892 return 1; 06893 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16128 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), siptcpsock, siptcpsock_accept(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16129 { 16130 int res; 16131 struct sip_pvt *sip; 16132 struct sip_peer *peer = NULL; 16133 time_t t; 16134 int fastrestart = FALSE; 16135 int lastpeernum = -1; 16136 int curpeernum; 16137 int reloading; 16138 16139 /* Add an I/O event to our SIP UDP socket */ 16140 if (sipsock > -1) 16141 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16142 if (siptcpsock > -1) 16143 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 16144 16145 /* From here on out, we die whenever asked */ 16146 for(;;) { 16147 /* Check for a reload request */ 16148 ast_mutex_lock(&sip_reload_lock); 16149 reloading = sip_reloading; 16150 sip_reloading = FALSE; 16151 ast_mutex_unlock(&sip_reload_lock); 16152 if (reloading) { 16153 if (option_verbose > 0) 16154 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16155 sip_do_reload(sip_reloadreason); 16156 16157 /* Change the I/O fd of our UDP socket */ 16158 if (sipsock > -1) { 16159 if (sipsock_read_id) 16160 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16161 else 16162 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16163 } else if (sipsock_read_id) { 16164 ast_io_remove(io, sipsock_read_id); 16165 sipsock_read_id = NULL; 16166 } 16167 16168 if (siptcpsock > -1) { 16169 if (siptcpsock_read_id) 16170 siptcpsock_read_id = ast_io_change(io, siptcpsock_read_id, siptcpsock, NULL, 0, NULL); 16171 else 16172 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 16173 } 16174 } 16175 restartsearch: 16176 /* Check for interfaces needing to be killed */ 16177 ast_mutex_lock(&iflock); 16178 t = time(NULL); 16179 /* don't scan the interface list if it hasn't been a reasonable period 16180 of time since the last time we did it (when MWI is being sent, we can 16181 get back to this point every millisecond or less) 16182 */ 16183 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16184 /*! \note If we can't get a lock on an interface, skip it and come 16185 * back later. Note that there is the possibility of a deadlock with 16186 * sip_hangup otherwise, because sip_hangup is called with the channel 16187 * locked first, and the iface lock is attempted second. 16188 */ 16189 if (ast_mutex_trylock(&sip->lock)) 16190 continue; 16191 16192 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16193 if (sip->rtp && sip->owner && 16194 (sip->owner->_state == AST_STATE_UP) && 16195 !sip->redirip.sin_addr.s_addr && 16196 sip->t38.state != T38_ENABLED) { 16197 if (sip->lastrtptx && 16198 ast_rtp_get_rtpkeepalive(sip->rtp) && 16199 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16200 /* Need to send an empty RTP packet */ 16201 sip->lastrtptx = time(NULL); 16202 ast_rtp_sendcng(sip->rtp, 0); 16203 } 16204 if (sip->lastrtprx && 16205 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16206 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16207 /* Might be a timeout now -- see if we're on hold */ 16208 struct sockaddr_in sin; 16209 ast_rtp_get_peer(sip->rtp, &sin); 16210 if (sin.sin_addr.s_addr || 16211 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16212 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16213 /* Needs a hangup */ 16214 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16215 while (sip->owner && ast_channel_trylock(sip->owner)) { 16216 DEADLOCK_AVOIDANCE(&sip->lock); 16217 } 16218 if (sip->owner) { 16219 ast_log(LOG_NOTICE, 16220 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16221 sip->owner->name, 16222 (long) (t - sip->lastrtprx)); 16223 /* Issue a softhangup */ 16224 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16225 ast_channel_unlock(sip->owner); 16226 /* forget the timeouts for this call, since a hangup 16227 has already been requested and we don't want to 16228 repeatedly request hangups 16229 */ 16230 ast_rtp_set_rtptimeout(sip->rtp, 0); 16231 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16232 if (sip->vrtp) { 16233 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16234 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16235 } 16236 } 16237 } 16238 } 16239 } 16240 } 16241 /* If we have sessions that needs to be destroyed, do it now */ 16242 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16243 !sip->owner) { 16244 ast_mutex_unlock(&sip->lock); 16245 __sip_destroy(sip, 1); 16246 ast_mutex_unlock(&iflock); 16247 usleep(1); 16248 goto restartsearch; 16249 } 16250 ast_mutex_unlock(&sip->lock); 16251 } 16252 ast_mutex_unlock(&iflock); 16253 16254 /* XXX TODO The scheduler usage in this module does not have sufficient 16255 * synchronization being done between running the scheduler and places 16256 * scheduling tasks. As it is written, any scheduled item may not run 16257 * any sooner than about 1 second, regardless of whether a sooner time 16258 * was asked for. */ 16259 16260 pthread_testcancel(); 16261 /* Wait for sched or io */ 16262 res = ast_sched_wait(sched); 16263 if ((res < 0) || (res > 1000)) 16264 res = 1000; 16265 /* If we might need to send more mailboxes, don't wait long at all.*/ 16266 if (fastrestart) 16267 res = 1; 16268 res = ast_io_wait(io, res); 16269 if (option_debug && res > 20) 16270 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16271 ast_mutex_lock(&monlock); 16272 res = ast_sched_runq(sched); 16273 if (option_debug && res >= 20) 16274 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16275 16276 /* Send MWI notifications to peers - static and cached realtime peers */ 16277 t = time(NULL); 16278 fastrestart = FALSE; 16279 curpeernum = 0; 16280 peer = NULL; 16281 /* Find next peer that needs mwi */ 16282 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16283 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16284 fastrestart = TRUE; 16285 lastpeernum = curpeernum; 16286 peer = ASTOBJ_REF(iterator); 16287 }; 16288 curpeernum++; 16289 } while (0) 16290 ); 16291 /* Send MWI to the peer */ 16292 if (peer) { 16293 ASTOBJ_WRLOCK(peer); 16294 sip_send_mwi_to_peer(peer); 16295 ASTOBJ_UNLOCK(peer); 16296 ASTOBJ_UNREF(peer,sip_destroy_peer); 16297 } else { 16298 /* Reset where we come from */ 16299 lastpeernum = -1; 16300 } 16301 ast_mutex_unlock(&monlock); 16302 } 16303 /* Never reached */ 16304 return NULL; 16305 16306 }
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 11638 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().
11639 { 11640 char digest[1024]; 11641 11642 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11643 return -2; 11644 11645 p->authtries++; 11646 if (option_debug > 1) 11647 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11648 memset(digest, 0, sizeof(digest)); 11649 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11650 /* No way to authenticate */ 11651 return -1; 11652 } 11653 /* Now we have a reply digest */ 11654 p->options->auth = digest; 11655 p->options->authheader = respheader; 11656 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11657 }
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 11617 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().
11618 { 11619 char digest[1024]; 11620 p->authtries++; 11621 memset(digest,0,sizeof(digest)); 11622 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11623 /* There's nothing to use for authentication */ 11624 /* No digest challenge in request */ 11625 if (sip_debug_test_pvt(p) && p->registry) 11626 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11627 /* No old challenge */ 11628 return -1; 11629 } 11630 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11631 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11632 if (sip_debug_test_pvt(p) && p->registry) 11633 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11634 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11635 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2775 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02776 { 02777 const char *mode = natflags ? "On" : "Off"; 02778 02779 if (p->rtp) { 02780 if (option_debug) 02781 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02782 ast_rtp_setnat(p->rtp, natflags); 02783 } 02784 if (p->vrtp) { 02785 if (option_debug) 02786 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02787 ast_rtp_setnat(p->vrtp, natflags); 02788 } 02789 if (p->udptl) { 02790 if (option_debug) 02791 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02792 ast_udptl_setnat(p->udptl, natflags); 02793 } 02794 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16107 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.
16108 { 16109 time_t t = time(NULL); 16110 16111 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16112 !peer->mwipvt) { /* We don't have a subscription */ 16113 peer->lastmsgcheck = t; /* Reset timer */ 16114 return FALSE; 16115 } 16116 16117 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16118 return TRUE; 16119 16120 return FALSE; 16121 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10464 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10465 { 10466 switch (mode) { 10467 case SIP_DOMAIN_AUTO: 10468 return "[Automatic]"; 10469 case SIP_DOMAIN_CONFIG: 10470 return "[Configured]"; 10471 } 10472 10473 return ""; 10474 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10244 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().
10245 { 10246 switch (mode) { 10247 case SIP_DTMF_RFC2833: 10248 return "rfc2833"; 10249 case SIP_DTMF_INFO: 10250 return "info"; 10251 case SIP_DTMF_INBAND: 10252 return "inband"; 10253 case SIP_DTMF_AUTO: 10254 return "auto"; 10255 } 10256 return "<error>"; 10257 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8010 of file chan_sip.c.
References sip_peer::addr, ast_clear_flag, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_SELFDESTRUCT, SIP_PAGE2_TCP_CONNECTED, and sip_peer::sockfd.
Referenced by parse_register_contact(), and reg_source_db().
08011 { 08012 struct sip_peer *peer = (struct sip_peer *)data; 08013 08014 if (!peer) /* Hmmm. We have no peer. Weird. */ 08015 return 0; 08016 08017 memset(&peer->addr, 0, sizeof(peer->addr)); 08018 if (peer->sockfd > 0) { 08019 close(peer->sockfd); 08020 ast_clear_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 08021 } 08022 08023 destroy_association(peer); /* remove registration data from storage */ 08024 08025 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08026 register_peer_exten(peer, FALSE); /* Remove regexten */ 08027 peer->expire = -1; 08028 ast_device_state_changed("SIP/%s", peer->name); 08029 08030 /* Do we need to release this peer from memory? 08031 Only for realtime peers and autocreated peers 08032 */ 08033 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08034 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08035 struct sip_peer *peer_ptr = peer_ptr; 08036 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08037 if (peer_ptr) { 08038 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08039 } 08040 } 08041 08042 ASTOBJ_UNREF(peer, sip_destroy_peer); 08043 08044 return 0; 08045 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6945 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), SIPBUFSIZE, and strsep().
Referenced by handle_request(), and handle_request_invite().
06946 { 06947 char stripped[SIPBUFSIZE]; 06948 char *c; 06949 06950 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06951 c = get_in_brackets(stripped); 06952 c = strsep(&c, ";"); /* trim ; and beyond */ 06953 if (!ast_strlen_zero(c)) 06954 ast_string_field_set(p, uri, c); 06955 }
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 4288 of file chan_sip.c.
References aliases.
04289 { 04290 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04291 static const struct cfalias { 04292 char * const fullname; 04293 char * const shortname; 04294 } aliases[] = { 04295 { "Content-Type", "c" }, 04296 { "Content-Encoding", "e" }, 04297 { "From", "f" }, 04298 { "Call-ID", "i" }, 04299 { "Contact", "m" }, 04300 { "Content-Length", "l" }, 04301 { "Subject", "s" }, 04302 { "To", "t" }, 04303 { "Supported", "k" }, 04304 { "Refer-To", "r" }, 04305 { "Referred-By", "b" }, 04306 { "Allow-Events", "u" }, 04307 { "Event", "o" }, 04308 { "Via", "v" }, 04309 { "Accept-Contact", "a" }, 04310 { "Reject-Contact", "j" }, 04311 { "Request-Disposition", "d" }, 04312 { "Session-Expires", "x" }, 04313 { "Identity", "y" }, 04314 { "Identity-Info", "n" }, 04315 }; 04316 int x; 04317 04318 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04319 if (!strcasecmp(aliases[x].fullname, name)) 04320 return aliases[x].shortname; 04321 04322 return _default; 04323 }
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 4648 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, FALSE, sip_pvt::flags, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.
Referenced by sipsock_read().
04649 { 04650 struct sip_pvt *p = NULL; 04651 char *tag = ""; /* note, tag is never NULL */ 04652 char totag[128]; 04653 char fromtag[128]; 04654 const char *callid = get_header(req, "Call-ID"); 04655 const char *from = get_header(req, "From"); 04656 const char *to = get_header(req, "To"); 04657 const char *cseq = get_header(req, "Cseq"); 04658 04659 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04660 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04661 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04662 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04663 return NULL; /* Invalid packet */ 04664 04665 if (pedanticsipchecking) { 04666 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04667 we need more to identify a branch - so we have to check branch, from 04668 and to tags to identify a call leg. 04669 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04670 in sip.conf 04671 */ 04672 if (gettag(req, "To", totag, sizeof(totag))) 04673 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04674 gettag(req, "From", fromtag, sizeof(fromtag)); 04675 04676 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04677 04678 if (option_debug > 4 ) 04679 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); 04680 } 04681 04682 ast_mutex_lock(&iflock); 04683 for (p = iflist; p; p = p->next) { 04684 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04685 int found = FALSE; 04686 if (ast_strlen_zero(p->callid)) 04687 continue; 04688 if (req->method == SIP_REGISTER) 04689 found = (!strcmp(p->callid, callid)); 04690 else { 04691 found = !strcmp(p->callid, callid); 04692 if (pedanticsipchecking && found) { 04693 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04694 } 04695 } 04696 04697 if (option_debug > 4) 04698 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); 04699 04700 /* If we get a new request within an existing to-tag - check the to tag as well */ 04701 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04702 if (p->tag[0] == '\0' && totag[0]) { 04703 /* We have no to tag, but they have. Wrong dialog */ 04704 found = FALSE; 04705 } else if (totag[0]) { /* Both have tags, compare them */ 04706 if (strcmp(totag, p->tag)) { 04707 found = FALSE; /* This is not our packet */ 04708 } 04709 } 04710 if (!found && option_debug > 4) 04711 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); 04712 } 04713 if (found) { 04714 /* Found the call */ 04715 ast_mutex_lock(&p->lock); 04716 ast_mutex_unlock(&iflock); 04717 return p; 04718 } 04719 } 04720 ast_mutex_unlock(&iflock); 04721 04722 /* See if the method is capable of creating a dialog */ 04723 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04724 if (intended_method == SIP_REFER) { 04725 /* We do support REFER, but not outside of a dialog yet */ 04726 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04727 } else if (intended_method == SIP_NOTIFY) { 04728 /* We do not support out-of-dialog NOTIFY either, 04729 like voicemail notification, so cancel that early */ 04730 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04731 } else { 04732 /* Ok, time to create a new SIP dialog object, a pvt */ 04733 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04734 /* Ok, we've created a dialog, let's go and process it */ 04735 ast_mutex_lock(&p->lock); 04736 } else { 04737 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04738 getting a dialog from sip_alloc. 04739 04740 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04741 send an error message. 04742 04743 Sorry, we apologize for the inconvienience 04744 */ 04745 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04746 if (option_debug > 3) 04747 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04748 } 04749 } 04750 return p; 04751 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04752 /* A method we do not support, let's take it on the volley */ 04753 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04754 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04755 /* This is a request outside of a dialog that we don't know about 04756 ...never reply to an ACK! 04757 */ 04758 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04759 } 04760 /* We do not respond to responses for dialogs that we don't know about, we just drop 04761 the session quickly */ 04762 04763 return p; 04764 }
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 2339 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02340 { 02341 char last_char = '\0'; 02342 const char *s; 02343 for (s = start; *s && s != lim; last_char = *s++) { 02344 if (*s == '"' && last_char != '\\') 02345 break; 02346 } 02347 return s; 02348 }
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 2687 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02688 { 02689 struct sip_peer *p = NULL; 02690 02691 if (peer) 02692 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02693 else 02694 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02695 02696 if (!p && (realtime || devstate_only)) 02697 p = realtime_peer(peer, sin, devstate_only); 02698 02699 return p; 02700 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 16947 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16948 { 16949 struct sip_auth *a; 16950 16951 for (a = authlist; a; a = a->next) { 16952 if (!strcasecmp(a->realm, realm)) 16953 break; 16954 } 16955 16956 return a; 16957 }
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 4970 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
04971 { 04972 const char *content_type; 04973 const char *content_length; 04974 const char *search; 04975 char *boundary; 04976 unsigned int x; 04977 int boundaryisquoted = FALSE; 04978 int found_application_sdp = FALSE; 04979 int found_end_of_headers = FALSE; 04980 04981 content_length = get_header(req, "Content-Length"); 04982 04983 if (!ast_strlen_zero(content_length)) { 04984 if (sscanf(content_length, "%ud", &x) != 1) { 04985 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 04986 return 0; 04987 } 04988 04989 /* Content-Length of zero means there can't possibly be an 04990 SDP here, even if the Content-Type says there is */ 04991 if (x == 0) 04992 return 0; 04993 } 04994 04995 content_type = get_header(req, "Content-Type"); 04996 04997 /* if the body contains only SDP, this is easy */ 04998 if (!strncasecmp(content_type, "application/sdp", 15)) { 04999 req->sdp_start = 0; 05000 req->sdp_end = req->lines; 05001 return req->lines ? 1 : 0; 05002 } 05003 05004 /* if it's not multipart/mixed, there cannot be an SDP */ 05005 if (strncasecmp(content_type, "multipart/mixed", 15)) 05006 return 0; 05007 05008 /* if there is no boundary marker, it's invalid */ 05009 if ((search = strcasestr(content_type, ";boundary="))) 05010 search += 10; 05011 else if ((search = strcasestr(content_type, "; boundary="))) 05012 search += 11; 05013 else 05014 return 0; 05015 05016 if (ast_strlen_zero(search)) 05017 return 0; 05018 05019 /* If the boundary is quoted with ", remove quote */ 05020 if (*search == '\"') { 05021 search++; 05022 boundaryisquoted = TRUE; 05023 } 05024 05025 /* make a duplicate of the string, with two extra characters 05026 at the beginning */ 05027 boundary = ast_strdupa(search - 2); 05028 boundary[0] = boundary[1] = '-'; 05029 /* Remove final quote */ 05030 if (boundaryisquoted) 05031 boundary[strlen(boundary) - 1] = '\0'; 05032 05033 /* search for the boundary marker, the empty line delimiting headers from 05034 sdp part and the end boundry if it exists */ 05035 05036 for (x = 0; x < (req->lines ); x++) { 05037 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05038 if(found_application_sdp && found_end_of_headers){ 05039 req->sdp_end = x-1; 05040 return 1; 05041 } 05042 found_application_sdp = FALSE; 05043 } 05044 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05045 found_application_sdp = TRUE; 05046 05047 if(strlen(req->line[x]) == 0 ){ 05048 if(found_application_sdp && !found_end_of_headers){ 05049 req->sdp_start = x; 05050 found_end_of_headers = TRUE; 05051 } 05052 } 05053 } 05054 if(found_application_sdp && found_end_of_headers) { 05055 req->sdp_end = x; 05056 return TRUE; 05057 } 05058 return FALSE; 05059 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1691 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01692 { 01693 int i, res = 0; 01694 01695 if (ast_strlen_zero(msg)) 01696 return 0; 01697 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01698 if (method_match(i, msg)) 01699 res = sip_methods[i].id; 01700 } 01701 return res; 01702 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10953 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10954 { 10955 int i; 10956 10957 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10958 if (subscription_types[i].type == subtype) { 10959 return &subscription_types[i]; 10960 } 10961 } 10962 return &subscription_types[0]; 10963 }
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 2766 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02767 { 02768 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02769 if (!u && realtime) 02770 u = realtime_user(name); 02771 return u; 02772 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8386 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08387 { 08388 struct sip_route *next; 08389 08390 while (route) { 08391 next = route->next; 08392 free(route); 08393 route = next; 08394 } 08395 }
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 11973 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), and check_sip_domain().
11974 { 11975 if (ast_strlen_zero(data)) { 11976 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11977 return -1; 11978 } 11979 if (check_sip_domain(data, NULL, 0)) 11980 ast_copy_string(buf, data, len); 11981 else 11982 buf[0] = '\0'; 11983 return 0; 11984 }
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 11909 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11910 { 11911 struct sip_pvt *p; 11912 const char *content = NULL; 11913 AST_DECLARE_APP_ARGS(args, 11914 AST_APP_ARG(header); 11915 AST_APP_ARG(number); 11916 ); 11917 int i, number, start = 0; 11918 11919 if (ast_strlen_zero(data)) { 11920 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11921 return -1; 11922 } 11923 11924 ast_channel_lock(chan); 11925 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11926 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11927 ast_channel_unlock(chan); 11928 return -1; 11929 } 11930 11931 AST_STANDARD_APP_ARGS(args, data); 11932 if (!args.number) { 11933 number = 1; 11934 } else { 11935 sscanf(args.number, "%d", &number); 11936 if (number < 1) 11937 number = 1; 11938 } 11939 11940 p = chan->tech_pvt; 11941 11942 /* If there is no private structure, this channel is no longer alive */ 11943 if (!p) { 11944 ast_channel_unlock(chan); 11945 return -1; 11946 } 11947 11948 for (i = 0; i < number; i++) 11949 content = __get_header(&p->initreq, args.header, &start); 11950 11951 if (ast_strlen_zero(content)) { 11952 ast_channel_unlock(chan); 11953 return -1; 11954 } 11955 11956 ast_copy_string(buf, content, len); 11957 ast_channel_unlock(chan); 11958 11959 return 0; 11960 }
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 12088 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.
12089 { 12090 struct sip_pvt *p; 12091 12092 *buf = 0; 12093 12094 if (!data) { 12095 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12096 return -1; 12097 } 12098 12099 ast_channel_lock(chan); 12100 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12101 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12102 ast_channel_unlock(chan); 12103 return -1; 12104 } 12105 12106 p = chan->tech_pvt; 12107 12108 /* If there is no private structure, this channel is no longer alive */ 12109 if (!p) { 12110 ast_channel_unlock(chan); 12111 return -1; 12112 } 12113 12114 if (!strcasecmp(data, "peerip")) { 12115 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12116 } else if (!strcasecmp(data, "recvip")) { 12117 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12118 } else if (!strcasecmp(data, "from")) { 12119 ast_copy_string(buf, p->from, len); 12120 } else if (!strcasecmp(data, "uri")) { 12121 ast_copy_string(buf, p->uri, len); 12122 } else if (!strcasecmp(data, "useragent")) { 12123 ast_copy_string(buf, p->useragent, len); 12124 } else if (!strcasecmp(data, "peername")) { 12125 ast_copy_string(buf, p->peername, len); 12126 } else if (!strcasecmp(data, "t38passthrough")) { 12127 if (p->t38.state == T38_DISABLED) 12128 ast_copy_string(buf, "0", sizeof("0")); 12129 else /* T38 is offered or enabled in this call */ 12130 ast_copy_string(buf, "1", sizeof("1")); 12131 } else { 12132 ast_channel_unlock(chan); 12133 return -1; 12134 } 12135 ast_channel_unlock(chan); 12136 12137 return 0; 12138 }
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 11998 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, strsep(), and sip_peer::useragent.
11999 { 12000 struct sip_peer *peer; 12001 char *colname; 12002 12003 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12004 *colname++ = '\0'; 12005 else if ((colname = strchr(data, '|'))) 12006 *colname++ = '\0'; 12007 else 12008 colname = "ip"; 12009 12010 if (!(peer = find_peer(data, NULL, 1, 0))) 12011 return -1; 12012 12013 if (!strcasecmp(colname, "ip")) { 12014 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12015 } else if (!strcasecmp(colname, "status")) { 12016 peer_status(peer, buf, len); 12017 } else if (!strcasecmp(colname, "language")) { 12018 ast_copy_string(buf, peer->language, len); 12019 } else if (!strcasecmp(colname, "regexten")) { 12020 ast_copy_string(buf, peer->regexten, len); 12021 } else if (!strcasecmp(colname, "limit")) { 12022 snprintf(buf, len, "%d", peer->call_limit); 12023 } else if (!strcasecmp(colname, "curcalls")) { 12024 snprintf(buf, len, "%d", peer->inUse); 12025 } else if (!strcasecmp(colname, "accountcode")) { 12026 ast_copy_string(buf, peer->accountcode, len); 12027 } else if (!strcasecmp(colname, "useragent")) { 12028 ast_copy_string(buf, peer->useragent, len); 12029 } else if (!strcasecmp(colname, "mailbox")) { 12030 ast_copy_string(buf, peer->mailbox, len); 12031 } else if (!strcasecmp(colname, "context")) { 12032 ast_copy_string(buf, peer->context, len); 12033 } else if (!strcasecmp(colname, "expire")) { 12034 snprintf(buf, len, "%d", peer->expire); 12035 } else if (!strcasecmp(colname, "dynamic")) { 12036 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12037 } else if (!strcasecmp(colname, "callerid_name")) { 12038 ast_copy_string(buf, peer->cid_name, len); 12039 } else if (!strcasecmp(colname, "callerid_num")) { 12040 ast_copy_string(buf, peer->cid_num, len); 12041 } else if (!strcasecmp(colname, "codecs")) { 12042 ast_getformatname_multiple(buf, len -1, peer->capability); 12043 } else if (!strncasecmp(colname, "codec[", 6)) { 12044 char *codecnum; 12045 int index = 0, codec = 0; 12046 12047 codecnum = colname + 6; /* move past the '[' */ 12048 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12049 index = atoi(codecnum); 12050 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12051 ast_copy_string(buf, ast_getformatname(codec), len); 12052 } 12053 } 12054 12055 ASTOBJ_UNREF(peer, sip_destroy_peer); 12056 12057 return 0; 12058 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4478 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04479 { 04480 long val[4]; 04481 int x; 04482 04483 for (x=0; x<4; x++) 04484 val[x] = ast_random(); 04485 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04486 04487 return buf; 04488 }
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 9319 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
09320 { 09321 char tmp[256] = "", *c, *a; 09322 struct sip_request *req = oreq ? oreq : &p->initreq; 09323 struct sip_refer *referdata = NULL; 09324 const char *transfer_context = NULL; 09325 09326 if (!p->refer && !sip_refer_allocate(p)) 09327 return -1; 09328 09329 referdata = p->refer; 09330 09331 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09332 c = get_in_brackets(tmp); 09333 09334 if (pedanticsipchecking) 09335 ast_uri_decode(c); 09336 09337 if (strncasecmp(c, "sip:", 4)) { 09338 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09339 return -1; 09340 } 09341 c += 4; 09342 if ((a = strchr(c, ';'))) /* Remove arguments */ 09343 *a = '\0'; 09344 09345 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09346 *a++ = '\0'; 09347 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09348 } 09349 09350 if (sip_debug_test_pvt(p)) 09351 ast_verbose("Looking for %s in %s\n", c, p->context); 09352 09353 if (p->owner) /* Mimic behaviour in res_features.c */ 09354 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09355 09356 /* By default, use the context in the channel sending the REFER */ 09357 if (ast_strlen_zero(transfer_context)) { 09358 transfer_context = S_OR(p->owner->macrocontext, 09359 S_OR(p->context, default_context)); 09360 } 09361 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09362 /* This is a blind transfer */ 09363 if (option_debug) 09364 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09365 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09366 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09367 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09368 referdata->refer_call = NULL; 09369 /* Set new context */ 09370 ast_string_field_set(p, context, transfer_context); 09371 return 0; 09372 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09373 return 1; 09374 } 09375 09376 return -1; 09377 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4272 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04273 { 04274 int x; 04275 int len = strlen(name); 04276 char *r; 04277 04278 for (x = 0; x < req->lines; x++) { 04279 r = get_body_by_line(req->line[x], name, len); 04280 if (r[0] != '\0') 04281 return r; 04282 } 04283 04284 return ""; 04285 }
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 4238 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04239 { 04240 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04241 return ast_skip_blanks(line + nameLen + 1); 04242 04243 return ""; 04244 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9431 of file chan_sip.c.
Referenced by check_user_full().
09432 { 09433 const char *end = strchr(input,'<'); /* first_bracket */ 09434 const char *tmp = strchr(input,'"'); /* first quote */ 09435 int bytes = 0; 09436 int maxbytes = outputsize - 1; 09437 09438 if (!end || end == input) /* we require a part in brackets */ 09439 return NULL; 09440 09441 end--; /* move just before "<" */ 09442 09443 if (tmp && tmp <= end) { 09444 /* The quote (tmp) precedes the bracket (end+1). 09445 * Find the matching quote and return the content. 09446 */ 09447 end = strchr(tmp+1, '"'); 09448 if (!end) 09449 return NULL; 09450 bytes = (int) (end - tmp); 09451 /* protect the output buffer */ 09452 if (bytes > maxbytes) 09453 bytes = maxbytes; 09454 ast_copy_string(output, tmp + 1, bytes); 09455 } else { 09456 /* No quoted string, or it is inside brackets. */ 09457 /* clear the empty characters in the begining*/ 09458 input = ast_skip_blanks(input); 09459 /* clear the empty characters in the end */ 09460 while(*end && *end < 33 && end > input) 09461 end--; 09462 if (end >= input) { 09463 bytes = (int) (end - input) + 2; 09464 /* protect the output buffer */ 09465 if (bytes > maxbytes) 09466 bytes = maxbytes; 09467 ast_copy_string(output, input, bytes); 09468 } else 09469 return NULL; 09470 } 09471 return output; 09472 }
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 8966 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, and strsep().
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08967 { 08968 char tmp[256] = "", *uri, *a; 08969 char tmpf[256] = "", *from; 08970 struct sip_request *req; 08971 char *colon; 08972 char *decoded_uri; 08973 08974 req = oreq; 08975 if (!req) 08976 req = &p->initreq; 08977 08978 /* Find the request URI */ 08979 if (req->rlPart2) 08980 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08981 08982 if (pedanticsipchecking) 08983 ast_uri_decode(tmp); 08984 08985 uri = get_in_brackets(tmp); 08986 08987 if (strncasecmp(uri, "sip:", 4)) { 08988 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08989 return -1; 08990 } 08991 uri += 4; 08992 08993 /* Now find the From: caller ID and name */ 08994 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08995 if (!ast_strlen_zero(tmpf)) { 08996 if (pedanticsipchecking) 08997 ast_uri_decode(tmpf); 08998 from = get_in_brackets(tmpf); 08999 } else { 09000 from = NULL; 09001 } 09002 09003 if (!ast_strlen_zero(from)) { 09004 if (strncasecmp(from, "sip:", 4)) { 09005 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09006 return -1; 09007 } 09008 from += 4; 09009 if ((a = strchr(from, '@'))) 09010 *a++ = '\0'; 09011 else 09012 a = from; /* just a domain */ 09013 from = strsep(&from, ";"); /* Remove userinfo options */ 09014 a = strsep(&a, ";"); /* Remove URI options */ 09015 ast_string_field_set(p, fromdomain, a); 09016 } 09017 09018 /* Skip any options and find the domain */ 09019 09020 /* Get the target domain */ 09021 if ((a = strchr(uri, '@'))) { 09022 *a++ = '\0'; 09023 } else { /* No username part */ 09024 a = uri; 09025 uri = "s"; /* Set extension to "s" */ 09026 } 09027 colon = strchr(a, ':'); /* Remove :port */ 09028 if (colon) 09029 *colon = '\0'; 09030 09031 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09032 a = strsep(&a, ";"); /* Remove URI options */ 09033 09034 ast_string_field_set(p, domain, a); 09035 09036 if (!AST_LIST_EMPTY(&domain_list)) { 09037 char domain_context[AST_MAX_EXTENSION]; 09038 09039 domain_context[0] = '\0'; 09040 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09041 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09042 if (option_debug) 09043 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09044 return -2; 09045 } 09046 } 09047 /* If we have a context defined, overwrite the original context */ 09048 if (!ast_strlen_zero(domain_context)) 09049 ast_string_field_set(p, context, domain_context); 09050 } 09051 09052 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09053 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09054 ast_string_field_set(p, context, p->subscribecontext); 09055 09056 if (sip_debug_test_pvt(p)) 09057 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09058 09059 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09060 if (req->method == SIP_SUBSCRIBE) { 09061 char hint[AST_MAX_EXTENSION]; 09062 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09063 } else { 09064 decoded_uri = ast_strdupa(uri); 09065 ast_uri_decode(decoded_uri); 09066 /* Check the dialplan for the username part of the request URI, 09067 the domain will be stored in the SIPDOMAIN variable 09068 Since extensions.conf can have unescaped characters, try matching a decoded 09069 uri in addition to the non-decoded uri 09070 Return 0 if we have a matching extension */ 09071 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) || 09072 !strcmp(decoded_uri, ast_pickup_ext())) { 09073 if (!oreq) 09074 ast_string_field_set(p, exten, decoded_uri); 09075 return 0; 09076 } 09077 } 09078 09079 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09080 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09081 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09082 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09083 return 1; 09084 } 09085 09086 return -1; 09087 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4361 of file chan_sip.c.
References __get_header().
04362 { 04363 int start = 0; 04364 return __get_header(req, name, &start); 04365 }
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 2361 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().
02362 { 02363 const char *parse = tmp; 02364 char *first_bracket; 02365 02366 /* 02367 * Skip any quoted text until we find the part in brackets. 02368 * On any error give up and return the full string. 02369 */ 02370 while ( (first_bracket = strchr(parse, '<')) ) { 02371 char *first_quote = strchr(parse, '"'); 02372 02373 if (!first_quote || first_quote > first_bracket) 02374 break; /* no need to look at quoted part */ 02375 /* the bracket is within quotes, so ignore it */ 02376 parse = find_closing_quote(first_quote + 1, NULL); 02377 if (!*parse) { /* not found, return full string ? */ 02378 /* XXX or be robust and return in-bracket part ? */ 02379 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02380 break; 02381 } 02382 parse++; 02383 } 02384 if (first_bracket) { 02385 char *second_bracket = strchr(first_bracket + 1, '>'); 02386 if (second_bracket) { 02387 *second_bracket = '\0'; 02388 tmp = first_bracket + 1; 02389 } else { 02390 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02391 } 02392 } 02393 return tmp; 02394 }
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 9837 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09838 { 09839 int x; 09840 int y; 09841 09842 buf[0] = '\0'; 09843 y = len - strlen(buf) - 5; 09844 if (y < 0) 09845 y = 0; 09846 for (x=0;x<req->lines;x++) { 09847 strncat(buf, req->line[x], y); /* safe */ 09848 y -= strlen(req->line[x]) + 1; 09849 if (y < 0) 09850 y = 0; 09851 if (y != 0) 09852 strcat(buf, "\n"); /* safe */ 09853 } 09854 return 0; 09855 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8937 of file chan_sip.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08938 { 08939 char tmp[256], *c, *a; 08940 struct sip_request *req; 08941 08942 req = oreq; 08943 if (!req) 08944 req = &p->initreq; 08945 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08946 if (ast_strlen_zero(tmp)) 08947 return 0; 08948 c = get_in_brackets(tmp); 08949 if (strncasecmp(c, "sip:", 4)) { 08950 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08951 return -1; 08952 } 08953 c += 4; 08954 a = c; 08955 strsep(&a, "@;"); /* trim anything after @ or ; */ 08956 if (sip_debug_test_pvt(p)) 08957 ast_verbose("RDNIS is %s\n", c); 08958 ast_string_field_set(p, rdnis, c); 08959 08960 return 0; 08961 }
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 9153 of file chan_sip.c.
References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
09154 { 09155 09156 const char *p_referred_by = NULL; 09157 char *h_refer_to = NULL; 09158 char *h_referred_by = NULL; 09159 char *refer_to; 09160 const char *p_refer_to; 09161 char *referred_by_uri = NULL; 09162 char *ptr; 09163 struct sip_request *req = NULL; 09164 const char *transfer_context = NULL; 09165 struct sip_refer *referdata; 09166 09167 09168 req = outgoing_req; 09169 referdata = transferer->refer; 09170 09171 if (!req) 09172 req = &transferer->initreq; 09173 09174 p_refer_to = get_header(req, "Refer-To"); 09175 if (ast_strlen_zero(p_refer_to)) { 09176 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09177 return -2; /* Syntax error */ 09178 } 09179 h_refer_to = ast_strdupa(p_refer_to); 09180 refer_to = get_in_brackets(h_refer_to); 09181 if (pedanticsipchecking) 09182 ast_uri_decode(refer_to); 09183 09184 if (strncasecmp(refer_to, "sip:", 4)) { 09185 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09186 return -3; 09187 } 09188 refer_to += 4; /* Skip sip: */ 09189 09190 /* Get referred by header if it exists */ 09191 p_referred_by = get_header(req, "Referred-By"); 09192 if (!ast_strlen_zero(p_referred_by)) { 09193 char *lessthan; 09194 h_referred_by = ast_strdupa(p_referred_by); 09195 if (pedanticsipchecking) 09196 ast_uri_decode(h_referred_by); 09197 09198 /* Store referrer's caller ID name */ 09199 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09200 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09201 *(lessthan - 1) = '\0'; /* Space */ 09202 } 09203 09204 referred_by_uri = get_in_brackets(h_referred_by); 09205 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09206 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09207 referred_by_uri = (char *) NULL; 09208 } else { 09209 referred_by_uri += 4; /* Skip sip: */ 09210 } 09211 } 09212 09213 /* Check for arguments in the refer_to header */ 09214 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09215 *ptr++ = '\0'; 09216 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09217 char *to = NULL, *from = NULL; 09218 09219 /* This is an attended transfer */ 09220 referdata->attendedtransfer = 1; 09221 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09222 ast_uri_decode(referdata->replaces_callid); 09223 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09224 *ptr++ = '\0'; 09225 } 09226 09227 if (ptr) { 09228 /* Find the different tags before we destroy the string */ 09229 to = strcasestr(ptr, "to-tag="); 09230 from = strcasestr(ptr, "from-tag="); 09231 } 09232 09233 /* Grab the to header */ 09234 if (to) { 09235 ptr = to + 7; 09236 if ((to = strchr(ptr, '&'))) 09237 *to = '\0'; 09238 if ((to = strchr(ptr, ';'))) 09239 *to = '\0'; 09240 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09241 } 09242 09243 if (from) { 09244 ptr = from + 9; 09245 if ((to = strchr(ptr, '&'))) 09246 *to = '\0'; 09247 if ((to = strchr(ptr, ';'))) 09248 *to = '\0'; 09249 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09250 } 09251 09252 if (option_debug > 1) { 09253 if (!pedanticsipchecking) 09254 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09255 else 09256 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>" ); 09257 } 09258 } 09259 } 09260 09261 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09262 char *urioption = NULL, *domain; 09263 *ptr++ = '\0'; 09264 09265 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09266 *urioption++ = '\0'; 09267 09268 domain = ptr; 09269 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09270 *ptr = '\0'; 09271 09272 /* Save the domain for the dial plan */ 09273 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09274 if (urioption) 09275 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09276 } 09277 09278 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09279 *ptr = '\0'; 09280 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09281 09282 if (referred_by_uri) { 09283 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09284 *ptr = '\0'; 09285 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09286 } else { 09287 referdata->referred_by[0] = '\0'; 09288 } 09289 09290 /* Determine transfer context */ 09291 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09292 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09293 09294 /* By default, use the context in the channel sending the REFER */ 09295 if (ast_strlen_zero(transfer_context)) { 09296 transfer_context = S_OR(transferer->owner->macrocontext, 09297 S_OR(transferer->context, default_context)); 09298 } 09299 09300 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09301 09302 /* Either an existing extension or the parking extension */ 09303 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09304 if (sip_debug_test_pvt(transferer)) { 09305 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09306 } 09307 /* We are ready to transfer to the extension */ 09308 return 0; 09309 } 09310 if (sip_debug_test_pvt(transferer)) 09311 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09312 09313 /* Failure, we can't find this extension */ 09314 return -1; 09315 }
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 9478 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09479 { 09480 char *start; 09481 char *end; 09482 09483 start = strchr(input,':'); 09484 if (!start) { 09485 output[0] = '\0'; 09486 return 0; 09487 } 09488 start++; 09489 09490 /* we found "number" */ 09491 ast_copy_string(output,start,maxlen); 09492 output[maxlen-1] = '\0'; 09493 09494 end = strchr(output,'@'); 09495 if (end) 09496 *end = '\0'; 09497 else 09498 output[0] = '\0'; 09499 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09500 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09501 09502 return 0; 09503 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4264 of file chan_sip.c.
References get_sdp_iterate().
04265 { 04266 int dummy = 0; 04267 04268 return get_sdp_iterate(&dummy, req, name); 04269 }
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 4250 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04251 { 04252 int len = strlen(name); 04253 04254 while (*start < req->sdp_end) { 04255 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04256 if (r[0] != '\0') 04257 return r; 04258 } 04259 04260 return ""; 04261 }
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 9091 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_PAGE2_OUTGOING_CALL, and sip_pvt::tag.
Referenced by handle_request_invite(), and local_attended_transfer().
09092 { 09093 struct sip_pvt *sip_pvt_ptr; 09094 09095 ast_mutex_lock(&iflock); 09096 09097 if (option_debug > 3 && totag) 09098 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09099 09100 /* Search interfaces and find the match */ 09101 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09102 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09103 int match = 1; 09104 09105 /* Go ahead and lock it (and its owner) before returning */ 09106 ast_mutex_lock(&sip_pvt_ptr->lock); 09107 09108 /* Check if tags match. If not, this is not the call we want 09109 (With a forking SIP proxy, several call legs share the 09110 call id, but have different tags) 09111 */ 09112 if (pedanticsipchecking) { 09113 const char *pvt_fromtag, *pvt_totag; 09114 09115 if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 09116 /* Outgoing call tags : from is "our", to is "their" */ 09117 pvt_fromtag = sip_pvt_ptr->tag ; 09118 pvt_totag = sip_pvt_ptr->theirtag ; 09119 } else { 09120 /* Incoming call tags : from is "their", to is "our" */ 09121 pvt_fromtag = sip_pvt_ptr->theirtag ; 09122 pvt_totag = sip_pvt_ptr->tag ; 09123 } 09124 if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag))) 09125 match = 0; 09126 } 09127 09128 if (!match) { 09129 ast_mutex_unlock(&sip_pvt_ptr->lock); 09130 continue; 09131 } 09132 09133 if (option_debug > 3 && totag) 09134 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09135 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09136 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09137 09138 /* deadlock avoidance... */ 09139 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09140 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09141 } 09142 break; 09143 } 09144 } 09145 ast_mutex_unlock(&iflock); 09146 if (option_debug > 3 && !sip_pvt_ptr) 09147 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09148 return sip_pvt_ptr; 09149 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13530 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13531 { 13532 const char *thetag; 13533 13534 if (!tagbuf) 13535 return NULL; 13536 tagbuf[0] = '\0'; /* reset the buffer */ 13537 thetag = get_header(req, header); 13538 thetag = strcasestr(thetag, ";tag="); 13539 if (thetag) { 13540 thetag += 5; 13541 ast_copy_string(tagbuf, thetag, tagbufsize); 13542 return strsep(&tagbuf, ";"); 13543 } 13544 return NULL; 13545 }
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 16696 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, ast_variable::name, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_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, strsep(), and ast_variable::value.
Referenced by build_peer(), and build_user().
16697 { 16698 int res = 1; 16699 16700 if (!strcasecmp(v->name, "trustrpid")) { 16701 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16702 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16703 } else if (!strcasecmp(v->name, "sendrpid")) { 16704 ast_set_flag(&mask[0], SIP_SENDRPID); 16705 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16706 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16707 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16708 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16709 } else if (!strcasecmp(v->name, "useclientcode")) { 16710 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16711 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16712 } else if (!strcasecmp(v->name, "dtmfmode")) { 16713 ast_set_flag(&mask[0], SIP_DTMF); 16714 ast_clear_flag(&flags[0], SIP_DTMF); 16715 if (!strcasecmp(v->value, "inband")) 16716 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16717 else if (!strcasecmp(v->value, "rfc2833")) 16718 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16719 else if (!strcasecmp(v->value, "info")) 16720 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16721 else if (!strcasecmp(v->value, "auto")) 16722 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16723 else { 16724 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16725 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16726 } 16727 } else if (!strcasecmp(v->name, "nat")) { 16728 ast_set_flag(&mask[0], SIP_NAT); 16729 ast_clear_flag(&flags[0], SIP_NAT); 16730 if (!strcasecmp(v->value, "never")) 16731 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16732 else if (!strcasecmp(v->value, "route")) 16733 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16734 else if (ast_true(v->value)) 16735 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16736 else 16737 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16738 } else if (!strcasecmp(v->name, "canreinvite")) { 16739 ast_set_flag(&mask[0], SIP_REINVITE); 16740 ast_clear_flag(&flags[0], SIP_REINVITE); 16741 if(ast_true(v->value)) { 16742 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16743 } else if (!ast_false(v->value)) { 16744 char buf[64]; 16745 char *word, *next = buf; 16746 16747 ast_copy_string(buf, v->value, sizeof(buf)); 16748 while ((word = strsep(&next, ","))) { 16749 if(!strcasecmp(word, "update")) { 16750 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16751 } else if(!strcasecmp(word, "nonat")) { 16752 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16753 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16754 } else { 16755 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16756 } 16757 } 16758 } 16759 } else if (!strcasecmp(v->name, "insecure")) { 16760 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16761 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16762 set_insecure_flags(flags, v->value, v->lineno); 16763 } else if (!strcasecmp(v->name, "progressinband")) { 16764 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16765 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16766 if (ast_true(v->value)) 16767 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16768 else if (strcasecmp(v->value, "never")) 16769 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16770 } else if (!strcasecmp(v->name, "promiscredir")) { 16771 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16772 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16773 } else if (!strcasecmp(v->name, "videosupport")) { 16774 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16775 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16776 } else if (!strcasecmp(v->name, "allowoverlap")) { 16777 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16778 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16779 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16780 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16781 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16782 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16783 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16784 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16785 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16786 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16787 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16788 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16789 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16790 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16791 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16792 #endif 16793 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16794 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16795 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16796 } else if (!strcasecmp(v->name, "buggymwi")) { 16797 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16798 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16799 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16800 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16801 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16802 } else 16803 res = 0; 16804 16805 return res; 16806 }
static int handle_invite_replaces | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | ignore, | |||
int | seqno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer.
Definition at line 13715 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13716 { 13717 struct ast_frame *f; 13718 int earlyreplace = 0; 13719 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13720 struct ast_channel *c = p->owner; /* Our incoming call */ 13721 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13722 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13723 13724 /* Check if we're in ring state */ 13725 if (replacecall->_state == AST_STATE_RING) 13726 earlyreplace = 1; 13727 13728 /* Check if we have a bridge */ 13729 if (!(targetcall = ast_bridged_channel(replacecall))) { 13730 /* We have no bridge */ 13731 if (!earlyreplace) { 13732 if (option_debug > 1) 13733 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13734 oneleggedreplace = 1; 13735 } 13736 } 13737 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13738 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13739 13740 if (option_debug > 3) { 13741 if (targetcall) 13742 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); 13743 else 13744 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13745 } 13746 13747 if (ignore) { 13748 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13749 /* We should answer something here. If we are here, the 13750 call we are replacing exists, so an accepted 13751 can't harm */ 13752 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13753 /* Do something more clever here */ 13754 ast_channel_unlock(c); 13755 ast_mutex_unlock(&p->refer->refer_call->lock); 13756 return 1; 13757 } 13758 if (!c) { 13759 /* What to do if no channel ??? */ 13760 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13761 transmit_response_reliable(p, "503 Service Unavailable", req); 13762 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13763 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13764 ast_mutex_unlock(&p->refer->refer_call->lock); 13765 return 1; 13766 } 13767 append_history(p, "Xfer", "INVITE/Replace received"); 13768 /* We have three channels to play with 13769 channel c: New incoming call 13770 targetcall: Call from PBX to target 13771 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13772 replacecall: The owner of the previous 13773 We need to masq C into refer_call to connect to 13774 targetcall; 13775 If we are talking to internal audio stream, target call is null. 13776 */ 13777 13778 /* Fake call progress */ 13779 transmit_response(p, "100 Trying", req); 13780 ast_setstate(c, AST_STATE_RING); 13781 13782 /* Masquerade the new call into the referred call to connect to target call 13783 Targetcall is not touched by the masq */ 13784 13785 /* Answer the incoming call and set channel to UP state */ 13786 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13787 13788 ast_setstate(c, AST_STATE_UP); 13789 13790 /* Stop music on hold and other generators */ 13791 ast_quiet_chan(replacecall); 13792 ast_quiet_chan(targetcall); 13793 if (option_debug > 3) 13794 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13795 /* Unlock clone, but not original (replacecall) */ 13796 if (!oneleggedreplace) 13797 ast_channel_unlock(c); 13798 13799 /* Unlock PVT */ 13800 ast_mutex_unlock(&p->refer->refer_call->lock); 13801 13802 /* Make sure that the masq does not free our PVT for the old call */ 13803 if (! earlyreplace && ! oneleggedreplace ) 13804 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13805 13806 /* Prepare the masquerade - if this does not happen, we will be gone */ 13807 if(ast_channel_masquerade(replacecall, c)) 13808 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13809 else if (option_debug > 3) 13810 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13811 13812 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13813 13814 /* C should now be in place of replacecall */ 13815 /* ast_read needs to lock channel */ 13816 ast_channel_unlock(c); 13817 13818 if (earlyreplace || oneleggedreplace ) { 13819 /* Force the masq to happen */ 13820 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13821 ast_frfree(f); 13822 f = NULL; 13823 if (option_debug > 3) 13824 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13825 } else { 13826 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13827 } 13828 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13829 if (!oneleggedreplace) 13830 ast_channel_unlock(replacecall); 13831 } else { /* Bridged call, UP channel */ 13832 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13833 /* Masq ok */ 13834 ast_frfree(f); 13835 f = NULL; 13836 if (option_debug > 2) 13837 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13838 } else { 13839 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13840 } 13841 ast_channel_unlock(replacecall); 13842 } 13843 ast_mutex_unlock(&p->refer->refer_call->lock); 13844 13845 ast_setstate(c, AST_STATE_DOWN); 13846 if (option_debug > 3) { 13847 struct ast_channel *test; 13848 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13849 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13850 if (replacecall) 13851 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13852 if (p->owner) { 13853 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13854 test = ast_bridged_channel(p->owner); 13855 if (test) 13856 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13857 else 13858 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13859 } else 13860 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13861 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13862 } 13863 13864 ast_channel_unlock(p->owner); /* Unlock new owner */ 13865 if (!oneleggedreplace) 13866 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13867 13868 /* The call should be down with no ast_channel, so hang it up */ 13869 c->tech_pvt = NULL; 13870 ast_hangup(c); 13871 return 0; 13872 }
static int handle_request | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Handle incoming SIP requests (methods).
Definition at line 15690 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
15691 { 15692 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15693 relatively static */ 15694 const char *cmd; 15695 const char *cseq; 15696 const char *useragent; 15697 int seqno; 15698 int len; 15699 int ignore = FALSE; 15700 int respid; 15701 int res = 0; 15702 int debug = sip_debug_test_pvt(p); 15703 char *e; 15704 int error = 0; 15705 15706 /* Get Method and Cseq */ 15707 cseq = get_header(req, "Cseq"); 15708 cmd = req->header[0]; 15709 15710 /* Must have Cseq */ 15711 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15712 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15713 error = 1; 15714 } 15715 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15716 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15717 error = 1; 15718 } 15719 if (error) { 15720 if (!p->initreq.headers) /* New call */ 15721 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15722 return -1; 15723 } 15724 /* Get the command XXX */ 15725 15726 cmd = req->rlPart1; 15727 e = req->rlPart2; 15728 15729 /* Save useragent of the client */ 15730 useragent = get_header(req, "User-Agent"); 15731 if (!ast_strlen_zero(useragent)) 15732 ast_string_field_set(p, useragent, useragent); 15733 15734 /* Find out SIP method for incoming request */ 15735 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15736 /* Response to our request -- Do some sanity checks */ 15737 if (!p->initreq.headers) { 15738 if (option_debug) 15739 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15740 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15741 return 0; 15742 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15743 if (option_debug) 15744 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15745 return -1; 15746 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15747 /* ignore means "don't do anything with it" but still have to 15748 respond appropriately */ 15749 ignore = TRUE; 15750 ast_set_flag(req, SIP_PKT_IGNORE); 15751 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15752 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15753 } else if (e) { 15754 e = ast_skip_blanks(e); 15755 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15756 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15757 } else { 15758 if (respid <= 0) { 15759 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15760 return 0; 15761 } 15762 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15763 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15764 extract_uri(p, req); 15765 handle_response(p, respid, e + len, req, ignore, seqno); 15766 } 15767 } 15768 return 0; 15769 } 15770 15771 /* New SIP request coming in 15772 (could be new request in existing SIP dialog as well...) 15773 */ 15774 15775 p->method = req->method; /* Find out which SIP method they are using */ 15776 if (option_debug > 3) 15777 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15778 15779 if (p->icseq && (p->icseq > seqno) ) { 15780 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15781 if (option_debug > 2) 15782 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15783 } else { 15784 if (option_debug) 15785 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15786 if (req->method != SIP_ACK) 15787 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15788 return -1; 15789 } 15790 } else if (p->icseq && 15791 p->icseq == seqno && 15792 req->method != SIP_ACK && 15793 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15794 /* ignore means "don't do anything with it" but still have to 15795 respond appropriately. We do this if we receive a repeat of 15796 the last sequence number */ 15797 ignore = 2; 15798 ast_set_flag(req, SIP_PKT_IGNORE); 15799 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15800 if (option_debug > 2) 15801 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15802 } 15803 15804 if (seqno >= p->icseq) 15805 /* Next should follow monotonically (but not necessarily 15806 incrementally -- thanks again to the genius authors of SIP -- 15807 increasing */ 15808 p->icseq = seqno; 15809 15810 /* Find their tag if we haven't got it */ 15811 if (ast_strlen_zero(p->theirtag)) { 15812 char tag[128]; 15813 15814 gettag(req, "From", tag, sizeof(tag)); 15815 ast_string_field_set(p, theirtag, tag); 15816 } 15817 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15818 15819 if (pedanticsipchecking) { 15820 /* If this is a request packet without a from tag, it's not 15821 correct according to RFC 3261 */ 15822 /* Check if this a new request in a new dialog with a totag already attached to it, 15823 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15824 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15825 /* If this is a first request and it got a to-tag, it is not for us */ 15826 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15827 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15828 /* Will cease to exist after ACK */ 15829 } else if (req->method != SIP_ACK) { 15830 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15831 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15832 } 15833 return res; 15834 } 15835 } 15836 15837 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15838 transmit_response(p, "400 Bad request", req); 15839 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15840 return -1; 15841 } 15842 15843 /* Handle various incoming SIP methods in requests */ 15844 switch (p->method) { 15845 case SIP_OPTIONS: 15846 res = handle_request_options(p, req); 15847 break; 15848 case SIP_INVITE: 15849 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15850 break; 15851 case SIP_REFER: 15852 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15853 break; 15854 case SIP_CANCEL: 15855 res = handle_request_cancel(p, req); 15856 break; 15857 case SIP_BYE: 15858 res = handle_request_bye(p, req); 15859 break; 15860 case SIP_MESSAGE: 15861 res = handle_request_message(p, req); 15862 break; 15863 case SIP_SUBSCRIBE: 15864 res = handle_request_subscribe(p, req, sin, seqno, e); 15865 break; 15866 case SIP_REGISTER: 15867 res = handle_request_register(p, req, sin, e); 15868 break; 15869 case SIP_INFO: 15870 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15871 ast_verbose("Receiving INFO!\n"); 15872 if (!ignore) 15873 handle_request_info(p, req); 15874 else /* if ignoring, transmit response */ 15875 transmit_response(p, "200 OK", req); 15876 break; 15877 case SIP_NOTIFY: 15878 res = handle_request_notify(p, req, sin, seqno, e); 15879 break; 15880 case SIP_ACK: 15881 /* Make sure we don't ignore this */ 15882 if (seqno == p->pendinginvite) { 15883 p->invitestate = INV_TERMINATED; 15884 p->pendinginvite = 0; 15885 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15886 if (find_sdp(req)) { 15887 if (process_sdp(p, req)) 15888 return -1; 15889 } 15890 check_pendings(p); 15891 } 15892 /* Got an ACK that we did not match. Ignore silently */ 15893 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15894 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15895 break; 15896 default: 15897 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15898 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15899 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15900 /* If this is some new method, and we don't have a call, destroy it now */ 15901 if (!p->initreq.headers) 15902 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15903 break; 15904 } 15905 return res; 15906 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15251 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(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
15252 { 15253 struct ast_channel *c=NULL; 15254 int res; 15255 struct ast_channel *bridged_to; 15256 15257 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15258 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 15259 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15260 15261 __sip_pretend_ack(p); 15262 15263 p->invitestate = INV_TERMINATED; 15264 15265 copy_request(&p->initreq, req); 15266 check_via(p, req); 15267 sip_alreadygone(p); 15268 15269 /* Get RTCP quality before end of call */ 15270 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15271 char *audioqos, *videoqos; 15272 if (p->rtp) { 15273 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15274 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15275 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15276 if (p->owner) 15277 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15278 } 15279 if (p->vrtp) { 15280 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15281 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15282 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15283 if (p->owner) 15284 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15285 } 15286 } 15287 15288 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15289 15290 if (!ast_strlen_zero(get_header(req, "Also"))) { 15291 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15292 ast_inet_ntoa(p->recv.sin_addr)); 15293 if (ast_strlen_zero(p->context)) 15294 ast_string_field_set(p, context, default_context); 15295 res = get_also_info(p, req); 15296 if (!res) { 15297 c = p->owner; 15298 if (c) { 15299 bridged_to = ast_bridged_channel(c); 15300 if (bridged_to) { 15301 /* Don't actually hangup here... */ 15302 ast_queue_control(c, AST_CONTROL_UNHOLD); 15303 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15304 } else 15305 ast_queue_hangup(p->owner); 15306 } 15307 } else { 15308 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15309 if (p->owner) 15310 ast_queue_hangup(p->owner); 15311 } 15312 } else if (p->owner) { 15313 ast_queue_hangup(p->owner); 15314 if (option_debug > 2) 15315 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15316 } else { 15317 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15318 if (option_debug > 2) 15319 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15320 } 15321 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15322 transmit_response(p, "200 OK", req); 15323 15324 return 1; 15325 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15145 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
15146 { 15147 15148 check_via(p, req); 15149 sip_alreadygone(p); 15150 15151 /* At this point, we could have cancelled the invite at the same time 15152 as the other side sends a CANCEL. Our final reply with error code 15153 might not have been received by the other side before the CANCEL 15154 was sent, so let's just give up retransmissions and waiting for 15155 ACK on our error code. The call is hanging up any way. */ 15156 if (p->invitestate == INV_TERMINATED) 15157 __sip_pretend_ack(p); 15158 else 15159 p->invitestate = INV_CANCELLED; 15160 15161 if (p->owner && p->owner->_state == AST_STATE_UP) { 15162 /* This call is up, cancel is ignored, we need a bye */ 15163 transmit_response(p, "200 OK", req); 15164 if (option_debug) 15165 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15166 return 0; 15167 } 15168 15169 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15170 update_call_counter(p, DEC_CALL_LIMIT); 15171 15172 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15173 if (p->owner) 15174 ast_queue_hangup(p->owner); 15175 else 15176 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15177 if (p->initreq.len > 0) { 15178 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15179 transmit_response(p, "200 OK", req); 15180 return 1; 15181 } else { 15182 transmit_response(p, "481 Call Leg Does Not Exist", req); 15183 return 0; 15184 } 15185 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11313 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
11314 { 11315 char buf[1024]; 11316 unsigned int event; 11317 const char *c = get_header(req, "Content-Type"); 11318 11319 /* Need to check the media/type */ 11320 if (!strcasecmp(c, "application/dtmf-relay") || 11321 !strcasecmp(c, "application/DTMF") || 11322 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11323 unsigned int duration = 0; 11324 11325 /* Try getting the "signal=" part */ 11326 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11327 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11328 transmit_response(p, "200 OK", req); /* Should return error */ 11329 return; 11330 } else { 11331 ast_copy_string(buf, c, sizeof(buf)); 11332 } 11333 11334 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11335 duration = atoi(c); 11336 if (!duration) 11337 duration = 100; /* 100 ms */ 11338 11339 if (!p->owner) { /* not a PBX call */ 11340 transmit_response(p, "481 Call leg/transaction does not exist", req); 11341 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11342 return; 11343 } 11344 11345 if (ast_strlen_zero(buf)) { 11346 transmit_response(p, "200 OK", req); 11347 return; 11348 } 11349 11350 if (buf[0] == '*') 11351 event = 10; 11352 else if (buf[0] == '#') 11353 event = 11; 11354 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11355 event = 12 + buf[0] - 'A'; 11356 else 11357 event = atoi(buf); 11358 if (event == 16) { 11359 /* send a FLASH event */ 11360 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11361 ast_queue_frame(p->owner, &f); 11362 if (sipdebug) 11363 ast_verbose("* DTMF-relay event received: FLASH\n"); 11364 } else { 11365 /* send a DTMF event */ 11366 struct ast_frame f = { AST_FRAME_DTMF, }; 11367 if (event < 10) { 11368 f.subclass = '0' + event; 11369 } else if (event < 11) { 11370 f.subclass = '*'; 11371 } else if (event < 12) { 11372 f.subclass = '#'; 11373 } else if (event < 16) { 11374 f.subclass = 'A' + (event - 12); 11375 } 11376 f.len = duration; 11377 ast_queue_frame(p->owner, &f); 11378 if (sipdebug) 11379 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11380 } 11381 transmit_response(p, "200 OK", req); 11382 return; 11383 } else if (!strcasecmp(c, "application/media_control+xml")) { 11384 /* Eh, we'll just assume it's a fast picture update for now */ 11385 if (p->owner) 11386 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11387 transmit_response(p, "200 OK", req); 11388 return; 11389 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11390 /* Client code (from SNOM phone) */ 11391 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11392 if (p->owner && p->owner->cdr) 11393 ast_cdr_setuserfield(p->owner, c); 11394 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11395 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11396 transmit_response(p, "200 OK", req); 11397 } else { 11398 transmit_response(p, "403 Unauthorized", req); 11399 } 11400 return; 11401 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11402 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11403 transmit_response(p, "200 OK", req); 11404 return; 11405 } 11406 11407 /* Other type of INFO message, not really understood by Asterisk */ 11408 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11409 11410 /* Nothing in the header is interesting, now check if content-length is 0 */ 11411 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11412 transmit_response(p, "200 OK", req); 11413 return; 11414 } /* else ... there issomething in the message body, do something with it if you need to */ 11415 11416 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11417 transmit_response(p, "415 Unsupported media type", req); 11418 return; 11419 }
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 14140 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), create_addr(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, sip_pvt::icseq, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pvt::packets, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pkt::retransid, sip_request::rlPart2, sip_pvt::rtp, S_OR, sched, sip_pkt::seqno, 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, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_invite(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14141 { 14142 int res = 1; 14143 int gotdest; 14144 const char *p_replaces; 14145 char *replace_id = NULL; 14146 const char *required; 14147 unsigned int required_profile = 0; 14148 struct ast_channel *c = NULL; /* New channel */ 14149 int reinvite = 0; 14150 14151 /* Find out what they support */ 14152 if (!p->sipoptions) { 14153 const char *supported = get_header(req, "Supported"); 14154 if (!ast_strlen_zero(supported)) 14155 parse_sip_options(p, supported); 14156 } 14157 14158 /* Find out what they require */ 14159 required = get_header(req, "Require"); 14160 if (!ast_strlen_zero(required)) { 14161 required_profile = parse_sip_options(NULL, required); 14162 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14163 /* At this point we only support REPLACES */ 14164 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14165 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14166 p->invitestate = INV_COMPLETED; 14167 if (!p->lastinvite) 14168 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14169 return -1; 14170 } 14171 } 14172 14173 /* Check if this is a loop */ 14174 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 14175 /* This is a call to ourself. Send ourselves an error code and stop 14176 processing immediately, as SIP really has no good mechanism for 14177 being able to call yourself */ 14178 /* If pedantic is on, we need to check the tags. If they're different, this is 14179 in fact a forked call through a SIP proxy somewhere. */ 14180 int different; 14181 if (pedanticsipchecking) 14182 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14183 else 14184 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14185 if (!different) { 14186 transmit_response(p, "482 Loop Detected", req); 14187 p->invitestate = INV_COMPLETED; 14188 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14189 return 0; 14190 } else { 14191 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14192 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14193 * that should be all we need to do. 14194 */ 14195 char *uri = ast_strdupa(req->rlPart2); 14196 char *at = strchr(uri, '@'); 14197 char *peerorhost; 14198 struct sip_pkt *pkt = NULL; 14199 if (option_debug > 2) { 14200 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14201 } 14202 if (at) { 14203 *at = '\0'; 14204 } 14205 /* Parse out "sip:" */ 14206 if ((peerorhost = strchr(uri, ':'))) { 14207 *peerorhost++ = '\0'; 14208 } 14209 create_addr(p, peerorhost); 14210 ast_string_field_free(p, theirtag); 14211 for (pkt = p->packets; pkt; pkt = pkt->next) { 14212 if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) { 14213 AST_SCHED_DEL(sched, pkt->retransid); 14214 } 14215 } 14216 return transmit_invite(p, SIP_INVITE, 1, 3); 14217 } 14218 } 14219 14220 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14221 /* We already have a pending invite. Sorry. You are on hold. */ 14222 transmit_response_reliable(p, "491 Request Pending", req); 14223 if (option_debug) 14224 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14225 /* Don't destroy dialog here */ 14226 return 0; 14227 } 14228 14229 p_replaces = get_header(req, "Replaces"); 14230 if (!ast_strlen_zero(p_replaces)) { 14231 /* We have a replaces header */ 14232 char *ptr; 14233 char *fromtag = NULL; 14234 char *totag = NULL; 14235 char *start, *to; 14236 int error = 0; 14237 14238 if (p->owner) { 14239 if (option_debug > 2) 14240 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14241 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14242 /* Do not destroy existing call */ 14243 return -1; 14244 } 14245 14246 if (sipdebug && option_debug > 2) 14247 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14248 /* Create a buffer we can manipulate */ 14249 replace_id = ast_strdupa(p_replaces); 14250 ast_uri_decode(replace_id); 14251 14252 if (!p->refer && !sip_refer_allocate(p)) { 14253 transmit_response_reliable(p, "500 Server Internal Error", req); 14254 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14255 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14256 p->invitestate = INV_COMPLETED; 14257 return -1; 14258 } 14259 14260 /* Todo: (When we find phones that support this) 14261 if the replaces header contains ";early-only" 14262 we can only replace the call in early 14263 stage, not after it's up. 14264 14265 If it's not in early mode, 486 Busy. 14266 */ 14267 14268 /* Skip leading whitespace */ 14269 replace_id = ast_skip_blanks(replace_id); 14270 14271 start = replace_id; 14272 while ( (ptr = strsep(&start, ";")) ) { 14273 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14274 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14275 totag = to + 7; /* skip the keyword */ 14276 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14277 fromtag = to + 9; /* skip the keyword */ 14278 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14279 } 14280 } 14281 14282 if (sipdebug && option_debug > 3) 14283 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>"); 14284 14285 14286 /* Try to find call that we are replacing 14287 If we have a Replaces header, we need to cancel that call if we succeed with this call 14288 */ 14289 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14290 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14291 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14292 error = 1; 14293 } 14294 14295 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14296 14297 /* The matched call is the call from the transferer to Asterisk . 14298 We want to bridge the bridged part of the call to the 14299 incoming invite, thus taking over the refered call */ 14300 14301 if (p->refer->refer_call == p) { 14302 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14303 p->refer->refer_call = NULL; 14304 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14305 error = 1; 14306 } 14307 14308 if (!error && !p->refer->refer_call->owner) { 14309 /* Oops, someting wrong anyway, no owner, no call */ 14310 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14311 /* Check for better return code */ 14312 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14313 error = 1; 14314 } 14315 14316 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 ) { 14317 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14318 transmit_response_reliable(p, "603 Declined (Replaces)", req); 14319 error = 1; 14320 } 14321 14322 if (error) { /* Give up this dialog */ 14323 append_history(p, "Xfer", "INVITE/Replace Failed."); 14324 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14325 ast_mutex_unlock(&p->lock); 14326 if (p->refer->refer_call) { 14327 ast_mutex_unlock(&p->refer->refer_call->lock); 14328 ast_channel_unlock(p->refer->refer_call->owner); 14329 } 14330 p->invitestate = INV_COMPLETED; 14331 return -1; 14332 } 14333 } 14334 14335 14336 /* Check if this is an INVITE that sets up a new dialog or 14337 a re-invite in an existing dialog */ 14338 14339 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14340 int newcall = (p->initreq.headers ? TRUE : FALSE); 14341 14342 if (sip_cancel_destroy(p)) 14343 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14344 /* This also counts as a pending invite */ 14345 p->pendinginvite = seqno; 14346 check_via(p, req); 14347 14348 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14349 if (!p->owner) { /* Not a re-invite */ 14350 if (debug) 14351 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14352 if (newcall) 14353 append_history(p, "Invite", "New call: %s", p->callid); 14354 parse_ok_contact(p, req); 14355 } else { /* Re-invite on existing call */ 14356 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14357 /* Handle SDP here if we already have an owner */ 14358 if (find_sdp(req)) { 14359 if (process_sdp(p, req)) { 14360 transmit_response_reliable(p, "488 Not acceptable here", req); 14361 if (!p->lastinvite) 14362 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14363 return -1; 14364 } 14365 } else { 14366 p->jointcapability = p->capability; 14367 if (option_debug > 2) 14368 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14369 /* Some devices signal they want to be put off hold by sending a re-invite 14370 *without* an SDP, which is supposed to mean "Go back to your state" 14371 and since they put os on remote hold, we go back to off hold */ 14372 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14373 change_hold_state(p, req, FALSE, 0); 14374 } 14375 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14376 append_history(p, "ReInv", "Re-invite received"); 14377 } 14378 } else if (debug) 14379 ast_verbose("Ignoring this INVITE request\n"); 14380 14381 14382 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14383 /* This is a new invite */ 14384 /* Handle authentication if this is our first invite */ 14385 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14386 if (res == AUTH_CHALLENGE_SENT) { 14387 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14388 return 0; 14389 } 14390 if (res < 0) { /* Something failed in authentication */ 14391 if (res == AUTH_FAKE_AUTH) { 14392 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14393 transmit_fake_auth_response(p, req, 1); 14394 } else { 14395 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14396 transmit_response_reliable(p, "403 Forbidden", req); 14397 } 14398 p->invitestate = INV_COMPLETED; 14399 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14400 ast_string_field_free(p, theirtag); 14401 return 0; 14402 } 14403 14404 /* We have a succesful authentication, process the SDP portion if there is one */ 14405 if (find_sdp(req)) { 14406 if (process_sdp(p, req)) { 14407 /* Unacceptable codecs */ 14408 transmit_response_reliable(p, "488 Not acceptable here", req); 14409 p->invitestate = INV_COMPLETED; 14410 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14411 if (option_debug) 14412 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14413 return -1; 14414 } 14415 } else { /* No SDP in invite, call control session */ 14416 p->jointcapability = p->capability; 14417 if (option_debug > 1) 14418 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14419 } 14420 14421 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14422 /* This seems redundant ... see !p-owner above */ 14423 if (p->owner) 14424 ast_queue_frame(p->owner, &ast_null_frame); 14425 14426 14427 /* Initialize the context if it hasn't been already */ 14428 if (ast_strlen_zero(p->context)) 14429 ast_string_field_set(p, context, default_context); 14430 14431 14432 /* Check number of concurrent calls -vs- incoming limit HERE */ 14433 if (option_debug) 14434 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14435 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14436 if (res < 0) { 14437 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14438 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14439 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14440 p->invitestate = INV_COMPLETED; 14441 } 14442 return 0; 14443 } 14444 gotdest = get_destination(p, NULL); /* Get destination right away */ 14445 get_rdnis(p, NULL); /* Get redirect information */ 14446 extract_uri(p, req); /* Get the Contact URI */ 14447 build_contact(p); /* Build our contact header */ 14448 14449 if (p->rtp) { 14450 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14451 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14452 } 14453 14454 if (!replace_id && gotdest) { /* No matching extension found */ 14455 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14456 transmit_response_reliable(p, "484 Address Incomplete", req); 14457 else { 14458 char *decoded_exten = ast_strdupa(p->exten); 14459 14460 transmit_response_reliable(p, "404 Not Found", req); 14461 ast_uri_decode(decoded_exten); 14462 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14463 " '%s' rejected because extension not found.\n", 14464 S_OR(p->username, p->peername), decoded_exten); 14465 } 14466 p->invitestate = INV_COMPLETED; 14467 update_call_counter(p, DEC_CALL_LIMIT); 14468 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14469 return 0; 14470 } else { 14471 /* If no extension was specified, use the s one */ 14472 /* Basically for calling to IP/Host name only */ 14473 if (ast_strlen_zero(p->exten)) 14474 ast_string_field_set(p, exten, "s"); 14475 /* Initialize our tag */ 14476 14477 make_our_tag(p->tag, sizeof(p->tag)); 14478 /* First invitation - create the channel */ 14479 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14480 *recount = 1; 14481 14482 /* Save Record-Route for any later requests we make on this dialogue */ 14483 build_route(p, req, 0); 14484 14485 if (c) { 14486 /* Pre-lock the call */ 14487 ast_channel_lock(c); 14488 } 14489 } 14490 } else { 14491 if (option_debug > 1 && sipdebug) { 14492 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14493 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14494 else 14495 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14496 } 14497 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14498 reinvite = 1; 14499 c = p->owner; 14500 } 14501 14502 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14503 p->lastinvite = seqno; 14504 14505 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14506 /* Go and take over the target call */ 14507 if (sipdebug && option_debug > 3) 14508 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14509 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14510 } 14511 14512 14513 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14514 switch(c->_state) { 14515 case AST_STATE_DOWN: 14516 if (option_debug > 1) 14517 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14518 transmit_response(p, "100 Trying", req); 14519 p->invitestate = INV_PROCEEDING; 14520 ast_setstate(c, AST_STATE_RING); 14521 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14522 enum ast_pbx_result res; 14523 14524 res = ast_pbx_start(c); 14525 14526 switch(res) { 14527 case AST_PBX_FAILED: 14528 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14529 p->invitestate = INV_COMPLETED; 14530 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14531 transmit_response(p, "503 Unavailable", req); 14532 else 14533 transmit_response_reliable(p, "503 Unavailable", req); 14534 break; 14535 case AST_PBX_CALL_LIMIT: 14536 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14537 p->invitestate = INV_COMPLETED; 14538 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14539 transmit_response(p, "480 Temporarily Unavailable", req); 14540 else 14541 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14542 break; 14543 case AST_PBX_SUCCESS: 14544 /* nothing to do */ 14545 break; 14546 } 14547 14548 if (res) { 14549 14550 /* Unlock locks so ast_hangup can do its magic */ 14551 ast_mutex_unlock(&c->lock); 14552 ast_mutex_unlock(&p->lock); 14553 ast_hangup(c); 14554 ast_mutex_lock(&p->lock); 14555 c = NULL; 14556 } 14557 } else { /* Pickup call in call group */ 14558 ast_channel_unlock(c); 14559 *nounlock = 1; 14560 if (ast_pickup_call(c)) { 14561 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14562 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14563 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14564 else 14565 transmit_response_reliable(p, "503 Unavailable", req); 14566 sip_alreadygone(p); 14567 /* Unlock locks so ast_hangup can do its magic */ 14568 ast_mutex_unlock(&p->lock); 14569 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14570 } else { 14571 ast_mutex_unlock(&p->lock); 14572 ast_setstate(c, AST_STATE_DOWN); 14573 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14574 } 14575 p->invitestate = INV_COMPLETED; 14576 ast_hangup(c); 14577 ast_mutex_lock(&p->lock); 14578 c = NULL; 14579 } 14580 break; 14581 case AST_STATE_RING: 14582 transmit_response(p, "100 Trying", req); 14583 p->invitestate = INV_PROCEEDING; 14584 break; 14585 case AST_STATE_RINGING: 14586 transmit_response(p, "180 Ringing", req); 14587 p->invitestate = INV_PROCEEDING; 14588 break; 14589 case AST_STATE_UP: 14590 if (option_debug > 1) 14591 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14592 14593 transmit_response(p, "100 Trying", req); 14594 14595 if (p->t38.state == T38_PEER_REINVITE) { 14596 struct ast_channel *bridgepeer = NULL; 14597 struct sip_pvt *bridgepvt = NULL; 14598 14599 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14600 /* 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*/ 14601 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14602 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14603 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14604 if (bridgepvt->t38.state == T38_DISABLED) { 14605 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14606 /* Send re-invite to the bridged channel */ 14607 sip_handle_t38_reinvite(bridgepeer, p, 1); 14608 } else { /* Something is wrong with peers udptl struct */ 14609 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14610 ast_mutex_lock(&bridgepvt->lock); 14611 bridgepvt->t38.state = T38_DISABLED; 14612 ast_mutex_unlock(&bridgepvt->lock); 14613 if (option_debug > 1) 14614 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14615 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14616 transmit_response(p, "488 Not acceptable here", req); 14617 else 14618 transmit_response_reliable(p, "488 Not acceptable here", req); 14619 14620 } 14621 } else { 14622 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14623 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14624 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14625 p->t38.state = T38_ENABLED; 14626 if (option_debug) 14627 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14628 } 14629 } else { 14630 /* Other side is not a SIP channel */ 14631 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14632 transmit_response(p, "488 Not acceptable here", req); 14633 else 14634 transmit_response_reliable(p, "488 Not acceptable here", req); 14635 p->t38.state = T38_DISABLED; 14636 if (option_debug > 1) 14637 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14638 14639 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14640 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14641 } 14642 } else { 14643 /* we are not bridged in a call */ 14644 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14645 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14646 p->t38.state = T38_ENABLED; 14647 if (option_debug) 14648 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14649 } 14650 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14651 int sendok = TRUE; 14652 14653 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14654 /* so handle it here (re-invite other party to RTP) */ 14655 struct ast_channel *bridgepeer = NULL; 14656 struct sip_pvt *bridgepvt = NULL; 14657 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14658 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14659 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14660 /* Does the bridged peer have T38 ? */ 14661 if (bridgepvt->t38.state == T38_ENABLED) { 14662 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14663 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14664 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14665 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14666 else 14667 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14668 sendok = FALSE; 14669 } 14670 /* No bridged peer with T38 enabled*/ 14671 } 14672 } 14673 /* Respond to normal re-invite */ 14674 if (sendok) { 14675 /* If this is not a re-invite or something to ignore - it's critical */ 14676 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14677 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14678 } 14679 } 14680 p->invitestate = INV_TERMINATED; 14681 break; 14682 default: 14683 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14684 transmit_response(p, "100 Trying", req); 14685 break; 14686 } 14687 } else { 14688 if (p && (p->autokillid == -1)) { 14689 const char *msg; 14690 14691 if (!p->jointcapability) 14692 msg = "488 Not Acceptable Here (codec error)"; 14693 else { 14694 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14695 msg = "503 Unavailable"; 14696 } 14697 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14698 transmit_response(p, msg, req); 14699 else 14700 transmit_response_reliable(p, msg, req); 14701 p->invitestate = INV_COMPLETED; 14702 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14703 } 14704 } 14705 return res; 14706 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15328 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().
15329 { 15330 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15331 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15332 ast_verbose("Receiving message!\n"); 15333 receive_message(p, req); 15334 } else 15335 transmit_response(p, "202 Accepted", req); 15336 return 1; 15337 }
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 13548 of file chan_sip.c.
References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13549 { 13550 /* This is mostly a skeleton for future improvements */ 13551 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13552 int res = 0; 13553 const char *event = get_header(req, "Event"); 13554 char *eventid = NULL; 13555 char *sep; 13556 13557 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13558 *sep++ = '\0'; 13559 eventid = sep; 13560 } 13561 13562 if (option_debug > 1 && sipdebug) 13563 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13564 13565 if (strcmp(event, "refer")) { 13566 /* We don't understand this event. */ 13567 /* Here's room to implement incoming voicemail notifications :-) */ 13568 transmit_response(p, "489 Bad event", req); 13569 res = -1; 13570 } else { 13571 /* Save nesting depth for now, since there might be other events we will 13572 support in the future */ 13573 13574 /* Handle REFER notifications */ 13575 13576 char buf[1024]; 13577 char *cmd, *code; 13578 int respcode; 13579 int success = TRUE; 13580 13581 /* EventID for each transfer... EventID is basically the REFER cseq 13582 13583 We are getting notifications on a call that we transfered 13584 We should hangup when we are getting a 200 OK in a sipfrag 13585 Check if we have an owner of this event */ 13586 13587 /* Check the content type */ 13588 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13589 /* We need a sipfrag */ 13590 transmit_response(p, "400 Bad request", req); 13591 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13592 return -1; 13593 } 13594 13595 /* Get the text of the attachment */ 13596 if (get_msg_text(buf, sizeof(buf), req)) { 13597 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13598 transmit_response(p, "400 Bad request", req); 13599 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13600 return -1; 13601 } 13602 13603 /* 13604 From the RFC... 13605 A minimal, but complete, implementation can respond with a single 13606 NOTIFY containing either the body: 13607 SIP/2.0 100 Trying 13608 13609 if the subscription is pending, the body: 13610 SIP/2.0 200 OK 13611 if the reference was successful, the body: 13612 SIP/2.0 503 Service Unavailable 13613 if the reference failed, or the body: 13614 SIP/2.0 603 Declined 13615 13616 if the REFER request was accepted before approval to follow the 13617 reference could be obtained and that approval was subsequently denied 13618 (see Section 2.4.7). 13619 13620 If there are several REFERs in the same dialog, we need to 13621 match the ID of the event header... 13622 */ 13623 if (option_debug > 2) 13624 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13625 cmd = ast_skip_blanks(buf); 13626 code = cmd; 13627 /* We are at SIP/2.0 */ 13628 while(*code && (*code > 32)) { /* Search white space */ 13629 code++; 13630 } 13631 *code++ = '\0'; 13632 code = ast_skip_blanks(code); 13633 sep = code; 13634 sep++; 13635 while(*sep && (*sep > 32)) { /* Search white space */ 13636 sep++; 13637 } 13638 *sep++ = '\0'; /* Response string */ 13639 respcode = atoi(code); 13640 switch (respcode) { 13641 case 100: /* Trying: */ 13642 case 101: /* dialog establishment */ 13643 /* Don't do anything yet */ 13644 break; 13645 case 183: /* Ringing: */ 13646 /* Don't do anything yet */ 13647 break; 13648 case 200: /* OK: The new call is up, hangup this call */ 13649 /* Hangup the call that we are replacing */ 13650 break; 13651 case 301: /* Moved permenantly */ 13652 case 302: /* Moved temporarily */ 13653 /* Do we get the header in the packet in this case? */ 13654 success = FALSE; 13655 break; 13656 case 503: /* Service Unavailable: The new call failed */ 13657 /* Cancel transfer, continue the call */ 13658 success = FALSE; 13659 break; 13660 case 603: /* Declined: Not accepted */ 13661 /* Cancel transfer, continue the current call */ 13662 success = FALSE; 13663 break; 13664 } 13665 if (!success) { 13666 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13667 } 13668 13669 /* Confirm that we received this packet */ 13670 transmit_response(p, "200 OK", req); 13671 }; 13672 13673 if (!p->lastinvite) 13674 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13675 13676 return res; 13677 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13680 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
13681 { 13682 int res; 13683 13684 13685 /* XXX Should we authenticate OPTIONS? XXX */ 13686 13687 if (p->lastinvite) { 13688 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 13689 transmit_response_with_allow(p, "200 OK", req, 0); 13690 return 0; 13691 } 13692 13693 res = get_destination(p, req); 13694 build_contact(p); 13695 13696 if (ast_strlen_zero(p->context)) 13697 ast_string_field_set(p, context, default_context); 13698 13699 if (ast_shutting_down()) 13700 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13701 else if (res < 0) 13702 transmit_response_with_allow(p, "404 Not Found", req, 0); 13703 else 13704 transmit_response_with_allow(p, "200 OK", req, 0); 13705 13706 /* Destroy if this OPTIONS was the opening request, but not if 13707 it's in the middle of a normal call flow. */ 13708 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13709 13710 return res; 13711 }
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 14874 of file chan_sip.c.
References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
14875 { 14876 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14877 /* Chan2: Call between asterisk and transferee */ 14878 14879 int res = 0; 14880 14881 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14882 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"); 14883 14884 if (!p->owner) { 14885 /* This is a REFER outside of an existing SIP dialog */ 14886 /* We can't handle that, so decline it */ 14887 if (option_debug > 2) 14888 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14889 transmit_response(p, "603 Declined (No dialog)", req); 14890 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14891 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14892 sip_alreadygone(p); 14893 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14894 } 14895 return 0; 14896 } 14897 14898 14899 /* Check if transfer is allowed from this device */ 14900 if (p->allowtransfer == TRANSFER_CLOSED ) { 14901 /* Transfer not allowed, decline */ 14902 transmit_response(p, "603 Declined (policy)", req); 14903 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14904 /* Do not destroy SIP session */ 14905 return 0; 14906 } 14907 14908 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14909 /* Already have a pending REFER */ 14910 transmit_response(p, "491 Request pending", req); 14911 append_history(p, "Xfer", "Refer failed. Request pending."); 14912 return 0; 14913 } 14914 14915 /* Allocate memory for call transfer data */ 14916 if (!p->refer && !sip_refer_allocate(p)) { 14917 transmit_response(p, "500 Internal Server Error", req); 14918 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14919 return -3; 14920 } 14921 14922 res = get_refer_info(p, req); /* Extract headers */ 14923 14924 p->refer->status = REFER_SENT; 14925 14926 if (res != 0) { 14927 switch (res) { 14928 case -2: /* Syntax error */ 14929 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14930 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14931 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14932 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14933 break; 14934 case -3: 14935 transmit_response(p, "603 Declined (Non sip: uri)", req); 14936 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14937 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14938 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14939 break; 14940 default: 14941 /* Refer-to extension not found, fake a failed transfer */ 14942 transmit_response(p, "202 Accepted", req); 14943 append_history(p, "Xfer", "Refer failed. Bad extension."); 14944 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14945 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14946 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14947 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14948 break; 14949 } 14950 return 0; 14951 } 14952 if (ast_strlen_zero(p->context)) 14953 ast_string_field_set(p, context, default_context); 14954 14955 /* If we do not support SIP domains, all transfers are local */ 14956 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14957 p->refer->localtransfer = 1; 14958 if (sipdebug && option_debug > 2) 14959 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14960 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14961 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 14962 p->refer->localtransfer = 1; 14963 } else if (sipdebug && option_debug > 2) 14964 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14965 14966 /* Is this a repeat of a current request? Ignore it */ 14967 /* Don't know what else to do right now. */ 14968 if (ignore) 14969 return res; 14970 14971 /* If this is a blind transfer, we have the following 14972 channels to work with: 14973 - chan1, chan2: The current call between transferer and transferee (2 channels) 14974 - target_channel: A new call from the transferee to the target (1 channel) 14975 We need to stay tuned to what happens in order to be able 14976 to bring back the call to the transferer */ 14977 14978 /* If this is a attended transfer, we should have all call legs within reach: 14979 - chan1, chan2: The call between the transferer and transferee (2 channels) 14980 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14981 We want to bridge chan2 with targetcall_pvt! 14982 14983 The replaces call id in the refer message points 14984 to the call leg between Asterisk and the transferer. 14985 So we need to connect the target and the transferee channel 14986 and hangup the two other channels silently 14987 14988 If the target is non-local, the call ID could be on a remote 14989 machine and we need to send an INVITE with replaces to the 14990 target. We basically handle this as a blind transfer 14991 and let the sip_call function catch that we need replaces 14992 header in the INVITE. 14993 */ 14994 14995 14996 /* Get the transferer's channel */ 14997 current.chan1 = p->owner; 14998 14999 /* Find the other part of the bridge (2) - transferee */ 15000 current.chan2 = ast_bridged_channel(current.chan1); 15001 15002 if (sipdebug && option_debug > 2) 15003 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>"); 15004 15005 if (!current.chan2 && !p->refer->attendedtransfer) { 15006 /* No bridged channel, propably IVR or echo or similar... */ 15007 /* Guess we should masquerade or something here */ 15008 /* Until we figure it out, refuse transfer of such calls */ 15009 if (sipdebug && option_debug > 2) 15010 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15011 p->refer->status = REFER_FAILED; 15012 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15013 transmit_response(p, "603 Declined", req); 15014 return -1; 15015 } 15016 15017 if (current.chan2) { 15018 if (sipdebug && option_debug > 3) 15019 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15020 15021 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15022 } 15023 15024 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15025 15026 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15027 if (p->refer->attendedtransfer) { 15028 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15029 return res; /* We're done with the transfer */ 15030 /* Fall through for remote transfers that we did not find locally */ 15031 if (sipdebug && option_debug > 3) 15032 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15033 /* Fallthrough if we can't find the call leg internally */ 15034 } 15035 15036 15037 /* Parking a call */ 15038 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15039 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15040 *nounlock = 1; 15041 ast_channel_unlock(current.chan1); 15042 copy_request(¤t.req, req); 15043 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15044 p->refer->status = REFER_200OK; 15045 append_history(p, "Xfer", "REFER to call parking."); 15046 if (sipdebug && option_debug > 3) 15047 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15048 sip_park(current.chan2, current.chan1, req, seqno); 15049 return res; 15050 } 15051 15052 /* Blind transfers and remote attended xfers */ 15053 transmit_response(p, "202 Accepted", req); 15054 15055 if (current.chan1 && current.chan2) { 15056 if (option_debug > 2) 15057 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15058 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15059 } 15060 if (current.chan2) { 15061 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15062 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15063 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15064 /* One for the new channel */ 15065 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15066 /* Attended transfer to remote host, prepare headers for the INVITE */ 15067 if (p->refer->referred_by) 15068 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15069 } 15070 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15071 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15072 char tempheader[SIPBUFSIZE]; 15073 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15074 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15075 p->refer->replaces_callid_totag, 15076 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15077 p->refer->replaces_callid_fromtag); 15078 if (current.chan2) 15079 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15080 } 15081 /* Must release lock now, because it will not longer 15082 be accessible after the transfer! */ 15083 *nounlock = 1; 15084 ast_channel_unlock(current.chan1); 15085 15086 /* Connect the call */ 15087 15088 /* FAKE ringing if not attended transfer */ 15089 if (!p->refer->attendedtransfer) 15090 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15091 15092 /* For blind transfer, this will lead to a new call */ 15093 /* For attended transfer to remote host, this will lead to 15094 a new SIP call with a replaces header, if the dial plan allows it 15095 */ 15096 if (!current.chan2) { 15097 /* We have no bridge, so we're talking with Asterisk somehow */ 15098 /* We need to masquerade this call */ 15099 /* What to do to fix this situation: 15100 * Set up the new call in a new channel 15101 * Let the new channel masq into this channel 15102 Please add that code here :-) 15103 */ 15104 p->refer->status = REFER_FAILED; 15105 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15106 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15107 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15108 return -1; 15109 } 15110 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15111 15112 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15113 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15114 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15115 15116 if (!res) { 15117 /* Success - we have a new channel */ 15118 if (option_debug > 2) 15119 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15120 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15121 if (p->refer->localtransfer) 15122 p->refer->status = REFER_200OK; 15123 if (p->owner) 15124 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15125 append_history(p, "Xfer", "Refer succeeded."); 15126 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15127 /* Do not hangup call, the other side do that when we say 200 OK */ 15128 /* We could possibly implement a timer here, auto congestion */ 15129 res = 0; 15130 } else { 15131 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15132 if (option_debug > 2) 15133 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15134 append_history(p, "Xfer", "Refer failed."); 15135 /* Failure of some kind */ 15136 p->refer->status = REFER_FAILED; 15137 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15138 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15139 res = -1; 15140 } 15141 return res; 15142 }
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 15637 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().
Referenced by handle_request().
15638 { 15639 enum check_auth_result res; 15640 15641 /* Use this as the basis */ 15642 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15643 ast_verbose("Using latest REGISTER request as basis request\n"); 15644 copy_request(&p->initreq, req); 15645 check_via(p, req); 15646 if ((res = register_verify(p, sin, req, e)) < 0) { 15647 const char *reason; 15648 15649 switch (res) { 15650 case AUTH_SECRET_FAILED: 15651 reason = "Wrong password"; 15652 break; 15653 case AUTH_USERNAME_MISMATCH: 15654 reason = "Username/auth name mismatch"; 15655 break; 15656 case AUTH_NOT_FOUND: 15657 reason = "No matching peer found"; 15658 break; 15659 case AUTH_UNKNOWN_DOMAIN: 15660 reason = "Not a local domain"; 15661 break; 15662 case AUTH_PEER_NOT_DYNAMIC: 15663 reason = "Peer is not supposed to register"; 15664 break; 15665 case AUTH_ACL_FAILED: 15666 reason = "Device does not match ACL"; 15667 break; 15668 default: 15669 reason = "Unknown failure"; 15670 break; 15671 } 15672 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15673 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15674 reason); 15675 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15676 } else 15677 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15678 15679 if (res < 1) { 15680 /* Destroy the session, but keep us around for just a bit in case they don't 15681 get our 200 OK */ 15682 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15683 } 15684 return res; 15685 }
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 15340 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.
Referenced by handle_request().
15341 { 15342 int gotdest; 15343 int res = 0; 15344 int firststate = AST_EXTENSION_REMOVED; 15345 struct sip_peer *authpeer = NULL; 15346 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15347 const char *accept = get_header(req, "Accept"); 15348 int resubscribe = (p->subscribed != NONE); 15349 char *temp, *event; 15350 15351 if (p->initreq.headers) { 15352 /* We already have a dialog */ 15353 if (p->initreq.method != SIP_SUBSCRIBE) { 15354 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15355 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15356 transmit_response(p, "403 Forbidden (within dialog)", req); 15357 /* Do not destroy session, since we will break the call if we do */ 15358 if (option_debug) 15359 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); 15360 return 0; 15361 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15362 if (option_debug) { 15363 if (resubscribe) 15364 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15365 else 15366 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15367 } 15368 } 15369 } 15370 15371 /* Check if we have a global disallow setting on subscriptions. 15372 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15373 */ 15374 if (!global_allowsubscribe) { 15375 transmit_response(p, "403 Forbidden (policy)", req); 15376 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15377 return 0; 15378 } 15379 15380 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15381 const char *to = get_header(req, "To"); 15382 char totag[128]; 15383 15384 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15385 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15386 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15387 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15388 transmit_response(p, "481 Subscription does not exist", req); 15389 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15390 return 0; 15391 } 15392 15393 /* Use this as the basis */ 15394 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15395 ast_verbose("Creating new subscription\n"); 15396 15397 copy_request(&p->initreq, req); 15398 check_via(p, req); 15399 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15400 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15401 15402 /* Find parameters to Event: header value and remove them for now */ 15403 if (ast_strlen_zero(eventheader)) { 15404 transmit_response(p, "489 Bad Event", req); 15405 if (option_debug > 1) 15406 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15407 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15408 return 0; 15409 } 15410 15411 if ( (strchr(eventheader, ';'))) { 15412 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15413 temp = strchr(event, ';'); 15414 *temp = '\0'; /* Remove any options for now */ 15415 /* We might need to use them later :-) */ 15416 } else 15417 event = (char *) eventheader; /* XXX is this legal ? */ 15418 15419 /* Handle authentication */ 15420 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15421 /* if an authentication response was sent, we are done here */ 15422 if (res == AUTH_CHALLENGE_SENT) { 15423 if (authpeer) 15424 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15425 return 0; 15426 } 15427 if (res < 0) { 15428 if (res == AUTH_FAKE_AUTH) { 15429 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15430 transmit_fake_auth_response(p, req, 1); 15431 } else { 15432 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15433 transmit_response_reliable(p, "403 Forbidden", req); 15434 } 15435 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15436 if (authpeer) 15437 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15438 return 0; 15439 } 15440 15441 /* Check if this user/peer is allowed to subscribe at all */ 15442 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15443 transmit_response(p, "403 Forbidden (policy)", req); 15444 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15445 if (authpeer) 15446 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15447 return 0; 15448 } 15449 15450 /* Get destination right away */ 15451 gotdest = get_destination(p, NULL); 15452 15453 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15454 parse_ok_contact(p, req); 15455 15456 build_contact(p); 15457 if (strcmp(event, "message-summary") && gotdest) { 15458 transmit_response(p, "404 Not Found", req); 15459 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15460 if (authpeer) 15461 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15462 return 0; 15463 } 15464 15465 /* Initialize tag for new subscriptions */ 15466 if (ast_strlen_zero(p->tag)) 15467 make_our_tag(p->tag, sizeof(p->tag)); 15468 15469 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15470 if (authpeer) /* No need for authpeer here */ 15471 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15472 15473 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15474 /* Polycom phones only handle xpidf+xml, even if they say they can 15475 handle pidf+xml as well 15476 */ 15477 if (strstr(p->useragent, "Polycom")) { 15478 p->subscribed = XPIDF_XML; 15479 } else if (strstr(accept, "application/pidf+xml")) { 15480 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15481 } else if (strstr(accept, "application/dialog-info+xml")) { 15482 p->subscribed = DIALOG_INFO_XML; 15483 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15484 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15485 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15486 } else if (strstr(accept, "application/xpidf+xml")) { 15487 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15488 } else if (ast_strlen_zero(accept)) { 15489 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15490 transmit_response(p, "489 Bad Event", req); 15491 15492 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15493 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15494 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15495 return 0; 15496 } 15497 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15498 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15499 } else { 15500 /* Can't find a format for events that we know about */ 15501 char mybuf[200]; 15502 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15503 transmit_response(p, mybuf, req); 15504 15505 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15506 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15507 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15508 return 0; 15509 } 15510 } else if (!strcmp(event, "message-summary")) { 15511 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15512 /* Format requested that we do not support */ 15513 transmit_response(p, "406 Not Acceptable", req); 15514 if (option_debug > 1) 15515 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15516 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15517 if (authpeer) /* No need for authpeer here */ 15518 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15519 return 0; 15520 } 15521 /* Looks like they actually want a mailbox status 15522 This version of Asterisk supports mailbox subscriptions 15523 The subscribed URI needs to exist in the dial plan 15524 In most devices, this is configurable to the voicemailmain extension you use 15525 */ 15526 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15527 transmit_response(p, "404 Not found (no mailbox)", req); 15528 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15529 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15530 if (authpeer) /* No need for authpeer here */ 15531 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15532 return 0; 15533 } 15534 15535 p->subscribed = MWI_NOTIFICATION; 15536 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15537 /* We only allow one subscription per peer */ 15538 sip_destroy(authpeer->mwipvt); 15539 authpeer->mwipvt = p; /* Link from peer to pvt */ 15540 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15541 } else { /* At this point, Asterisk does not understand the specified event */ 15542 transmit_response(p, "489 Bad Event", req); 15543 if (option_debug > 1) 15544 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15545 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15546 if (authpeer) /* No need for authpeer here */ 15547 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15548 return 0; 15549 } 15550 15551 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15552 if (p->stateid > -1) 15553 ast_extension_state_del(p->stateid, cb_extensionstate); 15554 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15555 } 15556 15557 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15558 p->lastinvite = seqno; 15559 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15560 p->expiry = atoi(get_header(req, "Expires")); 15561 15562 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15563 if (p->expiry > max_expiry) 15564 p->expiry = max_expiry; 15565 if (p->expiry < min_expiry && p->expiry > 0) 15566 p->expiry = min_expiry; 15567 15568 if (sipdebug || option_debug > 1) { 15569 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15570 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15571 else 15572 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15573 } 15574 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15575 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15576 if (p->expiry > 0) 15577 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15578 15579 if (p->subscribed == MWI_NOTIFICATION) { 15580 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15581 transmit_response(p, "200 OK", req); 15582 if (p->relatedpeer) { /* Send first notification */ 15583 ASTOBJ_WRLOCK(p->relatedpeer); 15584 sip_send_mwi_to_peer(p->relatedpeer); 15585 ASTOBJ_UNLOCK(p->relatedpeer); 15586 } 15587 } else { 15588 struct sip_pvt *p_old; 15589 15590 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15591 15592 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)); 15593 transmit_response(p, "404 Not found", req); 15594 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15595 return 0; 15596 } 15597 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15598 transmit_response(p, "200 OK", req); 15599 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15600 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15601 /* hide the 'complete' exten/context in the refer_to field for later display */ 15602 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15603 15604 /* remove any old subscription from this peer for the same exten/context, 15605 as the peer has obviously forgotten about it and it's wasteful to wait 15606 for it to expire and send NOTIFY messages to the peer only to have them 15607 ignored (or generate errors) 15608 */ 15609 ast_mutex_lock(&iflock); 15610 for (p_old = iflist; p_old; p_old = p_old->next) { 15611 if (p_old == p) 15612 continue; 15613 if (p_old->initreq.method != SIP_SUBSCRIBE) 15614 continue; 15615 if (p_old->subscribed == NONE) 15616 continue; 15617 ast_mutex_lock(&p_old->lock); 15618 if (!strcmp(p_old->username, p->username)) { 15619 if (!strcmp(p_old->exten, p->exten) && 15620 !strcmp(p_old->context, p->context)) { 15621 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15622 ast_mutex_unlock(&p_old->lock); 15623 break; 15624 } 15625 } 15626 ast_mutex_unlock(&p_old->lock); 15627 } 15628 ast_mutex_unlock(&iflock); 15629 } 15630 if (!p->expiry) 15631 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15632 } 15633 return 1; 15634 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 12841 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), cb_extensionstate(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12842 { 12843 struct ast_channel *owner; 12844 int sipmethod; 12845 int res = 1; 12846 const char *c = get_header(req, "Cseq"); 12847 /* 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 */ 12848 char *c_copy = ast_strdupa(c); 12849 /* Skip the Cseq and its subsequent spaces */ 12850 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 12851 12852 if (!msg) 12853 msg = ""; 12854 12855 sipmethod = find_sip_method(msg); 12856 12857 owner = p->owner; 12858 if (owner) 12859 owner->hangupcause = hangup_sip2cause(resp); 12860 12861 /* Acknowledge whatever it is destined for */ 12862 if ((resp >= 100) && (resp <= 199)) 12863 __sip_semi_ack(p, seqno, 0, sipmethod); 12864 else 12865 __sip_ack(p, seqno, 0, sipmethod); 12866 12867 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12868 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12869 p->pendinginvite = 0; 12870 12871 /* Get their tag if we haven't already */ 12872 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12873 char tag[128]; 12874 12875 gettag(req, "To", tag, sizeof(tag)); 12876 ast_string_field_set(p, theirtag, tag); 12877 } 12878 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12879 /* We don't really care what the response is, just that it replied back. 12880 Well, as long as it's not a 100 response... since we might 12881 need to hang around for something more "definitive" */ 12882 if (resp != 100) 12883 handle_response_peerpoke(p, resp, req); 12884 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12885 switch(resp) { 12886 case 100: /* 100 Trying */ 12887 case 101: /* 101 Dialog establishment */ 12888 if (sipmethod == SIP_INVITE) 12889 handle_response_invite(p, resp, rest, req, seqno); 12890 break; 12891 case 183: /* 183 Session Progress */ 12892 if (sipmethod == SIP_INVITE) 12893 handle_response_invite(p, resp, rest, req, seqno); 12894 break; 12895 case 180: /* 180 Ringing */ 12896 if (sipmethod == SIP_INVITE) 12897 handle_response_invite(p, resp, rest, req, seqno); 12898 break; 12899 case 182: /* 182 Queued */ 12900 if (sipmethod == SIP_INVITE) 12901 handle_response_invite(p, resp, rest, req, seqno); 12902 break; 12903 case 200: /* 200 OK */ 12904 p->authtries = 0; /* Reset authentication counter */ 12905 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12906 /* We successfully transmitted a message 12907 or a video update request in INFO */ 12908 /* Nothing happens here - the message is inside a dialog */ 12909 } else if (sipmethod == SIP_INVITE) { 12910 handle_response_invite(p, resp, rest, req, seqno); 12911 } else if (sipmethod == SIP_NOTIFY) { 12912 /* They got the notify, this is the end */ 12913 if (p->owner) { 12914 if (!p->refer) { 12915 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12916 ast_queue_hangup(p->owner); 12917 } else if (option_debug > 3) 12918 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12919 } else { 12920 if (p->subscribed == NONE) 12921 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12922 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12923 /* Ready to send the next state we have on queue */ 12924 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12925 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 12926 } 12927 } 12928 } else if (sipmethod == SIP_REGISTER) 12929 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12930 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 12931 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12932 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12933 } else if (sipmethod == SIP_SUBSCRIBE) 12934 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12935 break; 12936 case 202: /* Transfer accepted */ 12937 if (sipmethod == SIP_REFER) 12938 handle_response_refer(p, resp, rest, req, seqno); 12939 break; 12940 case 401: /* Not www-authorized on SIP method */ 12941 if (sipmethod == SIP_INVITE) 12942 handle_response_invite(p, resp, rest, req, seqno); 12943 else if (sipmethod == SIP_REFER) 12944 handle_response_refer(p, resp, rest, req, seqno); 12945 else if (p->registry && sipmethod == SIP_REGISTER) 12946 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12947 else if (sipmethod == SIP_BYE) { 12948 if (ast_strlen_zero(p->authname)) { 12949 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12950 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12951 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12952 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12953 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12954 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12955 /* We fail to auth bye on our own call, but still needs to tear down the call. 12956 Life, they call it. */ 12957 } 12958 } else { 12959 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12960 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12961 } 12962 break; 12963 case 403: /* Forbidden - we failed authentication */ 12964 if (sipmethod == SIP_INVITE) 12965 handle_response_invite(p, resp, rest, req, seqno); 12966 else if (p->registry && sipmethod == SIP_REGISTER) 12967 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12968 else { 12969 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12970 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12971 } 12972 break; 12973 case 404: /* Not found */ 12974 if (p->registry && sipmethod == SIP_REGISTER) 12975 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12976 else if (sipmethod == SIP_INVITE) 12977 handle_response_invite(p, resp, rest, req, seqno); 12978 else if (owner) 12979 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12980 break; 12981 case 407: /* Proxy auth required */ 12982 if (sipmethod == SIP_INVITE) 12983 handle_response_invite(p, resp, rest, req, seqno); 12984 else if (sipmethod == SIP_REFER) 12985 handle_response_refer(p, resp, rest, req, seqno); 12986 else if (p->registry && sipmethod == SIP_REGISTER) 12987 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12988 else if (sipmethod == SIP_BYE) { 12989 if (ast_strlen_zero(p->authname)) { 12990 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12991 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12992 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12993 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12994 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12995 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12996 } 12997 } else /* We can't handle this, giving up in a bad way */ 12998 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12999 13000 break; 13001 case 408: /* Request timeout - terminate dialog */ 13002 if (sipmethod == SIP_INVITE) 13003 handle_response_invite(p, resp, rest, req, seqno); 13004 else if (sipmethod == SIP_REGISTER) 13005 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13006 else if (sipmethod == SIP_BYE) { 13007 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13008 if (option_debug) 13009 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13010 } else { 13011 if (owner) 13012 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13013 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13014 } 13015 break; 13016 case 481: /* Call leg does not exist */ 13017 if (sipmethod == SIP_INVITE) { 13018 handle_response_invite(p, resp, rest, req, seqno); 13019 } else if (sipmethod == SIP_REFER) { 13020 handle_response_refer(p, resp, rest, req, seqno); 13021 } else if (sipmethod == SIP_BYE) { 13022 /* The other side has no transaction to bye, 13023 just assume it's all right then */ 13024 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13025 } else if (sipmethod == SIP_CANCEL) { 13026 /* The other side has no transaction to cancel, 13027 just assume it's all right then */ 13028 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13029 } else { 13030 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13031 /* Guessing that this is not an important request */ 13032 } 13033 break; 13034 case 487: 13035 if (sipmethod == SIP_INVITE) 13036 handle_response_invite(p, resp, rest, req, seqno); 13037 break; 13038 case 488: /* Not acceptable here - codec error */ 13039 if (sipmethod == SIP_INVITE) 13040 handle_response_invite(p, resp, rest, req, seqno); 13041 break; 13042 case 491: /* Pending */ 13043 if (sipmethod == SIP_INVITE) 13044 handle_response_invite(p, resp, rest, req, seqno); 13045 else { 13046 if (option_debug) 13047 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13048 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13049 } 13050 break; 13051 case 501: /* Not Implemented */ 13052 if (sipmethod == SIP_INVITE) 13053 handle_response_invite(p, resp, rest, req, seqno); 13054 else if (sipmethod == SIP_REFER) 13055 handle_response_refer(p, resp, rest, req, seqno); 13056 else 13057 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13058 break; 13059 case 603: /* Declined transfer */ 13060 if (sipmethod == SIP_REFER) { 13061 handle_response_refer(p, resp, rest, req, seqno); 13062 break; 13063 } 13064 /* Fallthrough */ 13065 default: 13066 if ((resp >= 300) && (resp < 700)) { 13067 /* Fatal response */ 13068 if ((option_verbose > 2) && (resp != 487)) 13069 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13070 13071 if (sipmethod == SIP_INVITE) 13072 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13073 13074 /* XXX Locking issues?? XXX */ 13075 switch(resp) { 13076 case 300: /* Multiple Choices */ 13077 case 301: /* Moved permenantly */ 13078 case 302: /* Moved temporarily */ 13079 case 305: /* Use Proxy */ 13080 parse_moved_contact(p, req); 13081 /* Fall through */ 13082 case 486: /* Busy here */ 13083 case 600: /* Busy everywhere */ 13084 case 603: /* Decline */ 13085 if (p->owner) 13086 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13087 break; 13088 case 482: /* 13089 \note SIP is incapable of performing a hairpin call, which 13090 is yet another failure of not having a layer 2 (again, YAY 13091 IETF for thinking ahead). So we treat this as a call 13092 forward and hope we end up at the right place... */ 13093 if (option_debug) 13094 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13095 if (p->owner) 13096 ast_string_field_build(p->owner, call_forward, 13097 "Local/%s@%s", p->username, p->context); 13098 /* Fall through */ 13099 case 480: /* Temporarily Unavailable */ 13100 case 404: /* Not Found */ 13101 case 410: /* Gone */ 13102 case 400: /* Bad Request */ 13103 case 500: /* Server error */ 13104 if (sipmethod == SIP_REFER) { 13105 handle_response_refer(p, resp, rest, req, seqno); 13106 break; 13107 } 13108 /* Fall through */ 13109 case 502: /* Bad gateway */ 13110 case 503: /* Service Unavailable */ 13111 case 504: /* Server Timeout */ 13112 if (owner) 13113 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13114 break; 13115 default: 13116 /* Send hangup */ 13117 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13118 ast_queue_hangup(p->owner); 13119 break; 13120 } 13121 /* ACK on invite */ 13122 if (sipmethod == SIP_INVITE) 13123 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13124 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13125 sip_alreadygone(p); 13126 if (!p->owner) 13127 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13128 } else if ((resp >= 100) && (resp < 200)) { 13129 if (sipmethod == SIP_INVITE) { 13130 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13131 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13132 if (find_sdp(req)) 13133 process_sdp(p, req); 13134 if (p->owner) { 13135 /* Queue a progress frame */ 13136 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13137 } 13138 } 13139 } else 13140 ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr)); 13141 } 13142 } else { 13143 /* Responses to OUTGOING SIP requests on INCOMING calls 13144 get handled here. As well as out-of-call message responses */ 13145 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13146 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13147 13148 if (sipmethod == SIP_INVITE && resp == 200) { 13149 /* Tags in early session is replaced by the tag in 200 OK, which is 13150 the final reply to our INVITE */ 13151 char tag[128]; 13152 13153 gettag(req, "To", tag, sizeof(tag)); 13154 ast_string_field_set(p, theirtag, tag); 13155 } 13156 13157 switch(resp) { 13158 case 200: 13159 if (sipmethod == SIP_INVITE) { 13160 handle_response_invite(p, resp, rest, req, seqno); 13161 } else if (sipmethod == SIP_CANCEL) { 13162 if (option_debug) 13163 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13164 13165 /* Wait for 487, then destroy */ 13166 } else if (sipmethod == SIP_NOTIFY) { 13167 /* They got the notify, this is the end */ 13168 if (p->owner) { 13169 if (p->refer) { 13170 if (option_debug) 13171 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13172 } else 13173 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13174 /* ast_queue_hangup(p->owner); Disabled */ 13175 } else { 13176 if (!p->subscribed && !p->refer) 13177 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13178 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13179 /* Ready to send the next state we have on queue */ 13180 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13181 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13182 } 13183 } 13184 } else if (sipmethod == SIP_BYE) 13185 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13186 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13187 /* We successfully transmitted a message or 13188 a video update request in INFO */ 13189 ; 13190 else if (sipmethod == SIP_BYE) 13191 /* Ok, we're ready to go */ 13192 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13193 break; 13194 case 202: /* Transfer accepted */ 13195 if (sipmethod == SIP_REFER) 13196 handle_response_refer(p, resp, rest, req, seqno); 13197 break; 13198 case 401: /* www-auth */ 13199 case 407: 13200 if (sipmethod == SIP_REFER) 13201 handle_response_refer(p, resp, rest, req, seqno); 13202 else if (sipmethod == SIP_INVITE) 13203 handle_response_invite(p, resp, rest, req, seqno); 13204 else if (sipmethod == SIP_BYE) { 13205 char *auth, *auth2; 13206 13207 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13208 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13209 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13210 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13211 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13212 } 13213 } 13214 break; 13215 case 481: /* Call leg does not exist */ 13216 if (sipmethod == SIP_INVITE) { 13217 /* Re-invite failed */ 13218 handle_response_invite(p, resp, rest, req, seqno); 13219 } else if (sipmethod == SIP_BYE) { 13220 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13221 } else if (sipdebug) { 13222 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13223 } 13224 break; 13225 case 501: /* Not Implemented */ 13226 if (sipmethod == SIP_INVITE) 13227 handle_response_invite(p, resp, rest, req, seqno); 13228 else if (sipmethod == SIP_REFER) 13229 handle_response_refer(p, resp, rest, req, seqno); 13230 break; 13231 case 603: /* Declined transfer */ 13232 if (sipmethod == SIP_REFER) { 13233 handle_response_refer(p, resp, rest, req, seqno); 13234 break; 13235 } 13236 /* Fallthrough */ 13237 default: /* Errors without handlers */ 13238 if ((resp >= 100) && (resp < 200)) { 13239 if (sipmethod == SIP_INVITE) { /* re-invite */ 13240 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13241 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13242 } 13243 } 13244 if ((resp >= 300) && (resp < 700)) { 13245 if ((option_verbose > 2) && (resp != 487)) 13246 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)); 13247 switch(resp) { 13248 case 488: /* Not acceptable here - codec error */ 13249 case 603: /* Decline */ 13250 case 500: /* Server error */ 13251 case 502: /* Bad gateway */ 13252 case 503: /* Service Unavailable */ 13253 case 504: /* Server timeout */ 13254 13255 /* re-invite failed */ 13256 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13257 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13258 break; 13259 } 13260 } 13261 break; 13262 } 13263 } 13264 }
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 12256 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
12257 { 12258 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12259 int res = 0; 12260 int xmitres = 0; 12261 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12262 struct ast_channel *bridgepeer = NULL; 12263 12264 if (option_debug > 3) { 12265 if (reinvite) 12266 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12267 else 12268 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12269 } 12270 12271 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12272 if (option_debug) 12273 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12274 return; 12275 } 12276 12277 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12278 /* Don't auto congest anymore since we've gotten something useful back */ 12279 AST_SCHED_DEL(sched, p->initid); 12280 12281 /* RFC3261 says we must treat every 1xx response (but not 100) 12282 that we don't recognize as if it was 183. 12283 */ 12284 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12285 resp = 183; 12286 12287 /* Any response between 100 and 199 is PROCEEDING */ 12288 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12289 p->invitestate = INV_PROCEEDING; 12290 12291 /* Final response, not 200 ? */ 12292 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12293 p->invitestate = INV_COMPLETED; 12294 12295 12296 switch (resp) { 12297 case 100: /* Trying */ 12298 case 101: /* Dialog establishment */ 12299 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12300 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12301 check_pendings(p); 12302 break; 12303 12304 case 180: /* 180 Ringing */ 12305 case 182: /* 182 Queued */ 12306 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12307 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12308 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12309 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12310 if (p->owner->_state != AST_STATE_UP) { 12311 ast_setstate(p->owner, AST_STATE_RINGING); 12312 } 12313 } 12314 if (find_sdp(req)) { 12315 if (p->invitestate != INV_CANCELLED) 12316 p->invitestate = INV_EARLY_MEDIA; 12317 res = process_sdp(p, req); 12318 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12319 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12320 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12321 } 12322 } 12323 check_pendings(p); 12324 break; 12325 12326 case 183: /* Session progress */ 12327 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12328 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12329 /* Ignore 183 Session progress without SDP */ 12330 if (find_sdp(req)) { 12331 if (p->invitestate != INV_CANCELLED) 12332 p->invitestate = INV_EARLY_MEDIA; 12333 res = process_sdp(p, req); 12334 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12335 /* Queue a progress frame */ 12336 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12337 } 12338 } 12339 check_pendings(p); 12340 break; 12341 12342 case 200: /* 200 OK on invite - someone's answering our call */ 12343 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12344 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12345 p->authtries = 0; 12346 if (find_sdp(req)) { 12347 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12348 if (!reinvite) 12349 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12350 /* For re-invites, we try to recover */ 12351 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12352 } 12353 12354 /* Parse contact header for continued conversation */ 12355 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12356 /* This is important when we have a SIP proxy between us and the phone */ 12357 if (outgoing) { 12358 update_call_counter(p, DEC_CALL_RINGING); 12359 parse_ok_contact(p, req); 12360 /* Save Record-Route for any later requests we make on this dialogue */ 12361 if (!reinvite) 12362 build_route(p, req, 1); 12363 12364 if(set_address_from_contact(p)) { 12365 /* Bad contact - we don't know how to reach this device */ 12366 /* We need to ACK, but then send a bye */ 12367 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12368 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12369 } 12370 12371 } 12372 12373 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12374 struct sip_pvt *bridgepvt = NULL; 12375 12376 if (!bridgepeer->tech) { 12377 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12378 break; 12379 } 12380 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12381 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12382 if (bridgepvt->udptl) { 12383 if (p->t38.state == T38_PEER_REINVITE) { 12384 sip_handle_t38_reinvite(bridgepeer, p, 0); 12385 ast_rtp_set_rtptimers_onhold(p->rtp); 12386 if (p->vrtp) 12387 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12388 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12389 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12390 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12391 /* XXXX Should we really destroy this session here, without any response at all??? */ 12392 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12393 } 12394 } else { 12395 if (option_debug > 1) 12396 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12397 ast_mutex_lock(&bridgepvt->lock); 12398 bridgepvt->t38.state = T38_DISABLED; 12399 ast_mutex_unlock(&bridgepvt->lock); 12400 if (option_debug) 12401 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12402 p->t38.state = T38_DISABLED; 12403 if (option_debug > 1) 12404 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12405 } 12406 } else { 12407 /* Other side is not a SIP channel */ 12408 if (option_debug > 1) 12409 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12410 p->t38.state = T38_DISABLED; 12411 if (option_debug > 1) 12412 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12413 } 12414 } 12415 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12416 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12417 p->t38.state = T38_ENABLED; 12418 if (option_debug) 12419 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12420 } 12421 12422 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12423 if (!reinvite) { 12424 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12425 } else { /* RE-invite */ 12426 ast_queue_frame(p->owner, &ast_null_frame); 12427 } 12428 } else { 12429 /* It's possible we're getting an 200 OK after we've tried to disconnect 12430 by sending CANCEL */ 12431 /* First send ACK, then send bye */ 12432 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12433 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12434 } 12435 /* If I understand this right, the branch is different for a non-200 ACK only */ 12436 p->invitestate = INV_TERMINATED; 12437 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12438 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12439 check_pendings(p); 12440 break; 12441 case 407: /* Proxy authentication */ 12442 case 401: /* Www auth */ 12443 /* First we ACK */ 12444 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12445 if (p->options) 12446 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12447 12448 /* Then we AUTH */ 12449 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12450 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12451 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12452 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12453 if (p->authtries < MAX_AUTHTRIES) 12454 p->invitestate = INV_CALLING; 12455 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12456 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12457 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12458 sip_alreadygone(p); 12459 if (p->owner) 12460 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12461 } 12462 } 12463 break; 12464 12465 case 403: /* Forbidden */ 12466 /* First we ACK */ 12467 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12468 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12469 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12470 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12471 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12472 sip_alreadygone(p); 12473 break; 12474 12475 case 404: /* Not found */ 12476 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12477 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12478 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12479 sip_alreadygone(p); 12480 break; 12481 12482 case 408: /* Request timeout */ 12483 case 481: /* Call leg does not exist */ 12484 /* Could be REFER caused INVITE with replaces */ 12485 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12486 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12487 if (p->owner) 12488 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12489 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12490 break; 12491 case 487: /* Cancelled transaction */ 12492 /* We have sent CANCEL on an outbound INVITE 12493 This transaction is already scheduled to be killed by sip_hangup(). 12494 */ 12495 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12496 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12497 ast_queue_hangup(p->owner); 12498 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12499 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12500 update_call_counter(p, DEC_CALL_LIMIT); 12501 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12502 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12503 sip_alreadygone(p); 12504 } 12505 break; 12506 case 488: /* Not acceptable here */ 12507 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12508 if (reinvite && p->udptl) { 12509 /* If this is a T.38 call, we should go back to 12510 audio. If this is an audio call - something went 12511 terribly wrong since we don't renegotiate codecs, 12512 only IP/port . 12513 */ 12514 p->t38.state = T38_DISABLED; 12515 /* Try to reset RTP timers */ 12516 ast_rtp_set_rtptimers_onhold(p->rtp); 12517 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12518 12519 /*! \bug Is there any way we can go back to the audio call on both 12520 sides here? 12521 */ 12522 /* While figuring that out, hangup the call */ 12523 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12524 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12525 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12526 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12527 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12528 right now we can't fall back to audio so totally abort. 12529 */ 12530 p->t38.state = T38_DISABLED; 12531 /* Try to reset RTP timers */ 12532 ast_rtp_set_rtptimers_onhold(p->rtp); 12533 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12534 12535 /* The dialog is now terminated */ 12536 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12537 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12538 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12539 sip_alreadygone(p); 12540 } else { 12541 /* We can't set up this call, so give up */ 12542 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12543 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12544 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12545 /* If there's no dialog to end, then mark p as already gone */ 12546 if (!reinvite) 12547 sip_alreadygone(p); 12548 } 12549 break; 12550 case 491: /* Pending */ 12551 /* we really should have to wait a while, then retransmit 12552 * We should support the retry-after at some point 12553 * At this point, we treat this as a congestion if the call is not in UP state 12554 */ 12555 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12556 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12557 if (p->owner->_state != AST_STATE_UP) { 12558 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12559 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12560 } else { 12561 /* This is a re-invite that failed. 12562 * Reset the flag after a while 12563 */ 12564 int wait = 3 + ast_random() % 5; 12565 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12566 if (option_debug > 2) 12567 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12568 } 12569 } 12570 break; 12571 12572 case 501: /* Not implemented */ 12573 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12574 if (p->owner) 12575 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12576 break; 12577 } 12578 if (xmitres == XMIT_ERROR) 12579 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12580 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12774 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12775 { 12776 struct sip_peer *peer = p->relatedpeer; 12777 int statechanged, is_reachable, was_reachable; 12778 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12779 12780 /* 12781 * Compute the response time to a ping (goes in peer->lastms.) 12782 * -1 means did not respond, 0 means unknown, 12783 * 1..maxms is a valid response, >maxms means late response. 12784 */ 12785 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12786 pingtime = 1; 12787 12788 /* Now determine new state and whether it has changed. 12789 * Use some helper variables to simplify the writing 12790 * of the expressions. 12791 */ 12792 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12793 is_reachable = pingtime <= peer->maxms; 12794 statechanged = peer->lastms == 0 /* yes, unknown before */ 12795 || was_reachable != is_reachable; 12796 12797 peer->lastms = pingtime; 12798 peer->call = NULL; 12799 if (statechanged) { 12800 const char *s = is_reachable ? "Reachable" : "Lagged"; 12801 12802 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12803 peer->name, s, pingtime, peer->maxms); 12804 ast_device_state_changed("SIP/%s", peer->name); 12805 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12806 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12807 peer->name, s, pingtime); 12808 } 12809 12810 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12811 struct sip_peer *peer_ptr = peer; 12812 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12813 } 12814 12815 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12816 12817 /* Try again eventually */ 12818 peer->pokeexpire = ast_sched_add(sched, 12819 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12820 sip_poke_peer_s, ASTOBJ_REF(peer)); 12821 12822 if (peer->pokeexpire == -1) { 12823 ASTOBJ_UNREF(peer, sip_destroy_peer); 12824 } 12825 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12585 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
12586 { 12587 char *auth = "Proxy-Authenticate"; 12588 char *auth2 = "Proxy-Authorization"; 12589 12590 /* If no refer structure exists, then do nothing */ 12591 if (!p->refer) 12592 return; 12593 12594 switch (resp) { 12595 case 202: /* Transfer accepted */ 12596 /* We need to do something here */ 12597 /* The transferee is now sending INVITE to target */ 12598 p->refer->status = REFER_ACCEPTED; 12599 /* Now wait for next message */ 12600 if (option_debug > 2) 12601 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12602 /* We should hang along, waiting for NOTIFY's here */ 12603 break; 12604 12605 case 401: /* Not www-authorized on SIP method */ 12606 case 407: /* Proxy auth */ 12607 if (ast_strlen_zero(p->authname)) { 12608 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12609 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12610 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12611 } 12612 if (resp == 401) { 12613 auth = "WWW-Authenticate"; 12614 auth2 = "Authorization"; 12615 } 12616 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12617 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12618 p->refer->status = REFER_NOAUTH; 12619 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12620 } 12621 break; 12622 case 481: /* Call leg does not exist */ 12623 12624 /* A transfer with Replaces did not work */ 12625 /* OEJ: We should Set flag, cancel the REFER, go back 12626 to original call - but right now we can't */ 12627 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12628 if (p->owner) 12629 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12630 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12631 break; 12632 12633 case 500: /* Server error */ 12634 case 501: /* Method not implemented */ 12635 /* Return to the current call onhold */ 12636 /* Status flag needed to be reset */ 12637 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12638 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12639 p->refer->status = REFER_FAILED; 12640 break; 12641 case 603: /* Transfer declined */ 12642 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12643 p->refer->status = REFER_FAILED; 12644 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12645 break; 12646 } 12647 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 12650 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12651 { 12652 int expires, expires_ms; 12653 struct sip_registry *r; 12654 r=p->registry; 12655 12656 switch (resp) { 12657 case 401: /* Unauthorized */ 12658 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12659 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12660 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12661 } 12662 break; 12663 case 403: /* Forbidden */ 12664 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12665 if (global_regattempts_max) 12666 p->registry->regattempts = global_regattempts_max+1; 12667 AST_SCHED_DEL(sched, r->timeout); 12668 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12669 break; 12670 case 404: /* Not found */ 12671 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12672 if (global_regattempts_max) 12673 p->registry->regattempts = global_regattempts_max+1; 12674 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12675 r->call = NULL; 12676 AST_SCHED_DEL(sched, r->timeout); 12677 break; 12678 case 407: /* Proxy auth */ 12679 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12680 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12681 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12682 } 12683 break; 12684 case 408: /* Request timeout */ 12685 /* Got a timeout response, so reset the counter of failed responses */ 12686 r->regattempts = 0; 12687 break; 12688 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12689 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12690 if (global_regattempts_max) 12691 p->registry->regattempts = global_regattempts_max+1; 12692 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12693 r->call = NULL; 12694 AST_SCHED_DEL(sched, r->timeout); 12695 break; 12696 case 200: /* 200 OK */ 12697 if (!r) { 12698 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12699 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12700 return 0; 12701 } 12702 12703 r->regstate = REG_STATE_REGISTERED; 12704 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12705 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12706 r->regattempts = 0; 12707 if (option_debug) 12708 ast_log(LOG_DEBUG, "Registration successful\n"); 12709 if (r->timeout > -1) { 12710 if (option_debug) 12711 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12712 } 12713 AST_SCHED_DEL(sched, r->timeout); 12714 r->call = NULL; 12715 p->registry = NULL; 12716 /* Let this one hang around until we have all the responses */ 12717 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12718 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12719 12720 /* set us up for re-registering */ 12721 /* figure out how long we got registered for */ 12722 AST_SCHED_DEL(sched, r->expire); 12723 /* according to section 6.13 of RFC, contact headers override 12724 expires headers, so check those first */ 12725 expires = 0; 12726 12727 /* XXX todo: try to save the extra call */ 12728 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12729 const char *contact = NULL; 12730 const char *tmptmp = NULL; 12731 int start = 0; 12732 for(;;) { 12733 contact = __get_header(req, "Contact", &start); 12734 /* this loop ensures we get a contact header about our register request */ 12735 if(!ast_strlen_zero(contact)) { 12736 if( (tmptmp=strstr(contact, p->our_contact))) { 12737 contact=tmptmp; 12738 break; 12739 } 12740 } else 12741 break; 12742 } 12743 tmptmp = strcasestr(contact, "expires="); 12744 if (tmptmp) { 12745 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12746 expires = 0; 12747 } 12748 12749 } 12750 if (!expires) 12751 expires=atoi(get_header(req, "expires")); 12752 if (!expires) 12753 expires=default_expiry; 12754 12755 expires_ms = expires * 1000; 12756 if (expires <= EXPIRY_GUARD_LIMIT) 12757 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12758 else 12759 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12760 if (sipdebug) 12761 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12762 12763 r->refresh= (int) expires_ms / 1000; 12764 12765 /* Schedule re-registration before we expire */ 12766 AST_SCHED_DEL(sched, r->expire); 12767 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12768 ASTOBJ_UNREF(r, sip_registry_destroy); 12769 } 12770 return 1; 12771 }
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 3472 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().
03473 { 03474 switch (cause) { 03475 case AST_CAUSE_UNALLOCATED: /* 1 */ 03476 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03477 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03478 return "404 Not Found"; 03479 case AST_CAUSE_CONGESTION: /* 34 */ 03480 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03481 return "503 Service Unavailable"; 03482 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03483 return "408 Request Timeout"; 03484 case AST_CAUSE_NO_ANSWER: /* 19 */ 03485 case AST_CAUSE_UNREGISTERED: /* 20 */ 03486 return "480 Temporarily unavailable"; 03487 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03488 return "403 Forbidden"; 03489 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03490 return "410 Gone"; 03491 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03492 return "480 Temporarily unavailable"; 03493 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03494 return "484 Address incomplete"; 03495 case AST_CAUSE_USER_BUSY: 03496 return "486 Busy here"; 03497 case AST_CAUSE_FAILURE: 03498 return "500 Server internal failure"; 03499 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03500 return "501 Not Implemented"; 03501 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03502 return "503 Service Unavailable"; 03503 /* Used in chan_iax2 */ 03504 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03505 return "502 Bad Gateway"; 03506 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03507 return "488 Not Acceptable Here"; 03508 03509 case AST_CAUSE_NOTDEFINED: 03510 default: 03511 if (option_debug) 03512 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03513 return NULL; 03514 } 03515 03516 /* Never reached */ 03517 return 0; 03518 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3360 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by handle_response().
03361 { 03362 /* Possible values taken from causes.h */ 03363 03364 switch(cause) { 03365 case 401: /* Unauthorized */ 03366 return AST_CAUSE_CALL_REJECTED; 03367 case 403: /* Not found */ 03368 return AST_CAUSE_CALL_REJECTED; 03369 case 404: /* Not found */ 03370 return AST_CAUSE_UNALLOCATED; 03371 case 405: /* Method not allowed */ 03372 return AST_CAUSE_INTERWORKING; 03373 case 407: /* Proxy authentication required */ 03374 return AST_CAUSE_CALL_REJECTED; 03375 case 408: /* No reaction */ 03376 return AST_CAUSE_NO_USER_RESPONSE; 03377 case 409: /* Conflict */ 03378 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03379 case 410: /* Gone */ 03380 return AST_CAUSE_UNALLOCATED; 03381 case 411: /* Length required */ 03382 return AST_CAUSE_INTERWORKING; 03383 case 413: /* Request entity too large */ 03384 return AST_CAUSE_INTERWORKING; 03385 case 414: /* Request URI too large */ 03386 return AST_CAUSE_INTERWORKING; 03387 case 415: /* Unsupported media type */ 03388 return AST_CAUSE_INTERWORKING; 03389 case 420: /* Bad extension */ 03390 return AST_CAUSE_NO_ROUTE_DESTINATION; 03391 case 480: /* No answer */ 03392 return AST_CAUSE_NO_ANSWER; 03393 case 481: /* No answer */ 03394 return AST_CAUSE_INTERWORKING; 03395 case 482: /* Loop detected */ 03396 return AST_CAUSE_INTERWORKING; 03397 case 483: /* Too many hops */ 03398 return AST_CAUSE_NO_ANSWER; 03399 case 484: /* Address incomplete */ 03400 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03401 case 485: /* Ambigous */ 03402 return AST_CAUSE_UNALLOCATED; 03403 case 486: /* Busy everywhere */ 03404 return AST_CAUSE_BUSY; 03405 case 487: /* Request terminated */ 03406 return AST_CAUSE_INTERWORKING; 03407 case 488: /* No codecs approved */ 03408 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03409 case 491: /* Request pending */ 03410 return AST_CAUSE_INTERWORKING; 03411 case 493: /* Undecipherable */ 03412 return AST_CAUSE_INTERWORKING; 03413 case 500: /* Server internal failure */ 03414 return AST_CAUSE_FAILURE; 03415 case 501: /* Call rejected */ 03416 return AST_CAUSE_FACILITY_REJECTED; 03417 case 502: 03418 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03419 case 503: /* Service unavailable */ 03420 return AST_CAUSE_CONGESTION; 03421 case 504: /* Gateway timeout */ 03422 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03423 case 505: /* SIP version not supported */ 03424 return AST_CAUSE_INTERWORKING; 03425 case 600: /* Busy everywhere */ 03426 return AST_CAUSE_USER_BUSY; 03427 case 603: /* Decline */ 03428 return AST_CAUSE_CALL_REJECTED; 03429 case 604: /* Does not exist anywhere */ 03430 return AST_CAUSE_UNALLOCATED; 03431 case 606: /* Not acceptable */ 03432 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03433 default: 03434 return AST_CAUSE_NORMAL; 03435 } 03436 /* Never reached */ 03437 return 0; 03438 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5960 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05961 { 05962 /* Initialize a request */ 05963 memset(req, 0, sizeof(*req)); 05964 req->method = sipmethod; 05965 req->header[0] = req->data; 05966 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05967 req->len = strlen(req->header[0]); 05968 req->headers++; 05969 return 0; 05970 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5947 of file chan_sip.c.
References SIP_RESPONSE.
05948 { 05949 /* Initialize a response */ 05950 memset(resp, 0, sizeof(*resp)); 05951 resp->method = SIP_RESPONSE; 05952 resp->header[0] = resp->data; 05953 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05954 resp->len = strlen(resp->header[0]); 05955 resp->headers++; 05956 return 0; 05957 }
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 1655 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_sip_request().
01656 { 01657 if (p->initreq.headers && option_debug) { 01658 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01659 } 01660 /* Use this as the basis */ 01661 copy_request(&p->initreq, req); 01662 parse_request(&p->initreq); 01663 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01664 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01665 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7047 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::ourip, ourport, sip_pvt::owner, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_invite_param::uri_options, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
07048 { 07049 char invite_buf[256] = ""; 07050 char *invite = invite_buf; 07051 size_t invite_max = sizeof(invite_buf); 07052 char from[256]; 07053 char to[256]; 07054 char tmp[SIPBUFSIZE/2]; 07055 char tmp2[SIPBUFSIZE/2]; 07056 const char *l = NULL, *n = NULL; 07057 const char *urioptions = ""; 07058 07059 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07060 const char *s = p->username; /* being a string field, cannot be NULL */ 07061 07062 /* Test p->username against allowed characters in AST_DIGIT_ANY 07063 If it matches the allowed characters list, then sipuser = ";user=phone" 07064 If not, then sipuser = "" 07065 */ 07066 /* + is allowed in first position in a tel: uri */ 07067 if (*s == '+') 07068 s++; 07069 for (; *s; s++) { 07070 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07071 break; 07072 } 07073 /* If we have only digits, add ;user=phone to the uri */ 07074 if (*s) 07075 urioptions = ";user=phone"; 07076 } 07077 07078 07079 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07080 07081 if (p->owner) { 07082 l = p->owner->cid.cid_num; 07083 n = p->owner->cid.cid_name; 07084 } 07085 /* if we are not sending RPID and user wants his callerid restricted */ 07086 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07087 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07088 l = CALLERID_UNKNOWN; 07089 n = l; 07090 } 07091 if (ast_strlen_zero(l)) 07092 l = default_callerid; 07093 if (ast_strlen_zero(n)) 07094 n = l; 07095 /* Allow user to be overridden */ 07096 if (!ast_strlen_zero(p->fromuser)) 07097 l = p->fromuser; 07098 else /* Save for any further attempts */ 07099 ast_string_field_set(p, fromuser, l); 07100 07101 /* Allow user to be overridden */ 07102 if (!ast_strlen_zero(p->fromname)) 07103 n = p->fromname; 07104 else /* Save for any further attempts */ 07105 ast_string_field_set(p, fromname, n); 07106 07107 if (pedanticsipchecking) { 07108 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07109 n = tmp; 07110 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07111 l = tmp2; 07112 } 07113 07114 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07115 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag); 07116 else 07117 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07118 07119 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07120 if (!ast_strlen_zero(p->fullcontact)) { 07121 /* If we have full contact, trust it */ 07122 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07123 } else { 07124 /* Otherwise, use the username while waiting for registration */ 07125 ast_build_string(&invite, &invite_max, "sip:"); 07126 if (!ast_strlen_zero(p->username)) { 07127 n = p->username; 07128 if (pedanticsipchecking) { 07129 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07130 n = tmp; 07131 } 07132 ast_build_string(&invite, &invite_max, "%s@", n); 07133 } 07134 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07135 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07136 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07137 ast_build_string(&invite, &invite_max, "%s", urioptions); 07138 } 07139 07140 /* If custom URI options have been provided, append them */ 07141 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07142 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07143 07144 ast_string_field_set(p, uri, invite_buf); 07145 07146 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07147 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07148 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07149 } else if (p->options && p->options->vxml_url) { 07150 /* If there is a VXML URL append it to the SIP URL */ 07151 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07152 } else 07153 snprintf(to, sizeof(to), "<%s>", p->uri); 07154 07155 init_req(req, sipmethod, p->uri); 07156 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07157 07158 add_header(req, "Via", p->via); 07159 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07160 * OTOH, then we won't have anything in p->route anyway */ 07161 /* Build Remote Party-ID and From */ 07162 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07163 build_rpid(p); 07164 add_header(req, "From", p->rpid_from); 07165 } else 07166 add_header(req, "From", from); 07167 add_header(req, "To", to); 07168 ast_string_field_set(p, exten, l); 07169 build_contact(p); 07170 add_header(req, "Contact", p->our_contact); 07171 add_header(req, "Call-ID", p->callid); 07172 add_header(req, "CSeq", tmp); 07173 if (!ast_strlen_zero(global_useragent)) 07174 add_header(req, "User-Agent", global_useragent); 07175 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07176 if (!ast_strlen_zero(p->rpid)) 07177 add_header(req, "Remote-Party-ID", p->rpid); 07178 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10260 of file chan_sip.c.
Referenced by _sip_show_peer().
10261 { 10262 if (port && invite) 10263 return "port,invite"; 10264 else if (port) 10265 return "port"; 10266 else if (invite) 10267 return "invite"; 10268 else 10269 return "no"; 10270 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8398 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08399 { 08400 if (!route) 08401 ast_verbose("list_route: no route\n"); 08402 else { 08403 for (;route; route = route->next) 08404 ast_verbose("list_route: hop: <%s>\n", route->hop); 08405 } 08406 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18691 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
18692 { 18693 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18694 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18695 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18696 18697 if (!(sched = sched_context_create())) { 18698 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18699 return AST_MODULE_LOAD_FAILURE; 18700 } 18701 18702 if (!(io = io_context_create())) { 18703 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18704 sched_context_destroy(sched); 18705 return AST_MODULE_LOAD_FAILURE; 18706 } 18707 18708 sip_reloadreason = CHANNEL_MODULE_LOAD; 18709 18710 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18711 return AST_MODULE_LOAD_DECLINE; 18712 18713 /* Make sure we can register our sip channel type */ 18714 if (ast_channel_register(&sip_tech)) { 18715 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18716 io_context_destroy(io); 18717 sched_context_destroy(sched); 18718 return AST_MODULE_LOAD_FAILURE; 18719 } 18720 18721 /* Register all CLI functions for SIP */ 18722 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18723 18724 /* Tell the RTP subdriver that we're here */ 18725 ast_rtp_proto_register(&sip_rtp); 18726 18727 /* Tell the UDPTL subdriver that we're here */ 18728 ast_udptl_proto_register(&sip_udptl); 18729 18730 /* Register dialplan applications */ 18731 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18732 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18733 18734 /* Register dialplan functions */ 18735 ast_custom_function_register(&sip_header_function); 18736 ast_custom_function_register(&sippeer_function); 18737 ast_custom_function_register(&sipchaninfo_function); 18738 ast_custom_function_register(&checksipdomain_function); 18739 18740 /* Register manager commands */ 18741 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18742 "List SIP peers (text format)", mandescr_show_peers); 18743 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18744 "Show SIP peer (text format)", mandescr_show_peer); 18745 18746 sip_poke_all_peers(); 18747 sip_send_all_registers(); 18748 18749 /* And start the monitor for the first time */ 18750 restart_monitor(); 18751 18752 return AST_MODULE_LOAD_SUCCESS; 18753 }
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 14710 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request_refer().
14711 { 14712 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14713 /* Chan 2: Call from Asterisk to target */ 14714 int res = 0; 14715 struct sip_pvt *targetcall_pvt; 14716 14717 /* Check if the call ID of the replaces header does exist locally */ 14718 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14719 transferer->refer->replaces_callid_fromtag))) { 14720 if (transferer->refer->localtransfer) { 14721 /* We did not find the refered call. Sorry, can't accept then */ 14722 transmit_response(transferer, "202 Accepted", req); 14723 /* Let's fake a response from someone else in order 14724 to follow the standard */ 14725 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14726 append_history(transferer, "Xfer", "Refer failed"); 14727 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14728 transferer->refer->status = REFER_FAILED; 14729 return -1; 14730 } 14731 /* Fall through for remote transfers that we did not find locally */ 14732 if (option_debug > 2) 14733 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14734 return 0; 14735 } 14736 14737 /* Ok, we can accept this transfer */ 14738 transmit_response(transferer, "202 Accepted", req); 14739 append_history(transferer, "Xfer", "Refer accepted"); 14740 if (!targetcall_pvt->owner) { /* No active channel */ 14741 if (option_debug > 3) 14742 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14743 /* Cancel transfer */ 14744 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14745 append_history(transferer, "Xfer", "Refer failed"); 14746 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14747 transferer->refer->status = REFER_FAILED; 14748 ast_mutex_unlock(&targetcall_pvt->lock); 14749 ast_channel_unlock(current->chan1); 14750 return -1; 14751 } 14752 14753 /* We have a channel, find the bridge */ 14754 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14755 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14756 14757 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14758 /* Wrong state of new channel */ 14759 if (option_debug > 3) { 14760 if (target.chan2) 14761 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14762 else if (target.chan1->_state != AST_STATE_RING) 14763 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14764 else 14765 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14766 } 14767 } 14768 14769 /* Transfer */ 14770 if (option_debug > 3 && sipdebug) { 14771 if (current->chan2) /* We have two bridges */ 14772 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14773 else /* One bridge, propably transfer of IVR/voicemail etc */ 14774 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14775 } 14776 14777 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14778 14779 /* Perform the transfer */ 14780 res = attempt_transfer(current, &target); 14781 ast_mutex_unlock(&targetcall_pvt->lock); 14782 if (res) { 14783 /* Failed transfer */ 14784 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14785 append_history(transferer, "Xfer", "Refer failed"); 14786 transferer->refer->status = REFER_FAILED; 14787 if (targetcall_pvt->owner) 14788 ast_channel_unlock(targetcall_pvt->owner); 14789 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14790 if (res != -2) 14791 ast_hangup(transferer->owner); 14792 else 14793 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14794 } else { 14795 /* Transfer succeeded! */ 14796 14797 /* Tell transferer that we're done. */ 14798 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14799 append_history(transferer, "Xfer", "Refer succeeded"); 14800 transferer->refer->status = REFER_200OK; 14801 if (targetcall_pvt->owner) { 14802 if (option_debug) 14803 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14804 ast_channel_unlock(targetcall_pvt->owner); 14805 } 14806 } 14807 return 1; 14808 }
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 4845 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04846 { 04847 int h = 0, t = 0; 04848 int lws = 0; 04849 04850 for (; h < len;) { 04851 /* Eliminate all CRs */ 04852 if (msgbuf[h] == '\r') { 04853 h++; 04854 continue; 04855 } 04856 /* Check for end-of-line */ 04857 if (msgbuf[h] == '\n') { 04858 /* Check for end-of-message */ 04859 if (h + 1 == len) 04860 break; 04861 /* Check for a continuation line */ 04862 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04863 /* Merge continuation line */ 04864 h++; 04865 continue; 04866 } 04867 /* Propagate LF and start new line */ 04868 msgbuf[t++] = msgbuf[h++]; 04869 lws = 0; 04870 continue; 04871 } 04872 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04873 if (lws) { 04874 h++; 04875 continue; 04876 } 04877 msgbuf[t++] = msgbuf[h++]; 04878 lws = 1; 04879 continue; 04880 } 04881 msgbuf[t++] = msgbuf[h++]; 04882 if (lws) 04883 lws = 0; 04884 } 04885 msgbuf[t] = '\0'; 04886 return t; 04887 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4512 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().
04513 { 04514 snprintf(tagbuf, len, "as%08lx", ast_random()); 04515 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10505 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().
10506 { 10507 const char *a[4]; 10508 const char *peer; 10509 int ret; 10510 10511 peer = astman_get_header(m,"Peer"); 10512 if (ast_strlen_zero(peer)) { 10513 astman_send_error(s, m, "Peer: <name> missing."); 10514 return 0; 10515 } 10516 a[0] = "sip"; 10517 a[1] = "show"; 10518 a[2] = "peer"; 10519 a[3] = peer; 10520 10521 ret = _sip_show_peer(1, -1, s, m, 4, a); 10522 astman_append(s, "\r\n\r\n" ); 10523 return ret; 10524 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10056 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().
10057 { 10058 const char *id = astman_get_header(m,"ActionID"); 10059 const char *a[] = {"sip", "show", "peers"}; 10060 char idtext[256] = ""; 10061 int total = 0; 10062 10063 if (!ast_strlen_zero(id)) 10064 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10065 10066 astman_send_ack(s, m, "Peer status list will follow"); 10067 /* List the peers in separate manager events */ 10068 _sip_show_peers(-1, &total, s, m, 3, a); 10069 /* Send final confirmation */ 10070 astman_append(s, 10071 "Event: PeerlistComplete\r\n" 10072 "ListItems: %d\r\n" 10073 "%s" 10074 "\r\n", total, idtext); 10075 return 0; 10076 }
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 1681 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01682 { 01683 int len = strlen(sip_methods[id].text); 01684 int l_name = name ? strlen(name) : 0; 01685 /* true if the string is long enough, and ends with whitespace, and matches */ 01686 return (l_name >= len && name[len] < 33 && 01687 !strncasecmp(sip_methods[id].text, name, len)); 01688 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9959 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().
09960 { 09961 switch(nat) { 09962 case SIP_NAT_NEVER: 09963 return "No"; 09964 case SIP_NAT_ROUTE: 09965 return "Route"; 09966 case SIP_NAT_ALWAYS: 09967 return "Always"; 09968 case SIP_NAT_RFC3581: 09969 return "RFC3581"; 09970 default: 09971 return "Unknown"; 09972 } 09973 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2266 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02267 { 02268 memset(dst, 0, sizeof(*dst)); 02269 memcpy(dst->data, src->data, sizeof(dst->data)); 02270 dst->len = src->len; 02271 parse_request(dst); 02272 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12157 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, SIPBUFSIZE, and t.
Referenced by handle_response().
12158 { 12159 char tmp[SIPBUFSIZE]; 12160 char *s, *e, *uri, *t; 12161 char *domain; 12162 12163 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12164 if ((t = strchr(tmp, ','))) 12165 *t = '\0'; 12166 s = get_in_brackets(tmp); 12167 uri = ast_strdupa(s); 12168 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12169 if (!strncasecmp(s, "sip:", 4)) 12170 s += 4; 12171 e = strchr(s, ';'); 12172 if (e) 12173 *e = '\0'; 12174 if (option_debug) 12175 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12176 if (p->owner) 12177 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12178 } else { 12179 e = strchr(tmp, '@'); 12180 if (e) { 12181 *e++ = '\0'; 12182 domain = e; 12183 } else { 12184 /* No username part */ 12185 domain = tmp; 12186 } 12187 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12188 if (e) 12189 *e = '\0'; 12190 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12191 if (e) 12192 *e = '\0'; 12193 12194 if (!strncasecmp(s, "sip:", 4)) 12195 s += 4; 12196 if (option_debug > 1) 12197 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12198 if (p->owner) { 12199 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12200 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12201 ast_string_field_set(p->owner, call_forward, s); 12202 } 12203 } 12204 }
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 8134 of file chan_sip.c.
References 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().
08135 { 08136 char contact[SIPBUFSIZE]; 08137 char *c; 08138 08139 /* Look for brackets */ 08140 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08141 c = get_in_brackets(contact); 08142 08143 /* Save full contact to call pvt for later bye or re-invite */ 08144 ast_string_field_set(pvt, fullcontact, c); 08145 08146 /* Save URI for later ACKs, BYE or RE-invites */ 08147 ast_string_field_set(pvt, okcontacturi, c); 08148 08149 /* We should return false for URI:s we can't handle, 08150 like sips:, tel:, mailto:,ldap: etc */ 08151 return TRUE; 08152 }
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 8223 of file chan_sip.c.
References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), ast_set_flag, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_pvt::sockfd, sip_peer::sockfd, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08224 { 08225 char contact[SIPBUFSIZE]; 08226 char data[SIPBUFSIZE]; 08227 const char *expires = get_header(req, "Expires"); 08228 int expiry = atoi(expires); 08229 char *curi, *n, *pt; 08230 int port; 08231 const char *useragent; 08232 struct hostent *hp; 08233 struct ast_hostent ahp; 08234 struct sockaddr_in oldsin; 08235 08236 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08237 08238 if (ast_strlen_zero(expires)) { /* No expires header */ 08239 expires = strcasestr(contact, ";expires="); 08240 if (expires) { 08241 /* XXX bug here, we overwrite the string */ 08242 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08243 if (sscanf(expires + 9, "%d", &expiry) != 1) 08244 expiry = default_expiry; 08245 } else { 08246 /* Nothing has been specified */ 08247 expiry = default_expiry; 08248 } 08249 } 08250 08251 /* Look for brackets */ 08252 curi = contact; 08253 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08254 strsep(&curi, ";"); /* This is Header options, not URI options */ 08255 curi = get_in_brackets(contact); 08256 08257 /* if they did not specify Contact: or Expires:, they are querying 08258 what we currently have stored as their contact address, so return 08259 it 08260 */ 08261 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08262 /* If we have an active registration, tell them when the registration is going to expire */ 08263 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08264 pvt->expiry = ast_sched_when(sched, peer->expire); 08265 return PARSE_REGISTER_QUERY; 08266 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08267 /* This means remove all registrations and return OK */ 08268 memset(&peer->addr, 0, sizeof(peer->addr)); 08269 if (!AST_SCHED_DEL(sched, peer->expire)) { 08270 struct sip_peer *peer_ptr = peer; 08271 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08272 } 08273 08274 destroy_association(peer); 08275 08276 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08277 peer->fullcontact[0] = '\0'; 08278 peer->useragent[0] = '\0'; 08279 peer->sipoptions = 0; 08280 peer->lastms = 0; 08281 08282 if (option_verbose > 2) 08283 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08284 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08285 return PARSE_REGISTER_UPDATE; 08286 } 08287 08288 /* Store whatever we got as a contact from the client */ 08289 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08290 08291 /* For the 200 OK, we should use the received contact */ 08292 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08293 08294 /* Make sure it's a SIP URL */ 08295 if (strncasecmp(curi, "sip:", 4)) { 08296 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08297 } else 08298 curi += 4; 08299 /* Ditch q */ 08300 curi = strsep(&curi, ";"); 08301 /* Grab host */ 08302 n = strchr(curi, '@'); 08303 if (!n) { 08304 n = curi; 08305 curi = NULL; 08306 } else 08307 *n++ = '\0'; 08308 pt = strchr(n, ':'); 08309 if (pt) { 08310 *pt++ = '\0'; 08311 port = atoi(pt); 08312 } else 08313 port = STANDARD_SIP_PORT; 08314 oldsin = peer->addr; 08315 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08316 /* XXX This could block for a long time XXX */ 08317 hp = ast_gethostbyname(n, &ahp); 08318 if (!hp) { 08319 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08320 return PARSE_REGISTER_FAILED; 08321 } 08322 peer->addr.sin_family = AF_INET; 08323 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08324 peer->addr.sin_port = htons(port); 08325 } else { 08326 /* Don't trust the contact field. Just use what they came to us 08327 with */ 08328 peer->addr = pvt->recv; 08329 } 08330 08331 /* Save SIP options profile */ 08332 peer->sipoptions = pvt->sipoptions; 08333 08334 if (curi && ast_strlen_zero(peer->username)) 08335 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08336 08337 if (!AST_SCHED_DEL(sched, peer->expire)) { 08338 struct sip_peer *peer_ptr = peer; 08339 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08340 } 08341 if (expiry > max_expiry) 08342 expiry = max_expiry; 08343 if (expiry < min_expiry) 08344 expiry = min_expiry; 08345 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08346 peer->expire = -1; 08347 } else { 08348 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08349 if (peer->expire == -1) { 08350 struct sip_peer *peer_ptr = peer; 08351 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08352 } 08353 } 08354 pvt->expiry = expiry; 08355 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); 08356 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08357 ast_db_put("SIP/Registry", peer->name, data); 08358 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08359 08360 /* Is this a new IP address for us? */ 08361 if (inaddrcmp(&peer->addr, &oldsin)) { 08362 sip_poke_peer(peer); 08363 if (option_verbose > 2) 08364 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry); 08365 register_peer_exten(peer, 1); 08366 } 08367 08368 /* Save User agent */ 08369 useragent = get_header(req, "User-Agent"); 08370 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08371 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08372 if (option_verbose > 3) 08373 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08374 } 08375 08376 /* Allocate A TCP Soccket of incoming connection*/ 08377 if (((!ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP)) || (peer->sockfd != pvt->sockfd)) && (ast_test_flag(&pvt->flags[1], SIP_PAGE2_TCP))) { 08378 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP); 08379 peer->sockfd=pvt->sockfd; 08380 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 08381 } 08382 return PARSE_REGISTER_UPDATE; 08383 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4892 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().
04893 { 04894 /* Divide fields by NULL's */ 04895 char *c; 04896 int f = 0; 04897 04898 c = req->data; 04899 04900 /* First header starts immediately */ 04901 req->header[f] = c; 04902 while(*c) { 04903 if (*c == '\n') { 04904 /* We've got a new header */ 04905 *c = 0; 04906 04907 if (sipdebug && option_debug > 3) 04908 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04909 if (ast_strlen_zero(req->header[f])) { 04910 /* Line by itself means we're now in content */ 04911 c++; 04912 break; 04913 } 04914 if (f >= SIP_MAX_HEADERS - 1) { 04915 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04916 } else 04917 f++; 04918 req->header[f] = c + 1; 04919 } else if (*c == '\r') { 04920 /* Ignore but eliminate \r's */ 04921 *c = 0; 04922 } 04923 c++; 04924 } 04925 /* Check for last header */ 04926 if (!ast_strlen_zero(req->header[f])) { 04927 if (sipdebug && option_debug > 3) 04928 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04929 f++; 04930 } 04931 req->headers = f; 04932 /* Now we process any mime content */ 04933 f = 0; 04934 req->line[f] = c; 04935 while(*c) { 04936 if (*c == '\n') { 04937 /* We've got a new line */ 04938 *c = 0; 04939 if (sipdebug && option_debug > 3) 04940 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04941 if (f >= SIP_MAX_LINES - 1) { 04942 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04943 } else 04944 f++; 04945 req->line[f] = c + 1; 04946 } else if (*c == '\r') { 04947 /* Ignore and eliminate \r's */ 04948 *c = 0; 04949 } 04950 c++; 04951 } 04952 /* Check for last line */ 04953 if (!ast_strlen_zero(req->line[f])) 04954 f++; 04955 req->lines = f; 04956 if (*c) 04957 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04958 /* Split up the first line parts */ 04959 return determine_firstline_parts(req); 04960 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1705 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01706 { 01707 char *next, *sep; 01708 char *temp; 01709 unsigned int profile = 0; 01710 int i, found; 01711 01712 if (ast_strlen_zero(supported) ) 01713 return 0; 01714 temp = ast_strdupa(supported); 01715 01716 if (option_debug > 2 && sipdebug) 01717 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01718 01719 for (next = temp; next; next = sep) { 01720 found = FALSE; 01721 if ( (sep = strchr(next, ',')) != NULL) 01722 *sep++ = '\0'; 01723 next = ast_skip_blanks(next); 01724 if (option_debug > 2 && sipdebug) 01725 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01726 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01727 if (!strcasecmp(next, sip_options[i].text)) { 01728 profile |= sip_options[i].id; 01729 found = TRUE; 01730 if (option_debug > 2 && sipdebug) 01731 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01732 break; 01733 } 01734 } 01735 if (!found && option_debug > 2 && sipdebug) { 01736 if (!strncasecmp(next, "x-", 2)) 01737 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01738 else 01739 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01740 } 01741 } 01742 01743 if (pvt) 01744 pvt->sipoptions = profile; 01745 return profile; 01746 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9978 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09979 { 09980 int res = 0; 09981 if (peer->maxms) { 09982 if (peer->lastms < 0) { 09983 ast_copy_string(status, "UNREACHABLE", statuslen); 09984 } else if (peer->lastms > peer->maxms) { 09985 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09986 res = 1; 09987 } else if (peer->lastms) { 09988 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09989 res = 1; 09990 } else { 09991 ast_copy_string(status, "UNKNOWN", statuslen); 09992 } 09993 } else { 09994 ast_copy_string(status, "Unmonitored", statuslen); 09995 /* Checking if port is 0 */ 09996 res = -1; 09997 } 09998 return res; 09999 }
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 10446 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().
10447 { 10448 int x, codec; 10449 10450 for(x = 0; x < 32 ; x++) { 10451 codec = ast_codec_pref_index(pref, x); 10452 if (!codec) 10453 break; 10454 ast_cli(fd, "%s", ast_getformatname(codec)); 10455 ast_cli(fd, ":%d", pref->framing[x]); 10456 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10457 ast_cli(fd, ","); 10458 } 10459 if (!x) 10460 ast_cli(fd, "none"); 10461 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10237 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10238 { 10239 char buf[256]; 10240 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10241 }
static int process_sdp | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
< RTP Audio port number
< RTP Video port number
< media socket address
< Video socket address
< RTP Audio host IP
< RTP video host IP
Definition at line 5093 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, sip_pvt::capability, t38properties::capability, change_hold_state(), debug, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LONG_MAX, LONG_MIN, MAX_RTP_PT, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
05094 { 05095 const char *m; /* SDP media offer */ 05096 const char *c; 05097 const char *a; 05098 char host[258]; 05099 int len = -1; 05100 int portno = -1; /*!< RTP Audio port number */ 05101 int vportno = -1; /*!< RTP Video port number */ 05102 int udptlportno = -1; 05103 int peert38capability = 0; 05104 char s[256]; 05105 int old = 0; 05106 05107 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05108 int peercapability = 0, peernoncodeccapability = 0; 05109 int vpeercapability = 0, vpeernoncodeccapability = 0; 05110 struct sockaddr_in sin; /*!< media socket address */ 05111 struct sockaddr_in vsin; /*!< Video socket address */ 05112 05113 const char *codecs; 05114 struct hostent *hp; /*!< RTP Audio host IP */ 05115 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05116 struct ast_hostent audiohp; 05117 struct ast_hostent videohp; 05118 int codec; 05119 int destiterator = 0; 05120 int iterator; 05121 int sendonly = -1; 05122 int numberofports; 05123 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05124 int newjointcapability; /* Negotiated capability */ 05125 int newpeercapability; 05126 int newnoncodeccapability; 05127 int numberofmediastreams = 0; 05128 int debug = sip_debug_test_pvt(p); 05129 05130 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05131 int last_rtpmap_codec=0; 05132 05133 if (!p->rtp) { 05134 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05135 return -1; 05136 } 05137 05138 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05139 #ifdef LOW_MEMORY 05140 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05141 #else 05142 newaudiortp = alloca(ast_rtp_alloc_size()); 05143 #endif 05144 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05145 ast_rtp_new_init(newaudiortp); 05146 ast_rtp_pt_clear(newaudiortp); 05147 05148 #ifdef LOW_MEMORY 05149 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05150 #else 05151 newvideortp = alloca(ast_rtp_alloc_size()); 05152 #endif 05153 memset(newvideortp, 0, ast_rtp_alloc_size()); 05154 ast_rtp_new_init(newvideortp); 05155 ast_rtp_pt_clear(newvideortp); 05156 05157 /* Update our last rtprx when we receive an SDP, too */ 05158 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05159 05160 05161 /* Try to find first media stream */ 05162 m = get_sdp(req, "m"); 05163 destiterator = req->sdp_start; 05164 c = get_sdp_iterate(&destiterator, req, "c"); 05165 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05166 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05167 return -1; 05168 } 05169 05170 /* Check for IPv4 address (not IPv6 yet) */ 05171 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05172 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05173 return -1; 05174 } 05175 05176 /* XXX This could block for a long time, and block the main thread! XXX */ 05177 hp = ast_gethostbyname(host, &audiohp); 05178 if (!hp) { 05179 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05180 return -1; 05181 } 05182 vhp = hp; /* Copy to video address as default too */ 05183 05184 iterator = req->sdp_start; 05185 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05186 05187 05188 /* Find media streams in this SDP offer */ 05189 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05190 int x; 05191 int audio = FALSE; 05192 05193 numberofports = 1; 05194 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05195 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 05196 audio = TRUE; 05197 numberofmediastreams++; 05198 /* Found audio stream in this media definition */ 05199 portno = x; 05200 /* Scan through the RTP payload types specified in a "m=" line: */ 05201 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05202 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05203 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05204 return -1; 05205 } 05206 if (debug) 05207 ast_verbose("Found RTP audio format %d\n", codec); 05208 ast_rtp_set_m_type(newaudiortp, codec); 05209 } 05210 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 05211 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 05212 /* If it is not audio - is it video ? */ 05213 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05214 numberofmediastreams++; 05215 vportno = x; 05216 /* Scan through the RTP payload types specified in a "m=" line: */ 05217 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05218 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05219 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05220 return -1; 05221 } 05222 if (debug) 05223 ast_verbose("Found RTP video format %d\n", codec); 05224 ast_rtp_set_m_type(newvideortp, codec); 05225 } 05226 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05227 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05228 if (debug) 05229 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05230 udptlportno = x; 05231 numberofmediastreams++; 05232 05233 if (p->owner && p->lastinvite) { 05234 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05235 if (option_debug > 1) 05236 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05237 } else { 05238 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05239 if (option_debug > 1) 05240 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05241 } 05242 } else 05243 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05244 if (numberofports > 1) 05245 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05246 05247 05248 /* Check for Media-description-level-address for audio */ 05249 c = get_sdp_iterate(&destiterator, req, "c"); 05250 if (!ast_strlen_zero(c)) { 05251 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05252 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05253 } else { 05254 /* XXX This could block for a long time, and block the main thread! XXX */ 05255 if (audio) { 05256 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05257 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05258 return -2; 05259 } 05260 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05261 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05262 return -2; 05263 } 05264 } 05265 05266 } 05267 } 05268 if (portno == -1 && vportno == -1 && udptlportno == -1) 05269 /* No acceptable offer found in SDP - we have no ports */ 05270 /* Do not change RTP or VRTP if this is a re-invite */ 05271 return -2; 05272 05273 if (numberofmediastreams > 2) 05274 /* We have too many fax, audio and/or video media streams, fail this offer */ 05275 return -3; 05276 05277 /* RTP addresses and ports for audio and video */ 05278 sin.sin_family = AF_INET; 05279 vsin.sin_family = AF_INET; 05280 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05281 if (vhp) 05282 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05283 05284 /* Setup UDPTL port number */ 05285 if (p->udptl) { 05286 if (udptlportno > 0) { 05287 sin.sin_port = htons(udptlportno); 05288 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05289 struct sockaddr_in peer; 05290 ast_rtp_get_peer(p->rtp, &peer); 05291 if (peer.sin_addr.s_addr) { 05292 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(&sin.sin_addr)); 05293 if (debug) { 05294 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(sin.sin_addr)); 05295 } 05296 } 05297 } 05298 ast_udptl_set_peer(p->udptl, &sin); 05299 if (debug) 05300 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05301 } else { 05302 ast_udptl_stop(p->udptl); 05303 if (debug) 05304 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05305 } 05306 } 05307 05308 05309 if (p->rtp) { 05310 if (portno > 0) { 05311 sin.sin_port = htons(portno); 05312 ast_rtp_set_peer(p->rtp, &sin); 05313 if (debug) 05314 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05315 } else { 05316 if (udptlportno > 0) { 05317 if (debug) 05318 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05319 } else { 05320 ast_rtp_stop(p->rtp); 05321 if (debug) 05322 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05323 } 05324 } 05325 } 05326 /* Setup video port number */ 05327 if (vportno != -1) 05328 vsin.sin_port = htons(vportno); 05329 05330 /* Next, scan through each "a=rtpmap:" line, noting each 05331 * specified RTP payload type (with corresponding MIME subtype): 05332 */ 05333 /* XXX This needs to be done per media stream, since it's media stream specific */ 05334 iterator = req->sdp_start; 05335 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05336 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05337 if (option_debug > 1) { 05338 int breakout = FALSE; 05339 05340 /* If we're debugging, check for unsupported sdp options */ 05341 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05342 if (debug) 05343 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05344 breakout = TRUE; 05345 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05346 /* Format parameters: Not supported */ 05347 /* Note: This is used for codec parameters, like bitrate for 05348 G722 and video formats for H263 and H264 05349 See RFC2327 for an example */ 05350 if (debug) 05351 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05352 breakout = TRUE; 05353 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05354 /* Video stuff: Not supported */ 05355 if (debug) 05356 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05357 breakout = TRUE; 05358 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05359 /* Video stuff: Not supported */ 05360 if (debug) 05361 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05362 breakout = TRUE; 05363 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05364 /* SRTP stuff, not yet supported */ 05365 if (debug) 05366 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05367 breakout = TRUE; 05368 } 05369 if (breakout) /* We have a match, skip to next header */ 05370 continue; 05371 } 05372 if (!strcasecmp(a, "sendonly")) { 05373 if (sendonly == -1) 05374 sendonly = 1; 05375 continue; 05376 } else if (!strcasecmp(a, "inactive")) { 05377 if (sendonly == -1) 05378 sendonly = 2; 05379 continue; 05380 } else if (!strcasecmp(a, "sendrecv")) { 05381 if (sendonly == -1) 05382 sendonly = 0; 05383 continue; 05384 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05385 char *tmp = strrchr(a, ':'); 05386 long int framing = 0; 05387 if (tmp) { 05388 tmp++; 05389 framing = strtol(tmp, NULL, 10); 05390 if (framing == LONG_MIN || framing == LONG_MAX) { 05391 framing = 0; 05392 if (option_debug) 05393 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05394 } 05395 } 05396 if (framing && p->autoframing) { 05397 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05398 int codec_n; 05399 int format = 0; 05400 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05401 format = ast_rtp_codec_getformat(codec_n); 05402 if (!format) /* non-codec or not found */ 05403 continue; 05404 if (option_debug) 05405 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05406 ast_codec_pref_setsize(pref, format, framing); 05407 } 05408 ast_rtp_codec_setpref(p->rtp, pref); 05409 } 05410 continue; 05411 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05412 /* We have a rtpmap to handle */ 05413 int found = FALSE; 05414 /* We should propably check if this is an audio or video codec 05415 so we know where to look */ 05416 05417 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05418 /* Note: should really look at the 'freq' and '#chans' params too */ 05419 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05420 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05421 if (debug) 05422 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05423 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05424 last_rtpmap_codec++; 05425 found = TRUE; 05426 05427 } else if (p->vrtp) { 05428 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05429 if (debug) 05430 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05431 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05432 last_rtpmap_codec++; 05433 found = TRUE; 05434 } 05435 } 05436 } else { 05437 if (debug) 05438 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05439 } 05440 05441 if (!found) { 05442 /* Remove this codec since it's an unknown media type for us */ 05443 /* XXX This is buggy since the media line for audio and video can have the 05444 same numbers. We need to check as described above, but for testing this works... */ 05445 ast_rtp_unset_m_type(newaudiortp, codec); 05446 ast_rtp_unset_m_type(newvideortp, codec); 05447 if (debug) 05448 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05449 } 05450 } 05451 } 05452 05453 if (udptlportno != -1) { 05454 int found = 0, x; 05455 05456 old = 0; 05457 05458 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05459 iterator = req->sdp_start; 05460 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05461 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05462 found = 1; 05463 if (option_debug > 2) 05464 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05465 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05466 found = 1; 05467 if (option_debug > 2) 05468 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05469 switch (x) { 05470 case 14400: 05471 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05472 break; 05473 case 12000: 05474 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05475 break; 05476 case 9600: 05477 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05478 break; 05479 case 7200: 05480 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05481 break; 05482 case 4800: 05483 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05484 break; 05485 case 2400: 05486 peert38capability |= T38FAX_RATE_2400; 05487 break; 05488 } 05489 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05490 found = 1; 05491 if (option_debug > 2) 05492 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05493 if (x == 0) 05494 peert38capability |= T38FAX_VERSION_0; 05495 else if (x == 1) 05496 peert38capability |= T38FAX_VERSION_1; 05497 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05498 found = 1; 05499 if (option_debug > 2) 05500 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05501 ast_udptl_set_far_max_datagram(p->udptl, x); 05502 ast_udptl_set_local_max_datagram(p->udptl, x); 05503 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05504 found = 1; 05505 if (option_debug > 2) 05506 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05507 if (x == 1) 05508 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05509 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05510 found = 1; 05511 if (option_debug > 2) 05512 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05513 if (x == 1) 05514 peert38capability |= T38FAX_TRANSCODING_MMR; 05515 } 05516 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05517 found = 1; 05518 if (option_debug > 2) 05519 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05520 if (x == 1) 05521 peert38capability |= T38FAX_TRANSCODING_JBIG; 05522 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05523 found = 1; 05524 if (option_debug > 2) 05525 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05526 if (!strcasecmp(s, "localTCF")) 05527 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05528 else if (!strcasecmp(s, "transferredTCF")) 05529 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05530 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05531 found = 1; 05532 if (option_debug > 2) 05533 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05534 if (!strcasecmp(s, "t38UDPRedundancy")) { 05535 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05536 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05537 } else if (!strcasecmp(s, "t38UDPFEC")) { 05538 peert38capability |= T38FAX_UDP_EC_FEC; 05539 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05540 } else { 05541 peert38capability |= T38FAX_UDP_EC_NONE; 05542 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05543 } 05544 } 05545 } 05546 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05547 p->t38.peercapability = peert38capability; 05548 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05549 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05550 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05551 } 05552 if (debug) 05553 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05554 p->t38.capability, 05555 p->t38.peercapability, 05556 p->t38.jointcapability); 05557 } else { 05558 p->t38.state = T38_DISABLED; 05559 if (option_debug > 2) 05560 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05561 } 05562 05563 /* Now gather all of the codecs that we are asked for: */ 05564 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05565 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05566 05567 newjointcapability = p->capability & (peercapability | vpeercapability); 05568 newpeercapability = (peercapability | vpeercapability); 05569 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05570 05571 05572 if (debug) { 05573 /* shame on whoever coded this.... */ 05574 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05575 05576 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05577 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05578 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05579 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05580 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05581 05582 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05583 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05584 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05585 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05586 } 05587 if (!newjointcapability) { 05588 /* If T.38 was not negotiated either, totally bail out... */ 05589 if (!p->t38.jointcapability || !udptlportno) { 05590 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05591 /* Do NOT Change current setting */ 05592 return -1; 05593 } else { 05594 if (option_debug > 2) 05595 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05596 return 0; 05597 } 05598 } 05599 05600 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05601 they are acceptable */ 05602 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05603 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05604 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05605 05606 ast_rtp_pt_copy(p->rtp, newaudiortp); 05607 if (p->vrtp) 05608 ast_rtp_pt_copy(p->vrtp, newvideortp); 05609 05610 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05611 ast_clear_flag(&p->flags[0], SIP_DTMF); 05612 if (newnoncodeccapability & AST_RTP_DTMF) { 05613 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05614 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05615 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05616 ast_rtp_setdtmf(p->rtp, 1); 05617 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05618 } else { 05619 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05620 } 05621 } 05622 05623 /* Setup audio port number */ 05624 if (p->rtp && sin.sin_port) { 05625 ast_rtp_set_peer(p->rtp, &sin); 05626 if (debug) 05627 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05628 } 05629 05630 /* Setup video port number */ 05631 if (p->vrtp && vsin.sin_port) { 05632 ast_rtp_set_peer(p->vrtp, &vsin); 05633 if (debug) 05634 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05635 } 05636 05637 /* Ok, we're going with this offer */ 05638 if (option_debug > 1) { 05639 char buf[SIPBUFSIZE]; 05640 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05641 } 05642 05643 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05644 return 0; 05645 05646 if (option_debug > 3) 05647 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05648 05649 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05650 if (debug) { 05651 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05652 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05653 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05654 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05655 } 05656 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05657 ast_set_read_format(p->owner, p->owner->readformat); 05658 ast_set_write_format(p->owner, p->owner->writeformat); 05659 } 05660 05661 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05662 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05663 /* Activate a re-invite */ 05664 ast_queue_frame(p->owner, &ast_null_frame); 05665 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05666 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05667 S_OR(p->mohsuggest, NULL), 05668 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05669 if (sendonly) 05670 ast_rtp_stop(p->rtp); 05671 /* RTCP needs to go ahead, even if we're on hold!!! */ 05672 /* Activate a re-invite */ 05673 ast_queue_frame(p->owner, &ast_null_frame); 05674 } 05675 05676 /* Manager Hold and Unhold events must be generated, if necessary */ 05677 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05678 change_hold_state(p, req, FALSE, sendonly); 05679 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05680 change_hold_state(p, req, TRUE, sendonly); 05681 return 0; 05682 }
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 2531 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ast_flags::flags, hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02532 { 02533 struct sip_peer *peer=NULL; 02534 struct ast_variable *var = NULL; 02535 struct ast_config *peerlist = NULL; 02536 struct ast_variable *tmp; 02537 struct ast_flags flags = {0}; 02538 const char *iabuf = NULL; 02539 char portstring[6]; /*up to five digits plus null terminator*/ 02540 const char *insecure; 02541 char *cat = NULL; 02542 unsigned short portnum; 02543 02544 /* First check on peer name */ 02545 if (newpeername) { 02546 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02547 if (!var && sin) 02548 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02549 if (!var) { 02550 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02551 /*!\note 02552 * If this one loaded something, then we need to ensure that the host 02553 * field matched. The only reason why we can't have this as a criteria 02554 * is because we only have the IP address and the host field might be 02555 * set as a name (and the reverse PTR might not match). 02556 */ 02557 if (var && sin) { 02558 for (tmp = var; tmp; tmp = tmp->next) { 02559 if (!strcasecmp(tmp->name, "host")) { 02560 struct hostent *hp; 02561 struct ast_hostent ahp; 02562 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02563 /* No match */ 02564 ast_variables_destroy(var); 02565 var = NULL; 02566 } 02567 break; 02568 } 02569 } 02570 } 02571 } 02572 } 02573 02574 if (!var && sin) { /* Then check on IP address */ 02575 iabuf = ast_inet_ntoa(sin->sin_addr); 02576 portnum = ntohs(sin->sin_port); 02577 sprintf(portstring, "%d", portnum); 02578 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02579 if (!var) 02580 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02581 if (!var) { 02582 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02583 if(peerlist){ 02584 while((cat = ast_category_browse(peerlist, cat))) 02585 { 02586 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02587 set_insecure_flags(&flags, insecure, -1); 02588 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02589 var = ast_category_root(peerlist, cat); 02590 break; 02591 } 02592 } 02593 } 02594 if(!var) { 02595 ast_config_destroy(peerlist); 02596 peerlist = NULL; /*for safety's sake*/ 02597 cat = NULL; 02598 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02599 if(peerlist) { 02600 while((cat = ast_category_browse(peerlist, cat))) 02601 { 02602 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02603 set_insecure_flags(&flags, insecure, -1); 02604 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02605 var = ast_category_root(peerlist, cat); 02606 break; 02607 } 02608 } 02609 } 02610 } 02611 } 02612 } 02613 02614 if (!var) { 02615 if(peerlist) 02616 ast_config_destroy(peerlist); 02617 return NULL; 02618 } 02619 02620 for (tmp = var; tmp; tmp = tmp->next) { 02621 /* If this is type=user, then skip this object. */ 02622 if (!strcasecmp(tmp->name, "type") && 02623 !strcasecmp(tmp->value, "user")) { 02624 ast_variables_destroy(var); 02625 return NULL; 02626 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02627 newpeername = tmp->value; 02628 } 02629 } 02630 02631 if (!newpeername) { /* Did not find peer in realtime */ 02632 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02633 if(peerlist) 02634 ast_config_destroy(peerlist); 02635 else 02636 ast_variables_destroy(var); 02637 return NULL; 02638 } 02639 02640 /* Peer found in realtime, now build it in memory */ 02641 peer = build_peer(newpeername, var, NULL, 1); 02642 if (!peer) { 02643 if(peerlist) 02644 ast_config_destroy(peerlist); 02645 else 02646 ast_variables_destroy(var); 02647 return NULL; 02648 } 02649 02650 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02651 /* Cache peer */ 02652 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02653 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02654 if (!AST_SCHED_DEL(sched, peer->expire)) { 02655 struct sip_peer *peer_ptr = peer; 02656 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02657 } 02658 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02659 if (peer->expire == -1) { 02660 struct sip_peer *peer_ptr = peer; 02661 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02662 } 02663 } 02664 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02665 } 02666 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02667 if(peerlist) 02668 ast_config_destroy(peerlist); 02669 else 02670 ast_variables_destroy(var); 02671 return peer; 02672 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey | |||
) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 2420 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02421 { 02422 char port[10]; 02423 char ipaddr[INET_ADDRSTRLEN]; 02424 char regseconds[20]; 02425 02426 char *sysname = ast_config_AST_SYSTEM_NAME; 02427 char *syslabel = NULL; 02428 02429 time_t nowtime = time(NULL) + expirey; 02430 const char *fc = fullcontact ? "fullcontact" : NULL; 02431 02432 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02433 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02434 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02435 02436 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02437 sysname = NULL; 02438 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02439 syslabel = "regserver"; 02440 02441 if (fc) 02442 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02443 "port", port, "regseconds", regseconds, 02444 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02445 else 02446 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02447 "port", port, "regseconds", regseconds, 02448 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02449 }
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 2722 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02723 { 02724 struct ast_variable *var; 02725 struct ast_variable *tmp; 02726 struct sip_user *user = NULL; 02727 02728 var = ast_load_realtime("sipusers", "name", username, NULL); 02729 02730 if (!var) 02731 return NULL; 02732 02733 for (tmp = var; tmp; tmp = tmp->next) { 02734 if (!strcasecmp(tmp->name, "type") && 02735 !strcasecmp(tmp->value, "peer")) { 02736 ast_variables_destroy(var); 02737 return NULL; 02738 } 02739 } 02740 02741 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02742 02743 if (!user) { /* No user found */ 02744 ast_variables_destroy(var); 02745 return NULL; 02746 } 02747 02748 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02749 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02750 suserobjs++; 02751 ASTOBJ_CONTAINER_LINK(&userl,user); 02752 } else { 02753 /* Move counter from s to r... */ 02754 suserobjs--; 02755 ruserobjs++; 02756 } 02757 ast_set_flag(&user->flags[0], SIP_REALTIME); 02758 ast_variables_destroy(var); 02759 return user; 02760 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9861 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
09862 { 09863 char buf[1024]; 09864 struct ast_frame f; 09865 const char *content_type = get_header(req, "Content-Type"); 09866 09867 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09868 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09869 if (!p->owner) 09870 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09871 return; 09872 } 09873 09874 if (get_msg_text(buf, sizeof(buf), req)) { 09875 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09876 transmit_response(p, "202 Accepted", req); 09877 if (!p->owner) 09878 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09879 return; 09880 } 09881 09882 if (p->owner) { 09883 if (sip_debug_test_pvt(p)) 09884 ast_verbose("Message received: '%s'\n", buf); 09885 memset(&f, 0, sizeof(f)); 09886 f.frametype = AST_FRAME_TEXT; 09887 f.subclass = 0; 09888 f.offset = 0; 09889 f.data = buf; 09890 f.datalen = strlen(buf); 09891 ast_queue_frame(p->owner, &f); 09892 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09893 } else { /* Message outside of a call, we do not support that */ 09894 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); 09895 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09896 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09897 } 09898 return; 09899 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1640 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01641 { 01642 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01643 int x; 01644 01645 for (x = 0; x < i; x++) { 01646 if (referstatusstrings[x].status == rstatus) 01647 return (char *) referstatusstrings[x].text; 01648 } 01649 return ""; 01650 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8062 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, siptcpsock, strsep(), TRUE, sip_peer::username, and username.
08063 { 08064 char data[256]; 08065 struct in_addr in; 08066 int expiry; 08067 int port; 08068 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08069 08070 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08071 return; 08072 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08073 return; 08074 08075 scan = data; 08076 addr = strsep(&scan, ":"); 08077 port_str = strsep(&scan, ":"); 08078 expiry_str = strsep(&scan, ":"); 08079 username = strsep(&scan, ":"); 08080 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08081 08082 if (!inet_aton(addr, &in)) 08083 return; 08084 08085 if (port_str) 08086 port = atoi(port_str); 08087 else 08088 return; 08089 08090 if (expiry_str) 08091 expiry = atoi(expiry_str); 08092 else 08093 return; 08094 08095 if (username) 08096 ast_copy_string(peer->username, username, sizeof(peer->username)); 08097 if (contact) 08098 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08099 08100 if (option_debug > 1) 08101 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08102 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08103 08104 memset(&peer->addr, 0, sizeof(peer->addr)); 08105 peer->addr.sin_family = AF_INET; 08106 peer->addr.sin_addr = in; 08107 peer->addr.sin_port = htons(port); 08108 if ((sipsock < 0) || (siptcpsock < 0)){ 08109 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08110 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08111 struct sip_peer *peer_ptr = peer; 08112 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08113 } 08114 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08115 if (peer->pokeexpire == -1) { 08116 struct sip_peer *peer_ptr = peer; 08117 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08118 } 08119 } else 08120 sip_poke_peer(peer); 08121 if (!AST_SCHED_DEL(sched, peer->expire)) { 08122 struct sip_peer *peer_ptr = peer; 08123 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08124 } 08125 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08126 if (peer->expire == -1) { 08127 struct sip_peer *peer_ptr = peer; 08128 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08129 } 08130 register_peer_exten(peer, TRUE); 08131 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2452 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), domain::context, ext, LOG_WARNING, sip_peer::regexten, S_OR, and strsep().
02453 { 02454 char multi[256]; 02455 char *stringp, *ext, *context; 02456 02457 /* XXX note that global_regcontext is both a global 'enable' flag and 02458 * the name of the global regexten context, if not specified 02459 * individually. 02460 */ 02461 if (ast_strlen_zero(global_regcontext)) 02462 return; 02463 02464 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02465 stringp = multi; 02466 while ((ext = strsep(&stringp, "&"))) { 02467 if ((context = strchr(ext, '@'))) { 02468 *context++ = '\0'; /* split ext@context */ 02469 if (!ast_context_find(context)) { 02470 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02471 continue; 02472 } 02473 } else { 02474 context = global_regcontext; 02475 } 02476 if (onoff) 02477 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02478 ast_strdup(peer->name), ast_free, "SIP"); 02479 else 02480 ast_context_remove_extension(context, ext, 1, NULL); 02481 } 02482 }
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 8771 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08773 { 08774 enum check_auth_result res = AUTH_NOT_FOUND; 08775 struct sip_peer *peer; 08776 char tmp[256]; 08777 char *name, *c; 08778 char *t; 08779 char *domain; 08780 08781 /* Terminate URI */ 08782 t = uri; 08783 while(*t && (*t > 32) && (*t != ';')) 08784 t++; 08785 *t = '\0'; 08786 08787 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08788 if (pedanticsipchecking) 08789 ast_uri_decode(tmp); 08790 08791 c = get_in_brackets(tmp); 08792 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08793 08794 if (!strncasecmp(c, "sip:", 4)) { 08795 name = c + 4; 08796 } else { 08797 name = c; 08798 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08799 } 08800 08801 /* Strip off the domain name */ 08802 if ((c = strchr(name, '@'))) { 08803 *c++ = '\0'; 08804 domain = c; 08805 if ((c = strchr(domain, ':'))) /* Remove :port */ 08806 *c = '\0'; 08807 if (!AST_LIST_EMPTY(&domain_list)) { 08808 if (!check_sip_domain(domain, NULL, 0)) { 08809 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08810 return AUTH_UNKNOWN_DOMAIN; 08811 } 08812 } 08813 } 08814 08815 ast_string_field_set(p, exten, name); 08816 build_contact(p); 08817 peer = find_peer(name, NULL, 1, 0); 08818 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08819 /* Peer fails ACL check */ 08820 if (peer) { 08821 ASTOBJ_UNREF(peer, sip_destroy_peer); 08822 res = AUTH_ACL_FAILED; 08823 } else 08824 res = AUTH_NOT_FOUND; 08825 } 08826 if (peer) { 08827 /* Set Frame packetization */ 08828 if (p->rtp) { 08829 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08830 p->autoframing = peer->autoframing; 08831 } 08832 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08833 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08834 res = AUTH_PEER_NOT_DYNAMIC; 08835 } else { 08836 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08837 transmit_response(p, "100 Trying", req); 08838 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08839 if (sip_cancel_destroy(p)) 08840 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08841 08842 /* We have a succesful registration attemp with proper authentication, 08843 now, update the peer */ 08844 switch (parse_register_contact(p, peer, req)) { 08845 case PARSE_REGISTER_FAILED: 08846 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08847 transmit_response_with_date(p, "400 Bad Request", req); 08848 peer->lastmsgssent = -1; 08849 res = 0; 08850 break; 08851 case PARSE_REGISTER_QUERY: 08852 transmit_response_with_date(p, "200 OK", req); 08853 peer->lastmsgssent = -1; 08854 res = 0; 08855 break; 08856 case PARSE_REGISTER_UPDATE: 08857 update_peer(peer, p->expiry); 08858 /* Say OK and ask subsystem to retransmit msg counter */ 08859 transmit_response_with_date(p, "200 OK", req); 08860 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08861 peer->lastmsgssent = -1; 08862 res = 0; 08863 break; 08864 } 08865 } 08866 } 08867 } 08868 if (!peer && autocreatepeer) { 08869 /* Create peer if we have autocreate mode enabled */ 08870 peer = temp_peer(name); 08871 if (peer) { 08872 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08873 if (sip_cancel_destroy(p)) 08874 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08875 switch (parse_register_contact(p, peer, req)) { 08876 case PARSE_REGISTER_FAILED: 08877 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08878 transmit_response_with_date(p, "400 Bad Request", req); 08879 peer->lastmsgssent = -1; 08880 res = 0; 08881 break; 08882 case PARSE_REGISTER_QUERY: 08883 transmit_response_with_date(p, "200 OK", req); 08884 peer->lastmsgssent = -1; 08885 res = 0; 08886 break; 08887 case PARSE_REGISTER_UPDATE: 08888 /* Say OK and ask subsystem to retransmit msg counter */ 08889 transmit_response_with_date(p, "200 OK", req); 08890 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08891 peer->lastmsgssent = -1; 08892 res = 0; 08893 break; 08894 } 08895 } 08896 } 08897 if (!res) { 08898 ast_device_state_changed("SIP/%s", peer->name); 08899 } 08900 if (res < 0) { 08901 switch (res) { 08902 case AUTH_SECRET_FAILED: 08903 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08904 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08905 break; 08906 case AUTH_USERNAME_MISMATCH: 08907 /* Username and digest username does not match. 08908 Asterisk uses the From: username for authentication. We need the 08909 users to use the same authentication user name until we support 08910 proper authentication by digest auth name */ 08911 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08912 break; 08913 case AUTH_NOT_FOUND: 08914 case AUTH_PEER_NOT_DYNAMIC: 08915 case AUTH_ACL_FAILED: 08916 if (global_alwaysauthreject) { 08917 transmit_fake_auth_response(p, &p->initreq, 1); 08918 } else { 08919 /* URI not found */ 08920 if (res == AUTH_PEER_NOT_DYNAMIC) 08921 transmit_response(p, "403 Forbidden", &p->initreq); 08922 else 08923 transmit_response(p, "404 Not found", &p->initreq); 08924 } 08925 break; 08926 default: 08927 break; 08928 } 08929 } 08930 if (peer) 08931 ASTOBJ_UNREF(peer, sip_destroy_peer); 08932 08933 return res; 08934 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7539 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.
07540 { 07541 switch(regstate) { 07542 case REG_STATE_FAILED: 07543 return "Failed"; 07544 case REG_STATE_UNREGISTERED: 07545 return "Unregistered"; 07546 case REG_STATE_REGSENT: 07547 return "Request Sent"; 07548 case REG_STATE_AUTHSENT: 07549 return "Auth. Sent"; 07550 case REG_STATE_REGISTERED: 07551 return "Registered"; 07552 case REG_STATE_REJECTED: 07553 return "Rejected"; 07554 case REG_STATE_TIMEOUT: 07555 return "Timeout"; 07556 case REG_STATE_NOAUTH: 07557 return "No Authentication"; 07558 default: 07559 return "Unknown"; 07560 } 07561 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18577 of file chan_sip.c.
References sip_reload().
18578 { 18579 return sip_reload(0, 0, NULL); 18580 }
static int reload_config | ( | enum channelreloadreason | reason | ) | [static] |
Re-read SIP.conf config file.
< Default DTMF setting: RFC2833
< NAT support if requested by device with rport
< Allow re-invites
Definition at line 17420 of file chan_sip.c.
References ahp, ast_config_load(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().
17421 { 17422 struct ast_config *cfg, *ucfg; 17423 struct ast_variable *v; 17424 struct sip_peer *peer; 17425 struct sip_user *user; 17426 struct ast_hostent ahp; 17427 char *cat, *stringp, *context, *oldregcontext; 17428 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17429 struct hostent *hp; 17430 int format; 17431 struct ast_flags dummy[2]; 17432 int auto_sip_domains = FALSE; 17433 struct sockaddr_in old_bindaddr = bindaddr; 17434 int registry_count = 0, peer_count = 0, user_count = 0; 17435 unsigned int temp_tos = 0; 17436 struct ast_flags debugflag = {0}; 17437 17438 cfg = ast_config_load(config); 17439 17440 /* We *must* have a config file otherwise stop immediately */ 17441 if (!cfg) { 17442 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17443 return -1; 17444 } 17445 17446 if (option_debug > 3) 17447 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17448 17449 clear_realm_authentication(authl); 17450 clear_sip_domains(); 17451 authl = NULL; 17452 17453 /* First, destroy all outstanding registry calls */ 17454 /* This is needed, since otherwise active registry entries will not be destroyed */ 17455 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17456 ASTOBJ_RDLOCK(iterator); 17457 if (iterator->call) { 17458 if (option_debug > 2) 17459 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17460 /* This will also remove references to the registry */ 17461 sip_destroy(iterator->call); 17462 } 17463 ASTOBJ_UNLOCK(iterator); 17464 17465 } while(0)); 17466 17467 /* Then, actually destroy users and registry */ 17468 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17469 if (option_debug > 3) 17470 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17471 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17472 if (option_debug > 3) 17473 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17474 ASTOBJ_CONTAINER_MARKALL(&peerl); 17475 17476 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17477 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17478 oldregcontext = oldcontexts; 17479 17480 /* Clear all flags before setting default values */ 17481 /* Preserve debugging settings for console */ 17482 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17483 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17484 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17485 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17486 17487 /* Reset IP addresses */ 17488 memset(&bindaddr, 0, sizeof(bindaddr)); 17489 ast_free_ha(localaddr); 17490 memset(&localaddr, 0, sizeof(localaddr)); 17491 memset(&externip, 0, sizeof(externip)); 17492 memset(&default_prefs, 0 , sizeof(default_prefs)); 17493 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17494 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17495 ourport = STANDARD_SIP_PORT; 17496 srvlookup = DEFAULT_SRVLOOKUP; 17497 global_tos_sip = DEFAULT_TOS_SIP; 17498 global_tos_audio = DEFAULT_TOS_AUDIO; 17499 global_tos_video = DEFAULT_TOS_VIDEO; 17500 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17501 externexpire = 0; /* Expiration for DNS re-issuing */ 17502 externrefresh = 10; 17503 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17504 17505 /* Reset channel settings to default before re-configuring */ 17506 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17507 global_regcontext[0] = '\0'; 17508 expiry = DEFAULT_EXPIRY; 17509 global_notifyringing = DEFAULT_NOTIFYRINGING; 17510 global_limitonpeers = FALSE; 17511 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17512 global_notifyhold = FALSE; 17513 global_alwaysauthreject = 0; 17514 global_allowsubscribe = FALSE; 17515 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17516 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17517 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17518 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17519 else 17520 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17521 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17522 compactheaders = DEFAULT_COMPACTHEADERS; 17523 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17524 global_regattempts_max = 0; 17525 pedanticsipchecking = DEFAULT_PEDANTIC; 17526 global_mwitime = DEFAULT_MWITIME; 17527 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17528 global_autoframing = 0; 17529 global_allowguest = DEFAULT_ALLOWGUEST; 17530 global_rtptimeout = 0; 17531 global_rtpholdtimeout = 0; 17532 global_rtpkeepalive = 0; 17533 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17534 global_rtautoclear = 120; 17535 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17536 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17537 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17538 17539 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17540 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17541 default_subscribecontext[0] = '\0'; 17542 default_language[0] = '\0'; 17543 default_fromdomain[0] = '\0'; 17544 default_qualify = DEFAULT_QUALIFY; 17545 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17546 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17547 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17548 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17549 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17550 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17551 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17552 17553 /* Debugging settings, always default to off */ 17554 dumphistory = FALSE; 17555 recordhistory = FALSE; 17556 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17557 17558 /* Misc settings for the channel */ 17559 global_relaxdtmf = FALSE; 17560 global_callevents = FALSE; 17561 global_t1min = DEFAULT_T1MIN; 17562 17563 global_matchexterniplocally = FALSE; 17564 17565 /* Copy the default jb config over global_jbconf */ 17566 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17567 17568 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17569 17570 /* Read the [general] config section of sip.conf (or from realtime config) */ 17571 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17572 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17573 continue; 17574 /* handle jb conf */ 17575 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17576 continue; 17577 17578 /* Create the interface list */ 17579 if (!strcasecmp(v->name, "context")) { 17580 ast_copy_string(default_context, v->value, sizeof(default_context)); 17581 } else if (!strcasecmp(v->name, "subscribecontext")) { 17582 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17583 } else if (!strcasecmp(v->name, "allowguest")) { 17584 global_allowguest = ast_true(v->value) ? 1 : 0; 17585 } else if (!strcasecmp(v->name, "realm")) { 17586 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17587 } else if (!strcasecmp(v->name, "useragent")) { 17588 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17589 if (option_debug) 17590 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17591 } else if (!strcasecmp(v->name, "allowtransfer")) { 17592 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17593 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17594 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17595 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17596 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17597 } else if (!strcasecmp(v->name, "rtupdate")) { 17598 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17599 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17600 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17601 } else if (!strcasecmp(v->name, "t1min")) { 17602 global_t1min = atoi(v->value); 17603 } else if (!strcasecmp(v->name, "rtautoclear")) { 17604 int i = atoi(v->value); 17605 if (i > 0) 17606 global_rtautoclear = i; 17607 else 17608 i = 0; 17609 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17610 } else if (!strcasecmp(v->name, "usereqphone")) { 17611 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17612 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17613 global_relaxdtmf = ast_true(v->value); 17614 } else if (!strcasecmp(v->name, "checkmwi")) { 17615 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17616 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17617 global_mwitime = DEFAULT_MWITIME; 17618 } 17619 } else if (!strcasecmp(v->name, "vmexten")) { 17620 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17621 } else if (!strcasecmp(v->name, "rtptimeout")) { 17622 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17623 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17624 global_rtptimeout = 0; 17625 } 17626 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17627 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17628 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17629 global_rtpholdtimeout = 0; 17630 } 17631 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17632 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17633 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17634 global_rtpkeepalive = 0; 17635 } 17636 } else if (!strcasecmp(v->name, "compactheaders")) { 17637 compactheaders = ast_true(v->value); 17638 } else if (!strcasecmp(v->name, "notifymimetype")) { 17639 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17640 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17641 global_limitonpeers = ast_true(v->value); 17642 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17643 global_directrtpsetup = ast_true(v->value); 17644 } else if (!strcasecmp(v->name, "notifyringing")) { 17645 global_notifyringing = ast_true(v->value); 17646 } else if (!strcasecmp(v->name, "notifyhold")) { 17647 global_notifyhold = ast_true(v->value); 17648 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17649 global_alwaysauthreject = ast_true(v->value); 17650 } else if (!strcasecmp(v->name, "mohinterpret") 17651 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17652 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17653 } else if (!strcasecmp(v->name, "mohsuggest")) { 17654 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17655 } else if (!strcasecmp(v->name, "language")) { 17656 ast_copy_string(default_language, v->value, sizeof(default_language)); 17657 } else if (!strcasecmp(v->name, "regcontext")) { 17658 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17659 stringp = newcontexts; 17660 /* Let's remove any contexts that are no longer defined in regcontext */ 17661 cleanup_stale_contexts(stringp, oldregcontext); 17662 /* Create contexts if they don't exist already */ 17663 while ((context = strsep(&stringp, "&"))) { 17664 if (!ast_context_find(context)) 17665 ast_context_create(NULL, context,"SIP"); 17666 } 17667 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17668 } else if (!strcasecmp(v->name, "callerid")) { 17669 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17670 } else if (!strcasecmp(v->name, "fromdomain")) { 17671 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17672 } else if (!strcasecmp(v->name, "outboundproxy")) { 17673 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17674 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17675 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17676 /* Port needs to be after IP */ 17677 sscanf(v->value, "%d", &format); 17678 outboundproxyip.sin_port = htons(format); 17679 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17680 autocreatepeer = ast_true(v->value); 17681 } else if (!strcasecmp(v->name, "srvlookup")) { 17682 srvlookup = ast_true(v->value); 17683 } else if (!strcasecmp(v->name, "pedantic")) { 17684 pedanticsipchecking = ast_true(v->value); 17685 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17686 max_expiry = atoi(v->value); 17687 if (max_expiry < 1) 17688 max_expiry = DEFAULT_MAX_EXPIRY; 17689 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17690 min_expiry = atoi(v->value); 17691 if (min_expiry < 1) 17692 min_expiry = DEFAULT_MIN_EXPIRY; 17693 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17694 default_expiry = atoi(v->value); 17695 if (default_expiry < 1) 17696 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17697 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17698 if (ast_true(v->value)) 17699 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17700 } else if (!strcasecmp(v->name, "dumphistory")) { 17701 dumphistory = ast_true(v->value); 17702 } else if (!strcasecmp(v->name, "recordhistory")) { 17703 recordhistory = ast_true(v->value); 17704 } else if (!strcasecmp(v->name, "registertimeout")) { 17705 global_reg_timeout = atoi(v->value); 17706 if (global_reg_timeout < 1) 17707 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17708 } else if (!strcasecmp(v->name, "registerattempts")) { 17709 global_regattempts_max = atoi(v->value); 17710 } else if (!strcasecmp(v->name, "bindaddr")) { 17711 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17712 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17713 } else { 17714 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17715 } 17716 } else if (!strcasecmp(v->name, "localnet")) { 17717 struct ast_ha *na; 17718 if (!(na = ast_append_ha("d", v->value, localaddr))) 17719 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17720 else 17721 localaddr = na; 17722 } else if (!strcasecmp(v->name, "localmask")) { 17723 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17724 } else if (!strcasecmp(v->name, "externip")) { 17725 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17726 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17727 else 17728 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17729 externexpire = 0; 17730 } else if (!strcasecmp(v->name, "externhost")) { 17731 ast_copy_string(externhost, v->value, sizeof(externhost)); 17732 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17733 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17734 else 17735 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17736 externexpire = time(NULL); 17737 } else if (!strcasecmp(v->name, "externrefresh")) { 17738 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17739 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17740 externrefresh = 10; 17741 } 17742 } else if (!strcasecmp(v->name, "allow")) { 17743 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17744 } else if (!strcasecmp(v->name, "disallow")) { 17745 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17746 } else if (!strcasecmp(v->name, "autoframing")) { 17747 global_autoframing = ast_true(v->value); 17748 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17749 allow_external_domains = ast_true(v->value); 17750 } else if (!strcasecmp(v->name, "autodomain")) { 17751 auto_sip_domains = ast_true(v->value); 17752 } else if (!strcasecmp(v->name, "domain")) { 17753 char *domain = ast_strdupa(v->value); 17754 char *context = strchr(domain, ','); 17755 17756 if (context) 17757 *context++ = '\0'; 17758 17759 if (option_debug && ast_strlen_zero(context)) 17760 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17761 if (ast_strlen_zero(domain)) 17762 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17763 else 17764 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17765 } else if (!strcasecmp(v->name, "register")) { 17766 if (sip_register(v->value, v->lineno) == 0) 17767 registry_count++; 17768 } else if (!strcasecmp(v->name, "tos")) { 17769 if (!ast_str2tos(v->value, &temp_tos)) { 17770 global_tos_sip = temp_tos; 17771 global_tos_audio = temp_tos; 17772 global_tos_video = temp_tos; 17773 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17774 } else 17775 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17776 } else if (!strcasecmp(v->name, "tos_sip")) { 17777 if (ast_str2tos(v->value, &global_tos_sip)) 17778 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17779 } else if (!strcasecmp(v->name, "tos_audio")) { 17780 if (ast_str2tos(v->value, &global_tos_audio)) 17781 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17782 } else if (!strcasecmp(v->name, "tos_video")) { 17783 if (ast_str2tos(v->value, &global_tos_video)) 17784 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17785 } else if (!strcasecmp(v->name, "bindport")) { 17786 if (sscanf(v->value, "%d", &ourport) == 1) { 17787 bindaddr.sin_port = htons(ourport); 17788 } else { 17789 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17790 } 17791 } else if (!strcasecmp(v->name, "qualify")) { 17792 if (!strcasecmp(v->value, "no")) { 17793 default_qualify = 0; 17794 } else if (!strcasecmp(v->value, "yes")) { 17795 default_qualify = DEFAULT_MAXMS; 17796 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17797 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17798 default_qualify = 0; 17799 } 17800 } else if (!strcasecmp(v->name, "callevents")) { 17801 global_callevents = ast_true(v->value); 17802 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17803 default_maxcallbitrate = atoi(v->value); 17804 if (default_maxcallbitrate < 0) 17805 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17806 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17807 global_matchexterniplocally = ast_true(v->value); 17808 } 17809 } 17810 17811 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17812 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17813 allow_external_domains = 1; 17814 } 17815 17816 /* Build list of authentication to various SIP realms, i.e. service providers */ 17817 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17818 /* Format for authentication is auth = username:password@realm */ 17819 if (!strcasecmp(v->name, "auth")) 17820 authl = add_realm_authentication(authl, v->value, v->lineno); 17821 } 17822 17823 ucfg = ast_config_load("users.conf"); 17824 if (ucfg) { 17825 struct ast_variable *gen; 17826 int genhassip, genregistersip; 17827 const char *hassip, *registersip; 17828 17829 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17830 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17831 gen = ast_variable_browse(ucfg, "general"); 17832 cat = ast_category_browse(ucfg, NULL); 17833 while (cat) { 17834 if (strcasecmp(cat, "general")) { 17835 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17836 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17837 if (ast_true(hassip) || (!hassip && genhassip)) { 17838 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17839 if (user) { 17840 ASTOBJ_CONTAINER_LINK(&userl,user); 17841 ASTOBJ_UNREF(user, sip_destroy_user); 17842 user_count++; 17843 } 17844 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17845 if (peer) { 17846 ast_device_state_changed("SIP/%s", peer->name); 17847 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17848 ASTOBJ_UNREF(peer, sip_destroy_peer); 17849 peer_count++; 17850 } 17851 } 17852 if (ast_true(registersip) || (!registersip && genregistersip)) { 17853 char tmp[256]; 17854 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17855 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17856 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17857 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17858 if (!host) 17859 host = ast_variable_retrieve(ucfg, "general", "host"); 17860 if (!username) 17861 username = ast_variable_retrieve(ucfg, "general", "username"); 17862 if (!secret) 17863 secret = ast_variable_retrieve(ucfg, "general", "secret"); 17864 if (!contact) 17865 contact = "s"; 17866 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 17867 if (!ast_strlen_zero(secret)) 17868 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 17869 else 17870 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 17871 if (sip_register(tmp, 0) == 0) 17872 registry_count++; 17873 } 17874 } 17875 } 17876 cat = ast_category_browse(ucfg, cat); 17877 } 17878 ast_config_destroy(ucfg); 17879 } 17880 17881 17882 /* Load peers, users and friends */ 17883 cat = NULL; 17884 while ( (cat = ast_category_browse(cfg, cat)) ) { 17885 const char *utype; 17886 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 17887 continue; 17888 utype = ast_variable_retrieve(cfg, cat, "type"); 17889 if (!utype) { 17890 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 17891 continue; 17892 } else { 17893 int is_user = 0, is_peer = 0; 17894 if (!strcasecmp(utype, "user")) 17895 is_user = 1; 17896 else if (!strcasecmp(utype, "friend")) 17897 is_user = is_peer = 1; 17898 else if (!strcasecmp(utype, "peer")) 17899 is_peer = 1; 17900 else { 17901 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 17902 continue; 17903 } 17904 if (is_user) { 17905 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 17906 if (user) { 17907 ASTOBJ_CONTAINER_LINK(&userl,user); 17908 ASTOBJ_UNREF(user, sip_destroy_user); 17909 user_count++; 17910 } 17911 } 17912 if (is_peer) { 17913 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 17914 if (peer) { 17915 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17916 ASTOBJ_UNREF(peer, sip_destroy_peer); 17917 peer_count++; 17918 } 17919 } 17920 } 17921 } 17922 if (ast_find_ourip(&__ourip, bindaddr)) { 17923 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 17924 ast_config_destroy(cfg); 17925 return 0; 17926 } 17927 if (!ntohs(bindaddr.sin_port)) 17928 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 17929 bindaddr.sin_family = AF_INET; 17930 ast_mutex_lock(&netlock); 17931 if (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in))) { 17932 if (sipsock > -1) { 17933 close(sipsock); 17934 sipsock = -1; 17935 } 17936 if (siptcpsock > -1) { 17937 close(siptcpsock); 17938 siptcpsock = -1; 17939 } 17940 } 17941 if (sipsock < 0) { 17942 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 17943 if (sipsock < 0) { 17944 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 17945 } else { 17946 /* Allow SIP clients on the same host to access us: */ 17947 const int reuseFlag = 1; 17948 17949 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 17950 (const char*)&reuseFlag, 17951 sizeof reuseFlag); 17952 17953 ast_enable_packet_fragmentation(sipsock); 17954 17955 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17956 ast_log(LOG_WARNING, "Failed to bind to UDP %s:%d: %s\n", 17957 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17958 strerror(errno)); 17959 close(sipsock); 17960 sipsock = -1; 17961 } else { 17962 if (option_verbose > 1) { 17963 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on UDP %s:%d\n", 17964 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17965 ast_verbose(VERBOSE_PREFIX_2 "Using SIP UDP TOS: %s\n", ast_tos2str(global_tos_sip)); 17966 } 17967 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 17968 ast_log(LOG_WARNING, "Unable to set SIP UDP TOS to %s\n", ast_tos2str(global_tos_sip)); 17969 } 17970 } 17971 } 17972 if (siptcpsock < 0) { 17973 siptcpsock = socket(AF_INET, SOCK_STREAM, 0); 17974 if (siptcpsock < 0) { 17975 ast_log(LOG_WARNING, "Unable to create SIP TCP socket: %s\n", strerror(errno)); 17976 } else { 17977 /* Allow SIP clients on the same host to access us: */ 17978 const int reuseFlag = 1; 17979 17980 setsockopt(siptcpsock, SOL_SOCKET, SO_REUSEADDR, 17981 (const char*)&reuseFlag, 17982 sizeof reuseFlag); 17983 17984 ast_enable_packet_fragmentation(sipsock); 17985 17986 if (bind(siptcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 17987 ast_log(LOG_WARNING, "Failed to bind to TCP %s:%d: %s\n", 17988 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 17989 strerror(errno)); 17990 close(siptcpsock); 17991 siptcpsock = -1; 17992 } else { 17993 if (listen(siptcpsock, 30) < 0) { 17994 ast_log(LOG_WARNING, "Failed to listen on SIP TCP\n"); 17995 } else { 17996 if (option_verbose > 1) { 17997 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on TCP %s:%d\n", 17998 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 17999 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TCP TOS: %s\n", ast_tos2str(global_tos_sip)); 18000 } 18001 if (setsockopt(siptcpsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18002 ast_log(LOG_WARNING, "Unable to set SIP TCP TOS to %s\n", ast_tos2str(global_tos_sip)); 18003 } 18004 } 18005 } 18006 } 18007 if ((sipsock < 0) && (siptcpsock <0)) { 18008 ast_config_destroy(cfg); 18009 return -1; 18010 } 18011 ast_mutex_unlock(&netlock); 18012 18013 /* Add default domains - host name, IP address and IP:port */ 18014 /* Only do this if user added any sip domain with "localdomains" */ 18015 /* In order to *not* break backwards compatibility */ 18016 /* Some phones address us at IP only, some with additional port number */ 18017 if (auto_sip_domains) { 18018 char temp[MAXHOSTNAMELEN]; 18019 18020 /* First our default IP address */ 18021 if (bindaddr.sin_addr.s_addr) 18022 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18023 else 18024 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18025 18026 /* Our extern IP address, if configured */ 18027 if (externip.sin_addr.s_addr) 18028 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18029 18030 /* Extern host name (NAT traversal support) */ 18031 if (!ast_strlen_zero(externhost)) 18032 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18033 18034 /* Our host name */ 18035 if (!gethostname(temp, sizeof(temp))) 18036 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18037 } 18038 18039 /* Release configuration from memory */ 18040 ast_config_destroy(cfg); 18041 18042 /* Load the list of manual NOTIFY types to support */ 18043 if (notify_types) 18044 ast_config_destroy(notify_types); 18045 notify_types = ast_config_load(notify_config); 18046 18047 /* Done, tell the manager */ 18048 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); 18049 18050 return 0; 18051 }
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 11663 of file chan_sip.c.
References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), keys, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11664 { 11665 char tmp[512]; 11666 char *c; 11667 char oldnonce[256]; 11668 11669 /* table of recognised keywords, and places where they should be copied */ 11670 const struct x { 11671 const char *key; 11672 int field_index; 11673 } *i, keys[] = { 11674 { "realm=", ast_string_field_index(p, realm) }, 11675 { "nonce=", ast_string_field_index(p, nonce) }, 11676 { "opaque=", ast_string_field_index(p, opaque) }, 11677 { "qop=", ast_string_field_index(p, qop) }, 11678 { "domain=", ast_string_field_index(p, domain) }, 11679 { NULL, 0 }, 11680 }; 11681 11682 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11683 if (ast_strlen_zero(tmp)) 11684 return -1; 11685 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11686 ast_log(LOG_WARNING, "missing Digest.\n"); 11687 return -1; 11688 } 11689 c = tmp + strlen("Digest "); 11690 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11691 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11692 for (i = keys; i->key != NULL; i++) { 11693 char *src, *separator; 11694 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11695 continue; 11696 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11697 c += strlen(i->key); 11698 if (*c == '"') { 11699 src = ++c; 11700 separator = "\""; 11701 } else { 11702 src = c; 11703 separator = ","; 11704 } 11705 strsep(&c, separator); /* clear separator and move ptr */ 11706 ast_string_field_index_set(p, i->field_index, src); 11707 break; 11708 } 11709 if (i->key == NULL) /* not found, try ',' */ 11710 strsep(&c, ","); 11711 } 11712 /* Reset nonce count */ 11713 if (strcmp(p->nonce, oldnonce)) 11714 p->noncecount = 0; 11715 11716 /* Save auth data for following registrations */ 11717 if (p->registry) { 11718 struct sip_registry *r = p->registry; 11719 11720 if (strcmp(r->nonce, p->nonce)) { 11721 ast_string_field_set(r, realm, p->realm); 11722 ast_string_field_set(r, nonce, p->nonce); 11723 ast_string_field_set(r, domain, p->domain); 11724 ast_string_field_set(r, opaque, p->opaque); 11725 ast_string_field_set(r, qop, p->qop); 11726 r->noncecount = 0; 11727 } 11728 } 11729 return build_reply_digest(p, sipmethod, digest, digest_len); 11730 }
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 6022 of file chan_sip.c.
References add_header(), add_route(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_request::rlPart2, sip_pvt::route, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, strcasestr(), strsep(), sip_pvt::tag, text, cfsip_methods::text, and TRUE.
06023 { 06024 struct sip_request *orig = &p->initreq; 06025 char stripped[80]; 06026 char tmp[80]; 06027 char newto[256]; 06028 const char *c; 06029 const char *ot, *of; 06030 int is_strict = FALSE; /*!< Strict routing flag */ 06031 06032 memset(req, 0, sizeof(struct sip_request)); 06033 06034 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06035 06036 if (!seqno) { 06037 p->ocseq++; 06038 seqno = p->ocseq; 06039 } 06040 06041 if (newbranch) { 06042 p->branch ^= ast_random(); 06043 build_via(p); 06044 } 06045 06046 /* Check for strict or loose router */ 06047 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06048 is_strict = TRUE; 06049 if (sipdebug) 06050 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06051 } 06052 06053 if (sipmethod == SIP_CANCEL) 06054 c = p->initreq.rlPart2; /* Use original URI */ 06055 else if (sipmethod == SIP_ACK) { 06056 /* Use URI from Contact: in 200 OK (if INVITE) 06057 (we only have the contacturi on INVITEs) */ 06058 if (!ast_strlen_zero(p->okcontacturi)) 06059 c = is_strict ? p->route->hop : p->okcontacturi; 06060 else 06061 c = p->initreq.rlPart2; 06062 } else if (!ast_strlen_zero(p->okcontacturi)) 06063 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06064 else if (!ast_strlen_zero(p->uri)) 06065 c = p->uri; 06066 else { 06067 char *n; 06068 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06069 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06070 sizeof(stripped)); 06071 n = get_in_brackets(stripped); 06072 c = strsep(&n, ";"); /* trim ; and beyond */ 06073 } 06074 init_req(req, sipmethod, c); 06075 06076 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06077 06078 add_header(req, "Via", p->via); 06079 if (p->route) { 06080 set_destination(p, p->route->hop); 06081 add_route(req, is_strict ? p->route->next : p->route); 06082 } 06083 06084 ot = get_header(orig, "To"); 06085 of = get_header(orig, "From"); 06086 06087 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06088 as our original request, including tag (or presumably lack thereof) */ 06089 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06090 /* Add the proper tag if we don't have it already. If they have specified 06091 their tag, use it. Otherwise, use our own tag */ 06092 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06093 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06094 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06095 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06096 else 06097 snprintf(newto, sizeof(newto), "%s", ot); 06098 ot = newto; 06099 } 06100 06101 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06102 add_header(req, "From", of); 06103 add_header(req, "To", ot); 06104 } else { 06105 add_header(req, "From", ot); 06106 add_header(req, "To", of); 06107 } 06108 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06109 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06110 add_header(req, "Contact", p->our_contact); 06111 06112 copy_header(req, orig, "Call-ID"); 06113 add_header(req, "CSeq", tmp); 06114 06115 if (!ast_strlen_zero(global_useragent)) 06116 add_header(req, "User-Agent", global_useragent); 06117 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06118 06119 if (!ast_strlen_zero(p->rpid)) 06120 add_header(req, "Remote-Party-ID", p->rpid); 06121 06122 return 0; 06123 }
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 5974 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.
05975 { 05976 char newto[256]; 05977 const char *ot; 05978 05979 init_resp(resp, msg); 05980 copy_via_headers(p, resp, req, "Via"); 05981 if (msg[0] == '1' || msg[0] == '2') 05982 copy_all_header(resp, req, "Record-Route"); 05983 copy_header(resp, req, "From"); 05984 ot = get_header(req, "To"); 05985 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05986 /* Add the proper tag if we don't have it already. If they have specified 05987 their tag, use it. Otherwise, use our own tag */ 05988 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05989 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05990 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05991 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05992 else 05993 ast_copy_string(newto, ot, sizeof(newto)); 05994 ot = newto; 05995 } 05996 add_header(resp, "To", ot); 05997 copy_header(resp, req, "Call-ID"); 05998 copy_header(resp, req, "CSeq"); 05999 if (!ast_strlen_zero(global_useragent)) 06000 add_header(resp, "User-Agent", global_useragent); 06001 add_header(resp, "Allow", ALLOWED_METHODS); 06002 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06003 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06004 /* For registration responses, we also need expiry and 06005 contact info */ 06006 char tmp[256]; 06007 06008 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06009 add_header(resp, "Expires", tmp); 06010 if (p->expiry) { /* Only add contact if we have an expiry time */ 06011 char contact[SIPBUFSIZE]; 06012 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 06013 add_header(resp, "Contact", contact); /* Not when we unregister */ 06014 } 06015 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 06016 add_header(resp, "Contact", p->our_contact); 06017 } 06018 return 0; 06019 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16309 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.
16310 { 16311 /* If we're supposed to be stopped -- stay stopped */ 16312 if (monitor_thread == AST_PTHREADT_STOP) 16313 return 0; 16314 ast_mutex_lock(&monlock); 16315 if (monitor_thread == pthread_self()) { 16316 ast_mutex_unlock(&monlock); 16317 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16318 return -1; 16319 } 16320 if (monitor_thread != AST_PTHREADT_NULL) { 16321 /* Wake up the thread */ 16322 pthread_kill(monitor_thread, SIGURG); 16323 } else { 16324 /* Start a new monitor */ 16325 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16326 ast_mutex_unlock(&monlock); 16327 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16328 return -1; 16329 } 16330 } 16331 ast_mutex_unlock(&monlock); 16332 return 0; 16333 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1922 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEADLOCK_AVOIDANCE, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01923 { 01924 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01925 int reschedule = DEFAULT_RETRANS; 01926 int xmitres = 0; 01927 01928 /* Lock channel PVT */ 01929 ast_mutex_lock(&pkt->owner->lock); 01930 01931 if (pkt->retrans < MAX_RETRANS) { 01932 pkt->retrans++; 01933 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01934 if (sipdebug && option_debug > 3) 01935 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); 01936 } else { 01937 int siptimer_a; 01938 01939 if (sipdebug && option_debug > 3) 01940 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01941 if (!pkt->timer_a) 01942 pkt->timer_a = 2 ; 01943 else 01944 pkt->timer_a = 2 * pkt->timer_a; 01945 01946 /* For non-invites, a maximum of 4 secs */ 01947 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01948 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01949 siptimer_a = 4000; 01950 01951 /* Reschedule re-transmit */ 01952 reschedule = siptimer_a; 01953 if (option_debug > 3) 01954 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); 01955 } 01956 01957 if (sip_debug_test_pvt(pkt->owner)) { 01958 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01959 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01960 pkt->retrans, sip_nat_mode(pkt->owner), 01961 ast_inet_ntoa(dst->sin_addr), 01962 ntohs(dst->sin_port), pkt->data); 01963 } 01964 01965 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01966 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01967 ast_mutex_unlock(&pkt->owner->lock); 01968 if (xmitres == XMIT_ERROR) 01969 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01970 else 01971 return reschedule; 01972 } 01973 /* Too many retries */ 01974 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01975 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01976 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); 01977 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01978 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 01979 } 01980 if (xmitres == XMIT_ERROR) { 01981 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01982 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01983 } else 01984 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01985 01986 pkt->retransid = -1; 01987 01988 if (ast_test_flag(pkt, FLAG_FATAL)) { 01989 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01990 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01991 } 01992 01993 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01994 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01995 01996 if (pkt->owner->owner) { 01997 sip_alreadygone(pkt->owner); 01998 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); 01999 ast_queue_hangup(pkt->owner->owner); 02000 ast_channel_unlock(pkt->owner->owner); 02001 } else { 02002 /* If no channel owner, destroy now */ 02003 02004 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02005 if (pkt->method != SIP_OPTIONS) { 02006 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02007 sip_alreadygone(pkt->owner); 02008 if (option_debug) 02009 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02010 } 02011 } 02012 } 02013 02014 if (pkt->method == SIP_BYE) { 02015 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02016 if (pkt->owner->owner) 02017 ast_channel_unlock(pkt->owner->owner); 02018 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02019 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02020 } 02021 02022 /* In any case, go ahead and remove the packet */ 02023 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02024 if (cur == pkt) 02025 break; 02026 } 02027 if (cur) { 02028 if (prev) 02029 prev->next = cur->next; 02030 else 02031 pkt->owner->packets = cur->next; 02032 ast_mutex_unlock(&pkt->owner->lock); 02033 free(cur); 02034 pkt = NULL; 02035 } else 02036 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02037 if (pkt) 02038 ast_mutex_unlock(&pkt->owner->lock); 02039 return 0; 02040 }
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 2313 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.
02314 { 02315 int res; 02316 02317 add_blank(req); 02318 if (sip_debug_test_pvt(p)) { 02319 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02320 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); 02321 else 02322 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); 02323 } 02324 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02325 struct sip_request tmp; 02326 parse_copy(&tmp, req); 02327 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02328 } 02329 res = (reliable) ? 02330 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02331 __sip_xmit(p, req->data, req->len); 02332 return res; 02333 }
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 2285 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02286 { 02287 int res; 02288 02289 add_blank(req); 02290 if (sip_debug_test_pvt(p)) { 02291 const struct sockaddr_in *dst = sip_real_dst(p); 02292 02293 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02294 reliable ? "Reliably " : "", sip_nat_mode(p), 02295 ast_inet_ntoa(dst->sin_addr), 02296 ntohs(dst->sin_port), req->data); 02297 } 02298 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02299 struct sip_request tmp; 02300 parse_copy(&tmp, req); 02301 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02302 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02303 } 02304 res = (reliable) ? 02305 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02306 __sip_xmit(p, req->data, req->len); 02307 if (res > 0) 02308 return 0; 02309 return res; 02310 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8209 of file chan_sip.c.
References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::recv, sip_pvt::sa, and SIP_NAT_ROUTE.
Referenced by handle_response_invite().
08210 { 08211 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08212 /* NAT: Don't trust the contact field. Just use what they came to us 08213 with. */ 08214 pvt->sa = pvt->recv; 08215 return 0; 08216 } 08217 08218 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08219 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5883 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05884 { 05885 char *h, *maddr, hostname[256]; 05886 int port, hn; 05887 struct hostent *hp; 05888 struct ast_hostent ahp; 05889 int debug=sip_debug_test_pvt(p); 05890 05891 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05892 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05893 05894 if (debug) 05895 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05896 05897 /* Find and parse hostname */ 05898 h = strchr(uri, '@'); 05899 if (h) 05900 ++h; 05901 else { 05902 h = uri; 05903 if (strncasecmp(h, "sip:", 4) == 0) 05904 h += 4; 05905 else if (strncasecmp(h, "sips:", 5) == 0) 05906 h += 5; 05907 } 05908 hn = strcspn(h, ":;>") + 1; 05909 if (hn > sizeof(hostname)) 05910 hn = sizeof(hostname); 05911 ast_copy_string(hostname, h, hn); 05912 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05913 h += hn - 1; 05914 05915 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05916 if (*h == ':') { 05917 /* Parse port */ 05918 ++h; 05919 port = strtol(h, &h, 10); 05920 } 05921 else 05922 port = STANDARD_SIP_PORT; 05923 05924 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05925 maddr = strstr(h, "maddr="); 05926 if (maddr) { 05927 maddr += 6; 05928 hn = strspn(maddr, "0123456789.") + 1; 05929 if (hn > sizeof(hostname)) 05930 hn = sizeof(hostname); 05931 ast_copy_string(hostname, maddr, hn); 05932 } 05933 05934 hp = ast_gethostbyname(hostname, &ahp); 05935 if (hp == NULL) { 05936 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05937 return; 05938 } 05939 p->sa.sin_family = AF_INET; 05940 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05941 p->sa.sin_port = htons(port); 05942 if (debug) 05943 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05944 }
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 16645 of file chan_sip.c.
References ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options().
16646 { 16647 static int dep_insecure_very = 0; 16648 static int dep_insecure_yes = 0; 16649 16650 if (ast_strlen_zero(value)) 16651 return; 16652 16653 if (!strcasecmp(value, "very")) { 16654 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16655 if(!dep_insecure_very) { 16656 if(lineno != -1) 16657 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16658 else 16659 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16660 dep_insecure_very = 1; 16661 } 16662 } 16663 else if (ast_true(value)) { 16664 ast_set_flag(flags, SIP_INSECURE_PORT); 16665 if(!dep_insecure_yes) { 16666 if(lineno != -1) 16667 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16668 else 16669 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16670 dep_insecure_yes = 1; 16671 } 16672 } 16673 else if (!ast_false(value)) { 16674 char buf[64]; 16675 char *word, *next; 16676 ast_copy_string(buf, value, sizeof(buf)); 16677 next = buf; 16678 while ((word = strsep(&next, ","))) { 16679 if (!strcasecmp(word, "port")) 16680 ast_set_flag(flags, SIP_INSECURE_PORT); 16681 else if (!strcasecmp(word, "invite")) 16682 ast_set_flag(flags, SIP_INSECURE_INVITE); 16683 else 16684 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16685 } 16686 } 16687 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17076 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().
17077 { 17078 if (peer->expire == 0) { 17079 /* Don't reset expire or port time during reload 17080 if we have an active registration 17081 */ 17082 peer->expire = -1; 17083 peer->pokeexpire = -1; 17084 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17085 } 17086 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17087 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17088 strcpy(peer->context, default_context); 17089 strcpy(peer->subscribecontext, default_subscribecontext); 17090 strcpy(peer->language, default_language); 17091 strcpy(peer->mohinterpret, default_mohinterpret); 17092 strcpy(peer->mohsuggest, default_mohsuggest); 17093 peer->addr.sin_family = AF_INET; 17094 peer->defaddr.sin_family = AF_INET; 17095 peer->capability = global_capability; 17096 peer->maxcallbitrate = default_maxcallbitrate; 17097 peer->rtptimeout = global_rtptimeout; 17098 peer->rtpholdtimeout = global_rtpholdtimeout; 17099 peer->rtpkeepalive = global_rtpkeepalive; 17100 peer->allowtransfer = global_allowtransfer; 17101 peer->autoframing = global_autoframing; 17102 strcpy(peer->vmexten, default_vmexten); 17103 peer->secret[0] = '\0'; 17104 peer->md5secret[0] = '\0'; 17105 peer->cid_num[0] = '\0'; 17106 peer->cid_name[0] = '\0'; 17107 peer->fromdomain[0] = '\0'; 17108 peer->fromuser[0] = '\0'; 17109 peer->regexten[0] = '\0'; 17110 peer->mailbox[0] = '\0'; 17111 peer->callgroup = 0; 17112 peer->pickupgroup = 0; 17113 peer->maxms = default_qualify; 17114 peer->prefs = default_prefs; 17115 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18390 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().
18391 { 18392 int no = 0; 18393 int ok = FALSE; 18394 char varbuf[30]; 18395 char *inbuf = (char *) data; 18396 18397 if (ast_strlen_zero(inbuf)) { 18398 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18399 return 0; 18400 } 18401 ast_channel_lock(chan); 18402 18403 /* Check for headers */ 18404 while (!ok && no <= 50) { 18405 no++; 18406 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 18407 18408 /* Compare without the leading underscores */ 18409 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 18410 ok = TRUE; 18411 } 18412 if (ok) { 18413 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18414 if (sipdebug) 18415 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18416 } else { 18417 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18418 } 18419 ast_channel_unlock(chan); 18420 return 0; 18421 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2675 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02676 { 02677 /* We know name is the first field, so we can cast */ 02678 struct sip_peer *p = (struct sip_peer *) name; 02679 return !(!inaddrcmp(&p->addr, sin) || 02680 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02681 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02682 }
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 4518 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04520 { 04521 struct sip_pvt *p; 04522 04523 if (!(p = ast_calloc(1, sizeof(*p)))) 04524 return NULL; 04525 04526 if (ast_string_field_init(p, 512)) { 04527 free(p); 04528 return NULL; 04529 } 04530 04531 ast_mutex_init(&p->lock); 04532 04533 p->method = intended_method; 04534 p->initid = -1; 04535 p->waitid = -1; 04536 p->autokillid = -1; 04537 p->subscribed = NONE; 04538 p->stateid = -1; 04539 p->sockfd=-1; 04540 p->prefs = default_prefs; /* Set default codecs for this call */ 04541 04542 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04543 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04544 04545 if (sin) { 04546 p->sa = *sin; 04547 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04548 p->ourip = __ourip; 04549 } else 04550 p->ourip = __ourip; 04551 04552 /* Copy global flags to this PVT at setup. */ 04553 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04554 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04555 04556 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04557 04558 p->branch = ast_random(); 04559 make_our_tag(p->tag, sizeof(p->tag)); 04560 p->ocseq = INITIAL_CSEQ; 04561 04562 if (sip_methods[intended_method].need_rtp) { 04563 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04564 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04565 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04566 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04567 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04568 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04569 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04570 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04571 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04572 ast_mutex_destroy(&p->lock); 04573 if (p->chanvars) { 04574 ast_variables_destroy(p->chanvars); 04575 p->chanvars = NULL; 04576 } 04577 free(p); 04578 return NULL; 04579 } 04580 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04581 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04582 ast_rtp_settos(p->rtp, global_tos_audio); 04583 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04584 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04585 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04586 if (p->vrtp) { 04587 ast_rtp_settos(p->vrtp, global_tos_video); 04588 ast_rtp_setdtmf(p->vrtp, 0); 04589 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04590 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04591 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04592 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04593 } 04594 if (p->udptl) 04595 ast_udptl_settos(p->udptl, global_tos_audio); 04596 p->maxcallbitrate = default_maxcallbitrate; 04597 p->autoframing = global_autoframing; 04598 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04599 } 04600 04601 if (useglobal_nat && sin) { 04602 /* Setup NAT structure according to global settings if we have an address */ 04603 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04604 p->recv = *sin; 04605 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04606 } 04607 04608 if (p->method != SIP_REGISTER) 04609 ast_string_field_set(p, fromdomain, default_fromdomain); 04610 build_via(p); 04611 if (!callid) 04612 build_callid_pvt(p); 04613 else 04614 ast_string_field_set(p, callid, callid); 04615 /* Assign default music on hold class */ 04616 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04617 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04618 p->capability = global_capability; 04619 p->allowtransfer = global_allowtransfer; 04620 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04621 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04622 p->noncodeccapability |= AST_RTP_DTMF; 04623 if (p->udptl) { 04624 p->t38.capability = global_t38_capability; 04625 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04626 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04627 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04628 p->t38.capability |= T38FAX_UDP_EC_FEC; 04629 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04630 p->t38.capability |= T38FAX_UDP_EC_NONE; 04631 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04632 p->t38.jointcapability = p->t38.capability; 04633 } 04634 ast_string_field_set(p, context, default_context); 04635 04636 /* Add to active dialog list */ 04637 ast_mutex_lock(&iflock); 04638 p->next = iflist; 04639 iflist = p; 04640 ast_mutex_unlock(&iflock); 04641 if (option_debug) 04642 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"); 04643 return p; 04644 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1667 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
01668 { 01669 if (option_debug > 2) 01670 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01671 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01672 }
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 3708 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03709 { 03710 int res = 0; 03711 struct sip_pvt *p = ast->tech_pvt; 03712 03713 ast_mutex_lock(&p->lock); 03714 if (ast->_state != AST_STATE_UP) { 03715 try_suggested_sip_codec(p); 03716 03717 ast_setstate(ast, AST_STATE_UP); 03718 if (option_debug) 03719 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03720 if (p->t38.state == T38_PEER_DIRECT) { 03721 p->t38.state = T38_ENABLED; 03722 if (option_debug > 1) 03723 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03724 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03725 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03726 } else { 03727 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03728 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03729 } 03730 } 03731 ast_mutex_unlock(&p->lock); 03732 return res; 03733 }
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 2986 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
02987 { 02988 int res, xmitres = 0; 02989 struct sip_pvt *p; 02990 struct varshead *headp; 02991 struct ast_var_t *current; 02992 const char *referer = NULL; /* SIP refererer */ 02993 02994 p = ast->tech_pvt; 02995 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02996 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02997 return -1; 02998 } 02999 03000 /* Check whether there is vxml_url, distinctive ring variables */ 03001 headp=&ast->varshead; 03002 AST_LIST_TRAVERSE(headp,current,entries) { 03003 /* Check whether there is a VXML_URL variable */ 03004 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03005 p->options->vxml_url = ast_var_value(current); 03006 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03007 p->options->uri_options = ast_var_value(current); 03008 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03009 /* Check whether there is a ALERT_INFO variable */ 03010 p->options->distinctive_ring = ast_var_value(current); 03011 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03012 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03013 p->options->addsipheaders = 1; 03014 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03015 /* This is a transfered call */ 03016 p->options->transfer = 1; 03017 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03018 /* This is the referer */ 03019 referer = ast_var_value(current); 03020 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03021 /* We're replacing a call. */ 03022 p->options->replaces = ast_var_value(current); 03023 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 03024 p->t38.state = T38_LOCAL_DIRECT; 03025 if (option_debug) 03026 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03027 } 03028 03029 } 03030 03031 res = 0; 03032 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03033 03034 if (p->options->transfer) { 03035 char buf[SIPBUFSIZE/2]; 03036 03037 if (referer) { 03038 if (sipdebug && option_debug > 2) 03039 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03040 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03041 } else 03042 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03043 ast_string_field_set(p, cid_name, buf); 03044 } 03045 if (option_debug) 03046 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03047 03048 res = update_call_counter(p, INC_CALL_RINGING); 03049 if ( res != -1 ) { 03050 p->callingpres = ast->cid.cid_pres; 03051 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03052 p->jointnoncodeccapability = p->noncodeccapability; 03053 03054 /* If there are no audio formats left to offer, punt */ 03055 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03056 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03057 res = -1; 03058 } else { 03059 p->t38.jointcapability = p->t38.capability; 03060 if (option_debug > 1) 03061 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03062 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03063 if (xmitres == XMIT_ERROR) 03064 return -1; /* Transmission error */ 03065 03066 p->invitestate = INV_CALLING; 03067 03068 /* Initialize auto-congest time */ 03069 AST_SCHED_DEL(sched, p->initid); 03070 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03071 } 03072 } 03073 return res; 03074 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2155 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02156 { 02157 int res = 0; 02158 if (p->autokillid > -1) { 02159 if (!(res = ast_sched_del(sched, p->autokillid))) { 02160 append_history(p, "CancelDestroy", ""); 02161 p->autokillid = -1; 02162 } 02163 } 02164 return res; 02165 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1749 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01750 { 01751 if (!sipdebug) 01752 return 0; 01753 if (debugaddr.sin_addr.s_addr) { 01754 if (((ntohs(debugaddr.sin_port) != 0) 01755 && (debugaddr.sin_port != addr->sin_port)) 01756 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01757 return 0; 01758 } 01759 return 1; 01760 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1775 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), add_t38_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01776 { 01777 if (!sipdebug) 01778 return 0; 01779 return sip_debug_test_addr(sip_real_dst(p)); 01780 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3350 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, and option_debug.
Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03351 { 03352 ast_mutex_lock(&iflock); 03353 if (option_debug > 2) 03354 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03355 __sip_destroy(p, 1); 03356 ast_mutex_unlock(&iflock); 03357 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2485 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().
02486 { 02487 if (option_debug > 2) 02488 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02489 02490 /* Delete it, it needs to disappear */ 02491 if (peer->call) 02492 sip_destroy(peer->call); 02493 02494 if (peer->mwipvt) /* We have an active subscription, delete it */ 02495 sip_destroy(peer->mwipvt); 02496 02497 if (peer->chanvars) { 02498 ast_variables_destroy(peer->chanvars); 02499 peer->chanvars = NULL; 02500 } 02501 02502 register_peer_exten(peer, FALSE); 02503 ast_free_ha(peer->ha); 02504 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02505 apeerobjs--; 02506 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02507 rpeerobjs--; 02508 else 02509 speerobjs--; 02510 clear_realm_authentication(peer->auth); 02511 peer->auth = NULL; 02512 free(peer); 02513 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2703 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02704 { 02705 if (option_debug > 2) 02706 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02707 ast_free_ha(user->ha); 02708 if (user->chanvars) { 02709 ast_variables_destroy(user->chanvars); 02710 user->chanvars = NULL; 02711 } 02712 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02713 ruserobjs--; 02714 else 02715 suserobjs--; 02716 free(user); 02717 }
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 16480 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().
16481 { 16482 char *host; 16483 char *tmp; 16484 16485 struct hostent *hp; 16486 struct ast_hostent ahp; 16487 struct sip_peer *p; 16488 16489 int res = AST_DEVICE_INVALID; 16490 16491 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16492 host = ast_strdupa(data ? data : ""); 16493 if ((tmp = strchr(host, '@'))) 16494 host = tmp + 1; 16495 16496 if (option_debug > 2) 16497 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16498 16499 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 16500 * is because when a peer tries to autoexpire, the last thing it does is to 16501 * queue up an event telling the system that the devicestate has changed 16502 * (presumably to unavailable). If we ask for a realtime peer here, this would 16503 * load it BACK into memory, thus defeating the point of trying to trying to 16504 * clear dead hosts out of memory. 16505 */ 16506 if ((p = find_peer(host, NULL, 0, 1))) { 16507 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16508 /* we have an address for the peer */ 16509 16510 /* Check status in this order 16511 - Hold 16512 - Ringing 16513 - Busy (enforced only by call limit) 16514 - Inuse (we have a call) 16515 - Unreachable (qualify) 16516 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16517 for registered devices */ 16518 16519 if (p->onHold) 16520 /* First check for hold or ring states */ 16521 res = AST_DEVICE_ONHOLD; 16522 else if (p->inRinging) { 16523 if (p->inRinging == p->inUse) 16524 res = AST_DEVICE_RINGING; 16525 else 16526 res = AST_DEVICE_RINGINUSE; 16527 } else if (p->call_limit && (p->inUse == p->call_limit)) 16528 /* check call limit */ 16529 res = AST_DEVICE_BUSY; 16530 else if (p->call_limit && p->inUse) 16531 /* Not busy, but we do have a call */ 16532 res = AST_DEVICE_INUSE; 16533 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16534 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16535 res = AST_DEVICE_UNAVAILABLE; 16536 else /* Default reply if we're registered and have no other data */ 16537 res = AST_DEVICE_NOT_INUSE; 16538 } else { 16539 /* there is no address, it's unavailable */ 16540 res = AST_DEVICE_UNAVAILABLE; 16541 } 16542 ASTOBJ_UNREF(p,sip_destroy_peer); 16543 } else { 16544 char *port = strchr(host, ':'); 16545 if (port) 16546 *port = '\0'; 16547 hp = ast_gethostbyname(host, &ahp); 16548 if (hp) 16549 res = AST_DEVICE_UNKNOWN; 16550 } 16551 16552 return res; 16553 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11476 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.
11477 { 11478 int oldsipdebug = sipdebug_console; 11479 if (argc != 3) { 11480 if (argc != 5) 11481 return RESULT_SHOWUSAGE; 11482 else if (strcmp(argv[3], "ip") == 0) 11483 return sip_do_debug_ip(fd, argc, argv); 11484 else if (strcmp(argv[3], "peer") == 0) 11485 return sip_do_debug_peer(fd, argc, argv); 11486 else 11487 return RESULT_SHOWUSAGE; 11488 } 11489 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11490 memset(&debugaddr, 0, sizeof(debugaddr)); 11491 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11492 return RESULT_SUCCESS; 11493 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11495 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.
11496 { 11497 int oldsipdebug = sipdebug_console; 11498 char *newargv[6] = { "sip", "set", "debug", NULL }; 11499 if (argc != 2) { 11500 if (argc != 4) 11501 return RESULT_SHOWUSAGE; 11502 else if (strcmp(argv[2], "ip") == 0) { 11503 newargv[3] = argv[2]; 11504 newargv[4] = argv[3]; 11505 return sip_do_debug_ip(fd, argc + 1, newargv); 11506 } else if (strcmp(argv[2], "peer") == 0) { 11507 newargv[3] = argv[2]; 11508 newargv[4] = argv[3]; 11509 return sip_do_debug_peer(fd, argc + 1, newargv); 11510 } else 11511 return RESULT_SHOWUSAGE; 11512 } 11513 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11514 memset(&debugaddr, 0, sizeof(debugaddr)); 11515 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11516 return RESULT_SUCCESS; 11517 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11422 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11423 { 11424 struct hostent *hp; 11425 struct ast_hostent ahp; 11426 int port = 0; 11427 char *p, *arg; 11428 11429 /* sip set debug ip <ip> */ 11430 if (argc != 5) 11431 return RESULT_SHOWUSAGE; 11432 p = arg = argv[4]; 11433 strsep(&p, ":"); 11434 if (p) 11435 port = atoi(p); 11436 hp = ast_gethostbyname(arg, &ahp); 11437 if (hp == NULL) 11438 return RESULT_SHOWUSAGE; 11439 11440 debugaddr.sin_family = AF_INET; 11441 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11442 debugaddr.sin_port = htons(port); 11443 if (port == 0) 11444 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11445 else 11446 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11447 11448 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11449 11450 return RESULT_SUCCESS; 11451 }
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 11454 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().
11455 { 11456 struct sip_peer *peer; 11457 if (argc != 5) 11458 return RESULT_SHOWUSAGE; 11459 peer = find_peer(argv[4], NULL, 1, 0); 11460 if (peer) { 11461 if (peer->addr.sin_addr.s_addr) { 11462 debugaddr.sin_family = AF_INET; 11463 debugaddr.sin_addr = peer->addr.sin_addr; 11464 debugaddr.sin_port = peer->addr.sin_port; 11465 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11466 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11467 } else 11468 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11469 ASTOBJ_UNREF(peer,sip_destroy_peer); 11470 } else 11471 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11472 return RESULT_SUCCESS; 11473 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11595 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11596 { 11597 if (argc != 2) { 11598 return RESULT_SHOWUSAGE; 11599 } 11600 recordhistory = TRUE; 11601 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11602 return RESULT_SUCCESS; 11603 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18536 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
18537 { 18538 reload_config(reason); 18539 18540 /* Prune peers who still are supposed to be deleted */ 18541 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18542 if (option_debug > 3) 18543 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18544 18545 /* Send qualify (OPTIONS) to all peers */ 18546 sip_poke_all_peers(); 18547 18548 /* Register with all services */ 18549 sip_send_all_registers(); 18550 18551 if (option_debug > 3) 18552 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18553 18554 return 0; 18555 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18335 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().
18336 { 18337 struct sip_pvt *p; 18338 char *mode; 18339 if (data) 18340 mode = (char *)data; 18341 else { 18342 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18343 return 0; 18344 } 18345 ast_channel_lock(chan); 18346 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18347 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18348 ast_channel_unlock(chan); 18349 return 0; 18350 } 18351 p = chan->tech_pvt; 18352 if (!p) { 18353 ast_channel_unlock(chan); 18354 return 0; 18355 } 18356 ast_mutex_lock(&p->lock); 18357 if (!strcasecmp(mode,"info")) { 18358 ast_clear_flag(&p->flags[0], SIP_DTMF); 18359 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18360 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18361 } else if (!strcasecmp(mode,"rfc2833")) { 18362 ast_clear_flag(&p->flags[0], SIP_DTMF); 18363 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18364 p->jointnoncodeccapability |= AST_RTP_DTMF; 18365 } else if (!strcasecmp(mode,"inband")) { 18366 ast_clear_flag(&p->flags[0], SIP_DTMF); 18367 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18368 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18369 } else 18370 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18371 if (p->rtp) 18372 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18373 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18374 if (!p->vad) { 18375 p->vad = ast_dsp_new(); 18376 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18377 } 18378 } else { 18379 if (p->vad) { 18380 ast_dsp_free(p->vad); 18381 p->vad = NULL; 18382 } 18383 } 18384 ast_mutex_unlock(&p->lock); 18385 ast_channel_unlock(chan); 18386 return 0; 18387 }
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 11280 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::history, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
11281 { 11282 int x = 0; 11283 struct sip_history *hist; 11284 static int errmsg = 0; 11285 11286 if (!dialog) 11287 return; 11288 11289 if (!option_debug && !sipdebug) { 11290 if (!errmsg) { 11291 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11292 errmsg = 1; 11293 } 11294 return; 11295 } 11296 11297 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11298 if (dialog->subscribed) 11299 ast_log(LOG_DEBUG, " * Subscription\n"); 11300 else 11301 ast_log(LOG_DEBUG, " * SIP Call\n"); 11302 if (dialog->history) 11303 AST_LIST_TRAVERSE(dialog->history, hist, list) 11304 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11305 if (!x) 11306 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11307 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11308 }
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 3814 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
03815 { 03816 int ret = -1; 03817 struct sip_pvt *p; 03818 03819 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03820 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03821 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03822 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03823 03824 if (!newchan || !newchan->tech_pvt) { 03825 if (!newchan) 03826 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03827 else 03828 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03829 return -1; 03830 } 03831 p = newchan->tech_pvt; 03832 03833 if (!p) { 03834 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03835 return -1; 03836 } 03837 03838 ast_mutex_lock(&p->lock); 03839 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03840 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03841 if (p->owner != oldchan) 03842 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03843 else { 03844 p->owner = newchan; 03845 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03846 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03847 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03848 redirect of both channels). Note that a channel can not be masqueraded *into* 03849 a native bridge. So there is no danger that this breaks a native bridge that 03850 should stay up. */ 03851 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03852 ret = 0; 03853 } 03854 if (option_debug > 2) 03855 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03856 03857 ast_mutex_unlock(&p->lock); 03858 return ret; 03859 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18480 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
18481 { 18482 struct sip_pvt *p = chan->tech_pvt; 18483 return p->peercapability ? p->peercapability : p->capability; 18484 }
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 18188 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.
18189 { 18190 struct sip_pvt *p = NULL; 18191 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18192 18193 if (!(p = chan->tech_pvt)) 18194 return AST_RTP_GET_FAILED; 18195 18196 ast_mutex_lock(&p->lock); 18197 if (!(p->rtp)) { 18198 ast_mutex_unlock(&p->lock); 18199 return AST_RTP_GET_FAILED; 18200 } 18201 18202 *rtp = p->rtp; 18203 18204 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18205 res = AST_RTP_TRY_PARTIAL; 18206 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18207 res = AST_RTP_TRY_NATIVE; 18208 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18209 res = AST_RTP_GET_FAILED; 18210 18211 ast_mutex_unlock(&p->lock); 18212 18213 return res; 18214 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18053 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.
18054 { 18055 struct sip_pvt *p; 18056 struct ast_udptl *udptl = NULL; 18057 18058 p = chan->tech_pvt; 18059 if (!p) 18060 return NULL; 18061 18062 ast_mutex_lock(&p->lock); 18063 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18064 udptl = p->udptl; 18065 ast_mutex_unlock(&p->lock); 18066 return udptl; 18067 }
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 18217 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.
18218 { 18219 struct sip_pvt *p = NULL; 18220 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18221 18222 if (!(p = chan->tech_pvt)) 18223 return AST_RTP_GET_FAILED; 18224 18225 ast_mutex_lock(&p->lock); 18226 if (!(p->vrtp)) { 18227 ast_mutex_unlock(&p->lock); 18228 return AST_RTP_GET_FAILED; 18229 } 18230 18231 *rtp = p->vrtp; 18232 18233 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18234 res = AST_RTP_TRY_NATIVE; 18235 18236 ast_mutex_unlock(&p->lock); 18237 18238 return res; 18239 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18105 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
18106 { 18107 struct sip_pvt *p; 18108 int flag = 0; 18109 18110 p = chan->tech_pvt; 18111 if (!p || !pvt->udptl) 18112 return -1; 18113 18114 /* Setup everything on the other side like offered/responded from first side */ 18115 ast_mutex_lock(&p->lock); 18116 18117 /*! \todo check if this is not set earlier when setting up the PVT. If not 18118 maybe it should move there. */ 18119 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18120 18121 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18122 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18123 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18124 18125 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18126 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18127 not really T38 re-invites which are different. In this 18128 case it's used properly, to see if we can reinvite over 18129 NAT 18130 */ 18131 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18132 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18133 flag =1; 18134 } else { 18135 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18136 } 18137 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18138 if (!p->pendinginvite) { 18139 if (option_debug > 2) { 18140 if (flag) 18141 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)); 18142 else 18143 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)); 18144 } 18145 transmit_reinvite_with_t38_sdp(p); 18146 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18147 if (option_debug > 2) { 18148 if (flag) 18149 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)); 18150 else 18151 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)); 18152 } 18153 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18154 } 18155 } 18156 /* Reset lastrtprx timer */ 18157 p->lastrtprx = p->lastrtptx = time(NULL); 18158 ast_mutex_unlock(&p->lock); 18159 return 0; 18160 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18161 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18162 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18163 flag = 1; 18164 } else { 18165 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18166 } 18167 if (option_debug > 2) { 18168 if (flag) 18169 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)); 18170 else 18171 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)); 18172 } 18173 pvt->t38.state = T38_ENABLED; 18174 p->t38.state = T38_ENABLED; 18175 if (option_debug > 1) { 18176 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18177 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18178 } 18179 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18180 p->lastrtprx = p->lastrtptx = time(NULL); 18181 ast_mutex_unlock(&p->lock); 18182 return 0; 18183 } 18184 }
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 3523 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, and XMIT_RELIABLE.
03524 { 03525 struct sip_pvt *p = ast->tech_pvt; 03526 int needcancel = FALSE; 03527 int needdestroy = 0; 03528 struct ast_channel *oldowner = ast; 03529 03530 if (!p) { 03531 if (option_debug) 03532 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03533 return 0; 03534 } 03535 03536 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03537 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03538 if (option_debug && sipdebug) 03539 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03540 update_call_counter(p, DEC_CALL_LIMIT); 03541 } 03542 if (option_debug >3) 03543 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03544 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03545 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03546 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03547 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03548 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03549 p->owner->tech_pvt = NULL; 03550 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03551 return 0; 03552 } 03553 if (option_debug) { 03554 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03555 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03556 else { 03557 if (option_debug) 03558 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03559 } 03560 } 03561 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03562 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03563 03564 ast_mutex_lock(&p->lock); 03565 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03566 if (option_debug && sipdebug) 03567 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03568 update_call_counter(p, DEC_CALL_LIMIT); 03569 } 03570 03571 /* Determine how to disconnect */ 03572 if (p->owner != ast) { 03573 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03574 ast_mutex_unlock(&p->lock); 03575 return 0; 03576 } 03577 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03578 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03579 needcancel = TRUE; 03580 if (option_debug > 3) 03581 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03582 } 03583 03584 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03585 03586 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03587 03588 /* Disconnect */ 03589 if (p->vad) 03590 ast_dsp_free(p->vad); 03591 03592 p->owner = NULL; 03593 ast->tech_pvt = NULL; 03594 03595 ast_module_unref(ast_module_info->self); 03596 03597 /* Do not destroy this pvt until we have timeout or 03598 get an answer to the BYE or INVITE/CANCEL 03599 If we get no answer during retransmit period, drop the call anyway. 03600 (Sorry, mother-in-law, you can't deny a hangup by sending 03601 603 declined to BYE...) 03602 */ 03603 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03604 needdestroy = 1; /* Set destroy flag at end of this function */ 03605 else if (p->invitestate != INV_CALLING) 03606 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03607 03608 /* Start the process if it's not already started */ 03609 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03610 if (needcancel) { /* Outgoing call, not up */ 03611 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03612 /* stop retransmitting an INVITE that has not received a response */ 03613 __sip_pretend_ack(p); 03614 p->invitestate = INV_CANCELLED; 03615 03616 /* if we can't send right now, mark it pending */ 03617 if (p->invitestate == INV_CALLING) { 03618 /* We can't send anything in CALLING state */ 03619 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03620 /* 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. */ 03621 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03622 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03623 } else { 03624 /* Send a new request: CANCEL */ 03625 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03626 /* Actually don't destroy us yet, wait for the 487 on our original 03627 INVITE, but do set an autodestruct just in case we never get it. */ 03628 needdestroy = 0; 03629 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03630 } 03631 if ( p->initid != -1 ) { 03632 /* channel still up - reverse dec of inUse counter 03633 only if the channel is not auto-congested */ 03634 update_call_counter(p, INC_CALL_LIMIT); 03635 } 03636 } else { /* Incoming call, not up */ 03637 const char *res; 03638 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03639 transmit_response_reliable(p, res, &p->initreq); 03640 else 03641 transmit_response_reliable(p, "603 Declined", &p->initreq); 03642 p->invitestate = INV_TERMINATED; 03643 } 03644 } else { /* Call is in UP state, send BYE */ 03645 if (!p->pendinginvite) { 03646 char *audioqos = ""; 03647 char *videoqos = ""; 03648 if (p->rtp) 03649 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03650 if (p->vrtp) 03651 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03652 /* Send a hangup */ 03653 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03654 03655 /* Get RTCP quality before end of call */ 03656 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03657 if (p->rtp) 03658 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03659 if (p->vrtp) 03660 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03661 } 03662 if (p->rtp && oldowner) 03663 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03664 if (p->vrtp && oldowner) 03665 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03666 } else { 03667 /* Note we will need a BYE when this all settles out 03668 but we can't send one while we have "INVITE" outstanding. */ 03669 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03670 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03671 AST_SCHED_DEL(sched, p->waitid); 03672 if (sip_cancel_destroy(p)) 03673 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03674 } 03675 } 03676 } 03677 if (needdestroy) 03678 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03679 ast_mutex_unlock(&p->lock); 03680 return 0; 03681 }
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 3930 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, sip_pvt::rtp, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03931 { 03932 struct sip_pvt *p = ast->tech_pvt; 03933 int res = 0; 03934 03935 ast_mutex_lock(&p->lock); 03936 switch(condition) { 03937 case AST_CONTROL_RINGING: 03938 if (ast->_state == AST_STATE_RING) { 03939 p->invitestate = INV_EARLY_MEDIA; 03940 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03941 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03942 /* Send 180 ringing if out-of-band seems reasonable */ 03943 transmit_response(p, "180 Ringing", &p->initreq); 03944 ast_set_flag(&p->flags[0], SIP_RINGING); 03945 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03946 break; 03947 } else { 03948 /* Well, if it's not reasonable, just send in-band */ 03949 } 03950 } 03951 res = -1; 03952 break; 03953 case AST_CONTROL_BUSY: 03954 if (ast->_state != AST_STATE_UP) { 03955 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 03956 p->invitestate = INV_COMPLETED; 03957 sip_alreadygone(p); 03958 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03959 break; 03960 } 03961 res = -1; 03962 break; 03963 case AST_CONTROL_CONGESTION: 03964 if (ast->_state != AST_STATE_UP) { 03965 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 03966 p->invitestate = INV_COMPLETED; 03967 sip_alreadygone(p); 03968 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03969 break; 03970 } 03971 res = -1; 03972 break; 03973 case AST_CONTROL_PROCEEDING: 03974 if ((ast->_state != AST_STATE_UP) && 03975 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03976 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03977 transmit_response(p, "100 Trying", &p->initreq); 03978 p->invitestate = INV_PROCEEDING; 03979 break; 03980 } 03981 res = -1; 03982 break; 03983 case AST_CONTROL_PROGRESS: 03984 if ((ast->_state != AST_STATE_UP) && 03985 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03986 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03987 p->invitestate = INV_EARLY_MEDIA; 03988 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03989 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03990 break; 03991 } 03992 res = -1; 03993 break; 03994 case AST_CONTROL_HOLD: 03995 ast_rtp_new_source(p->rtp); 03996 ast_moh_start(ast, data, p->mohinterpret); 03997 break; 03998 case AST_CONTROL_UNHOLD: 03999 ast_rtp_new_source(p->rtp); 04000 ast_moh_stop(ast); 04001 break; 04002 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04003 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04004 transmit_info_with_vidupdate(p); 04005 /* ast_rtcp_send_h261fur(p->vrtp); */ 04006 } else 04007 res = -1; 04008 break; 04009 case AST_CONTROL_SRCUPDATE: 04010 ast_rtp_new_source(p->rtp); 04011 break; 04012 case -1: 04013 res = -1; 04014 break; 04015 default: 04016 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04017 res = -1; 04018 break; 04019 } 04020 ast_mutex_unlock(&p->lock); 04021 return res; 04022 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1769 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().
01770 { 01771 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01772 }
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 4030 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_verbose(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, f, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04031 { 04032 struct ast_channel *tmp; 04033 struct ast_variable *v = NULL; 04034 int fmt; 04035 int what; 04036 int needvideo = 0, video = 0; 04037 char *decoded_exten; 04038 04039 if (option_debug != 0) { 04040 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04041 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04042 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04043 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04044 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04045 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04046 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04047 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04048 } 04049 04050 { 04051 char my_name[128]; /* pick a good name */ 04052 const char *f, *fromdomain = NULL; 04053 04054 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04055 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04056 else 04057 fromdomain = i->fromdomain; 04058 04059 if (!ast_strlen_zero(i->username)) { 04060 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04061 /* title not empty and different from username */ 04062 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04063 } else { 04064 /* username not empty, title is empty or equal to username */ 04065 snprintf(my_name, sizeof(my_name), "%s", i->username); 04066 } 04067 } else { /* username empty */ 04068 if (!ast_strlen_zero(i->peername)) { 04069 /* call from unregisted peer */ 04070 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04071 } else { /* username and peername empty */ 04072 if (!ast_strlen_zero(title)) { /* title not empty */ 04073 snprintf(my_name, sizeof(my_name), "%s", title); 04074 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04075 f = i->from; 04076 if (!strncmp(f, "sip:", 4)) 04077 f += 4; 04078 snprintf(my_name, sizeof(my_name), "%s", f); 04079 } else { /* fallback to fromdomain */ 04080 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04081 } 04082 } 04083 } 04084 ast_mutex_unlock(&i->lock); 04085 /* Don't hold a sip pvt lock while we allocate a channel */ 04086 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i); 04087 04088 } 04089 if (!tmp) { 04090 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04091 ast_mutex_lock(&i->lock); 04092 return NULL; 04093 } 04094 ast_mutex_lock(&i->lock); 04095 04096 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04097 tmp->tech = &sip_tech_info; 04098 else 04099 tmp->tech = &sip_tech; 04100 04101 /* Select our native format based on codec preference until we receive 04102 something from another device to the contrary. */ 04103 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04104 what = i->jointcapability; 04105 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04106 } else if (i->capability) { /* Our configured capability for this peer */ 04107 what = i->capability; 04108 video = i->capability & AST_FORMAT_VIDEO_MASK; 04109 } else { 04110 what = global_capability; /* Global codec support */ 04111 video = global_capability & AST_FORMAT_VIDEO_MASK; 04112 } 04113 04114 /* Set the native formats for audio and merge in video */ 04115 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04116 if (option_debug > 2) { 04117 char buf[SIPBUFSIZE]; 04118 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04119 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04120 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04121 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04122 if (i->prefcodec) 04123 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04124 } 04125 04126 /* XXX Why are we choosing a codec from the native formats?? */ 04127 fmt = ast_best_codec(tmp->nativeformats); 04128 04129 /* If we have a prefcodec setting, we have an inbound channel that set a 04130 preferred format for this call. Otherwise, we check the jointcapability 04131 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04132 */ 04133 if (i->vrtp) { 04134 if (i->prefcodec) 04135 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04136 else 04137 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04138 } 04139 04140 if (option_debug > 2) { 04141 if (needvideo) 04142 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04143 else 04144 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04145 } 04146 04147 04148 04149 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04150 i->vad = ast_dsp_new(); 04151 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04152 if (global_relaxdtmf) 04153 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04154 } 04155 if (i->rtp) { 04156 tmp->fds[0] = ast_rtp_fd(i->rtp); 04157 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04158 } 04159 if (needvideo && i->vrtp) { 04160 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04161 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04162 } 04163 if (i->udptl) { 04164 tmp->fds[5] = ast_udptl_fd(i->udptl); 04165 } 04166 if (state == AST_STATE_RING) 04167 tmp->rings = 1; 04168 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04169 tmp->writeformat = fmt; 04170 tmp->rawwriteformat = fmt; 04171 tmp->readformat = fmt; 04172 tmp->rawreadformat = fmt; 04173 tmp->tech_pvt = i; 04174 04175 tmp->callgroup = i->callgroup; 04176 tmp->pickupgroup = i->pickupgroup; 04177 tmp->cid.cid_pres = i->callingpres; 04178 if (!ast_strlen_zero(i->accountcode)) 04179 ast_string_field_set(tmp, accountcode, i->accountcode); 04180 if (i->amaflags) 04181 tmp->amaflags = i->amaflags; 04182 if (!ast_strlen_zero(i->language)) 04183 ast_string_field_set(tmp, language, i->language); 04184 i->owner = tmp; 04185 ast_module_ref(ast_module_info->self); 04186 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04187 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04188 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04189 * structure so that there aren't issues when forming URI's 04190 */ 04191 decoded_exten = ast_strdupa(i->exten); 04192 ast_uri_decode(decoded_exten); 04193 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04194 04195 /* Don't use ast_set_callerid() here because it will 04196 * generate an unnecessary NewCallerID event */ 04197 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04198 if (!ast_strlen_zero(i->rdnis)) 04199 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04200 04201 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04202 tmp->cid.cid_dnid = ast_strdup(i->exten); 04203 04204 tmp->priority = 1; 04205 if (!ast_strlen_zero(i->uri)) 04206 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04207 if (!ast_strlen_zero(i->domain)) 04208 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04209 if (!ast_strlen_zero(i->useragent)) 04210 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04211 if (!ast_strlen_zero(i->callid)) 04212 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04213 if (i->rtp) 04214 ast_jb_configure(tmp, &global_jbconf); 04215 04216 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04217 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04218 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04219 04220 /* Set channel variables for this call from configuration */ 04221 for (v = i->chanvars ; v ; v = v->next) 04222 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04223 04224 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04225 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04226 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04227 ast_hangup(tmp); 04228 tmp = NULL; 04229 } 04230 04231 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04232 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04233 04234 return tmp; 04235 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11576 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11577 { 11578 if (argc != 4) 11579 return RESULT_SHOWUSAGE; 11580 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11581 ast_cli(fd, "SIP Debugging Disabled\n"); 11582 return RESULT_SUCCESS; 11583 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11585 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11586 { 11587 if (argc != 3) 11588 return RESULT_SHOWUSAGE; 11589 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11590 ast_cli(fd, "SIP Debugging Disabled\n"); 11591 return RESULT_SUCCESS; 11592 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11606 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11607 { 11608 if (argc != 3) { 11609 return RESULT_SHOWUSAGE; 11610 } 11611 recordhistory = FALSE; 11612 ast_cli(fd, "SIP History Recording Disabled\n"); 11613 return RESULT_SUCCESS; 11614 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11520 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
11521 { 11522 struct ast_variable *varlist; 11523 int i; 11524 11525 if (argc < 4) 11526 return RESULT_SHOWUSAGE; 11527 11528 if (!notify_types) { 11529 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11530 return RESULT_FAILURE; 11531 } 11532 11533 varlist = ast_variable_browse(notify_types, argv[2]); 11534 11535 if (!varlist) { 11536 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11537 return RESULT_FAILURE; 11538 } 11539 11540 for (i = 3; i < argc; i++) { 11541 struct sip_pvt *p; 11542 struct sip_request req; 11543 struct ast_variable *var; 11544 11545 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11546 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11547 return RESULT_FAILURE; 11548 } 11549 11550 if (create_addr(p, argv[i])) { 11551 /* Maybe they're not registered, etc. */ 11552 sip_destroy(p); 11553 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11554 continue; 11555 } 11556 11557 initreqprep(&req, p, SIP_NOTIFY); 11558 11559 for (var = varlist; var; var = var->next) 11560 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11561 11562 /* Recalculate our side, and recalculate Call ID */ 11563 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11564 p->ourip = __ourip; 11565 build_via(p); 11566 build_callid_pvt(p); 11567 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11568 transmit_sip_request(p, &req); 11569 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11570 } 11571 11572 return RESULT_SUCCESS; 11573 }
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 13339 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
13340 { 13341 struct sip_dual *d; 13342 struct ast_channel *transferee, *transferer; 13343 /* Chan2m: The transferer, chan1m: The transferee */ 13344 pthread_t th; 13345 13346 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13347 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13348 if ((!transferer) || (!transferee)) { 13349 if (transferee) { 13350 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13351 ast_hangup(transferee); 13352 } 13353 if (transferer) { 13354 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13355 ast_hangup(transferer); 13356 } 13357 return -1; 13358 } 13359 13360 /* Make formats okay */ 13361 transferee->readformat = chan1->readformat; 13362 transferee->writeformat = chan1->writeformat; 13363 13364 /* Prepare for taking over the channel */ 13365 ast_channel_masquerade(transferee, chan1); 13366 13367 /* Setup the extensions and such */ 13368 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13369 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13370 transferee->priority = chan1->priority; 13371 13372 /* We make a clone of the peer channel too, so we can play 13373 back the announcement */ 13374 13375 /* Make formats okay */ 13376 transferer->readformat = chan2->readformat; 13377 transferer->writeformat = chan2->writeformat; 13378 13379 /* Prepare for taking over the channel. Go ahead and grab this channel 13380 * lock here to avoid a deadlock with callbacks into the channel driver 13381 * that hold the channel lock and want the pvt lock. */ 13382 while (ast_channel_trylock(chan2)) { 13383 struct sip_pvt *pvt = chan2->tech_pvt; 13384 DEADLOCK_AVOIDANCE(&pvt->lock); 13385 } 13386 ast_channel_masquerade(transferer, chan2); 13387 ast_channel_unlock(chan2); 13388 13389 /* Setup the extensions and such */ 13390 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13391 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13392 transferer->priority = chan2->priority; 13393 13394 ast_channel_lock(transferer); 13395 if (ast_do_masquerade(transferer)) { 13396 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13397 ast_channel_unlock(transferer); 13398 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13399 ast_hangup(transferer); 13400 return -1; 13401 } 13402 ast_channel_unlock(transferer); 13403 if (!transferer || !transferee) { 13404 if (!transferer) { 13405 if (option_debug) 13406 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13407 } 13408 if (!transferee) { 13409 if (option_debug) 13410 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13411 } 13412 return -1; 13413 } 13414 if ((d = ast_calloc(1, sizeof(*d)))) { 13415 pthread_attr_t attr; 13416 13417 pthread_attr_init(&attr); 13418 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13419 13420 /* Save original request for followup */ 13421 copy_request(&d->req, req); 13422 d->chan1 = transferee; /* Transferee */ 13423 d->chan2 = transferer; /* Transferer */ 13424 d->seqno = seqno; 13425 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13426 /* Could not start thread */ 13427 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13428 by sip_park_thread() */ 13429 pthread_attr_destroy(&attr); 13430 return 0; 13431 } 13432 pthread_attr_destroy(&attr); 13433 } 13434 return -1; 13435 }
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 13272 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
13273 { 13274 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13275 struct sip_dual *d; 13276 struct sip_request req; 13277 int ext; 13278 int res; 13279 13280 d = stuff; 13281 transferee = d->chan1; 13282 transferer = d->chan2; 13283 copy_request(&req, &d->req); 13284 free(d); 13285 13286 if (!transferee || !transferer) { 13287 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13288 return NULL; 13289 } 13290 if (option_debug > 3) 13291 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13292 13293 ast_channel_lock(transferee); 13294 if (ast_do_masquerade(transferee)) { 13295 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13296 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13297 ast_channel_unlock(transferee); 13298 return NULL; 13299 } 13300 ast_channel_unlock(transferee); 13301 13302 res = ast_park_call(transferee, transferer, 0, &ext); 13303 13304 13305 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13306 if (!res) { 13307 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13308 } else { 13309 /* Then tell the transferer what happened */ 13310 sprintf(buf, "Call parked on extension '%d'", ext); 13311 transmit_message_with_text(transferer->tech_pvt, buf); 13312 } 13313 #endif 13314 13315 /* Any way back to the current call??? */ 13316 /* Transmit response to the REFER request */ 13317 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13318 if (!res) { 13319 /* Transfer succeeded */ 13320 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13321 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13322 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13323 ast_hangup(transferer); /* This will cause a BYE */ 13324 if (option_debug) 13325 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13326 } else { 13327 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13328 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13329 if (option_debug) 13330 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13331 /* Do not hangup call */ 13332 } 13333 return NULL; 13334 }
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 8695 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), and sip_peer::onHold.
Referenced by change_hold_state(), and update_call_counter().
08696 { 08697 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 08698 08699 if (!peer) 08700 return; 08701 08702 /* If they put someone on hold, increment the value... otherwise decrement it */ 08703 if (hold) 08704 peer->onHold++; 08705 else 08706 peer->onHold--; 08707 08708 /* Request device state update */ 08709 ast_device_state_changed("SIP/%s", peer->name); 08710 08711 return; 08712 }
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 18490 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sched, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
18491 { 18492 int ms = 0; 18493 18494 if (!speerobjs) /* No peers, just give up */ 18495 return; 18496 18497 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18498 ASTOBJ_WRLOCK(iterator); 18499 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18500 struct sip_peer *peer_ptr = iterator; 18501 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18502 } 18503 ms += 100; 18504 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18505 if (iterator->pokeexpire == -1) { 18506 struct sip_peer *peer_ptr = iterator; 18507 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18508 } 18509 ASTOBJ_UNLOCK(iterator); 18510 } while (0) 18511 ); 18512 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16336 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
16337 { 16338 struct sip_peer *peer = (struct sip_peer *)data; 16339 16340 peer->pokeexpire = -1; 16341 if (peer->lastms > -1) { 16342 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16343 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16344 } 16345 if (peer->call) 16346 sip_destroy(peer->call); 16347 peer->call = NULL; 16348 peer->lastms = -1; 16349 ast_device_state_changed("SIP/%s", peer->name); 16350 16351 /* This function gets called one place outside of the scheduler ... */ 16352 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16353 struct sip_peer *peer_ptr = peer; 16354 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16355 } 16356 16357 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16358 * inherit the reference that the current callback already has. */ 16359 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16360 if (peer->pokeexpire == -1) { 16361 ASTOBJ_UNREF(peer, sip_destroy_peer); 16362 } 16363 16364 return 0; 16365 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16370 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), 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_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_noanswer(), sipdebug, sip_peer::sockfd, sip_pvt::sockfd, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
16371 { 16372 struct sip_pvt *p; 16373 int xmitres = 0; 16374 16375 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16376 /* IF we have no IP, or this isn't to be monitored, return 16377 imeediately after clearing things out */ 16378 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16379 struct sip_peer *peer_ptr = peer; 16380 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16381 } 16382 peer->lastms = 0; 16383 peer->call = NULL; 16384 return 0; 16385 } 16386 if (peer->call) { 16387 if (sipdebug) 16388 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16389 sip_destroy(peer->call); 16390 } 16391 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16392 return -1; 16393 16394 p->sa = peer->addr; 16395 p->recv = peer->addr; 16396 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16397 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16398 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 16399 p->sockfd = peer->sockfd; 16400 16401 /* Send OPTIONs to peer's fullcontact */ 16402 if (!ast_strlen_zero(peer->fullcontact)) 16403 ast_string_field_set(p, fullcontact, peer->fullcontact); 16404 16405 if (!ast_strlen_zero(peer->tohost)) 16406 ast_string_field_set(p, tohost, peer->tohost); 16407 else 16408 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16409 16410 /* Recalculate our side, and recalculate Call ID */ 16411 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16412 p->ourip = __ourip; 16413 build_via(p); 16414 build_callid_pvt(p); 16415 16416 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16417 struct sip_peer *peer_ptr = peer; 16418 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16419 } 16420 16421 p->relatedpeer = ASTOBJ_REF(peer); 16422 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16423 #ifdef VOCAL_DATA_HACK 16424 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16425 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16426 #else 16427 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16428 #endif 16429 gettimeofday(&peer->ps, NULL); 16430 if (xmitres == XMIT_ERROR) { 16431 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16432 } else { 16433 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16434 struct sip_peer *peer_ptr = peer; 16435 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16436 } 16437 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16438 if (peer->pokeexpire == -1) { 16439 struct sip_peer *peer_ptr = peer; 16440 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16441 } 16442 } 16443 16444 return 0; 16445 }
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 8048 of file chan_sip.c.
References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
08049 { 08050 struct sip_peer *peer = (struct sip_peer *) data; 08051 08052 peer->pokeexpire = -1; 08053 08054 sip_poke_peer(peer); 08055 08056 ASTOBJ_UNREF(peer, sip_destroy_peer); 08057 08058 return 0; 08059 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10299 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.
10300 { 10301 struct sip_peer *peer; 10302 struct sip_user *user; 10303 int pruneuser = FALSE; 10304 int prunepeer = FALSE; 10305 int multi = FALSE; 10306 char *name = NULL; 10307 regex_t regexbuf; 10308 10309 switch (argc) { 10310 case 4: 10311 if (!strcasecmp(argv[3], "user")) 10312 return RESULT_SHOWUSAGE; 10313 if (!strcasecmp(argv[3], "peer")) 10314 return RESULT_SHOWUSAGE; 10315 if (!strcasecmp(argv[3], "like")) 10316 return RESULT_SHOWUSAGE; 10317 if (!strcasecmp(argv[3], "all")) { 10318 multi = TRUE; 10319 pruneuser = prunepeer = TRUE; 10320 } else { 10321 pruneuser = prunepeer = TRUE; 10322 name = argv[3]; 10323 } 10324 break; 10325 case 5: 10326 if (!strcasecmp(argv[4], "like")) 10327 return RESULT_SHOWUSAGE; 10328 if (!strcasecmp(argv[3], "all")) 10329 return RESULT_SHOWUSAGE; 10330 if (!strcasecmp(argv[3], "like")) { 10331 multi = TRUE; 10332 name = argv[4]; 10333 pruneuser = prunepeer = TRUE; 10334 } else if (!strcasecmp(argv[3], "user")) { 10335 pruneuser = TRUE; 10336 if (!strcasecmp(argv[4], "all")) 10337 multi = TRUE; 10338 else 10339 name = argv[4]; 10340 } else if (!strcasecmp(argv[3], "peer")) { 10341 prunepeer = TRUE; 10342 if (!strcasecmp(argv[4], "all")) 10343 multi = TRUE; 10344 else 10345 name = argv[4]; 10346 } else 10347 return RESULT_SHOWUSAGE; 10348 break; 10349 case 6: 10350 if (strcasecmp(argv[4], "like")) 10351 return RESULT_SHOWUSAGE; 10352 if (!strcasecmp(argv[3], "user")) { 10353 pruneuser = TRUE; 10354 name = argv[5]; 10355 } else if (!strcasecmp(argv[3], "peer")) { 10356 prunepeer = TRUE; 10357 name = argv[5]; 10358 } else 10359 return RESULT_SHOWUSAGE; 10360 break; 10361 default: 10362 return RESULT_SHOWUSAGE; 10363 } 10364 10365 if (multi && name) { 10366 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10367 return RESULT_SHOWUSAGE; 10368 } 10369 10370 if (multi) { 10371 if (prunepeer) { 10372 int pruned = 0; 10373 10374 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10375 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10376 ASTOBJ_RDLOCK(iterator); 10377 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10378 ASTOBJ_UNLOCK(iterator); 10379 continue; 10380 }; 10381 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10382 ASTOBJ_MARK(iterator); 10383 pruned++; 10384 } 10385 ASTOBJ_UNLOCK(iterator); 10386 } while (0) ); 10387 if (pruned) { 10388 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10389 ast_cli(fd, "%d peers pruned.\n", pruned); 10390 } else 10391 ast_cli(fd, "No peers found to prune.\n"); 10392 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10393 } 10394 if (pruneuser) { 10395 int pruned = 0; 10396 10397 ASTOBJ_CONTAINER_WRLOCK(&userl); 10398 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10399 ASTOBJ_RDLOCK(iterator); 10400 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10401 ASTOBJ_UNLOCK(iterator); 10402 continue; 10403 }; 10404 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10405 ASTOBJ_MARK(iterator); 10406 pruned++; 10407 } 10408 ASTOBJ_UNLOCK(iterator); 10409 } while (0) ); 10410 if (pruned) { 10411 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10412 ast_cli(fd, "%d users pruned.\n", pruned); 10413 } else 10414 ast_cli(fd, "No users found to prune.\n"); 10415 ASTOBJ_CONTAINER_UNLOCK(&userl); 10416 } 10417 } else { 10418 if (prunepeer) { 10419 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10420 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10421 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10422 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10423 } else 10424 ast_cli(fd, "Peer '%s' pruned.\n", name); 10425 ASTOBJ_UNREF(peer, sip_destroy_peer); 10426 } else 10427 ast_cli(fd, "Peer '%s' not found.\n", name); 10428 } 10429 if (pruneuser) { 10430 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10431 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10432 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10433 ASTOBJ_CONTAINER_LINK(&userl, user); 10434 } else 10435 ast_cli(fd, "User '%s' pruned.\n", name); 10436 ASTOBJ_UNREF(user, sip_destroy_user); 10437 } else 10438 ast_cli(fd, "User '%s' not found.\n", name); 10439 } 10440 } 10441 10442 return RESULT_SUCCESS; 10443 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4438 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, 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().
04439 { 04440 struct ast_frame *fr; 04441 struct sip_pvt *p = ast->tech_pvt; 04442 int faxdetected = FALSE; 04443 04444 ast_mutex_lock(&p->lock); 04445 fr = sip_rtp_read(ast, p, &faxdetected); 04446 p->lastrtprx = time(NULL); 04447 04448 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04449 /* 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 */ 04450 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04451 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04452 if (!p->pendinginvite) { 04453 if (option_debug > 2) 04454 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04455 p->t38.state = T38_LOCAL_REINVITE; 04456 transmit_reinvite_with_t38_sdp(p); 04457 if (option_debug > 1) 04458 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04459 } 04460 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04461 if (option_debug > 2) 04462 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04463 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04464 } 04465 } 04466 04467 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04468 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04469 fr = &ast_null_frame; 04470 } 04471 04472 ast_mutex_unlock(&p->lock); 04473 return fr; 04474 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1763 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().
01764 { 01765 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01766 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7849 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().
07850 { 07851 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07852 return p->refer ? 1 : 0; 07853 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7596 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_pvt::lock, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, and transmit_register().
Referenced by transmit_register().
07597 { 07598 07599 /* if we are here, our registration timed out, so we'll just do it over */ 07600 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07601 struct sip_pvt *p; 07602 int res; 07603 07604 /* if we couldn't get a reference to the registry object, punt */ 07605 if (!r) 07606 return 0; 07607 07608 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07609 if (r->call) { 07610 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07611 in the single SIP manager thread. */ 07612 p = r->call; 07613 ast_mutex_lock(&p->lock); 07614 if (p->registry) 07615 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07616 r->call = NULL; 07617 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07618 /* Pretend to ACK anything just in case */ 07619 __sip_pretend_ack(p); 07620 ast_mutex_unlock(&p->lock); 07621 } 07622 /* If we have a limit, stop registration and give up */ 07623 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07624 /* Ok, enough is enough. Don't try any more */ 07625 /* We could add an external notification here... 07626 steal it from app_voicemail :-) */ 07627 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07628 r->regstate = REG_STATE_FAILED; 07629 } else { 07630 r->regstate = REG_STATE_UNREGISTERED; 07631 r->timeout = -1; 07632 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07633 } 07634 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)); 07635 ASTOBJ_UNREF(r, sip_registry_destroy); 07636 return 0; 07637 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4767 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.
04768 { 04769 struct sip_registry *reg; 04770 int portnum = 0; 04771 char username[256] = ""; 04772 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04773 char *porta=NULL; 04774 char *contact=NULL; 04775 04776 if (!value) 04777 return -1; 04778 ast_copy_string(username, value, sizeof(username)); 04779 /* First split around the last '@' then parse the two components. */ 04780 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04781 if (hostname) 04782 *hostname++ = '\0'; 04783 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04784 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04785 return -1; 04786 } 04787 /* split user[:secret[:authuser]] */ 04788 secret = strchr(username, ':'); 04789 if (secret) { 04790 *secret++ = '\0'; 04791 authuser = strchr(secret, ':'); 04792 if (authuser) 04793 *authuser++ = '\0'; 04794 } 04795 /* split host[:port][/contact] */ 04796 contact = strchr(hostname, '/'); 04797 if (contact) 04798 *contact++ = '\0'; 04799 if (ast_strlen_zero(contact)) 04800 contact = "s"; 04801 porta = strchr(hostname, ':'); 04802 if (porta) { 04803 *porta++ = '\0'; 04804 portnum = atoi(porta); 04805 if (portnum == 0) { 04806 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04807 return -1; 04808 } 04809 } 04810 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04811 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04812 return -1; 04813 } 04814 04815 if (ast_string_field_init(reg, 256)) { 04816 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04817 free(reg); 04818 return -1; 04819 } 04820 04821 regobjs++; 04822 ASTOBJ_INIT(reg); 04823 ast_string_field_set(reg, contact, contact); 04824 if (!ast_strlen_zero(username)) 04825 ast_string_field_set(reg, username, username); 04826 if (hostname) 04827 ast_string_field_set(reg, hostname, hostname); 04828 if (authuser) 04829 ast_string_field_set(reg, authuser, authuser); 04830 if (secret) 04831 ast_string_field_set(reg, secret, secret); 04832 reg->expire = -1; 04833 reg->timeout = -1; 04834 reg->refresh = default_expiry; 04835 reg->portno = portnum; 04836 reg->callid_valid = FALSE; 04837 reg->ocseq = INITIAL_CSEQ; 04838 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04839 ASTOBJ_UNREF(reg,sip_registry_destroy); 04840 return 0; 04841 }
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 3078 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03079 { 03080 /* Really delete */ 03081 if (option_debug > 2) 03082 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03083 03084 if (reg->call) { 03085 /* Clear registry before destroying to ensure 03086 we don't get reentered trying to grab the registry lock */ 03087 reg->call->registry = NULL; 03088 if (option_debug > 2) 03089 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03090 sip_destroy(reg->call); 03091 } 03092 AST_SCHED_DEL(sched, reg->expire); 03093 AST_SCHED_DEL(sched, reg->timeout); 03094 ast_string_field_free_memory(reg); 03095 regobjs--; 03096 free(reg); 03097 03098 }
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 12245 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12246 { 12247 struct sip_pvt *p = (struct sip_pvt *) data; 12248 12249 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12250 p->waitid = -1; 12251 return 0; 12252 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18558 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), and TRUE.
Referenced by reload().
18559 { 18560 ast_mutex_lock(&sip_reload_lock); 18561 if (sip_reloading) 18562 ast_verbose("Previous SIP reload not yet done\n"); 18563 else { 18564 sip_reloading = TRUE; 18565 if (fd) 18566 sip_reloadreason = CHANNEL_CLI_RELOAD; 18567 else 18568 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18569 } 18570 ast_mutex_unlock(&sip_reload_lock); 18571 restart_monitor(); 18572 18573 return 0; 18574 }
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 16557 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
16558 { 16559 int oldformat; 16560 struct sip_pvt *p; 16561 struct ast_channel *tmpc = NULL; 16562 char *ext, *host; 16563 char tmp[256]; 16564 char *dest = data; 16565 16566 oldformat = format; 16567 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16568 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)); 16569 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16570 return NULL; 16571 } 16572 if (option_debug) 16573 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16574 16575 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16576 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16577 *cause = AST_CAUSE_SWITCH_CONGESTION; 16578 return NULL; 16579 } 16580 16581 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16582 16583 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16584 sip_destroy(p); 16585 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16586 *cause = AST_CAUSE_SWITCH_CONGESTION; 16587 return NULL; 16588 } 16589 16590 ast_copy_string(tmp, dest, sizeof(tmp)); 16591 host = strchr(tmp, '@'); 16592 if (host) { 16593 *host++ = '\0'; 16594 ext = tmp; 16595 } else { 16596 ext = strchr(tmp, '/'); 16597 if (ext) 16598 *ext++ = '\0'; 16599 host = tmp; 16600 } 16601 16602 if (create_addr(p, host)) { 16603 *cause = AST_CAUSE_UNREGISTERED; 16604 if (option_debug > 2) 16605 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16606 sip_destroy(p); 16607 return NULL; 16608 } 16609 if (ast_strlen_zero(p->peername) && ext) 16610 ast_string_field_set(p, peername, ext); 16611 /* Recalculate our side, and recalculate Call ID */ 16612 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16613 p->ourip = __ourip; 16614 build_via(p); 16615 build_callid_pvt(p); 16616 16617 /* We have an extension to call, don't use the full contact here */ 16618 /* This to enable dialing registered peers with extension dialling, 16619 like SIP/peername/extension 16620 SIP/peername will still use the full contact */ 16621 if (ext) { 16622 ast_string_field_set(p, username, ext); 16623 ast_string_field_free(p, fullcontact); 16624 } 16625 #if 0 16626 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16627 #endif 16628 p->prefcodec = oldformat; /* Format for this call */ 16629 ast_mutex_lock(&p->lock); 16630 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16631 ast_mutex_unlock(&p->lock); 16632 if (!tmpc) 16633 sip_destroy(p); 16634 ast_update_use_count(); 16635 restart_monitor(); 16636 return tmpc; 16637 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7564 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), and sipdebug.
Referenced by handle_response_register(), and sip_send_all_registers().
07565 { 07566 /* if we are here, we know that we need to reregister. */ 07567 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07568 07569 /* if we couldn't get a reference to the registry object, punt */ 07570 if (!r) 07571 return 0; 07572 07573 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07574 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07575 /* Since registry's are only added/removed by the the monitor thread, this 07576 may be overkill to reference/dereference at all here */ 07577 if (sipdebug) 07578 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07579 07580 r->expire = -1; 07581 __sip_do_register(r); 07582 ASTOBJ_UNREF(r, sip_registry_destroy); 07583 return 0; 07584 }
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 4368 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04369 { 04370 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04371 struct ast_frame *f; 04372 04373 if (!p->rtp) { 04374 /* We have no RTP allocated for this channel */ 04375 return &ast_null_frame; 04376 } 04377 04378 switch(ast->fdno) { 04379 case 0: 04380 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04381 break; 04382 case 1: 04383 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04384 break; 04385 case 2: 04386 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04387 break; 04388 case 3: 04389 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04390 break; 04391 case 5: 04392 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04393 break; 04394 default: 04395 f = &ast_null_frame; 04396 } 04397 /* Don't forward RFC2833 if we're not supposed to */ 04398 if (f && (f->frametype == AST_FRAME_DTMF) && 04399 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04400 return &ast_null_frame; 04401 04402 /* We already hold the channel lock */ 04403 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04404 return f; 04405 04406 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04407 if (!(f->subclass & p->jointcapability)) { 04408 if (option_debug) { 04409 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04410 ast_getformatname(f->subclass), p->owner->name); 04411 } 04412 return &ast_null_frame; 04413 } 04414 if (option_debug) 04415 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04416 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04417 ast_set_read_format(p->owner, p->owner->readformat); 04418 ast_set_write_format(p->owner, p->owner->writeformat); 04419 } 04420 04421 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04422 f = ast_dsp_process(p->owner, p->vad, f); 04423 if (f && f->frametype == AST_FRAME_DTMF) { 04424 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04425 if (option_debug) 04426 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04427 *faxdetect = 1; 04428 } else if (option_debug) { 04429 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04430 } 04431 } 04432 } 04433 04434 return f; 04435 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2138 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02139 { 02140 if (ms < 0) { 02141 if (p->timer_t1 == 0) 02142 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02143 ms = p->timer_t1 * 64; 02144 } 02145 if (sip_debug_test_pvt(p)) 02146 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02147 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02148 append_history(p, "SchedDestroy", "%d ms", ms); 02149 02150 AST_SCHED_DEL(sched, p->autokillid); 02151 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02152 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 18515 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
18516 { 18517 int ms; 18518 int regspacing; 18519 if (!regobjs) 18520 return; 18521 regspacing = default_expiry * 1000/regobjs; 18522 if (regspacing > 100) 18523 regspacing = 100; 18524 ms = regspacing; 18525 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18526 ASTOBJ_WRLOCK(iterator); 18527 AST_SCHED_DEL(sched, iterator->expire); 18528 ms += regspacing; 18529 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18530 ASTOBJ_UNLOCK(iterator); 18531 } while (0) 18532 ); 18533 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer | ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 16057 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by handle_request_subscribe().
16058 { 16059 /* Called with peerl lock, but releases it */ 16060 struct sip_pvt *p; 16061 int newmsgs, oldmsgs; 16062 16063 /* Do we have an IP address? If not, skip this peer */ 16064 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16065 return 0; 16066 16067 /* Check for messages */ 16068 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16069 16070 peer->lastmsgcheck = time(NULL); 16071 16072 /* Return now if it's the same thing we told them last time */ 16073 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16074 return 0; 16075 } 16076 16077 16078 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16079 16080 if (peer->mwipvt) { 16081 /* Base message on subscription */ 16082 p = peer->mwipvt; 16083 } else { 16084 /* Build temporary dialog for this message */ 16085 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16086 return -1; 16087 if (create_addr_from_peer(p, peer)) { 16088 /* Maybe they're not registered, etc. */ 16089 sip_destroy(p); 16090 return 0; 16091 } 16092 /* Recalculate our side, and recalculate Call ID */ 16093 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16094 p->ourip = __ourip; 16095 build_via(p); 16096 build_callid_pvt(p); 16097 /* Destroy this session after 32 secs */ 16098 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16099 } 16100 /* Send MWI */ 16101 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16102 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16103 return 0; 16104 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3861 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.
03862 { 03863 struct sip_pvt *p = ast->tech_pvt; 03864 int res = 0; 03865 03866 ast_mutex_lock(&p->lock); 03867 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03868 case SIP_DTMF_INBAND: 03869 res = -1; /* Tell Asterisk to generate inband indications */ 03870 break; 03871 case SIP_DTMF_RFC2833: 03872 if (p->rtp) 03873 ast_rtp_senddigit_begin(p->rtp, digit); 03874 break; 03875 default: 03876 break; 03877 } 03878 ast_mutex_unlock(&p->lock); 03879 03880 return res; 03881 }
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 3885 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
03886 { 03887 struct sip_pvt *p = ast->tech_pvt; 03888 int res = 0; 03889 03890 ast_mutex_lock(&p->lock); 03891 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03892 case SIP_DTMF_INFO: 03893 transmit_info_with_digit(p, digit, duration); 03894 break; 03895 case SIP_DTMF_RFC2833: 03896 if (p->rtp) 03897 ast_rtp_senddigit_end(p->rtp, digit); 03898 break; 03899 case SIP_DTMF_INBAND: 03900 res = -1; /* Tell Asterisk to stop inband indications */ 03901 break; 03902 } 03903 ast_mutex_unlock(&p->lock); 03904 03905 return res; 03906 }
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 2398 of file chan_sip.c.
References ast_strlen_zero(), ast_verbose(), debug, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02399 { 02400 struct sip_pvt *p = ast->tech_pvt; 02401 int debug = sip_debug_test_pvt(p); 02402 02403 if (debug) 02404 ast_verbose("Sending text %s on %s\n", text, ast->name); 02405 if (!p) 02406 return -1; 02407 if (ast_strlen_zero(text)) 02408 return 0; 02409 if (debug) 02410 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02411 transmit_message_with_text(p, text); 02412 return 0; 02413 }
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 18242 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
18243 { 18244 struct sip_pvt *p; 18245 int changed = 0; 18246 18247 p = chan->tech_pvt; 18248 if (!p) 18249 return -1; 18250 18251 /* Disable early RTP bridge */ 18252 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 18253 return 0; 18254 18255 ast_mutex_lock(&p->lock); 18256 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18257 /* If we're destroyed, don't bother */ 18258 ast_mutex_unlock(&p->lock); 18259 return 0; 18260 } 18261 18262 /* if this peer cannot handle reinvites of the media stream to devices 18263 that are known to be behind a NAT, then stop the process now 18264 */ 18265 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18266 ast_mutex_unlock(&p->lock); 18267 return 0; 18268 } 18269 18270 if (rtp) { 18271 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18272 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18273 memset(&p->redirip, 0, sizeof(p->redirip)); 18274 changed = 1; 18275 } 18276 if (vrtp) { 18277 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18278 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18279 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18280 changed = 1; 18281 } 18282 if (codecs) { 18283 if ((p->redircodecs != codecs)) { 18284 p->redircodecs = codecs; 18285 changed = 1; 18286 } 18287 if ((p->capability & codecs) != p->capability) { 18288 p->jointcapability &= codecs; 18289 p->capability &= codecs; 18290 changed = 1; 18291 } 18292 } 18293 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18294 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18295 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18296 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18297 if (option_debug) 18298 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)); 18299 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18300 if (option_debug > 2) { 18301 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)); 18302 } 18303 transmit_reinvite_with_sdp(p); 18304 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18305 if (option_debug > 2) { 18306 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)); 18307 } 18308 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18309 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18310 } 18311 } 18312 /* Reset lastrtprx timer */ 18313 p->lastrtprx = p->lastrtptx = time(NULL); 18314 ast_mutex_unlock(&p->lock); 18315 return 0; 18316 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18069 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
18070 { 18071 struct sip_pvt *p; 18072 18073 p = chan->tech_pvt; 18074 if (!p) 18075 return -1; 18076 ast_mutex_lock(&p->lock); 18077 if (udptl) 18078 ast_udptl_get_peer(udptl, &p->udptlredirip); 18079 else 18080 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18081 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18082 if (!p->pendinginvite) { 18083 if (option_debug > 2) { 18084 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); 18085 } 18086 transmit_reinvite_with_t38_sdp(p); 18087 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18088 if (option_debug > 2) { 18089 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); 18090 } 18091 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18092 } 18093 } 18094 /* Reset lastrtprx timer */ 18095 p->lastrtprx = p->lastrtptx = time(NULL); 18096 ast_mutex_unlock(&p->lock); 18097 return 0; 18098 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11175 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
11176 { 11177 struct sip_pvt *cur; 11178 size_t len; 11179 int found = 0; 11180 11181 if (argc != 4) 11182 return RESULT_SHOWUSAGE; 11183 len = strlen(argv[3]); 11184 ast_mutex_lock(&iflock); 11185 for (cur = iflist; cur; cur = cur->next) { 11186 if (!strncasecmp(cur->callid, argv[3], len)) { 11187 char formatbuf[SIPBUFSIZE/2]; 11188 ast_cli(fd,"\n"); 11189 if (cur->subscribed != NONE) 11190 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11191 else 11192 ast_cli(fd, " * SIP Call\n"); 11193 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11194 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11195 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11196 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11197 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11198 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11199 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11200 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11201 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11202 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11203 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11204 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11205 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11206 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)" ); 11207 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11208 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11209 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11210 if (!ast_strlen_zero(cur->username)) 11211 ast_cli(fd, " Username: %s\n", cur->username); 11212 if (!ast_strlen_zero(cur->peername)) 11213 ast_cli(fd, " Peername: %s\n", cur->peername); 11214 if (!ast_strlen_zero(cur->uri)) 11215 ast_cli(fd, " Original uri: %s\n", cur->uri); 11216 if (!ast_strlen_zero(cur->cid_num)) 11217 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11218 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11219 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11220 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11221 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11222 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11223 ast_cli(fd, " SIP Options: "); 11224 if (cur->sipoptions) { 11225 int x; 11226 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11227 if (cur->sipoptions & sip_options[x].id) 11228 ast_cli(fd, "%s ", sip_options[x].text); 11229 } 11230 } else 11231 ast_cli(fd, "(none)\n"); 11232 ast_cli(fd, "\n\n"); 11233 found++; 11234 } 11235 } 11236 ast_mutex_unlock(&iflock); 11237 if (!found) 11238 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11239 return RESULT_SUCCESS; 11240 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10966 of file chan_sip.c.
References __sip_show_channels().
10967 { 10968 return __sip_show_channels(fd, argc, argv, 0); 10969 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10477 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), FORMAT, domain::mode, RESULT_SUCCESS, and S_OR.
10478 { 10479 struct domain *d; 10480 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10481 10482 if (AST_LIST_EMPTY(&domain_list)) { 10483 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10484 return RESULT_SUCCESS; 10485 } else { 10486 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10487 AST_LIST_LOCK(&domain_list); 10488 AST_LIST_TRAVERSE(&domain_list, d, list) 10489 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10490 domain_mode_to_text(d->mode)); 10491 AST_LIST_UNLOCK(&domain_list); 10492 ast_cli(fd, "\n"); 10493 return RESULT_SUCCESS; 10494 } 10495 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11243 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
11244 { 11245 struct sip_pvt *cur; 11246 size_t len; 11247 int found = 0; 11248 11249 if (argc != 4) 11250 return RESULT_SHOWUSAGE; 11251 if (!recordhistory) 11252 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11253 len = strlen(argv[3]); 11254 ast_mutex_lock(&iflock); 11255 for (cur = iflist; cur; cur = cur->next) { 11256 if (!strncasecmp(cur->callid, argv[3], len)) { 11257 struct sip_history *hist; 11258 int x = 0; 11259 11260 ast_cli(fd,"\n"); 11261 if (cur->subscribed != NONE) 11262 ast_cli(fd, " * Subscription\n"); 11263 else 11264 ast_cli(fd, " * SIP Call\n"); 11265 if (cur->history) 11266 AST_LIST_TRAVERSE(cur->history, hist, list) 11267 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11268 if (x == 0) 11269 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11270 found++; 11271 } 11272 } 11273 ast_mutex_unlock(&iflock); 11274 if (!found) 11275 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11276 return RESULT_SUCCESS; 11277 }
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 9902 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
09903 { 09904 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09905 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09906 char ilimits[40]; 09907 char iused[40]; 09908 int showall = FALSE; 09909 09910 if (argc < 3) 09911 return RESULT_SHOWUSAGE; 09912 09913 if (argc == 4 && !strcmp(argv[3],"all")) 09914 showall = TRUE; 09915 09916 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09917 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09918 ASTOBJ_RDLOCK(iterator); 09919 if (iterator->call_limit) 09920 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09921 else 09922 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09923 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09924 if (showall || iterator->call_limit) 09925 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09926 ASTOBJ_UNLOCK(iterator); 09927 } while (0) ); 09928 09929 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09930 09931 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09932 ASTOBJ_RDLOCK(iterator); 09933 if (iterator->call_limit) 09934 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09935 else 09936 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09937 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09938 if (showall || iterator->call_limit) 09939 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09940 ASTOBJ_UNLOCK(iterator); 09941 } while (0) ); 09942 09943 return RESULT_SUCCESS; 09944 #undef FORMAT 09945 #undef FORMAT2 09946 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10223 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10224 { 10225 char tmp[256]; 10226 if (argc != 3) 10227 return RESULT_SHOWUSAGE; 10228 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10229 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10230 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10231 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10232 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10233 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10234 return RESULT_SUCCESS; 10235 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10529 of file chan_sip.c.
References _sip_show_peer().
10530 { 10531 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10532 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10079 of file chan_sip.c.
References _sip_show_peers().
10080 { 10081 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10082 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10803 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.
10804 { 10805 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10806 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10807 char host[80]; 10808 char tmpdat[256]; 10809 struct tm tm; 10810 10811 10812 if (argc != 3) 10813 return RESULT_SHOWUSAGE; 10814 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10815 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10816 ASTOBJ_RDLOCK(iterator); 10817 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10818 if (iterator->regtime) { 10819 ast_localtime(&iterator->regtime, &tm, NULL); 10820 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10821 } else { 10822 tmpdat[0] = 0; 10823 } 10824 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10825 ASTOBJ_UNLOCK(iterator); 10826 } while(0)); 10827 return RESULT_SUCCESS; 10828 #undef FORMAT 10829 #undef FORMAT2 10830 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10833 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().
10834 { 10835 int realtimepeers; 10836 int realtimeusers; 10837 char codec_buf[SIPBUFSIZE]; 10838 10839 realtimepeers = ast_check_realtime("sippeers"); 10840 realtimeusers = ast_check_realtime("sipusers"); 10841 10842 if (argc != 3) 10843 return RESULT_SHOWUSAGE; 10844 ast_cli(fd, "\n\nGlobal Settings:\n"); 10845 ast_cli(fd, "----------------\n"); 10846 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10847 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10848 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10849 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10850 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10851 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10852 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10853 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10854 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10855 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10856 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10857 ast_cli(fd, " Our auth realm %s\n", global_realm); 10858 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10859 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10860 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10861 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10862 ast_cli(fd, " User Agent: %s\n", global_useragent); 10863 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10864 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10865 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10866 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10867 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10868 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10869 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10870 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10871 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10872 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10873 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10874 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10875 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10876 #endif 10877 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10878 if (!realtimepeers && !realtimeusers) 10879 ast_cli(fd, " SIP realtime: Disabled\n" ); 10880 else 10881 ast_cli(fd, " SIP realtime: Enabled\n" ); 10882 10883 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10884 ast_cli(fd, "---------------------------\n"); 10885 ast_cli(fd, " Codecs: "); 10886 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10887 ast_cli(fd, "%s\n", codec_buf); 10888 ast_cli(fd, " Codec Order: "); 10889 print_codec_to_cli(fd, &default_prefs); 10890 ast_cli(fd, "\n"); 10891 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10892 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10893 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10894 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10895 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10896 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10897 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10898 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10899 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10900 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10901 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10902 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10903 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10904 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10905 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10906 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10907 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10908 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10909 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10910 ast_cli(fd, "\nDefault Settings:\n"); 10911 ast_cli(fd, "-----------------\n"); 10912 ast_cli(fd, " Context: %s\n", default_context); 10913 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10914 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10915 ast_cli(fd, " Qualify: %d\n", default_qualify); 10916 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10917 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" ); 10918 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10919 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10920 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10921 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10922 10923 10924 if (realtimepeers || realtimeusers) { 10925 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10926 ast_cli(fd, "----------------------\n"); 10927 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10928 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10929 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10930 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10931 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10932 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10933 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10934 } 10935 ast_cli(fd, "\n----\n"); 10936 return RESULT_SUCCESS; 10937 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10972 of file chan_sip.c.
References __sip_show_channels().
10973 { 10974 return __sip_show_channels(fd, argc, argv, 1); 10975 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10748 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.
10749 { 10750 char cbuf[256]; 10751 struct sip_user *user; 10752 struct ast_variable *v; 10753 int load_realtime; 10754 10755 if (argc < 4) 10756 return RESULT_SHOWUSAGE; 10757 10758 /* Load from realtime storage? */ 10759 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10760 10761 user = find_user(argv[3], load_realtime); 10762 if (user) { 10763 ast_cli(fd,"\n\n"); 10764 ast_cli(fd, " * Name : %s\n", user->name); 10765 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10766 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10767 ast_cli(fd, " Context : %s\n", user->context); 10768 ast_cli(fd, " Language : %s\n", user->language); 10769 if (!ast_strlen_zero(user->accountcode)) 10770 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10771 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10772 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10773 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10774 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10775 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10776 ast_cli(fd, " Callgroup : "); 10777 print_group(fd, user->callgroup, 0); 10778 ast_cli(fd, " Pickupgroup : "); 10779 print_group(fd, user->pickupgroup, 0); 10780 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10781 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10782 ast_cli(fd, " Codec Order : ("); 10783 print_codec_to_cli(fd, &user->prefs); 10784 ast_cli(fd, ")\n"); 10785 10786 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10787 if (user->chanvars) { 10788 ast_cli(fd, " Variables :\n"); 10789 for (v = user->chanvars ; v ; v = v->next) 10790 ast_cli(fd, " %s = %s\n", v->name, v->value); 10791 } 10792 ast_cli(fd,"\n"); 10793 ASTOBJ_UNREF(user,sip_destroy_user); 10794 } else { 10795 ast_cli(fd,"User %s not found.\n", argv[3]); 10796 ast_cli(fd,"\n"); 10797 } 10798 10799 return RESULT_SUCCESS; 10800 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10002 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.
10003 { 10004 regex_t regexbuf; 10005 int havepattern = FALSE; 10006 10007 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10008 10009 switch (argc) { 10010 case 5: 10011 if (!strcasecmp(argv[3], "like")) { 10012 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10013 return RESULT_SHOWUSAGE; 10014 havepattern = TRUE; 10015 } else 10016 return RESULT_SHOWUSAGE; 10017 case 3: 10018 break; 10019 default: 10020 return RESULT_SHOWUSAGE; 10021 } 10022 10023 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10024 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10025 ASTOBJ_RDLOCK(iterator); 10026 10027 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10028 ASTOBJ_UNLOCK(iterator); 10029 continue; 10030 } 10031 10032 ast_cli(fd, FORMAT, iterator->name, 10033 iterator->secret, 10034 iterator->accountcode, 10035 iterator->context, 10036 iterator->ha ? "Yes" : "No", 10037 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10038 ASTOBJ_UNLOCK(iterator); 10039 } while (0) 10040 ); 10041 10042 if (havepattern) 10043 regfree(®exbuf); 10044 10045 return RESULT_SUCCESS; 10046 #undef FORMAT 10047 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18429 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
18430 { 18431 char *cdest; 18432 char *extension, *host, *port; 18433 char tmp[80]; 18434 18435 cdest = ast_strdupa(dest); 18436 18437 extension = strsep(&cdest, "@"); 18438 host = strsep(&cdest, ":"); 18439 port = strsep(&cdest, ":"); 18440 if (ast_strlen_zero(extension)) { 18441 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18442 return 0; 18443 } 18444 18445 /* we'll issue the redirect message here */ 18446 if (!host) { 18447 char *localtmp; 18448 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18449 if (ast_strlen_zero(tmp)) { 18450 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18451 return 0; 18452 } 18453 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18454 char lhost[80], lport[80]; 18455 memset(lhost, 0, sizeof(lhost)); 18456 memset(lport, 0, sizeof(lport)); 18457 localtmp++; 18458 /* This is okey because lhost and lport are as big as tmp */ 18459 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18460 if (ast_strlen_zero(lhost)) { 18461 ast_log(LOG_ERROR, "Can't find the host address\n"); 18462 return 0; 18463 } 18464 host = ast_strdupa(lhost); 18465 if (!ast_strlen_zero(lport)) { 18466 port = ast_strdupa(lport); 18467 } 18468 } 18469 } 18470 18471 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18472 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18473 18474 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18475 sip_alreadygone(p); 18476 return 0; 18477 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3909 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().
03910 { 03911 struct sip_pvt *p = ast->tech_pvt; 03912 int res; 03913 03914 if (dest == NULL) /* functions below do not take a NULL */ 03915 dest = ""; 03916 ast_mutex_lock(&p->lock); 03917 if (ast->_state == AST_STATE_RING) 03918 res = sip_sipredirect(p, dest); 03919 else 03920 res = transmit_refer(p, dest); 03921 ast_mutex_unlock(&p->lock); 03922 return res; 03923 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14051 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), sip_uri_params_cmp(), and strsep().
Referenced by handle_request_invite().
14052 { 14053 char *uri1 = ast_strdupa(input1); 14054 char *uri2 = ast_strdupa(input2); 14055 char *host1; 14056 char *host2; 14057 char *params1; 14058 char *params2; 14059 char *headers1; 14060 char *headers2; 14061 14062 /* Strip off "sip:" from the URI. We know this is present 14063 * because it was checked back in parse_request() 14064 */ 14065 strsep(&uri1, ":"); 14066 strsep(&uri2, ":"); 14067 14068 if ((host1 = strchr(uri1, '@'))) { 14069 *host1++ = '\0'; 14070 } 14071 if ((host2 = strchr(uri2, '@'))) { 14072 *host2++ = '\0'; 14073 } 14074 14075 /* Check for mismatched username and passwords. This is the 14076 * only case-sensitive comparison of a SIP URI 14077 */ 14078 if ((host1 && !host2) || 14079 (host2 && !host1) || 14080 (host1 && host2 && strcmp(uri1, uri2))) { 14081 return 1; 14082 } 14083 14084 if (!host1) 14085 host1 = uri1; 14086 if (!host2) 14087 host2 = uri2; 14088 14089 /* Strip off the parameters and headers so we can compare 14090 * host and port 14091 */ 14092 14093 if ((params1 = strchr(host1, ';'))) { 14094 *params1++ = '\0'; 14095 } 14096 if ((params2 = strchr(host2, ';'))) { 14097 *params2++ = '\0'; 14098 } 14099 14100 /* Headers come after parameters, but there may be headers without 14101 * parameters, thus the S_OR 14102 */ 14103 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14104 *headers1++ = '\0'; 14105 } 14106 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14107 *headers2++ = '\0'; 14108 } 14109 14110 /* Now the host/port are properly isolated. We can get by with a string comparison 14111 * because the SIP URI checking rules have some interesting exceptions that make 14112 * this possible. I will note 2 in particular 14113 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14114 * IP address are not considered a match with SIP URI's. 14115 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14116 * This includes if one URI explicitly contains port 5060 and the other implies it 14117 * by not having a port specified. 14118 */ 14119 14120 if (strcasecmp(host1, host2)) { 14121 return 1; 14122 } 14123 14124 /* Headers have easier rules to follow, so do those first */ 14125 if (sip_uri_headers_cmp(headers1, headers2)) { 14126 return 1; 14127 } 14128 14129 /* And now the parameters. Ugh */ 14130 return sip_uri_params_cmp(params1, params2); 14131 }
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 14017 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().
Referenced by sip_uri_cmp().
14018 { 14019 char *headers1 = ast_strdupa(input1); 14020 char *headers2 = ast_strdupa(input2); 14021 int zerolength1 = ast_strlen_zero(headers1); 14022 int zerolength2 = ast_strlen_zero(headers2); 14023 int different = 0; 14024 char *header1; 14025 14026 if ((zerolength1 && !zerolength2) || 14027 (zerolength2 && !zerolength1)) 14028 return 1; 14029 14030 if (zerolength1 && zerolength2) 14031 return 0; 14032 14033 /* At this point, we can definitively state that both inputs are 14034 * not zero-length. First, one more optimization. If the length 14035 * of the headers is not equal, then we definitely have no match 14036 */ 14037 if (strlen(headers1) != strlen(headers2)) { 14038 return 1; 14039 } 14040 14041 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14042 if (!strcasestr(headers2, header1)) { 14043 different = 1; 14044 break; 14045 } 14046 } 14047 14048 return different; 14049 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 13890 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
13891 { 13892 char *params1 = ast_strdupa(input1); 13893 char *params2 = ast_strdupa(input2); 13894 char *pos1; 13895 char *pos2; 13896 int maddrmatch = 0; 13897 int ttlmatch = 0; 13898 int usermatch = 0; 13899 int methodmatch = 0; 13900 13901 /*Quick optimization. If both params are zero-length, then 13902 * they match 13903 */ 13904 if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) { 13905 return 0; 13906 } 13907 13908 pos1 = params1; 13909 while (!ast_strlen_zero(pos1)) { 13910 char *name1 = pos1; 13911 char *value1 = strchr(pos1, '='); 13912 char *semicolon1 = strchr(pos1, ';'); 13913 int matched = 0; 13914 if (semicolon1) { 13915 *semicolon1++ = '\0'; 13916 } 13917 if (!value1) { 13918 goto fail; 13919 } 13920 *value1++ = '\0'; 13921 /* Checkpoint reached. We have the name and value parsed for param1 13922 * We have to duplicate params2 each time through the second loop 13923 * or else we can't search and replace the semicolons with \0 each 13924 * time 13925 */ 13926 pos2 = ast_strdupa(params2); 13927 while (!ast_strlen_zero(pos2)) { 13928 char *name2 = pos2; 13929 char *value2 = strchr(pos2, '='); 13930 char *semicolon2 = strchr(pos2, ';'); 13931 if (semicolon2) { 13932 *semicolon2++ = '\0'; 13933 } 13934 if (!value2) { 13935 goto fail; 13936 } 13937 *value2++ = '\0'; 13938 if (!strcasecmp(name1, name2)) { 13939 if (strcasecmp(value1, value2)) { 13940 goto fail; 13941 } else { 13942 matched = 1; 13943 break; 13944 } 13945 } 13946 pos2 = semicolon2; 13947 } 13948 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 13949 if (!strcasecmp(name1, "maddr")) { 13950 if (matched) { 13951 maddrmatch = 1; 13952 } else { 13953 goto fail; 13954 } 13955 } else if (!strcasecmp(name1, "ttl")) { 13956 if (matched) { 13957 ttlmatch = 1; 13958 } else { 13959 goto fail; 13960 } 13961 } else if (!strcasecmp(name1, "user")) { 13962 if (matched) { 13963 usermatch = 1; 13964 } else { 13965 goto fail; 13966 } 13967 } else if (!strcasecmp(name1, "method")) { 13968 if (matched) { 13969 methodmatch = 1; 13970 } else { 13971 goto fail; 13972 } 13973 } 13974 pos1 = semicolon1; 13975 } 13976 13977 /* We've made it out of that horrible O(m*n) construct and there are no 13978 * failures yet. We're not done yet, though, because params2 could have 13979 * an maddr, ttl, user, or method header and params1 did not. 13980 */ 13981 pos2 = params2; 13982 while (!ast_strlen_zero(pos2)) { 13983 char *name2 = pos2; 13984 char *value2 = strchr(pos2, '='); 13985 char *semicolon2 = strchr(pos2, ';'); 13986 if (semicolon2) { 13987 *semicolon2++ = '\0'; 13988 } 13989 if (!value2) { 13990 goto fail; 13991 } 13992 *value2++ = '\0'; 13993 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 13994 (!strcasecmp(name2, "ttl") && !ttlmatch) || 13995 (!strcasecmp(name2, "user") && !usermatch) || 13996 (!strcasecmp(name2, "method") && !methodmatch)) { 13997 goto fail; 13998 } 13999 } 14000 return 0; 14001 14002 fail: 14003 return 1; 14004 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3736 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(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03737 { 03738 struct sip_pvt *p = ast->tech_pvt; 03739 int res = 0; 03740 03741 switch (frame->frametype) { 03742 case AST_FRAME_VOICE: 03743 if (!(frame->subclass & ast->nativeformats)) { 03744 char s1[512], s2[512], s3[512]; 03745 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03746 frame->subclass, 03747 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03748 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03749 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03750 ast->readformat, 03751 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03752 ast->writeformat); 03753 return 0; 03754 } 03755 if (p) { 03756 ast_mutex_lock(&p->lock); 03757 if (p->rtp) { 03758 /* If channel is not up, activate early media session */ 03759 if ((ast->_state != AST_STATE_UP) && 03760 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03761 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03762 ast_rtp_new_source(p->rtp); 03763 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03764 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03765 } 03766 p->lastrtptx = time(NULL); 03767 res = ast_rtp_write(p->rtp, frame); 03768 } 03769 ast_mutex_unlock(&p->lock); 03770 } 03771 break; 03772 case AST_FRAME_VIDEO: 03773 if (p) { 03774 ast_mutex_lock(&p->lock); 03775 if (p->vrtp) { 03776 /* Activate video early media */ 03777 if ((ast->_state != AST_STATE_UP) && 03778 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03779 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03780 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03781 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03782 } 03783 p->lastrtptx = time(NULL); 03784 res = ast_rtp_write(p->vrtp, frame); 03785 } 03786 ast_mutex_unlock(&p->lock); 03787 } 03788 break; 03789 case AST_FRAME_IMAGE: 03790 return 0; 03791 break; 03792 case AST_FRAME_MODEM: 03793 if (p) { 03794 ast_mutex_lock(&p->lock); 03795 /* UDPTL requires two-way communication, so early media is not needed here. 03796 we simply forget the frames if we get modem frames before the bridge is up. 03797 Fax will re-transmit. 03798 */ 03799 if (p->udptl && ast->_state == AST_STATE_UP) 03800 res = ast_udptl_write(p->udptl, frame); 03801 ast_mutex_unlock(&p->lock); 03802 } 03803 break; 03804 default: 03805 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03806 return 0; 03807 } 03808 03809 return res; 03810 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15913 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PAGE2_TCP, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor(), and siptcpsock_accept().
15914 { 15915 struct sip_request req; 15916 struct sockaddr_in sin = { 0, }; 15917 struct sip_pvt *p; 15918 int res; 15919 socklen_t len = sizeof(sin); 15920 int nounlock; 15921 int recount = 0; 15922 int lockretry; 15923 15924 memset(&req, 0, sizeof(req)); 15925 if (fd == sipsock) 15926 res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15927 else { 15928 if (getpeername(fd, (struct sockaddr *)&sin, &len) < 0) { 15929 close(fd); 15930 return 1; 15931 } 15932 if ((res = read(fd, req.data, sizeof(req.data) - 1)) == 0) { 15933 close(fd); 15934 return 1; 15935 } 15936 } 15937 if (res < 0) { 15938 #if !defined(__FreeBSD__) 15939 if (errno == EAGAIN) 15940 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15941 else 15942 #endif 15943 if (errno != ECONNREFUSED) 15944 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15945 return 1; 15946 } 15947 if (option_debug && res == sizeof(req.data) - 1) 15948 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15949 15950 req.data[res] = '\0'; 15951 req.len = res; 15952 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15953 ast_set_flag(&req, SIP_PKT_DEBUG); 15954 if (pedanticsipchecking) 15955 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15956 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15957 ast_verbose("\n<--- SIP read from %s:%d:%s --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 15958 fd == sipsock ? "UDP" : "TCP",req.data); 15959 15960 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 15961 return 1; 15962 15963 req.method = find_sip_method(req.rlPart1); 15964 15965 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15966 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15967 15968 if (req.headers < 2) /* Must have at least two headers */ 15969 return 1; 15970 15971 /* Process request, with netlock held, and with usual deadlock avoidance */ 15972 for (lockretry = 100; lockretry > 0; lockretry--) { 15973 ast_mutex_lock(&netlock); 15974 15975 /* Find the active SIP dialog or create a new one */ 15976 p = find_call(&req, &sin, req.method); /* returns p locked */ 15977 if (p == NULL) { 15978 if (option_debug) 15979 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15980 ast_mutex_unlock(&netlock); 15981 return 1; 15982 } 15983 /* Go ahead and lock the owner if it has one -- we may need it */ 15984 /* because this is deadlock-prone, we need to try and unlock if failed */ 15985 if (!p->owner || !ast_channel_trylock(p->owner)) 15986 break; /* locking succeeded */ 15987 if (lockretry == 1) { 15988 if (option_debug) { 15989 ast_log(LOG_DEBUG, "Failed to grab owner channel lock. (SIP call %s)\n", p->callid); 15990 } 15991 } else { 15992 if (option_debug) { 15993 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15994 } 15995 ast_mutex_unlock(&p->lock); 15996 ast_mutex_unlock(&netlock); 15997 /* Sleep for a very short amount of time */ 15998 usleep(1); 15999 } 16000 } 16001 p->recv = sin; 16002 16003 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16004 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16005 16006 if (!lockretry) { 16007 /* XXX Wouldn't p->owner always exist here? */ 16008 /* This is unsafe, since p->owner wouldn't be locked. */ 16009 if (p->owner) 16010 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 16011 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16012 if (req.method != SIP_ACK) 16013 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16014 /* XXX We could add retry-after to make sure they come back */ 16015 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16016 ast_mutex_unlock(&p->lock); 16017 ast_mutex_unlock(&netlock); 16018 return 1; 16019 } 16020 nounlock = 0; 16021 /* Is this a TCP connection ?? if so set the socket accordingly*/ 16022 if (fd != sipsock) { 16023 p->sockfd=fd; 16024 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP); 16025 } else { 16026 p->sockfd=-1; 16027 } 16028 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16029 /* Request failed */ 16030 if (option_debug) 16031 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16032 } 16033 16034 if (p->owner && !nounlock) 16035 ast_channel_unlock(p->owner); 16036 ast_mutex_unlock(&p->lock); 16037 ast_mutex_unlock(&netlock); 16038 if (recount) 16039 ast_update_use_count(); 16040 16041 return 1; 16042 }
static int siptcpsock_accept | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Accept incoming TCP connections.
Definition at line 16045 of file chan_sip.c.
References ast_io_add(), AST_IO_IN, io, sipsock_read(), and siptcpsock.
Referenced by do_monitor().
16046 { 16047 struct sockaddr_in sa; 16048 socklen_t sa_len=sizeof(sa); 16049 int newfd; 16050 16051 if ((newfd=accept(siptcpsock, (struct sockaddr *)&sa, &sa_len)) >= 0) 16052 ast_io_add(io, newfd, sipsock_read, AST_IO_IN, NULL); 16053 return 1; 16054 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12828 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().
12829 { 12830 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12831 if (p->rtp) 12832 ast_rtp_stop(p->rtp); 12833 if (p->vrtp) 12834 ast_rtp_stop(p->vrtp); 12835 if (p->udptl) 12836 ast_udptl_stop(p->udptl); 12837 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10940 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10941 { 10942 int i; 10943 10944 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10945 if (subscription_types[i].type == subtype) { 10946 return subscription_types[i].text; 10947 } 10948 } 10949 return subscription_types[0].text; 10950 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6374 of file chan_sip.c.
References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.
Referenced by add_t38_sdp().
06375 { 06376 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06377 06378 if (maxrate & T38FAX_RATE_14400) { 06379 if (option_debug > 1) 06380 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06381 return 14400; 06382 } else if (maxrate & T38FAX_RATE_12000) { 06383 if (option_debug > 1) 06384 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06385 return 12000; 06386 } else if (maxrate & T38FAX_RATE_9600) { 06387 if (option_debug > 1) 06388 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06389 return 9600; 06390 } else if (maxrate & T38FAX_RATE_7200) { 06391 if (option_debug > 1) 06392 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06393 return 7200; 06394 } else if (maxrate & T38FAX_RATE_4800) { 06395 if (option_debug > 1) 06396 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06397 return 4800; 06398 } else if (maxrate & T38FAX_RATE_2400) { 06399 if (option_debug > 1) 06400 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06401 return 2400; 06402 } else { 06403 if (option_debug > 1) 06404 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06405 return 0; 06406 } 06407 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17118 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
17119 { 17120 struct sip_peer *peer; 17121 17122 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17123 return NULL; 17124 17125 apeerobjs++; 17126 ASTOBJ_INIT(peer); 17127 set_peer_defaults(peer); 17128 17129 ast_copy_string(peer->name, name, sizeof(peer->name)); 17130 17131 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17132 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17133 peer->prefs = default_prefs; 17134 reg_source_db(peer); 17135 17136 return peer; 17137 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6149 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06150 { 06151 struct sip_pvt *p = data; 06152 06153 ast_string_field_free_memory(p); 06154 06155 free(data); 06156 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9949 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().
09950 { 09951 if (mode == TRANSFER_OPENFORALL) 09952 return "open"; 09953 else if (mode == TRANSFER_CLOSED) 09954 return "closed"; 09955 return "strict"; 09956 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8760 of file chan_sip.c.
References ast_random(), ast_string_field_build, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08761 { 08762 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08763 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08764 }
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 7930 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07931 { 07932 struct sip_request req; 07933 07934 reqprep(&req, p, SIP_INFO, 0, 1); 07935 add_digit(&req, digit, duration); 07936 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07937 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7940 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07941 { 07942 struct sip_request req; 07943 07944 reqprep(&req, p, SIP_INFO, 0, 1); 07945 add_vidupdate(&req); 07946 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07947 }
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 7181 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), handle_request_invite(), sip_call(), and sip_poke_peer().
07182 { 07183 struct sip_request req; 07184 07185 req.method = sipmethod; 07186 if (init) { /* Seems like init always is 2 */ 07187 /* Bump branch even on initial requests */ 07188 p->branch ^= ast_random(); 07189 build_via(p); 07190 if (init > 1) 07191 initreqprep(&req, p, sipmethod); 07192 else 07193 reqprep(&req, p, sipmethod, 0, 1); 07194 } else 07195 reqprep(&req, p, sipmethod, 0, 1); 07196 07197 if (p->options && p->options->auth) 07198 add_header(&req, p->options->authheader, p->options->auth); 07199 append_date(&req); 07200 if (sipmethod == SIP_REFER) { /* Call transfer */ 07201 if (p->refer) { 07202 char buf[SIPBUFSIZE]; 07203 if (!ast_strlen_zero(p->refer->refer_to)) 07204 add_header(&req, "Refer-To", p->refer->refer_to); 07205 if (!ast_strlen_zero(p->refer->referred_by)) { 07206 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07207 add_header(&req, "Referred-By", buf); 07208 } 07209 } 07210 } 07211 /* This new INVITE is part of an attended transfer. Make sure that the 07212 other end knows and replace the current call with this new call */ 07213 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07214 add_header(&req, "Replaces", p->options->replaces); 07215 add_header(&req, "Require", "replaces"); 07216 } 07217 07218 add_header(&req, "Allow", ALLOWED_METHODS); 07219 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07220 if (p->options && p->options->addsipheaders && p->owner) { 07221 struct ast_channel *chan = p->owner; /* The owner channel */ 07222 struct varshead *headp; 07223 07224 ast_channel_lock(chan); 07225 07226 headp = &chan->varshead; 07227 07228 if (!headp) 07229 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07230 else { 07231 const struct ast_var_t *current; 07232 AST_LIST_TRAVERSE(headp, current, entries) { 07233 /* SIPADDHEADER: Add SIP header to outgoing call */ 07234 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07235 char *content, *end; 07236 const char *header = ast_var_value(current); 07237 char *headdup = ast_strdupa(header); 07238 07239 /* Strip of the starting " (if it's there) */ 07240 if (*headdup == '"') 07241 headdup++; 07242 if ((content = strchr(headdup, ':'))) { 07243 *content++ = '\0'; 07244 content = ast_skip_blanks(content); /* Skip white space */ 07245 /* Strip the ending " (if it's there) */ 07246 end = content + strlen(content) -1; 07247 if (*end == '"') 07248 *end = '\0'; 07249 07250 add_header(&req, headdup, content); 07251 if (sipdebug) 07252 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07253 } 07254 } 07255 } 07256 } 07257 07258 ast_channel_unlock(chan); 07259 } 07260 if (sdp) { 07261 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07262 ast_udptl_offered_from_local(p->udptl, 1); 07263 if (option_debug) 07264 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07265 add_t38_sdp(&req, p); 07266 } else if (p->rtp) 07267 add_sdp(&req, p); 07268 } else { 07269 add_header_contentLength(&req, 0); 07270 } 07271 07272 if (!p->initreq.headers || init > 2) 07273 initialize_initreq(p, &req); 07274 p->lastinvite = p->ocseq; 07275 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07276 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7839 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().
07840 { 07841 struct sip_request req; 07842 07843 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07844 add_text(&req, text); 07845 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07846 }
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 7467 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07468 { 07469 struct sip_request req; 07470 char tmp[500]; 07471 char *t = tmp; 07472 size_t maxbytes = sizeof(tmp); 07473 07474 initreqprep(&req, p, SIP_NOTIFY); 07475 add_header(&req, "Event", "message-summary"); 07476 add_header(&req, "Content-Type", default_notifymime); 07477 07478 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07479 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07480 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07481 /* Cisco has a bug in the SIP stack where it can't accept the 07482 (0/0) notification. This can temporarily be disabled in 07483 sip.conf with the "buggymwi" option */ 07484 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)")); 07485 07486 if (p->subscribed) { 07487 if (p->expiry) 07488 add_header(&req, "Subscription-State", "active"); 07489 else /* Expired */ 07490 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07491 } 07492 07493 if (t > tmp + sizeof(tmp)) 07494 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07495 07496 add_header_contentLength(&req, strlen(tmp)); 07497 add_line(&req, tmp); 07498 07499 if (!p->initreq.headers) 07500 initialize_initreq(p, &req); 07501 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07502 }
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 7513 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07514 { 07515 struct sip_request req; 07516 char tmp[SIPBUFSIZE/2]; 07517 07518 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07519 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07520 add_header(&req, "Event", tmp); 07521 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07522 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07523 add_header(&req, "Allow", ALLOWED_METHODS); 07524 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07525 07526 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07527 add_header_contentLength(&req, strlen(tmp)); 07528 add_line(&req, tmp); 07529 07530 if (!p->initreq.headers) 07531 initialize_initreq(p, &req); 07532 07533 p->lastnoninvite = p->ocseq; 07534 07535 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07536 }
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 7860 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.
Referenced by sip_transfer().
07861 { 07862 struct sip_request req = { 07863 .headers = 0, 07864 }; 07865 char from[256]; 07866 const char *of; 07867 char *c; 07868 char referto[256]; 07869 char *ttag, *ftag; 07870 char *theirtag = ast_strdupa(p->theirtag); 07871 07872 if (option_debug || sipdebug) 07873 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07874 07875 /* Are we transfering an inbound or outbound call ? */ 07876 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07877 of = get_header(&p->initreq, "To"); 07878 ttag = theirtag; 07879 ftag = p->tag; 07880 } else { 07881 of = get_header(&p->initreq, "From"); 07882 ftag = theirtag; 07883 ttag = p->tag; 07884 } 07885 07886 ast_copy_string(from, of, sizeof(from)); 07887 of = get_in_brackets(from); 07888 ast_string_field_set(p, from, of); 07889 if (strncasecmp(of, "sip:", 4)) 07890 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07891 else 07892 of += 4; 07893 /* Get just the username part */ 07894 if ((c = strchr(dest, '@'))) 07895 c = NULL; 07896 else if ((c = strchr(of, '@'))) 07897 *c++ = '\0'; 07898 if (c) 07899 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07900 else 07901 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07902 07903 /* save in case we get 407 challenge */ 07904 sip_refer_allocate(p); 07905 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07906 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07907 p->refer->status = REFER_SENT; /* Set refer status */ 07908 07909 reqprep(&req, p, SIP_REFER, 0, 1); 07910 07911 add_header(&req, "Refer-To", referto); 07912 add_header(&req, "Allow", ALLOWED_METHODS); 07913 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07914 if (!ast_strlen_zero(p->our_contact)) 07915 add_header(&req, "Referred-By", p->our_contact); 07916 07917 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07918 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07919 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07920 07921 /*! \todo In theory, we should hang around and wait for a reply, before 07922 returning to the dial plan here. Don't know really how that would 07923 affect the transfer() app or the pbx, but, well, to make this 07924 useful we should have a STATUS code on transfer(). 07925 */ 07926 }
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 7640 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07641 { 07642 struct sip_request req; 07643 char from[256]; 07644 char to[256]; 07645 char tmp[80]; 07646 char addr[80]; 07647 struct sip_pvt *p; 07648 char *fromdomain; 07649 07650 /* exit if we are already in process with this registrar ?*/ 07651 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07652 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07653 return 0; 07654 } 07655 07656 if (r->call) { /* We have a registration */ 07657 if (!auth) { 07658 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07659 return 0; 07660 } else { 07661 p = r->call; 07662 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07663 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07664 } 07665 } else { 07666 /* Build callid for registration if we haven't registered before */ 07667 if (!r->callid_valid) { 07668 build_callid_registry(r, __ourip, default_fromdomain); 07669 r->callid_valid = TRUE; 07670 } 07671 /* Allocate SIP packet for registration */ 07672 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07673 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07674 return 0; 07675 } 07676 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07677 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07678 /* Find address to hostname */ 07679 if (create_addr(p, r->hostname)) { 07680 /* we have what we hope is a temporary network error, 07681 * probably DNS. We need to reschedule a registration try */ 07682 sip_destroy(p); 07683 07684 if (r->timeout > -1) 07685 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07686 else 07687 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); 07688 07689 AST_SCHED_DEL(sched, r->timeout); 07690 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07691 r->regattempts++; 07692 return 0; 07693 } 07694 /* Copy back Call-ID in case create_addr changed it */ 07695 ast_string_field_set(r, callid, p->callid); 07696 if (r->portno) { 07697 p->sa.sin_port = htons(r->portno); 07698 p->recv.sin_port = htons(r->portno); 07699 } else /* Set registry port to the port set from the peer definition/srv or default */ 07700 r->portno = ntohs(p->sa.sin_port); 07701 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07702 r->call=p; /* Save pointer to SIP packet */ 07703 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07704 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07705 ast_string_field_set(p, peersecret, r->secret); 07706 if (!ast_strlen_zero(r->md5secret)) 07707 ast_string_field_set(p, peermd5secret, r->md5secret); 07708 /* User name in this realm 07709 - if authuser is set, use that, otherwise use username */ 07710 if (!ast_strlen_zero(r->authuser)) { 07711 ast_string_field_set(p, peername, r->authuser); 07712 ast_string_field_set(p, authname, r->authuser); 07713 } else if (!ast_strlen_zero(r->username)) { 07714 ast_string_field_set(p, peername, r->username); 07715 ast_string_field_set(p, authname, r->username); 07716 ast_string_field_set(p, fromuser, r->username); 07717 } 07718 if (!ast_strlen_zero(r->username)) 07719 ast_string_field_set(p, username, r->username); 07720 /* Save extension in packet */ 07721 ast_string_field_set(p, exten, r->contact); 07722 07723 /* 07724 check which address we should use in our contact header 07725 based on whether the remote host is on the external or 07726 internal network so we can register through nat 07727 */ 07728 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07729 p->ourip = bindaddr.sin_addr; 07730 build_contact(p); 07731 } 07732 07733 /* set up a timeout */ 07734 if (auth == NULL) { 07735 if (r->timeout > -1) 07736 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07737 AST_SCHED_DEL(sched, r->timeout); 07738 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07739 if (option_debug) 07740 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07741 } 07742 07743 if ((fromdomain = strchr(r->username, '@'))) { 07744 /* We have a domain in the username for registration */ 07745 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07746 if (!ast_strlen_zero(p->theirtag)) 07747 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07748 else 07749 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07750 07751 /* If the registration username contains '@', then the domain should be used as 07752 the equivalent of "fromdomain" for the registration */ 07753 if (ast_strlen_zero(p->fromdomain)) { 07754 ast_string_field_set(p, fromdomain, ++fromdomain); 07755 } 07756 } else { 07757 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07758 if (!ast_strlen_zero(p->theirtag)) 07759 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07760 else 07761 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07762 } 07763 07764 /* Fromdomain is what we are registering to, regardless of actual 07765 host name from SRV */ 07766 if (!ast_strlen_zero(p->fromdomain)) { 07767 if (r->portno && r->portno != STANDARD_SIP_PORT) 07768 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07769 else 07770 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07771 } else { 07772 if (r->portno && r->portno != STANDARD_SIP_PORT) 07773 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07774 else 07775 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07776 } 07777 ast_string_field_set(p, uri, addr); 07778 07779 p->branch ^= ast_random(); 07780 07781 init_req(&req, sipmethod, addr); 07782 07783 /* Add to CSEQ */ 07784 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07785 p->ocseq = r->ocseq; 07786 07787 build_via(p); 07788 add_header(&req, "Via", p->via); 07789 add_header(&req, "From", from); 07790 add_header(&req, "To", to); 07791 add_header(&req, "Call-ID", p->callid); 07792 add_header(&req, "CSeq", tmp); 07793 if (!ast_strlen_zero(global_useragent)) 07794 add_header(&req, "User-Agent", global_useragent); 07795 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07796 07797 07798 if (auth) /* Add auth header */ 07799 add_header(&req, authheader, auth); 07800 else if (!ast_strlen_zero(r->nonce)) { 07801 char digest[1024]; 07802 07803 /* We have auth data to reuse, build a digest header! */ 07804 if (sipdebug) 07805 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07806 ast_string_field_set(p, realm, r->realm); 07807 ast_string_field_set(p, nonce, r->nonce); 07808 ast_string_field_set(p, domain, r->domain); 07809 ast_string_field_set(p, opaque, r->opaque); 07810 ast_string_field_set(p, qop, r->qop); 07811 r->noncecount++; 07812 p->noncecount = r->noncecount; 07813 07814 memset(digest,0,sizeof(digest)); 07815 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07816 add_header(&req, "Authorization", digest); 07817 else 07818 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07819 07820 } 07821 07822 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07823 add_header(&req, "Expires", tmp); 07824 add_header(&req, "Contact", p->our_contact); 07825 add_header(&req, "Event", "registration"); 07826 add_header_contentLength(&req, 0); 07827 07828 initialize_initreq(p, &req); 07829 if (sip_debug_test_pvt(p)) 07830 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07831 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07832 r->regattempts++; /* Another attempt */ 07833 if (option_debug > 3) 07834 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07835 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07836 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6901 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
06902 { 06903 struct sip_request req; 06904 06905 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06906 06907 add_header(&req, "Allow", ALLOWED_METHODS); 06908 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06909 if (sipdebug) 06910 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06911 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06912 append_history(p, "ReInv", "Re-invite sent"); 06913 add_sdp(&req, p); 06914 /* Use this as the basis */ 06915 initialize_initreq(p, &req); 06916 p->lastinvite = p->ocseq; 06917 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06918 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06919 }
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 6925 of file chan_sip.c.
References add_header(), add_t38_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, ast_udptl_offered_from_local(), sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, sip_pvt::udptl, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), and sip_set_udptl_peer().
06926 { 06927 struct sip_request req; 06928 06929 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06930 06931 add_header(&req, "Allow", ALLOWED_METHODS); 06932 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06933 if (sipdebug) 06934 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06935 ast_udptl_offered_from_local(p->udptl, 1); 06936 add_t38_sdp(&req, p); 06937 /* Use this as the basis */ 06938 initialize_initreq(p, &req); 06939 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06940 p->lastinvite = p->ocseq; 06941 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06942 }
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 7952 of file chan_sip.c.
References add_header_contentLength(), INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), and SIP_ACK.
Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().
07953 { 07954 struct sip_request resp; 07955 07956 if (sipmethod == SIP_ACK) 07957 p->invitestate = INV_CONFIRMED; 07958 07959 reqprep(&resp, p, sipmethod, seqno, newbranch); 07960 add_header_contentLength(&resp, 0); 07961 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07962 }
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 7965 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
07966 { 07967 struct sip_request resp; 07968 07969 reqprep(&resp, p, sipmethod, seqno, newbranch); 07970 if (!ast_strlen_zero(p->realm)) { 07971 char digest[1024]; 07972 07973 memset(digest, 0, sizeof(digest)); 07974 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07975 if (p->options && p->options->auth_type == PROXY_AUTH) 07976 add_header(&resp, "Proxy-Authorization", digest); 07977 else if (p->options && p->options->auth_type == WWW_AUTH) 07978 add_header(&resp, "Authorization", digest); 07979 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07980 add_header(&resp, "Proxy-Authorization", digest); 07981 } else 07982 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07983 } 07984 /* If we are hanging up and know a cause for that, send it in clear text to make 07985 debugging easier. */ 07986 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07987 char buf[10]; 07988 07989 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07990 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07991 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07992 } 07993 07994 add_header_contentLength(&resp, 0); 07995 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07996 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6210 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06211 { 06212 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06213 }
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 6229 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), sip_indicate(), and sip_sipredirect().
06230 { 06231 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06232 }
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 6159 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, build_via(), check_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.
06160 { 06161 struct sip_pvt *p = NULL; 06162 06163 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06164 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06165 return -1; 06166 } 06167 06168 /* if the structure was just allocated, initialize it */ 06169 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06170 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06171 if (ast_string_field_init(p, 512)) 06172 return -1; 06173 } 06174 06175 /* Initialize the bare minimum */ 06176 p->method = intended_method; 06177 06178 if (sin) { 06179 p->sa = *sin; 06180 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06181 p->ourip = __ourip; 06182 } else 06183 p->ourip = __ourip; 06184 06185 p->branch = ast_random(); 06186 make_our_tag(p->tag, sizeof(p->tag)); 06187 p->ocseq = INITIAL_CSEQ; 06188 06189 if (useglobal_nat && sin) { 06190 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06191 p->recv = *sin; 06192 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06193 } 06194 check_via(p, req); 06195 06196 ast_string_field_set(p, fromdomain, default_fromdomain); 06197 build_via(p); 06198 ast_string_field_set(p, callid, callid); 06199 06200 /* Use this temporary pvt structure to send the message */ 06201 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06202 06203 /* Free the string fields, but not the pool space */ 06204 ast_string_field_reset_all(p); 06205 06206 return 0; 06207 }
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 6257 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06258 { 06259 struct sip_request resp; 06260 respprep(&resp, p, msg, req); 06261 add_header(&resp, "Accept", "application/sdp"); 06262 add_header_contentLength(&resp, 0); 06263 return send_response(p, &resp, reliable, 0); 06264 }
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 6267 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
06268 { 06269 struct sip_request resp; 06270 char tmp[512]; 06271 int seqno = 0; 06272 06273 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06274 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06275 return -1; 06276 } 06277 /* Stale means that they sent us correct authentication, but 06278 based it on an old challenge (nonce) */ 06279 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06280 respprep(&resp, p, msg, req); 06281 add_header(&resp, header, tmp); 06282 add_header_contentLength(&resp, 0); 06283 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06284 return send_response(p, &resp, reliable, seqno); 06285 }
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 6247 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06248 { 06249 struct sip_request resp; 06250 respprep(&resp, p, msg, req); 06251 append_date(&resp); 06252 add_header_contentLength(&resp, 0); 06253 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06254 }
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 6830 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06831 { 06832 struct sip_request resp; 06833 int seqno; 06834 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06835 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06836 return -1; 06837 } 06838 respprep(&resp, p, msg, req); 06839 if (p->rtp) { 06840 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06841 if (option_debug) 06842 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06843 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06844 } 06845 try_suggested_sip_codec(p); 06846 add_sdp(&resp, p); 06847 } else 06848 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06849 if (reliable && !p->pendinginvite) 06850 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06851 return send_response(p, &resp, reliable, seqno); 06852 }
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 6790 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06791 { 06792 struct sip_request resp; 06793 int seqno; 06794 06795 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06796 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06797 return -1; 06798 } 06799 respprep(&resp, p, msg, req); 06800 if (p->udptl) { 06801 ast_udptl_offered_from_local(p->udptl, 0); 06802 add_t38_sdp(&resp, p); 06803 } else 06804 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06805 if (retrans && !p->pendinginvite) 06806 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06807 return send_response(p, &resp, retrans, seqno); 06808 }
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 6216 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06217 { 06218 struct sip_request resp; 06219 respprep(&resp, p, msg, req); 06220 append_date(&resp); 06221 add_header(&resp, "Unsupported", unsupported); 06222 add_header_contentLength(&resp, 0); 06223 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06224 }
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 7505 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().
07506 { 07507 if (!p->initreq.headers) /* Initialize first request before sending */ 07508 initialize_initreq(p, req); 07509 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07510 }
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 7279 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
07280 { 07281 char tmp[4000], from[256], to[256]; 07282 char *t = tmp, *c, *mfrom, *mto; 07283 size_t maxbytes = sizeof(tmp); 07284 struct sip_request req; 07285 char hint[AST_MAX_EXTENSION]; 07286 char *statestring = "terminated"; 07287 const struct cfsubscription_types *subscriptiontype; 07288 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07289 char *pidfstate = "--"; 07290 char *pidfnote= "Ready"; 07291 07292 memset(from, 0, sizeof(from)); 07293 memset(to, 0, sizeof(to)); 07294 memset(tmp, 0, sizeof(tmp)); 07295 07296 switch (state) { 07297 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07298 statestring = (global_notifyringing) ? "early" : "confirmed"; 07299 local_state = NOTIFY_INUSE; 07300 pidfstate = "busy"; 07301 pidfnote = "Ringing"; 07302 break; 07303 case AST_EXTENSION_RINGING: 07304 statestring = "early"; 07305 local_state = NOTIFY_INUSE; 07306 pidfstate = "busy"; 07307 pidfnote = "Ringing"; 07308 break; 07309 case AST_EXTENSION_INUSE: 07310 statestring = "confirmed"; 07311 local_state = NOTIFY_INUSE; 07312 pidfstate = "busy"; 07313 pidfnote = "On the phone"; 07314 break; 07315 case AST_EXTENSION_BUSY: 07316 statestring = "confirmed"; 07317 local_state = NOTIFY_CLOSED; 07318 pidfstate = "busy"; 07319 pidfnote = "On the phone"; 07320 break; 07321 case AST_EXTENSION_UNAVAILABLE: 07322 statestring = "terminated"; 07323 local_state = NOTIFY_CLOSED; 07324 pidfstate = "away"; 07325 pidfnote = "Unavailable"; 07326 break; 07327 case AST_EXTENSION_ONHOLD: 07328 statestring = "confirmed"; 07329 local_state = NOTIFY_CLOSED; 07330 pidfstate = "busy"; 07331 pidfnote = "On Hold"; 07332 break; 07333 case AST_EXTENSION_NOT_INUSE: 07334 default: 07335 /* Default setting */ 07336 break; 07337 } 07338 07339 subscriptiontype = find_subscription_type(p->subscribed); 07340 07341 /* Check which device/devices we are watching and if they are registered */ 07342 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07343 char *hint2 = hint, *individual_hint = NULL; 07344 int hint_count = 0, unavailable_count = 0; 07345 07346 while ((individual_hint = strsep(&hint2, "&"))) { 07347 hint_count++; 07348 07349 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07350 unavailable_count++; 07351 } 07352 07353 /* If none of the hinted devices are registered, we will 07354 * override notification and show no availability. 07355 */ 07356 if (hint_count > 0 && hint_count == unavailable_count) { 07357 local_state = NOTIFY_CLOSED; 07358 pidfstate = "away"; 07359 pidfnote = "Not online"; 07360 } 07361 } 07362 07363 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07364 c = get_in_brackets(from); 07365 if (strncasecmp(c, "sip:", 4)) { 07366 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07367 return -1; 07368 } 07369 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07370 07371 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07372 c = get_in_brackets(to); 07373 if (strncasecmp(c, "sip:", 4)) { 07374 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07375 return -1; 07376 } 07377 mto = strsep(&c, ";"); /* trim ; and beyond */ 07378 07379 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07380 07381 07382 add_header(&req, "Event", subscriptiontype->event); 07383 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07384 switch(state) { 07385 case AST_EXTENSION_DEACTIVATED: 07386 if (timeout) 07387 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07388 else { 07389 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07390 add_header(&req, "Retry-After", "60"); 07391 } 07392 break; 07393 case AST_EXTENSION_REMOVED: 07394 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07395 break; 07396 default: 07397 if (p->expiry) 07398 add_header(&req, "Subscription-State", "active"); 07399 else /* Expired */ 07400 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07401 } 07402 switch (p->subscribed) { 07403 case XPIDF_XML: 07404 case CPIM_PIDF_XML: 07405 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07406 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07407 ast_build_string(&t, &maxbytes, "<presence>\n"); 07408 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07409 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07410 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07411 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07412 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07413 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07414 break; 07415 case PIDF_XML: /* Eyebeam supports this format */ 07416 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07417 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); 07418 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07419 if (pidfstate[0] != '-') 07420 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07421 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07422 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07423 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07424 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07425 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07426 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07427 else 07428 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07429 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07430 break; 07431 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07432 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07433 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); 07434 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07435 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07436 else 07437 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07438 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07439 if (state == AST_EXTENSION_ONHOLD) { 07440 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07441 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07442 "</target>\n</local>\n", mto); 07443 } 07444 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07445 break; 07446 case NONE: 07447 default: 07448 break; 07449 } 07450 07451 if (t > tmp + sizeof(tmp)) 07452 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07453 07454 add_header_contentLength(&req, strlen(tmp)); 07455 add_line(&req, tmp); 07456 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07457 07458 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07459 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3684 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03685 { 03686 int fmt; 03687 const char *codec; 03688 03689 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03690 if (!codec) 03691 return; 03692 03693 fmt = ast_getformatbyname(codec); 03694 if (fmt) { 03695 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03696 if (p->jointcapability & fmt) { 03697 p->jointcapability &= fmt; 03698 p->capability &= fmt; 03699 } else 03700 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03701 } else 03702 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03703 return; 03704 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18756 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, siptcpsock, TRUE, and userl.
18757 { 18758 struct sip_pvt *p, *pl; 18759 18760 /* First, take us out of the channel type list */ 18761 ast_channel_unregister(&sip_tech); 18762 18763 /* Unregister dial plan functions */ 18764 ast_custom_function_unregister(&sipchaninfo_function); 18765 ast_custom_function_unregister(&sippeer_function); 18766 ast_custom_function_unregister(&sip_header_function); 18767 ast_custom_function_unregister(&checksipdomain_function); 18768 18769 /* Unregister dial plan applications */ 18770 ast_unregister_application(app_dtmfmode); 18771 ast_unregister_application(app_sipaddheader); 18772 18773 /* Unregister CLI commands */ 18774 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18775 18776 /* Disconnect from the RTP subsystem */ 18777 ast_rtp_proto_unregister(&sip_rtp); 18778 18779 /* Disconnect from UDPTL */ 18780 ast_udptl_proto_unregister(&sip_udptl); 18781 18782 /* Unregister AMI actions */ 18783 ast_manager_unregister("SIPpeers"); 18784 ast_manager_unregister("SIPshowpeer"); 18785 18786 ast_mutex_lock(&iflock); 18787 /* Hangup all interfaces if they have an owner */ 18788 for (p = iflist; p ; p = p->next) { 18789 if (p->owner) 18790 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18791 } 18792 ast_mutex_unlock(&iflock); 18793 18794 ast_mutex_lock(&monlock); 18795 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18796 pthread_cancel(monitor_thread); 18797 pthread_kill(monitor_thread, SIGURG); 18798 pthread_join(monitor_thread, NULL); 18799 } 18800 monitor_thread = AST_PTHREADT_STOP; 18801 ast_mutex_unlock(&monlock); 18802 18803 restartdestroy: 18804 ast_mutex_lock(&iflock); 18805 /* Destroy all the interfaces and free their memory */ 18806 p = iflist; 18807 while (p) { 18808 pl = p; 18809 p = p->next; 18810 if (__sip_destroy(pl, TRUE) < 0) { 18811 /* Something is still bridged, let it react to getting a hangup */ 18812 iflist = p; 18813 ast_mutex_unlock(&iflock); 18814 usleep(1); 18815 goto restartdestroy; 18816 } 18817 } 18818 iflist = NULL; 18819 ast_mutex_unlock(&iflock); 18820 18821 /* Free memory for local network address mask */ 18822 ast_free_ha(localaddr); 18823 18824 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18825 ASTOBJ_CONTAINER_DESTROY(&userl); 18826 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18827 ASTOBJ_CONTAINER_DESTROY(&peerl); 18828 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18829 ASTOBJ_CONTAINER_DESTROY(®l); 18830 18831 clear_realm_authentication(authl); 18832 clear_sip_domains(); 18833 close(sipsock); 18834 close(siptcpsock); 18835 sched_context_destroy(sched); 18836 18837 return 0; 18838 }
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 3235 of file chan_sip.c.
References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_peer::flags, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03236 { 03237 char name[256]; 03238 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03239 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03240 struct sip_user *u = NULL; 03241 struct sip_peer *p = NULL; 03242 03243 if (option_debug > 2) 03244 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03245 03246 /* Test if we need to check call limits, in order to avoid 03247 realtime lookups if we do not need it */ 03248 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03249 return 0; 03250 03251 ast_copy_string(name, fup->username, sizeof(name)); 03252 03253 /* Check the list of users only for incoming calls */ 03254 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03255 inuse = &u->inUse; 03256 call_limit = &u->call_limit; 03257 inringing = NULL; 03258 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03259 inuse = &p->inUse; 03260 call_limit = &p->call_limit; 03261 inringing = &p->inRinging; 03262 ast_copy_string(name, fup->peername, sizeof(name)); 03263 } 03264 if (!p && !u) { 03265 if (option_debug > 1) 03266 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03267 return 0; 03268 } 03269 03270 switch(event) { 03271 /* incoming and outgoing affects the inUse counter */ 03272 case DEC_CALL_LIMIT: 03273 if ( *inuse > 0 ) { 03274 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03275 (*inuse)--; 03276 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03277 } 03278 } else { 03279 *inuse = 0; 03280 } 03281 if (inringing) { 03282 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03283 if (*inringing > 0) 03284 (*inringing)--; 03285 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03286 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03287 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03288 } 03289 } 03290 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03291 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03292 sip_peer_hold(fup, 0); 03293 } 03294 if (option_debug > 1 || sipdebug) { 03295 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03296 } 03297 break; 03298 03299 case INC_CALL_RINGING: 03300 case INC_CALL_LIMIT: 03301 if (*call_limit > 0 ) { 03302 /* Let call limit affect only outgoing calls */ 03303 if (outgoing && (*inuse >= *call_limit)) { 03304 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); 03305 if (u) 03306 ASTOBJ_UNREF(u, sip_destroy_user); 03307 else 03308 ASTOBJ_UNREF(p, sip_destroy_peer); 03309 return -1; 03310 } 03311 } 03312 if (inringing && (event == INC_CALL_RINGING)) { 03313 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03314 (*inringing)++; 03315 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03316 } 03317 } 03318 /* Continue */ 03319 (*inuse)++; 03320 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03321 if (option_debug > 1 || sipdebug) { 03322 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03323 } 03324 break; 03325 03326 case DEC_CALL_RINGING: 03327 if (inringing) { 03328 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03329 if (*inringing > 0) 03330 (*inringing)--; 03331 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03332 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03333 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03334 } 03335 } 03336 break; 03337 03338 default: 03339 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03340 } 03341 if (p) { 03342 ast_device_state_changed("SIP/%s", p->name); 03343 ASTOBJ_UNREF(p, sip_destroy_peer); 03344 } else /* u must be set */ 03345 ASTOBJ_UNREF(u, sip_destroy_user); 03346 return 0; 03347 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2516 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02517 { 02518 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02519 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02520 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02521 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02522 } 02523 }
struct in_addr __ourip [static] |
Definition at line 1222 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 565 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 581 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 18320 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18322 of file chan_sip.c.
Definition at line 1210 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 545 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1216 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 18582 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 18587 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 559 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 231 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11870 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1225 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 525 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 522 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 192 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 222 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 524 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 533 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 530 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 531 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 534 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 528 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 529 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 18319 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18325 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 561 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1219 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 1218 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 1217 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 552 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 553 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 569 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 542 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 568 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 566 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 537 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 584 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 229 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 538 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 571 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 555 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 541 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 540 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 562 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 550 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 551 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 563 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 546 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 539 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 549 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 547 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 567 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 556 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 558 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 564 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11887 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
struct io_context* io [static] |
The IO context
Definition at line 605 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1221 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 10498 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 10049 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 191 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 190 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 599 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 11879 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 11883 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 232 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1227 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 11819 of file chan_sip.c.
int ourport [static] |
Definition at line 1224 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1223 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 544 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 11861 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 560 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
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 582 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 580 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 578 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 604 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 11843 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 11839 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 11814 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 11847 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 11834 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 11900 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 11856 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 11851 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 11866 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 11904 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 11896 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 11829 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 11824 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 11892 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 601 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 602 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 1624 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 1566 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 1592 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 1633 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 12141 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12061 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication UDP
Definition at line 1214 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 606 of file chan_sip.c.
int siptcpsock = -1 [static] |
Main socket for SIP network communication TCP
Definition at line 1215 of file chan_sip.c.
Referenced by do_monitor(), reg_source_db(), siptcpsock_accept(), and unload_module().
int* siptcpsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 607 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 579 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 543 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 577 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 18318 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18323 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.