#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Include dependency graph for chan_sip.c:
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP FALSE |
#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 %-4.4s %-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 %-4.4s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_SAMPLE_RATE(x) (x == AST_FORMAT_G722) ? 16000 : 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission. | |
static int | __sip_autodestruct (void *data) |
Kill a SIP dialog (called by scheduler). | |
static void | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
Add realm authentication in list. | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add T.38 Session Description Protocol message. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
static | AST_LIST_HEAD_STATIC (domain_list, domain) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the SIP dialog list (of sip_pvt's). | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
A per-thread temporary pvt structure. | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock
| |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static void | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static void | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (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 (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 (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_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 (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_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
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 | 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. |
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 468 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 1831 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 361 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 362 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 360 of file chan_sip.c.
#define DEC_CALL_LIMIT 0 |
Definition at line 601 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 603 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
#define DEFAULT_ALLOWGUEST TRUE |
#define DEFAULT_AUTOCREATEPEER FALSE |
#define DEFAULT_CALLERID "asterisk" |
#define DEFAULT_COMPACTHEADERS FALSE |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 166 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 183 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 198 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 197 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 168 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 170 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), transmit_refer(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 196 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 167 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
#define DEFAULT_MOHSUGGEST "" |
#define DEFAULT_MWITIME 10 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_NOTIFYRINGING TRUE |
#define DEFAULT_PEDANTIC FALSE |
#define DEFAULT_QUALIFY FALSE |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 200 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP FALSE |
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 506 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 498 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 497 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 499 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 205 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 509 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_VMEXTEN "asterisk" |
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 175 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 177 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 181 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 174 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 150 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1015 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 %-4.4s %-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 %-4.4s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
Referenced by __sip_show_channels().
#define INC_CALL_LIMIT 1 |
Definition at line 602 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 212 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 161 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 191 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 206 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 1013 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 201 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 228 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 401 of file chan_sip.c.
#define RTP 1 |
Definition at line 227 of file chan_sip.c.
#define SDP_SAMPLE_RATE | ( | x | ) | (x == AST_FORMAT_G722) ? 16000 : 8000 |
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 708 of file chan_sip.c.
Referenced by handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 749 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 737 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 738 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 723 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), and sip_hangup().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 724 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 728 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 726 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 727 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 725 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 754 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 722 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 752 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 715 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 751 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 742 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 741 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), realtime_peer(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 208 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 209 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 210 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 730 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 734 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 731 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 732 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 733 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 709 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 713 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 748 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 710 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 404 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 406 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 407 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 408 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 410 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 409 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 411 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 412 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 405 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 721 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 775 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 774 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 787 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 782 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 785 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 784 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 768 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 770 of file chan_sip.c.
Referenced by reload_config(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 771 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI)
Definition at line 790 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 767 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 777 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 788 of file chan_sip.c.
Referenced by sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 786 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 764 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 761 of file chan_sip.c.
Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 765 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 762 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 772 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 776 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 778 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 780 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 781 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 779 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 773 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), reload_config(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 714 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 795 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 797 of file chan_sip.c.
Referenced by check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 796 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 744 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 746 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 747 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 712 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 716 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 719 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 739 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 750 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 202 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 717 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 720 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 718 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 827 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 828 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 829 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 474 of file chan_sip.c.
Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), reload_config(), set_address_from_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 400 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 471 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 802 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 821 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 822 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 817 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 818 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 819 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 820 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 807 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 806 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 804 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 803 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 810 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 809 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 811 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 813 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 814 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 815 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 154 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1592 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 159 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 157 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 336 of file chan_sip.c.
00336 { 00337 AUTH_SUCCESSFUL = 0, 00338 AUTH_CHALLENGE_SENT = 1, 00339 AUTH_SECRET_FAILED = -1, 00340 AUTH_USERNAME_MISMATCH = -2, 00341 AUTH_NOT_FOUND = -3, 00342 AUTH_FAKE_AUTH = -4, 00343 AUTH_UNKNOWN_DOMAIN = -5, 00344 AUTH_PEER_NOT_DYNAMIC = -6, 00345 AUTH_ACL_FAILED = -7, 00346 };
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 671 of file chan_sip.c.
00671 { 00672 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00673 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00674 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 247 of file chan_sip.c.
00247 { 00248 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00249 INV_CALLING = 1, /*!< Invite sent, no answer */ 00250 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00251 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00252 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00253 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00254 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00255 The only way out of this is a BYE from one side */ 00256 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00257 };
Definition at line 274 of file chan_sip.c.
00274 { 00275 PARSE_REGISTER_FAILED, 00276 PARSE_REGISTER_UPDATE, 00277 PARSE_REGISTER_QUERY, 00278 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 851 of file chan_sip.c.
00851 { 00852 REFER_IDLE, /*!< No REFER is in progress */ 00853 REFER_SENT, /*!< Sent REFER to transferee */ 00854 REFER_RECEIVED, /*!< Received REFER from transferer */ 00855 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00856 REFER_ACCEPTED, /*!< Accepted by transferee */ 00857 REFER_RINGING, /*!< Target Ringing */ 00858 REFER_200OK, /*!< Answered by transfer target */ 00859 REFER_FAILED, /*!< REFER declined - go on */ 00860 REFER_NOAUTH /*!< We had no auth for REFER */ 00861 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 330 of file chan_sip.c.
00330 { 00331 PROXY_AUTH, 00332 WWW_AUTH, 00333 };
enum sip_result |
Definition at line 239 of file chan_sip.c.
00239 { 00240 AST_SUCCESS = 0, 00241 AST_FAILURE = -1, 00242 };
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 305 of file chan_sip.c.
00305 { 00306 SIP_UNKNOWN, /* Unknown response */ 00307 SIP_RESPONSE, /* Not request, response to outbound request */ 00308 SIP_REGISTER, 00309 SIP_OPTIONS, 00310 SIP_NOTIFY, 00311 SIP_INVITE, 00312 SIP_ACK, 00313 SIP_PRACK, /* Not supported at all */ 00314 SIP_BYE, 00315 SIP_REFER, 00316 SIP_SUBSCRIBE, 00317 SIP_MESSAGE, 00318 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00319 SIP_INFO, 00320 SIP_CANCEL, 00321 SIP_PUBLISH, /* Not supported at all */ 00322 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00323 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 349 of file chan_sip.c.
00349 { 00350 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00351 REG_STATE_REGSENT, /*!< Registration request sent */ 00352 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00353 REG_STATE_REGISTERED, /*!< Registred and done */ 00354 REG_STATE_REJECTED, /*!< Registration rejected */ 00355 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00356 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00357 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00358 };
enum subscriptiontype |
Definition at line 280 of file chan_sip.c.
00280 { 00281 NONE = 0, 00282 XPIDF_XML, 00283 DIALOG_INFO_XML, 00284 CPIM_PIDF_XML, 00285 PIDF_XML, 00286 MWI_NOTIFICATION 00287 };
enum t38state |
T38 States for a call.
Definition at line 832 of file chan_sip.c.
00832 { 00833 T38_DISABLED = 0, /*!< Not enabled */ 00834 T38_LOCAL_DIRECT, /*!< Offered from local */ 00835 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00836 T38_PEER_DIRECT, /*!< Offered from peer */ 00837 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00838 T38_ENABLED /*!< Negotiated (enabled) */ 00839 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 233 of file chan_sip.c.
00233 { 00234 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00235 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00236 };
enum xmittype |
Definition at line 267 of file chan_sip.c.
00267 { 00268 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00269 If it fails, it's critical and will cause a teardown of the session */ 00270 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00271 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00272 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4144 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04145 { 04146 int pass; 04147 04148 /* 04149 * Technically you can place arbitrary whitespace both before and after the ':' in 04150 * a header, although RFC3261 clearly says you shouldn't before, and place just 04151 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04152 * a good idea to say you can do it, and if you can do it, why in the hell would. 04153 * you say you shouldn't. 04154 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04155 * and we always allow spaces after that for compatibility. 04156 */ 04157 for (pass = 0; name && pass < 2;pass++) { 04158 int x, len = strlen(name); 04159 for (x=*start; x<req->headers; x++) { 04160 if (!strncasecmp(req->header[x], name, len)) { 04161 char *r = req->header[x] + len; /* skip name */ 04162 if (pedanticsipchecking) 04163 r = ast_skip_blanks(r); 04164 04165 if (*r == ':') { 04166 *start = x+1; 04167 return ast_skip_blanks(r+1); 04168 } 04169 } 04170 } 04171 if (pass == 0) /* Try aliases */ 04172 name = find_alias(name, NULL); 04173 } 04174 04175 /* Don't return NULL, so get_header is always a valid pointer */ 04176 return ""; 04177 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission.
Definition at line 2123 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02124 { 02125 struct sip_pkt *cur, *prev = NULL; 02126 02127 /* Just in case... */ 02128 char *msg; 02129 int res = FALSE; 02130 02131 msg = sip_methods[sipmethod].text; 02132 02133 ast_mutex_lock(&p->lock); 02134 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02135 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02136 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02137 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02138 if (!resp && (seqno == p->pendinginvite)) { 02139 if (option_debug) 02140 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02141 p->pendinginvite = 0; 02142 } 02143 /* this is our baby */ 02144 res = TRUE; 02145 UNLINK(cur, p->packets, prev); 02146 if (cur->retransid > -1) { 02147 if (sipdebug && option_debug > 3) 02148 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02149 ast_sched_del(sched, cur->retransid); 02150 cur->retransid = -1; 02151 } 02152 free(cur); 02153 break; 02154 } 02155 } 02156 ast_mutex_unlock(&p->lock); 02157 if (option_debug) 02158 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02159 }
static int __sip_autodestruct | ( | void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2057 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02058 { 02059 struct sip_pvt *p = data; 02060 02061 /* If this is a subscription, tell the phone that we got a timeout */ 02062 if (p->subscribed) { 02063 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02064 p->subscribed = NONE; 02065 append_history(p, "Subscribestatus", "timeout"); 02066 if (option_debug > 2) 02067 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02068 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02069 } 02070 02071 /* If we're destroying a subscription, dereference peer object too */ 02072 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02073 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02074 02075 /* Reset schedule ID */ 02076 p->autokillid = -1; 02077 02078 if (option_debug) 02079 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02080 append_history(p, "AutoDestroy", "%s", p->callid); 02081 if (p->owner) { 02082 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02083 ast_queue_hangup(p->owner); 02084 } else if (p->refer) { 02085 if (option_debug > 2) 02086 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02087 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02088 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02089 } else 02090 sip_destroy(p); 02091 return 0; 02092 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3011 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_sched_del(), 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::relatedpeer, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), cfsip_methods::text, UNLINK, and update_call_counter().
Referenced by do_monitor(), sip_destroy(), and unload_module().
03012 { 03013 struct sip_pvt *cur, *prev = NULL; 03014 struct sip_pkt *cp; 03015 03016 if (sip_debug_test_pvt(p) || option_debug > 2) 03017 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03018 03019 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03020 update_call_counter(p, DEC_CALL_LIMIT); 03021 if (option_debug > 1) 03022 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03023 } 03024 03025 /* Remove link from peer to subscription of MWI */ 03026 if (p->relatedpeer && p->relatedpeer->mwipvt) 03027 p->relatedpeer->mwipvt = NULL; 03028 03029 if (dumphistory) 03030 sip_dump_history(p); 03031 03032 if (p->options) 03033 free(p->options); 03034 03035 if (p->stateid > -1) 03036 ast_extension_state_del(p->stateid, NULL); 03037 if (p->initid > -1) 03038 ast_sched_del(sched, p->initid); 03039 if (p->autokillid > -1) 03040 ast_sched_del(sched, p->autokillid); 03041 03042 if (p->rtp) 03043 ast_rtp_destroy(p->rtp); 03044 if (p->vrtp) 03045 ast_rtp_destroy(p->vrtp); 03046 if (p->udptl) 03047 ast_udptl_destroy(p->udptl); 03048 if (p->refer) 03049 free(p->refer); 03050 if (p->route) { 03051 free_old_route(p->route); 03052 p->route = NULL; 03053 } 03054 if (p->registry) { 03055 if (p->registry->call == p) 03056 p->registry->call = NULL; 03057 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03058 } 03059 03060 /* Unlink us from the owner if we have one */ 03061 if (p->owner) { 03062 if (lockowner) 03063 ast_channel_lock(p->owner); 03064 if (option_debug) 03065 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03066 p->owner->tech_pvt = NULL; 03067 if (lockowner) 03068 ast_channel_unlock(p->owner); 03069 } 03070 /* Clear history */ 03071 if (p->history) { 03072 struct sip_history *hist; 03073 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03074 free(hist); 03075 p->history_entries--; 03076 } 03077 free(p->history); 03078 p->history = NULL; 03079 } 03080 03081 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03082 if (cur == p) { 03083 UNLINK(cur, iflist, prev); 03084 break; 03085 } 03086 } 03087 if (!cur) { 03088 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03089 return; 03090 } 03091 03092 /* remove all current packets in this dialog */ 03093 while((cp = p->packets)) { 03094 p->packets = p->packets->next; 03095 if (cp->retransid > -1) 03096 ast_sched_del(sched, cp->retransid); 03097 free(cp); 03098 } 03099 if (p->chanvars) { 03100 ast_variables_destroy(p->chanvars); 03101 p->chanvars = NULL; 03102 } 03103 ast_mutex_destroy(&p->lock); 03104 03105 ast_string_field_free_pools(p); 03106 03107 free(p); 03108 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7311 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07312 { 07313 int res; 07314 07315 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07316 return res; 07317 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race.
Definition at line 2163 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by sip_hangup(), and sip_reg_timeout().
02164 { 02165 struct sip_pkt *cur = NULL; 02166 02167 while (p->packets) { 02168 int method; 02169 if (cur == p->packets) { 02170 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02171 return; 02172 } 02173 cur = p->packets; 02174 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02175 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02176 } 02177 }
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 2009 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_sched_del(), ast_set_flag, AST_SUCCESS, ast_test_flag, 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().
02010 { 02011 struct sip_pkt *pkt; 02012 int siptimer_a = DEFAULT_RETRANS; 02013 int xmitres = 0; 02014 02015 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02016 return AST_FAILURE; 02017 memcpy(pkt->data, data, len); 02018 pkt->method = sipmethod; 02019 pkt->packetlen = len; 02020 pkt->next = p->packets; 02021 pkt->owner = p; 02022 pkt->seqno = seqno; 02023 if (resp) 02024 ast_set_flag(pkt, FLAG_RESPONSE); 02025 pkt->data[len] = '\0'; 02026 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02027 if (fatal) 02028 ast_set_flag(pkt, FLAG_FATAL); 02029 if (pkt->timer_t1) 02030 siptimer_a = pkt->timer_t1 * 2; 02031 02032 /* Schedule retransmission */ 02033 if (pkt->retransid > -1) 02034 ast_sched_del(sched, pkt->retransid); 02035 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02036 if (option_debug > 3 && sipdebug) 02037 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 02038 pkt->next = p->packets; 02039 p->packets = pkt; 02040 if (sipmethod == SIP_INVITE) { 02041 /* Note this is a pending invite */ 02042 p->pendinginvite = seqno; 02043 } 02044 02045 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02046 02047 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02048 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02049 ast_sched_del(sched, pkt->retransid); /* No more retransmission */ 02050 pkt->retransid = -1; 02051 return AST_FAILURE; 02052 } else 02053 return AST_SUCCESS; 02054 }
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 2180 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().
02181 { 02182 struct sip_pkt *cur; 02183 int res = -1; 02184 02185 for (cur = p->packets; cur; cur = cur->next) { 02186 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02187 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02188 /* this is our baby */ 02189 if (cur->retransid > -1) { 02190 if (option_debug > 3 && sipdebug) 02191 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02192 ast_sched_del(sched, cur->retransid); 02193 cur->retransid = -1; 02194 } 02195 res = 0; 02196 break; 02197 } 02198 } 02199 if (option_debug) 02200 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02201 return res; 02202 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10595 of file chan_sip.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, 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, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10596 { 10597 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10598 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 10599 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10600 struct sip_pvt *cur; 10601 int numchans = 0; 10602 char *referstatus = NULL; 10603 10604 if (argc != 3) 10605 return RESULT_SHOWUSAGE; 10606 ast_mutex_lock(&iflock); 10607 cur = iflist; 10608 if (!subscriptions) 10609 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10610 else 10611 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10612 for (; cur; cur = cur->next) { 10613 referstatus = ""; 10614 if (cur->refer) { /* SIP transfer in progress */ 10615 referstatus = referstatus2str(cur->refer->status); 10616 } 10617 if (cur->subscribed == NONE && !subscriptions) { 10618 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10619 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10620 cur->callid, 10621 cur->ocseq, cur->icseq, 10622 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 10623 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10624 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10625 cur->lastmsg , 10626 referstatus 10627 ); 10628 numchans++; 10629 } 10630 if (cur->subscribed != NONE && subscriptions) { 10631 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10632 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10633 cur->callid, 10634 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10635 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10636 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10637 subscription_type2str(cur->subscribed), 10638 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10639 ); 10640 numchans++; 10641 } 10642 } 10643 ast_mutex_unlock(&iflock); 10644 if (!subscriptions) 10645 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10646 else 10647 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10648 return RESULT_SUCCESS; 10649 #undef FORMAT 10650 #undef FORMAT2 10651 #undef FORMAT3 10652 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1759 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01760 { 01761 int res; 01762 const struct sockaddr_in *dst = sip_real_dst(p); 01763 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01764 01765 if (res == -1) { 01766 switch (errno) { 01767 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01768 case EHOSTUNREACH: /* Host can't be reached */ 01769 case ENETDOWN: /* Inteface down */ 01770 case ENETUNREACH: /* Network failure */ 01771 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01772 } 01773 } 01774 if (res != len) 01775 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)); 01776 return res; 01777 }
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 5874 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().
05875 { 05876 struct sip_request resp; 05877 int seqno = 0; 05878 05879 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05880 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05881 return -1; 05882 } 05883 respprep(&resp, p, msg, req); 05884 add_header_contentLength(&resp, 0); 05885 /* If we are cancelling an incoming invite for some reason, add information 05886 about the reason why we are doing this in clear text */ 05887 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05888 char buf[10]; 05889 05890 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05891 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05892 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05893 } 05894 return send_response(p, &resp, reliable, seqno); 05895 }
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 10147 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_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().
10148 { 10149 char status[30] = ""; 10150 char cbuf[256]; 10151 struct sip_peer *peer; 10152 char codec_buf[512]; 10153 struct ast_codec_pref *pref; 10154 struct ast_variable *v; 10155 struct sip_auth *auth; 10156 int x = 0, codec = 0, load_realtime; 10157 int realtimepeers; 10158 10159 realtimepeers = ast_check_realtime("sippeers"); 10160 10161 if (argc < 4) 10162 return RESULT_SHOWUSAGE; 10163 10164 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10165 peer = find_peer(argv[3], NULL, load_realtime); 10166 if (s) { /* Manager */ 10167 if (peer) { 10168 const char *id = astman_get_header(m,"ActionID"); 10169 10170 astman_append(s, "Response: Success\r\n"); 10171 if (!ast_strlen_zero(id)) 10172 astman_append(s, "ActionID: %s\r\n",id); 10173 } else { 10174 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10175 astman_send_error(s, m, cbuf); 10176 return 0; 10177 } 10178 } 10179 if (peer && type==0 ) { /* Normal listing */ 10180 ast_cli(fd,"\n\n"); 10181 ast_cli(fd, " * Name : %s\n", peer->name); 10182 if (realtimepeers) { /* Realtime is enabled */ 10183 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10184 } 10185 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10186 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10187 for (auth = peer->auth; auth; auth = auth->next) { 10188 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10189 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10190 } 10191 ast_cli(fd, " Context : %s\n", peer->context); 10192 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10193 ast_cli(fd, " Language : %s\n", peer->language); 10194 if (!ast_strlen_zero(peer->accountcode)) 10195 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10196 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10197 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10198 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10199 if (!ast_strlen_zero(peer->fromuser)) 10200 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10201 if (!ast_strlen_zero(peer->fromdomain)) 10202 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10203 ast_cli(fd, " Callgroup : "); 10204 print_group(fd, peer->callgroup, 0); 10205 ast_cli(fd, " Pickupgroup : "); 10206 print_group(fd, peer->pickupgroup, 0); 10207 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10208 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10209 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10210 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10211 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10212 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10213 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10214 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10215 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))); 10216 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10217 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10218 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10219 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10220 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10221 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10222 #endif 10223 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10224 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10225 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10226 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10227 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10228 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10229 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10230 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10231 10232 /* - is enumerated */ 10233 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10234 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10235 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10236 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)); 10237 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10238 if (!ast_strlen_zero(global_regcontext)) 10239 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10240 ast_cli(fd, " Def. Username: %s\n", peer->username); 10241 ast_cli(fd, " SIP Options : "); 10242 if (peer->sipoptions) { 10243 int lastoption = -1; 10244 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10245 if (sip_options[x].id != lastoption) { 10246 if (peer->sipoptions & sip_options[x].id) 10247 ast_cli(fd, "%s ", sip_options[x].text); 10248 lastoption = x; 10249 } 10250 } 10251 } else 10252 ast_cli(fd, "(none)"); 10253 10254 ast_cli(fd, "\n"); 10255 ast_cli(fd, " Codecs : "); 10256 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10257 ast_cli(fd, "%s\n", codec_buf); 10258 ast_cli(fd, " Codec Order : ("); 10259 print_codec_to_cli(fd, &peer->prefs); 10260 ast_cli(fd, ")\n"); 10261 10262 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10263 ast_cli(fd, " Status : "); 10264 peer_status(peer, status, sizeof(status)); 10265 ast_cli(fd, "%s\n",status); 10266 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10267 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10268 if (peer->chanvars) { 10269 ast_cli(fd, " Variables :\n"); 10270 for (v = peer->chanvars ; v ; v = v->next) 10271 ast_cli(fd, " %s = %s\n", v->name, v->value); 10272 } 10273 ast_cli(fd,"\n"); 10274 ASTOBJ_UNREF(peer,sip_destroy_peer); 10275 } else if (peer && type == 1) { /* manager listing */ 10276 char buf[256]; 10277 astman_append(s, "Channeltype: SIP\r\n"); 10278 astman_append(s, "ObjectName: %s\r\n", peer->name); 10279 astman_append(s, "ChanObjectType: peer\r\n"); 10280 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10281 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10282 astman_append(s, "Context: %s\r\n", peer->context); 10283 astman_append(s, "Language: %s\r\n", peer->language); 10284 if (!ast_strlen_zero(peer->accountcode)) 10285 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10286 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10287 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10288 if (!ast_strlen_zero(peer->fromuser)) 10289 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10290 if (!ast_strlen_zero(peer->fromdomain)) 10291 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10292 astman_append(s, "Callgroup: "); 10293 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10294 astman_append(s, "Pickupgroup: "); 10295 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10296 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10297 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10298 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10299 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10300 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10301 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10302 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10303 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10304 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))); 10305 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10306 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10307 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10308 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10309 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10310 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10311 10312 /* - is enumerated */ 10313 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10314 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10315 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10316 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)); 10317 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)); 10318 astman_append(s, "Default-Username: %s\r\n", peer->username); 10319 if (!ast_strlen_zero(global_regcontext)) 10320 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10321 astman_append(s, "Codecs: "); 10322 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10323 astman_append(s, "%s\r\n", codec_buf); 10324 astman_append(s, "CodecOrder: "); 10325 pref = &peer->prefs; 10326 for(x = 0; x < 32 ; x++) { 10327 codec = ast_codec_pref_index(pref,x); 10328 if (!codec) 10329 break; 10330 astman_append(s, "%s", ast_getformatname(codec)); 10331 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10332 astman_append(s, ","); 10333 } 10334 10335 astman_append(s, "\r\n"); 10336 astman_append(s, "Status: "); 10337 peer_status(peer, status, sizeof(status)); 10338 astman_append(s, "%s\r\n", status); 10339 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10340 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10341 if (peer->chanvars) { 10342 for (v = peer->chanvars ; v ; v = v->next) { 10343 astman_append(s, "ChanVariable:\n"); 10344 astman_append(s, " %s,%s\r\n", v->name, v->value); 10345 } 10346 } 10347 10348 ASTOBJ_UNREF(peer,sip_destroy_peer); 10349 10350 } else { 10351 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10352 ast_cli(fd,"\n"); 10353 } 10354 10355 return RESULT_SUCCESS; 10356 }
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 9697 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().
09698 { 09699 regex_t regexbuf; 09700 int havepattern = FALSE; 09701 09702 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09703 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09704 09705 char name[256]; 09706 int total_peers = 0; 09707 int peers_mon_online = 0; 09708 int peers_mon_offline = 0; 09709 int peers_unmon_offline = 0; 09710 int peers_unmon_online = 0; 09711 const char *id; 09712 char idtext[256] = ""; 09713 int realtimepeers; 09714 09715 realtimepeers = ast_check_realtime("sippeers"); 09716 09717 if (s) { /* Manager - get ActionID */ 09718 id = astman_get_header(m,"ActionID"); 09719 if (!ast_strlen_zero(id)) 09720 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09721 } 09722 09723 switch (argc) { 09724 case 5: 09725 if (!strcasecmp(argv[3], "like")) { 09726 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09727 return RESULT_SHOWUSAGE; 09728 havepattern = TRUE; 09729 } else 09730 return RESULT_SHOWUSAGE; 09731 case 3: 09732 break; 09733 default: 09734 return RESULT_SHOWUSAGE; 09735 } 09736 09737 if (!s) /* Normal list */ 09738 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09739 09740 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09741 char status[20] = ""; 09742 char srch[2000]; 09743 char pstatus; 09744 09745 ASTOBJ_RDLOCK(iterator); 09746 09747 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09748 ASTOBJ_UNLOCK(iterator); 09749 continue; 09750 } 09751 09752 if (!ast_strlen_zero(iterator->username) && !s) 09753 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09754 else 09755 ast_copy_string(name, iterator->name, sizeof(name)); 09756 09757 pstatus = peer_status(iterator, status, sizeof(status)); 09758 if (pstatus == 1) 09759 peers_mon_online++; 09760 else if (pstatus == 0) 09761 peers_mon_offline++; 09762 else { 09763 if (iterator->addr.sin_port == 0) 09764 peers_unmon_offline++; 09765 else 09766 peers_unmon_online++; 09767 } 09768 09769 snprintf(srch, sizeof(srch), FORMAT, name, 09770 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09771 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09772 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09773 iterator->ha ? " A " : " ", /* permit/deny */ 09774 ntohs(iterator->addr.sin_port), status, 09775 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09776 09777 if (!s) {/* Normal CLI list */ 09778 ast_cli(fd, FORMAT, name, 09779 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09780 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09781 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09782 iterator->ha ? " A " : " ", /* permit/deny */ 09783 09784 ntohs(iterator->addr.sin_port), status, 09785 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09786 } else { /* Manager format */ 09787 /* The names here need to be the same as other channels */ 09788 astman_append(s, 09789 "Event: PeerEntry\r\n%s" 09790 "Channeltype: SIP\r\n" 09791 "ObjectName: %s\r\n" 09792 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 09793 "IPaddress: %s\r\n" 09794 "IPport: %d\r\n" 09795 "Dynamic: %s\r\n" 09796 "Natsupport: %s\r\n" 09797 "VideoSupport: %s\r\n" 09798 "ACL: %s\r\n" 09799 "Status: %s\r\n" 09800 "RealtimeDevice: %s\r\n\r\n", 09801 idtext, 09802 iterator->name, 09803 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 09804 ntohs(iterator->addr.sin_port), 09805 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 09806 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 09807 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 09808 iterator->ha ? "yes" : "no", /* permit/deny */ 09809 status, 09810 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 09811 } 09812 09813 ASTOBJ_UNLOCK(iterator); 09814 09815 total_peers++; 09816 } while(0) ); 09817 09818 if (!s) 09819 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 09820 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 09821 09822 if (havepattern) 09823 regfree(®exbuf); 09824 09825 if (total) 09826 *total = total_peers; 09827 09828 09829 return RESULT_SUCCESS; 09830 #undef FORMAT 09831 #undef FORMAT2 09832 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14376 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.
14377 { 14378 struct ast_rtp_quality qos; 14379 struct sip_pvt *p = chan->tech_pvt; 14380 char *all = "", *parse = ast_strdupa(preparse); 14381 AST_DECLARE_APP_ARGS(args, 14382 AST_APP_ARG(param); 14383 AST_APP_ARG(type); 14384 AST_APP_ARG(field); 14385 ); 14386 AST_STANDARD_APP_ARGS(args, parse); 14387 14388 /* Sanity check */ 14389 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14390 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14391 return 0; 14392 } 14393 14394 if (strcasecmp(args.param, "rtpqos")) 14395 return 0; 14396 14397 /* Default arguments of audio,all */ 14398 if (ast_strlen_zero(args.type)) 14399 args.type = "audio"; 14400 if (ast_strlen_zero(args.field)) 14401 args.field = "all"; 14402 14403 memset(buf, 0, buflen); 14404 memset(&qos, 0, sizeof(qos)); 14405 14406 if (strcasecmp(args.type, "AUDIO") == 0) { 14407 all = ast_rtp_get_quality(p->rtp, &qos); 14408 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14409 all = ast_rtp_get_quality(p->vrtp, &qos); 14410 } 14411 14412 if (strcasecmp(args.field, "local_ssrc") == 0) 14413 snprintf(buf, buflen, "%u", qos.local_ssrc); 14414 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14415 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14416 else if (strcasecmp(args.field, "local_jitter") == 0) 14417 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14418 else if (strcasecmp(args.field, "local_count") == 0) 14419 snprintf(buf, buflen, "%u", qos.local_count); 14420 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14421 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14422 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14423 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14424 else if (strcasecmp(args.field, "remote_jitter") == 0) 14425 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14426 else if (strcasecmp(args.field, "remote_count") == 0) 14427 snprintf(buf, buflen, "%u", qos.remote_count); 14428 else if (strcasecmp(args.field, "rtt") == 0) 14429 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14430 else if (strcasecmp(args.field, "all") == 0) 14431 ast_copy_string(buf, all, buflen); 14432 else { 14433 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14434 return -1; 14435 } 14436 return 0; 14437 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2215 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02216 { 02217 if (!req->lines) { 02218 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02219 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02220 req->len += strlen(req->data + req->len); 02221 } 02222 }
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 6078 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().
06081 { 06082 int rtp_code; 06083 struct ast_format_list fmt; 06084 06085 06086 if (debug) 06087 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06088 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06089 return; 06090 06091 if (p->rtp) { 06092 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06093 fmt = ast_codec_pref_getsize(pref, codec); 06094 } 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 */ 06095 return; 06096 ast_build_string(m_buf, m_size, " %d", rtp_code); 06097 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06098 ast_rtp_lookup_mime_subtype(1, codec, 06099 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06100 sample_rate); 06101 if (codec == AST_FORMAT_G729A) { 06102 /* Indicate that we don't support VAD (G.729 annex B) */ 06103 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06104 } else if (codec == AST_FORMAT_G723_1) { 06105 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06106 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06107 } else if (codec == AST_FORMAT_ILBC) { 06108 /* Add information about us using only 20/30 ms packetization */ 06109 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06110 } 06111 06112 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06113 *min_packet_size = fmt.cur_ms; 06114 06115 /* Our first codec packetization processed cannot be less than zero */ 06116 if ((*min_packet_size) == 0 && fmt.cur_ms) 06117 *min_packet_size = fmt.cur_ms; 06118 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6046 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06047 { 06048 char tmp[256]; 06049 06050 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06051 add_header(req, "Content-Type", "application/dtmf-relay"); 06052 add_header_contentLength(req, strlen(tmp)); 06053 add_line(req, tmp); 06054 return 0; 06055 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5437 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.
05438 { 05439 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05440 05441 if (req->headers == SIP_MAX_HEADERS) { 05442 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05443 return -1; 05444 } 05445 05446 if (req->lines) { 05447 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05448 return -1; 05449 } 05450 05451 if (maxlen <= 0) { 05452 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05453 return -1; 05454 } 05455 05456 req->header[req->headers] = req->data + req->len; 05457 05458 if (compactheaders) 05459 var = find_alias(var, var); 05460 05461 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05462 req->len += strlen(req->header[req->headers]); 05463 req->headers++; 05464 if (req->headers < SIP_MAX_HEADERS) 05465 req->headers++; 05466 else 05467 ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n"); 05468 05469 return 0; 05470 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5473 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().
05474 { 05475 char clen[10]; 05476 05477 snprintf(clen, sizeof(clen), "%d", len); 05478 return add_header(req, "Content-Length", clen); 05479 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5482 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05483 { 05484 if (req->lines == SIP_MAX_LINES) { 05485 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05486 return -1; 05487 } 05488 if (!req->lines) { 05489 /* Add extra empty return */ 05490 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05491 req->len += strlen(req->data + req->len); 05492 } 05493 if (req->len >= sizeof(req->data) - 4) { 05494 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05495 return -1; 05496 } 05497 req->line[req->lines] = req->data + req->len; 05498 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05499 req->len += strlen(req->line[req->lines]); 05500 req->lines++; 05501 return 0; 05502 }
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 6254 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().
06257 { 06258 int rtp_code; 06259 06260 if (debug) 06261 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06262 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06263 return; 06264 06265 ast_build_string(m_buf, m_size, " %d", rtp_code); 06266 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06267 ast_rtp_lookup_mime_subtype(0, format, 0), 06268 sample_rate); 06269 if (format == AST_RTP_DTMF) 06270 /* Indicate we support DTMF and FLASH... */ 06271 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06272 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 15953 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().
15954 { 15955 char authcopy[256]; 15956 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 15957 char *stringp; 15958 struct sip_auth *a, *b, *auth; 15959 15960 if (ast_strlen_zero(configuration)) 15961 return authlist; 15962 15963 if (option_debug) 15964 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 15965 15966 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 15967 stringp = authcopy; 15968 15969 username = stringp; 15970 realm = strrchr(stringp, '@'); 15971 if (realm) 15972 *realm++ = '\0'; 15973 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 15974 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 15975 return authlist; 15976 } 15977 stringp = username; 15978 username = strsep(&stringp, ":"); 15979 if (username) { 15980 secret = strsep(&stringp, ":"); 15981 if (!secret) { 15982 stringp = username; 15983 md5secret = strsep(&stringp,"#"); 15984 } 15985 } 15986 if (!(auth = ast_calloc(1, sizeof(*auth)))) 15987 return authlist; 15988 15989 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 15990 ast_copy_string(auth->username, username, sizeof(auth->username)); 15991 if (secret) 15992 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 15993 if (md5secret) 15994 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 15995 15996 /* find the end of the list */ 15997 for (b = NULL, a = authlist; a ; b = a, a = a->next) 15998 ; 15999 if (b) 16000 b->next = auth; /* Add structure add end of list */ 16001 else 16002 authlist = auth; 16003 16004 if (option_verbose > 2) 16005 ast_verbose("Added authentication for realm %s\n", realm); 16006 16007 return authlist; 16008 16009 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5603 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05604 { 05605 char r[BUFSIZ*2], *p; 05606 int n, rem = sizeof(r); 05607 05608 if (!route) 05609 return; 05610 05611 p = r; 05612 for (;route ; route = route->next) { 05613 n = strlen(route->hop); 05614 if (rem < n+3) /* we need room for ",<route>" */ 05615 break; 05616 if (p != r) { /* add a separator after fist route */ 05617 *p++ = ','; 05618 --rem; 05619 } 05620 *p++ = '<'; 05621 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05622 p += n; 05623 *p++ = '>'; 05624 rem -= (n+2); 05625 } 05626 *p = '\0'; 05627 add_header(req, "Route", r); 05628 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6277 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, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06278 { 06279 int len = 0; 06280 int alreadysent = 0; 06281 06282 struct sockaddr_in sin; 06283 struct sockaddr_in vsin; 06284 struct sockaddr_in dest; 06285 struct sockaddr_in vdest = { 0, }; 06286 06287 /* SDP fields */ 06288 char *version = "v=0\r\n"; /* Protocol version */ 06289 char *subject = "s=session\r\n"; /* Subject of the session */ 06290 char owner[256]; /* Session owner/creator */ 06291 char connection[256]; /* Connection data */ 06292 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06293 char bandwidth[256] = ""; /* Max bitrate */ 06294 char *hold; 06295 char m_audio[256]; /* Media declaration line for audio */ 06296 char m_video[256]; /* Media declaration line for video */ 06297 char a_audio[1024]; /* Attributes for audio */ 06298 char a_video[1024]; /* Attributes for video */ 06299 char *m_audio_next = m_audio; 06300 char *m_video_next = m_video; 06301 size_t m_audio_left = sizeof(m_audio); 06302 size_t m_video_left = sizeof(m_video); 06303 char *a_audio_next = a_audio; 06304 char *a_video_next = a_video; 06305 size_t a_audio_left = sizeof(a_audio); 06306 size_t a_video_left = sizeof(a_video); 06307 06308 int x; 06309 int capability; 06310 int needvideo = FALSE; 06311 int debug = sip_debug_test_pvt(p); 06312 int min_audio_packet_size = 0; 06313 int min_video_packet_size = 0; 06314 06315 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06316 06317 if (!p->rtp) { 06318 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06319 return AST_FAILURE; 06320 } 06321 06322 /* Set RTP Session ID and version */ 06323 if (!p->sessionid) { 06324 p->sessionid = getpid(); 06325 p->sessionversion = p->sessionid; 06326 } else 06327 p->sessionversion++; 06328 06329 /* Get our addresses */ 06330 ast_rtp_get_us(p->rtp, &sin); 06331 if (p->vrtp) 06332 ast_rtp_get_us(p->vrtp, &vsin); 06333 06334 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06335 if (p->redirip.sin_addr.s_addr) { 06336 dest.sin_port = p->redirip.sin_port; 06337 dest.sin_addr = p->redirip.sin_addr; 06338 } else { 06339 dest.sin_addr = p->ourip; 06340 dest.sin_port = sin.sin_port; 06341 } 06342 06343 capability = p->jointcapability; 06344 06345 06346 if (option_debug > 1) { 06347 char codecbuf[BUFSIZ]; 06348 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"); 06349 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06350 } 06351 06352 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06353 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06354 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06355 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06356 } 06357 #endif 06358 06359 /* Check if we need video in this call */ 06360 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06361 if (p->vrtp) { 06362 needvideo = TRUE; 06363 if (option_debug > 1) 06364 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06365 } else if (option_debug > 1) 06366 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06367 } 06368 06369 06370 /* Ok, we need video. Let's add what we need for video and set codecs. 06371 Video is handled differently than audio since we can not transcode. */ 06372 if (needvideo) { 06373 /* Determine video destination */ 06374 if (p->vredirip.sin_addr.s_addr) { 06375 vdest.sin_addr = p->vredirip.sin_addr; 06376 vdest.sin_port = p->vredirip.sin_port; 06377 } else { 06378 vdest.sin_addr = p->ourip; 06379 vdest.sin_port = vsin.sin_port; 06380 } 06381 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06382 06383 /* Build max bitrate string */ 06384 if (p->maxcallbitrate) 06385 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06386 if (debug) 06387 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06388 } 06389 06390 if (debug) 06391 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06392 06393 /* Start building generic SDP headers */ 06394 06395 /* We break with the "recommendation" and send our IP, in order that our 06396 peer doesn't have to ast_gethostbyname() us */ 06397 06398 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06399 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06400 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06401 06402 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06403 hold = "a=recvonly\r\n"; 06404 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06405 hold = "a=inactive\r\n"; 06406 else 06407 hold = "a=sendrecv\r\n"; 06408 06409 /* Now, start adding audio codecs. These are added in this order: 06410 - First what was requested by the calling channel 06411 - Then preferences in order from sip.conf device config for this peer/user 06412 - Then other codecs in capabilities, including video 06413 */ 06414 06415 /* Prefer the audio codec we were requested to use, first, no matter what 06416 Note that p->prefcodec can include video codecs, so mask them out 06417 */ 06418 if (capability & p->prefcodec) { 06419 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06420 06421 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06422 &m_audio_next, &m_audio_left, 06423 &a_audio_next, &a_audio_left, 06424 debug, &min_audio_packet_size); 06425 alreadysent |= codec; 06426 } 06427 06428 /* Start by sending our preferred audio codecs */ 06429 for (x = 0; x < 32; x++) { 06430 int codec; 06431 06432 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06433 break; 06434 06435 if (!(capability & codec)) 06436 continue; 06437 06438 if (alreadysent & codec) 06439 continue; 06440 06441 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06442 &m_audio_next, &m_audio_left, 06443 &a_audio_next, &a_audio_left, 06444 debug, &min_audio_packet_size); 06445 alreadysent |= codec; 06446 } 06447 06448 /* Now send any other common audio and video codecs, and non-codec formats: */ 06449 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06450 if (!(capability & x)) /* Codec not requested */ 06451 continue; 06452 06453 if (alreadysent & x) /* Already added to SDP */ 06454 continue; 06455 06456 if (x <= AST_FORMAT_MAX_AUDIO) 06457 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06458 &m_audio_next, &m_audio_left, 06459 &a_audio_next, &a_audio_left, 06460 debug, &min_audio_packet_size); 06461 else 06462 add_codec_to_sdp(p, x, 90000, 06463 &m_video_next, &m_video_left, 06464 &a_video_next, &a_video_left, 06465 debug, &min_video_packet_size); 06466 } 06467 06468 /* Now add DTMF RFC2833 telephony-event as a codec */ 06469 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06470 if (!(p->jointnoncodeccapability & x)) 06471 continue; 06472 06473 add_noncodec_to_sdp(p, x, 8000, 06474 &m_audio_next, &m_audio_left, 06475 &a_audio_next, &a_audio_left, 06476 debug); 06477 } 06478 06479 if (option_debug > 2) 06480 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06481 06482 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06483 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06484 06485 if (min_audio_packet_size) 06486 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06487 06488 if (min_video_packet_size) 06489 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06490 06491 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06492 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06493 06494 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06495 if (needvideo) 06496 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06497 06498 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06499 if (needvideo) /* only if video response is appropriate */ 06500 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06501 06502 add_header(resp, "Content-Type", "application/sdp"); 06503 add_header_contentLength(resp, len); 06504 add_line(resp, version); 06505 add_line(resp, owner); 06506 add_line(resp, subject); 06507 add_line(resp, connection); 06508 if (needvideo) /* only if video response is appropriate */ 06509 add_line(resp, bandwidth); 06510 add_line(resp, stime); 06511 add_line(resp, m_audio); 06512 add_line(resp, a_audio); 06513 add_line(resp, hold); 06514 if (needvideo) { /* only if video response is appropriate */ 06515 add_line(resp, m_video); 06516 add_line(resp, a_video); 06517 add_line(resp, hold); /* Repeat hold for the video stream */ 06518 } 06519 06520 /* Update lastrtprx when we send our SDP */ 06521 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06522 06523 if (option_debug > 2) { 06524 char buf[BUFSIZ]; 06525 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06526 } 06527 06528 return AST_SUCCESS; 06529 }
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 15889 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.
15890 { 15891 struct domain *d; 15892 15893 if (ast_strlen_zero(domain)) { 15894 ast_log(LOG_WARNING, "Zero length domain.\n"); 15895 return 1; 15896 } 15897 15898 if (!(d = ast_calloc(1, sizeof(*d)))) 15899 return 0; 15900 15901 ast_copy_string(d->domain, domain, sizeof(d->domain)); 15902 15903 if (!ast_strlen_zero(context)) 15904 ast_copy_string(d->context, context, sizeof(d->context)); 15905 15906 d->mode = mode; 15907 15908 AST_LIST_LOCK(&domain_list); 15909 AST_LIST_INSERT_TAIL(&domain_list, d, list); 15910 AST_LIST_UNLOCK(&domain_list); 15911 15912 if (sipdebug) 15913 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 15914 15915 return 1; 15916 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6157 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().
06158 { 06159 int len = 0; 06160 int x = 0; 06161 struct sockaddr_in udptlsin; 06162 char v[256] = ""; 06163 char s[256] = ""; 06164 char o[256] = ""; 06165 char c[256] = ""; 06166 char t[256] = ""; 06167 char m_modem[256]; 06168 char a_modem[1024]; 06169 char *m_modem_next = m_modem; 06170 size_t m_modem_left = sizeof(m_modem); 06171 char *a_modem_next = a_modem; 06172 size_t a_modem_left = sizeof(a_modem); 06173 struct sockaddr_in udptldest = { 0, }; 06174 int debug; 06175 06176 debug = sip_debug_test_pvt(p); 06177 len = 0; 06178 if (!p->udptl) { 06179 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06180 return -1; 06181 } 06182 06183 if (!p->sessionid) { 06184 p->sessionid = getpid(); 06185 p->sessionversion = p->sessionid; 06186 } else 06187 p->sessionversion++; 06188 06189 /* Our T.38 end is */ 06190 ast_udptl_get_us(p->udptl, &udptlsin); 06191 06192 /* Determine T.38 UDPTL destination */ 06193 if (p->udptlredirip.sin_addr.s_addr) { 06194 udptldest.sin_port = p->udptlredirip.sin_port; 06195 udptldest.sin_addr = p->udptlredirip.sin_addr; 06196 } else { 06197 udptldest.sin_addr = p->ourip; 06198 udptldest.sin_port = udptlsin.sin_port; 06199 } 06200 06201 if (debug) 06202 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06203 06204 /* We break with the "recommendation" and send our IP, in order that our 06205 peer doesn't have to ast_gethostbyname() us */ 06206 06207 if (debug) { 06208 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06209 p->t38.capability, 06210 p->t38.peercapability, 06211 p->t38.jointcapability); 06212 } 06213 snprintf(v, sizeof(v), "v=0\r\n"); 06214 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06215 snprintf(s, sizeof(s), "s=session\r\n"); 06216 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06217 snprintf(t, sizeof(t), "t=0 0\r\n"); 06218 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06219 06220 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06221 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06222 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06223 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06224 if ((x = t38_get_rate(p->t38.jointcapability))) 06225 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06226 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06227 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06228 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06229 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06230 x = ast_udptl_get_local_max_datagram(p->udptl); 06231 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06232 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06233 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06234 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06235 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06236 add_header(resp, "Content-Type", "application/sdp"); 06237 add_header_contentLength(resp, len); 06238 add_line(resp, v); 06239 add_line(resp, o); 06240 add_line(resp, s); 06241 add_line(resp, c); 06242 add_line(resp, t); 06243 add_line(resp, m_modem); 06244 add_line(resp, a_modem); 06245 06246 /* Update lastrtprx when we send our SDP */ 06247 p->lastrtprx = p->lastrtptx = time(NULL); 06248 06249 return 0; 06250 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6035 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06036 { 06037 /* XXX Convert \n's to \r\n's XXX */ 06038 add_header(req, "Content-Type", "text/plain"); 06039 add_header_contentLength(req, strlen(text)); 06040 add_line(req, text); 06041 return 0; 06042 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6059 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06060 { 06061 const char *xml_is_a_huge_waste_of_space = 06062 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06063 " <media_control>\r\n" 06064 " <vc_primitive>\r\n" 06065 " <to_encoder>\r\n" 06066 " <picture_fast_update>\r\n" 06067 " </picture_fast_update>\r\n" 06068 " </to_encoder>\r\n" 06069 " </vc_primitive>\r\n" 06070 " </media_control>\r\n"; 06071 add_header(req, "Content-Type", "application/media_control+xml"); 06072 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06073 add_line(req, xml_is_a_huge_waste_of_space); 06074 return 0; 06075 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 5982 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().
05983 { 05984 char tmpdat[256]; 05985 struct tm tm; 05986 time_t t = time(NULL); 05987 05988 gmtime_r(&t, &tm); 05989 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 05990 add_header(req, "Date", tmpdat); 05991 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1864 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01865 { 01866 va_list ap; 01867 01868 if (!p) 01869 return; 01870 01871 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01872 && !recordhistory && !dumphistory) { 01873 return; 01874 } 01875 01876 va_start(ap, fmt); 01877 append_history_va(p, fmt, ap); 01878 va_end(ap); 01879 01880 return; 01881 }
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 1837 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().
01838 { 01839 char buf[80], *c = buf; /* max history length */ 01840 struct sip_history *hist; 01841 int l; 01842 01843 vsnprintf(buf, sizeof(buf), fmt, ap); 01844 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01845 l = strlen(buf) + 1; 01846 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01847 return; 01848 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01849 free(hist); 01850 return; 01851 } 01852 memcpy(hist->event, buf, l); 01853 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01854 struct sip_history *oldest; 01855 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01856 p->history_entries--; 01857 free(oldest); 01858 } 01859 AST_LIST_INSERT_TAIL(p->history, hist, list); 01860 p->history_entries++; 01861 }
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 12946 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
12947 { 12948 if (chan && chan->_state == AST_STATE_UP) { 12949 if (chan->generatordata) 12950 ast_deactivate_generator(chan); 12951 } 12952 }
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 1797 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().
01798 { 01799 struct sockaddr_in theirs, ours; 01800 01801 /* Get our local information */ 01802 ast_ouraddrfor(them, us); 01803 theirs.sin_addr = *them; 01804 ours.sin_addr = *us; 01805 01806 if (localaddr && externip.sin_addr.s_addr && 01807 (ast_apply_ha(localaddr, &theirs)) && 01808 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01809 if (externexpire && time(NULL) >= externexpire) { 01810 struct ast_hostent ahp; 01811 struct hostent *hp; 01812 01813 externexpire = time(NULL) + externrefresh; 01814 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01815 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01816 } else 01817 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01818 } 01819 *us = externip.sin_addr; 01820 if (option_debug) { 01821 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01822 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01823 } 01824 } else if (bindaddr.sin_addr.s_addr) 01825 *us = bindaddr.sin_addr; 01826 return AST_SUCCESS; 01827 }
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 12956 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, and option_debug.
12957 { 12958 int res = 0; 12959 struct ast_channel *peera = NULL, 12960 *peerb = NULL, 12961 *peerc = NULL, 12962 *peerd = NULL; 12963 12964 12965 /* We will try to connect the transferee with the target and hangup 12966 all channels to the transferer */ 12967 if (option_debug > 3) { 12968 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 12969 if (transferer->chan1) 12970 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 12971 else 12972 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 12973 if (target->chan1) 12974 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 12975 else 12976 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 12977 if (transferer->chan2) 12978 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 12979 else 12980 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 12981 if (target->chan2) 12982 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)"); 12983 else 12984 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 12985 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 12986 } 12987 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 12988 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 12989 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 12990 peerc = transferer->chan2; /* Asterisk to Transferee */ 12991 peerd = target->chan2; /* Asterisk to Target */ 12992 if (option_debug > 2) 12993 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 12994 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 12995 peera = target->chan1; /* Transferer to PBX -> target channel */ 12996 peerb = transferer->chan1; /* Transferer to IVR*/ 12997 peerc = target->chan2; /* Asterisk to Target */ 12998 peerd = transferer->chan2; /* Nothing */ 12999 if (option_debug > 2) 13000 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13001 } 13002 13003 if (peera && peerb && peerc && (peerb != peerc)) { 13004 ast_quiet_chan(peera); /* Stop generators */ 13005 ast_quiet_chan(peerb); 13006 ast_quiet_chan(peerc); 13007 if (peerd) 13008 ast_quiet_chan(peerd); 13009 13010 /* Fix CDRs so they're attached to the remaining channel */ 13011 if (peera->cdr && peerb->cdr) 13012 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 13013 else if (peera->cdr) 13014 peerb->cdr = peera->cdr; 13015 peera->cdr = NULL; 13016 13017 if (peerb->cdr && peerc->cdr) 13018 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 13019 else if (peerc->cdr) 13020 peerb->cdr = peerc->cdr; 13021 peerc->cdr = NULL; 13022 13023 if (option_debug > 3) 13024 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13025 if (ast_channel_masquerade(peerb, peerc)) { 13026 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13027 res = -1; 13028 } else 13029 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13030 return res; 13031 } else { 13032 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13033 if (transferer->chan1) 13034 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13035 if (target->chan1) 13036 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13037 return -2; 13038 } 13039 return 0; 13040 }
static int auto_congest | ( | void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2871 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.
02872 { 02873 struct sip_pvt *p = nothing; 02874 02875 ast_mutex_lock(&p->lock); 02876 p->initid = -1; 02877 if (p->owner) { 02878 /* XXX fails on possible deadlock */ 02879 if (!ast_channel_trylock(p->owner)) { 02880 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02881 append_history(p, "Cong", "Auto-congesting (timer)"); 02882 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02883 ast_channel_unlock(p->owner); 02884 } 02885 } 02886 ast_mutex_unlock(&p->lock); 02887 return 0; 02888 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4313 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().
04314 { 04315 char buf[33]; 04316 04317 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04318 04319 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04320 04321 }
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 4324 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04325 { 04326 char buf[33]; 04327 04328 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04329 04330 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04331 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6700 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().
06701 { 06702 /* Construct Contact: header */ 06703 if (ourport != STANDARD_SIP_PORT) 06704 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); 06705 else 06706 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06707 }
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 16219 of file chan_sip.c.
References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, format, 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_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
16220 { 16221 struct sip_peer *peer = NULL; 16222 struct ast_ha *oldha = NULL; 16223 int obproxyfound=0; 16224 int found=0; 16225 int firstpass=1; 16226 int format=0; /* Ama flags */ 16227 time_t regseconds = 0; 16228 char *varname = NULL, *varval = NULL; 16229 struct ast_variable *tmpvar = NULL; 16230 struct ast_flags peerflags[2] = {{(0)}}; 16231 struct ast_flags mask[2] = {{(0)}}; 16232 16233 16234 if (!realtime) 16235 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16236 /* We also use a case-sensitive comparison (unlike find_peer) so 16237 that case changes made to the peer name will be properly handled 16238 during reload 16239 */ 16240 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16241 16242 if (peer) { 16243 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16244 found = 1; 16245 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16246 firstpass = 0; 16247 } else { 16248 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16249 return NULL; 16250 16251 if (realtime) 16252 rpeerobjs++; 16253 else 16254 speerobjs++; 16255 ASTOBJ_INIT(peer); 16256 } 16257 /* Note that our peer HAS had its reference count incrased */ 16258 if (firstpass) { 16259 peer->lastmsgssent = -1; 16260 oldha = peer->ha; 16261 peer->ha = NULL; 16262 set_peer_defaults(peer); /* Set peer defaults */ 16263 } 16264 if (!found && name) 16265 ast_copy_string(peer->name, name, sizeof(peer->name)); 16266 16267 /* If we have channel variables, remove them (reload) */ 16268 if (peer->chanvars) { 16269 ast_variables_destroy(peer->chanvars); 16270 peer->chanvars = NULL; 16271 /* XXX should unregister ? */ 16272 } 16273 16274 /* If we have realm authentication information, remove them (reload) */ 16275 clear_realm_authentication(peer->auth); 16276 peer->auth = NULL; 16277 16278 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16279 if (handle_common_options(&peerflags[0], &mask[0], v)) 16280 continue; 16281 if (realtime && !strcasecmp(v->name, "regseconds")) { 16282 ast_get_time_t(v->value, ®seconds, 0, NULL); 16283 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16284 inet_aton(v->value, &(peer->addr.sin_addr)); 16285 } else if (realtime && !strcasecmp(v->name, "name")) 16286 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16287 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16288 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16289 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16290 } else if (!strcasecmp(v->name, "secret")) 16291 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16292 else if (!strcasecmp(v->name, "md5secret")) 16293 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16294 else if (!strcasecmp(v->name, "auth")) 16295 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16296 else if (!strcasecmp(v->name, "callerid")) { 16297 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16298 } else if (!strcasecmp(v->name, "fullname")) { 16299 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16300 } else if (!strcasecmp(v->name, "cid_number")) { 16301 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16302 } else if (!strcasecmp(v->name, "context")) { 16303 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16304 } else if (!strcasecmp(v->name, "subscribecontext")) { 16305 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16306 } else if (!strcasecmp(v->name, "fromdomain")) { 16307 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16308 } else if (!strcasecmp(v->name, "usereqphone")) { 16309 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16310 } else if (!strcasecmp(v->name, "fromuser")) { 16311 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16312 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16313 if (!strcasecmp(v->value, "dynamic")) { 16314 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16315 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16316 } else { 16317 /* They'll register with us */ 16318 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16319 /* Initialize stuff if this is a new peer, or if it used to be 16320 * non-dynamic before the reload. */ 16321 memset(&peer->addr.sin_addr, 0, 4); 16322 if (peer->addr.sin_port) { 16323 /* If we've already got a port, make it the default rather than absolute */ 16324 peer->defaddr.sin_port = peer->addr.sin_port; 16325 peer->addr.sin_port = 0; 16326 } 16327 } 16328 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16329 } 16330 } else { 16331 /* Non-dynamic. Make sure we become that way if we're not */ 16332 if (peer->expire > -1) 16333 ast_sched_del(sched, peer->expire); 16334 peer->expire = -1; 16335 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16336 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16337 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16338 ASTOBJ_UNREF(peer, sip_destroy_peer); 16339 return NULL; 16340 } 16341 } 16342 if (!strcasecmp(v->name, "outboundproxy")) 16343 obproxyfound=1; 16344 else { 16345 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16346 if (!peer->addr.sin_port) 16347 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16348 } 16349 } 16350 } else if (!strcasecmp(v->name, "defaultip")) { 16351 if (ast_get_ip(&peer->defaddr, v->value)) { 16352 ASTOBJ_UNREF(peer, sip_destroy_peer); 16353 return NULL; 16354 } 16355 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16356 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16357 } else if (!strcasecmp(v->name, "port")) { 16358 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16359 peer->defaddr.sin_port = htons(atoi(v->value)); 16360 else 16361 peer->addr.sin_port = htons(atoi(v->value)); 16362 } else if (!strcasecmp(v->name, "callingpres")) { 16363 peer->callingpres = ast_parse_caller_presentation(v->value); 16364 if (peer->callingpres == -1) 16365 peer->callingpres = atoi(v->value); 16366 } else if (!strcasecmp(v->name, "username")) { 16367 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16368 } else if (!strcasecmp(v->name, "language")) { 16369 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16370 } else if (!strcasecmp(v->name, "regexten")) { 16371 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16372 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16373 peer->call_limit = atoi(v->value); 16374 if (peer->call_limit < 0) 16375 peer->call_limit = 0; 16376 } else if (!strcasecmp(v->name, "amaflags")) { 16377 format = ast_cdr_amaflags2int(v->value); 16378 if (format < 0) { 16379 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16380 } else { 16381 peer->amaflags = format; 16382 } 16383 } else if (!strcasecmp(v->name, "accountcode")) { 16384 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16385 } else if (!strcasecmp(v->name, "mohinterpret") 16386 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16387 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16388 } else if (!strcasecmp(v->name, "mohsuggest")) { 16389 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16390 } else if (!strcasecmp(v->name, "mailbox")) { 16391 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16392 } else if (!strcasecmp(v->name, "subscribemwi")) { 16393 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16394 } else if (!strcasecmp(v->name, "vmexten")) { 16395 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16396 } else if (!strcasecmp(v->name, "callgroup")) { 16397 peer->callgroup = ast_get_group(v->value); 16398 } else if (!strcasecmp(v->name, "allowtransfer")) { 16399 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16400 } else if (!strcasecmp(v->name, "pickupgroup")) { 16401 peer->pickupgroup = ast_get_group(v->value); 16402 } else if (!strcasecmp(v->name, "allow")) { 16403 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16404 } else if (!strcasecmp(v->name, "disallow")) { 16405 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16406 } else if (!strcasecmp(v->name, "autoframing")) { 16407 peer->autoframing = ast_true(v->value); 16408 } else if (!strcasecmp(v->name, "rtptimeout")) { 16409 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16410 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16411 peer->rtptimeout = global_rtptimeout; 16412 } 16413 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16414 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16415 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16416 peer->rtpholdtimeout = global_rtpholdtimeout; 16417 } 16418 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16419 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16420 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16421 peer->rtpkeepalive = global_rtpkeepalive; 16422 } 16423 } else if (!strcasecmp(v->name, "setvar")) { 16424 /* Set peer channel variable */ 16425 varname = ast_strdupa(v->value); 16426 if ((varval = strchr(varname, '='))) { 16427 *varval++ = '\0'; 16428 if ((tmpvar = ast_variable_new(varname, varval))) { 16429 tmpvar->next = peer->chanvars; 16430 peer->chanvars = tmpvar; 16431 } 16432 } 16433 } else if (!strcasecmp(v->name, "qualify")) { 16434 if (!strcasecmp(v->value, "no")) { 16435 peer->maxms = 0; 16436 } else if (!strcasecmp(v->value, "yes")) { 16437 peer->maxms = DEFAULT_MAXMS; 16438 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16439 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); 16440 peer->maxms = 0; 16441 } 16442 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16443 peer->maxcallbitrate = atoi(v->value); 16444 if (peer->maxcallbitrate < 0) 16445 peer->maxcallbitrate = default_maxcallbitrate; 16446 } 16447 } 16448 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16449 time_t nowtime = time(NULL); 16450 16451 if ((nowtime - regseconds) > 0) { 16452 destroy_association(peer); 16453 memset(&peer->addr, 0, sizeof(peer->addr)); 16454 if (option_debug) 16455 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16456 } 16457 } 16458 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16459 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16460 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16461 global_allowsubscribe = TRUE; /* No global ban any more */ 16462 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16463 reg_source_db(peer); 16464 ASTOBJ_UNMARK(peer); 16465 ast_free_ha(oldha); 16466 return peer; 16467 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11335 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::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().
11336 { 11337 char a1[256]; 11338 char a2[256]; 11339 char a1_hash[256]; 11340 char a2_hash[256]; 11341 char resp[256]; 11342 char resp_hash[256]; 11343 char uri[256]; 11344 char cnonce[80]; 11345 const char *username; 11346 const char *secret; 11347 const char *md5secret; 11348 struct sip_auth *auth = NULL; /* Realm authentication */ 11349 11350 if (!ast_strlen_zero(p->domain)) 11351 ast_copy_string(uri, p->domain, sizeof(uri)); 11352 else if (!ast_strlen_zero(p->uri)) 11353 ast_copy_string(uri, p->uri, sizeof(uri)); 11354 else 11355 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11356 11357 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11358 11359 /* Check if we have separate auth credentials */ 11360 if ((auth = find_realm_authentication(authl, p->realm))) { 11361 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11362 auth->username, p->peername, p->username); 11363 username = auth->username; 11364 secret = auth->secret; 11365 md5secret = auth->md5secret; 11366 if (sipdebug) 11367 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11368 } else { 11369 /* No authentication, use peer or register= config */ 11370 username = p->authname; 11371 secret = p->peersecret; 11372 md5secret = p->peermd5secret; 11373 } 11374 if (ast_strlen_zero(username)) /* We have no authentication */ 11375 return -1; 11376 11377 /* Calculate SIP digest response */ 11378 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11379 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11380 if (!ast_strlen_zero(md5secret)) 11381 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11382 else 11383 ast_md5_hash(a1_hash,a1); 11384 ast_md5_hash(a2_hash,a2); 11385 11386 p->noncecount++; 11387 if (!ast_strlen_zero(p->qop)) 11388 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11389 else 11390 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11391 ast_md5_hash(resp_hash, resp); 11392 /* XXX We hard code our qop to "auth" for now. XXX */ 11393 if (!ast_strlen_zero(p->qop)) 11394 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount); 11395 else 11396 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque); 11397 11398 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11399 11400 return 0; 11401 }
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 8079 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().
08080 { 08081 struct sip_route *thishop, *head, *tail; 08082 int start = 0; 08083 int len; 08084 const char *rr, *contact, *c; 08085 08086 /* Once a persistant route is set, don't fool with it */ 08087 if (p->route && p->route_persistant) { 08088 if (option_debug) 08089 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08090 return; 08091 } 08092 08093 if (p->route) { 08094 free_old_route(p->route); 08095 p->route = NULL; 08096 } 08097 08098 p->route_persistant = backwards; 08099 08100 /* Build a tailq, then assign it to p->route when done. 08101 * If backwards, we add entries from the head so they end up 08102 * in reverse order. However, we do need to maintain a correct 08103 * tail pointer because the contact is always at the end. 08104 */ 08105 head = NULL; 08106 tail = head; 08107 /* 1st we pass through all the hops in any Record-Route headers */ 08108 for (;;) { 08109 /* Each Record-Route header */ 08110 rr = __get_header(req, "Record-Route", &start); 08111 if (*rr == '\0') 08112 break; 08113 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08114 ++rr; 08115 len = strcspn(rr, ">") + 1; 08116 /* Make a struct route */ 08117 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08118 /* ast_calloc is not needed because all fields are initialized in this block */ 08119 ast_copy_string(thishop->hop, rr, len); 08120 if (option_debug > 1) 08121 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08122 /* Link in */ 08123 if (backwards) { 08124 /* Link in at head so they end up in reverse order */ 08125 thishop->next = head; 08126 head = thishop; 08127 /* If this was the first then it'll be the tail */ 08128 if (!tail) 08129 tail = thishop; 08130 } else { 08131 thishop->next = NULL; 08132 /* Link in at the end */ 08133 if (tail) 08134 tail->next = thishop; 08135 else 08136 head = thishop; 08137 tail = thishop; 08138 } 08139 } 08140 } 08141 } 08142 08143 /* Only append the contact if we are dealing with a strict router */ 08144 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08145 /* 2nd append the Contact: if there is one */ 08146 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08147 contact = get_header(req, "Contact"); 08148 if (!ast_strlen_zero(contact)) { 08149 if (option_debug > 1) 08150 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08151 /* Look for <: delimited address */ 08152 c = strchr(contact, '<'); 08153 if (c) { 08154 /* Take to > */ 08155 ++c; 08156 len = strcspn(c, ">") + 1; 08157 } else { 08158 /* No <> - just take the lot */ 08159 c = contact; 08160 len = strlen(contact) + 1; 08161 } 08162 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08163 /* ast_calloc is not needed because all fields are initialized in this block */ 08164 ast_copy_string(thishop->hop, c, len); 08165 thishop->next = NULL; 08166 /* Goes at the end */ 08167 if (tail) 08168 tail->next = thishop; 08169 else 08170 head = thishop; 08171 } 08172 } 08173 } 08174 08175 /* Store as new route */ 08176 p->route = head; 08177 08178 /* For debugging dump what we ended up with */ 08179 if (sip_debug_test_pvt(p)) 08180 list_route(p->route); 08181 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6710 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().
06711 { 06712 int send_pres_tags = TRUE; 06713 const char *privacy=NULL; 06714 const char *screen=NULL; 06715 char buf[256]; 06716 const char *clid = default_callerid; 06717 const char *clin = NULL; 06718 const char *fromdomain; 06719 06720 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06721 return; 06722 06723 if (p->owner && p->owner->cid.cid_num) 06724 clid = p->owner->cid.cid_num; 06725 if (p->owner && p->owner->cid.cid_name) 06726 clin = p->owner->cid.cid_name; 06727 if (ast_strlen_zero(clin)) 06728 clin = clid; 06729 06730 switch (p->callingpres) { 06731 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06732 privacy = "off"; 06733 screen = "no"; 06734 break; 06735 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06736 privacy = "off"; 06737 screen = "yes"; 06738 break; 06739 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06740 privacy = "off"; 06741 screen = "no"; 06742 break; 06743 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06744 privacy = "off"; 06745 screen = "yes"; 06746 break; 06747 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06748 privacy = "full"; 06749 screen = "no"; 06750 break; 06751 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06752 privacy = "full"; 06753 screen = "yes"; 06754 break; 06755 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06756 privacy = "full"; 06757 screen = "no"; 06758 break; 06759 case AST_PRES_PROHIB_NETWORK_NUMBER: 06760 privacy = "full"; 06761 screen = "yes"; 06762 break; 06763 case AST_PRES_NUMBER_NOT_AVAILABLE: 06764 send_pres_tags = FALSE; 06765 break; 06766 default: 06767 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06768 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06769 privacy = "full"; 06770 else 06771 privacy = "off"; 06772 screen = "no"; 06773 break; 06774 } 06775 06776 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06777 06778 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06779 if (send_pres_tags) 06780 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06781 ast_string_field_set(p, rpid, buf); 06782 06783 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06784 S_OR(p->fromuser, clid), 06785 fromdomain, p->tag); 06786 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 16040 of file chan_sip.c.
References sip_user::allowtransfer, ast_append_ha(), ast_calloc, ast_copy_flags, ast_strdupa, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::chanvars, default_prefs, format, global_flags, sip_user::ha, handle_common_options(), ast_variable::name, ast_variable::next, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, and ast_variable::value.
16041 { 16042 struct sip_user *user; 16043 int format; 16044 struct ast_ha *oldha = NULL; 16045 char *varname = NULL, *varval = NULL; 16046 struct ast_variable *tmpvar = NULL; 16047 struct ast_flags userflags[2] = {{(0)}}; 16048 struct ast_flags mask[2] = {{(0)}}; 16049 16050 16051 if (!(user = ast_calloc(1, sizeof(*user)))) 16052 return NULL; 16053 16054 suserobjs++; 16055 ASTOBJ_INIT(user); 16056 ast_copy_string(user->name, name, sizeof(user->name)); 16057 oldha = user->ha; 16058 user->ha = NULL; 16059 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16060 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16061 user->capability = global_capability; 16062 user->allowtransfer = global_allowtransfer; 16063 user->maxcallbitrate = default_maxcallbitrate; 16064 user->autoframing = global_autoframing; 16065 user->prefs = default_prefs; 16066 /* set default context */ 16067 strcpy(user->context, default_context); 16068 strcpy(user->language, default_language); 16069 strcpy(user->mohinterpret, default_mohinterpret); 16070 strcpy(user->mohsuggest, default_mohsuggest); 16071 for (; v; v = v->next) { 16072 if (handle_common_options(&userflags[0], &mask[0], v)) 16073 continue; 16074 16075 if (!strcasecmp(v->name, "context")) { 16076 ast_copy_string(user->context, v->value, sizeof(user->context)); 16077 } else if (!strcasecmp(v->name, "subscribecontext")) { 16078 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16079 } else if (!strcasecmp(v->name, "setvar")) { 16080 varname = ast_strdupa(v->value); 16081 if ((varval = strchr(varname,'='))) { 16082 *varval++ = '\0'; 16083 if ((tmpvar = ast_variable_new(varname, varval))) { 16084 tmpvar->next = user->chanvars; 16085 user->chanvars = tmpvar; 16086 } 16087 } 16088 } else if (!strcasecmp(v->name, "permit") || 16089 !strcasecmp(v->name, "deny")) { 16090 user->ha = ast_append_ha(v->name, v->value, user->ha); 16091 } else if (!strcasecmp(v->name, "allowtransfer")) { 16092 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16093 } else if (!strcasecmp(v->name, "secret")) { 16094 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16095 } else if (!strcasecmp(v->name, "md5secret")) { 16096 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16097 } else if (!strcasecmp(v->name, "callerid")) { 16098 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16099 } else if (!strcasecmp(v->name, "fullname")) { 16100 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16101 } else if (!strcasecmp(v->name, "cid_number")) { 16102 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16103 } else if (!strcasecmp(v->name, "callgroup")) { 16104 user->callgroup = ast_get_group(v->value); 16105 } else if (!strcasecmp(v->name, "pickupgroup")) { 16106 user->pickupgroup = ast_get_group(v->value); 16107 } else if (!strcasecmp(v->name, "language")) { 16108 ast_copy_string(user->language, v->value, sizeof(user->language)); 16109 } else if (!strcasecmp(v->name, "mohinterpret") 16110 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16111 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16112 } else if (!strcasecmp(v->name, "mohsuggest")) { 16113 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16114 } else if (!strcasecmp(v->name, "accountcode")) { 16115 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16116 } else if (!strcasecmp(v->name, "call-limit")) { 16117 user->call_limit = atoi(v->value); 16118 if (user->call_limit < 0) 16119 user->call_limit = 0; 16120 } else if (!strcasecmp(v->name, "amaflags")) { 16121 format = ast_cdr_amaflags2int(v->value); 16122 if (format < 0) { 16123 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16124 } else { 16125 user->amaflags = format; 16126 } 16127 } else if (!strcasecmp(v->name, "allow")) { 16128 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16129 } else if (!strcasecmp(v->name, "disallow")) { 16130 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16131 } else if (!strcasecmp(v->name, "autoframing")) { 16132 user->autoframing = ast_true(v->value); 16133 } else if (!strcasecmp(v->name, "callingpres")) { 16134 user->callingpres = ast_parse_caller_presentation(v->value); 16135 if (user->callingpres == -1) 16136 user->callingpres = atoi(v->value); 16137 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16138 user->maxcallbitrate = atoi(v->value); 16139 if (user->maxcallbitrate < 0) 16140 user->maxcallbitrate = default_maxcallbitrate; 16141 } 16142 /* We can't just report unknown options here because this may be a 16143 * type=friend entry. All user options are valid for a peer, but not 16144 * the other way around. */ 16145 } 16146 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16147 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16148 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16149 global_allowsubscribe = TRUE; /* No global ban any more */ 16150 ast_free_ha(oldha); 16151 return user; 16152 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1781 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
01782 { 01783 /* Work around buggy UNIDEN UIP200 firmware */ 01784 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01785 01786 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01787 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01788 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01789 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8371 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe().
08372 { 08373 struct sip_pvt *p = data; 08374 08375 ast_mutex_lock(&p->lock); 08376 08377 switch(state) { 08378 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08379 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08380 if (p->autokillid > -1) 08381 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08382 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08383 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); 08384 p->stateid = -1; 08385 p->subscribed = NONE; 08386 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08387 break; 08388 default: /* Tell user */ 08389 p->laststate = state; 08390 break; 08391 } 08392 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08393 transmit_state_notify(p, state, 1, FALSE); 08394 08395 if (option_verbose > 1) 08396 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08397 08398 ast_mutex_unlock(&p->lock); 08399 08400 return 0; 08401 }
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 4854 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, sip_request::data, EVENT_FLAG_CALL, 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().
04855 { 04856 if (global_notifyhold) 04857 sip_peer_hold(dialog, holdstate); 04858 if (global_callevents) 04859 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04860 "Channel: %s\r\n" 04861 "Uniqueid: %s\r\n", 04862 dialog->owner->name, 04863 dialog->owner->uniqueid); 04864 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04865 if (!holdstate) { /* Put off remote hold */ 04866 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04867 return; 04868 } 04869 /* No address for RTP, we're on hold */ 04870 04871 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 04872 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 04873 else if (sendonly == 2) /* Inactive stream */ 04874 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 04875 else 04876 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 04877 return; 04878 }
static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const char * | username, | |||
const char * | secret, | |||
const char * | md5secret, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
int | ignore | |||
) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
Definition at line 8189 of file chan_sip.c.
References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), AUTH_CHALLENGE_SENT, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), key(), keys, LOG_NOTICE, s, S_OR, sip_methods, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08192 { 08193 const char *response = "407 Proxy Authentication Required"; 08194 const char *reqheader = "Proxy-Authorization"; 08195 const char *respheader = "Proxy-Authenticate"; 08196 const char *authtoken; 08197 char a1_hash[256]; 08198 char resp_hash[256]=""; 08199 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08200 char *c; 08201 int wrongnonce = FALSE; 08202 int good_response; 08203 const char *usednonce = p->randdata; 08204 08205 /* table of recognised keywords, and their value in the digest */ 08206 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08207 struct x { 08208 const char *key; 08209 const char *s; 08210 } *i, keys[] = { 08211 [K_RESP] = { "response=", "" }, 08212 [K_URI] = { "uri=", "" }, 08213 [K_USER] = { "username=", "" }, 08214 [K_NONCE] = { "nonce=", "" }, 08215 [K_LAST] = { NULL, NULL} 08216 }; 08217 08218 /* Always OK if no secret */ 08219 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08220 return AUTH_SUCCESSFUL; 08221 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08222 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08223 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08224 different circumstances! What a surprise. */ 08225 response = "401 Unauthorized"; 08226 reqheader = "Authorization"; 08227 respheader = "WWW-Authenticate"; 08228 } 08229 authtoken = get_header(req, reqheader); 08230 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08231 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08232 information */ 08233 if (!reliable) { 08234 /* Resend message if this was NOT a reliable delivery. Otherwise the 08235 retransmission should get it */ 08236 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08237 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08238 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08239 } 08240 return AUTH_CHALLENGE_SENT; 08241 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08242 /* We have no auth, so issue challenge and request authentication */ 08243 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08244 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08245 /* Schedule auto destroy in 32 seconds */ 08246 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08247 return AUTH_CHALLENGE_SENT; 08248 } 08249 08250 /* --- We have auth, so check it */ 08251 08252 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08253 an example in the spec of just what it is you're doing a hash on. */ 08254 08255 08256 /* Make a copy of the response and parse it */ 08257 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08258 c = tmp; 08259 08260 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08261 for (i = keys; i->key != NULL; i++) { 08262 const char *separator = ","; /* default */ 08263 08264 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08265 continue; 08266 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08267 c += strlen(i->key); 08268 if (*c == '"') { /* in quotes. Skip first and look for last */ 08269 c++; 08270 separator = "\""; 08271 } 08272 i->s = c; 08273 strsep(&c, separator); 08274 break; 08275 } 08276 if (i->key == NULL) /* not found, jump after space or comma */ 08277 strsep(&c, " ,"); 08278 } 08279 08280 /* Verify that digest username matches the username we auth as */ 08281 if (strcmp(username, keys[K_USER].s)) { 08282 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08283 username, keys[K_USER].s); 08284 /* Oops, we're trying something here */ 08285 return AUTH_USERNAME_MISMATCH; 08286 } 08287 08288 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08289 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08290 wrongnonce = TRUE; 08291 usednonce = keys[K_NONCE].s; 08292 } 08293 08294 if (!ast_strlen_zero(md5secret)) 08295 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08296 else { 08297 char a1[256]; 08298 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08299 ast_md5_hash(a1_hash, a1); 08300 } 08301 08302 /* compute the expected response to compare with what we received */ 08303 { 08304 char a2[256]; 08305 char a2_hash[256]; 08306 char resp[256]; 08307 08308 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08309 S_OR(keys[K_URI].s, uri)); 08310 ast_md5_hash(a2_hash, a2); 08311 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08312 ast_md5_hash(resp_hash, resp); 08313 } 08314 08315 good_response = keys[K_RESP].s && 08316 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08317 if (wrongnonce) { 08318 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08319 if (good_response) { 08320 if (sipdebug) 08321 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08322 /* We got working auth token, based on stale nonce . */ 08323 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08324 } else { 08325 /* Everything was wrong, so give the device one more try with a new challenge */ 08326 if (sipdebug) 08327 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08328 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08329 } 08330 08331 /* Schedule auto destroy in 32 seconds */ 08332 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08333 return AUTH_CHALLENGE_SENT; 08334 } 08335 if (good_response) { 08336 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08337 return AUTH_SUCCESSFUL; 08338 } 08339 08340 /* Ok, we have a bad username/secret pair */ 08341 /* Challenge again, and again, and again */ 08342 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08343 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08344 08345 return AUTH_CHALLENGE_SENT; 08346 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 11796 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
11797 { 11798 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 11799 /* if we can't BYE, then this is really a pending CANCEL */ 11800 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 11801 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 11802 /* Actually don't destroy us yet, wait for the 487 on our original 11803 INVITE, but do set an autodestruct just in case we never get it. */ 11804 else 11805 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 11806 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 11807 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11808 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 11809 if (option_debug) 11810 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 11811 /* Didn't get to reinvite yet, so do it now */ 11812 transmit_reinvite_with_sdp(p); 11813 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 11814 } 11815 }
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 15919 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
15920 { 15921 struct domain *d; 15922 int result = 0; 15923 15924 AST_LIST_LOCK(&domain_list); 15925 AST_LIST_TRAVERSE(&domain_list, d, list) { 15926 if (strcasecmp(d->domain, domain)) 15927 continue; 15928 15929 if (len && !ast_strlen_zero(d->context)) 15930 ast_copy_string(context, d->context, len); 15931 15932 result = 1; 15933 break; 15934 } 15935 AST_LIST_UNLOCK(&domain_list); 15936 15937 return result; 15938 }
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 9445 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09446 { 09447 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09448 }
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 9124 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().
09127 { 09128 struct sip_user *user = NULL; 09129 struct sip_peer *peer; 09130 char from[256], *c; 09131 char *of; 09132 char rpid_num[50]; 09133 const char *rpid; 09134 enum check_auth_result res = AUTH_SUCCESSFUL; 09135 char *t; 09136 char calleridname[50]; 09137 int debug=sip_debug_test_addr(sin); 09138 struct ast_variable *tmpvar = NULL, *v = NULL; 09139 char *uri2 = ast_strdupa(uri); 09140 09141 /* Terminate URI */ 09142 t = uri2; 09143 while (*t && *t > 32 && *t != ';') 09144 t++; 09145 *t = '\0'; 09146 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09147 if (pedanticsipchecking) 09148 ast_uri_decode(from); 09149 /* XXX here tries to map the username for invite things */ 09150 memset(calleridname, 0, sizeof(calleridname)); 09151 get_calleridname(from, calleridname, sizeof(calleridname)); 09152 if (calleridname[0]) 09153 ast_string_field_set(p, cid_name, calleridname); 09154 09155 rpid = get_header(req, "Remote-Party-ID"); 09156 memset(rpid_num, 0, sizeof(rpid_num)); 09157 if (!ast_strlen_zero(rpid)) 09158 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09159 09160 of = get_in_brackets(from); 09161 if (ast_strlen_zero(p->exten)) { 09162 t = uri2; 09163 if (!strncasecmp(t, "sip:", 4)) 09164 t+= 4; 09165 ast_string_field_set(p, exten, t); 09166 t = strchr(p->exten, '@'); 09167 if (t) 09168 *t = '\0'; 09169 if (ast_strlen_zero(p->our_contact)) 09170 build_contact(p); 09171 } 09172 /* save the URI part of the From header */ 09173 ast_string_field_set(p, from, of); 09174 if (strncasecmp(of, "sip:", 4)) { 09175 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09176 } else 09177 of += 4; 09178 /* Get just the username part */ 09179 if ((c = strchr(of, '@'))) { 09180 char *tmp; 09181 *c = '\0'; 09182 if ((c = strchr(of, ':'))) 09183 *c = '\0'; 09184 tmp = ast_strdupa(of); 09185 /* We need to be able to handle auth-headers looking like 09186 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09187 */ 09188 tmp = strsep(&tmp, ";"); 09189 if (ast_is_shrinkable_phonenumber(tmp)) 09190 ast_shrink_phone_number(tmp); 09191 ast_string_field_set(p, cid_num, tmp); 09192 } 09193 if (ast_strlen_zero(of)) 09194 return AUTH_SUCCESSFUL; 09195 09196 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09197 user = find_user(of, 1); 09198 09199 /* Find user based on user name in the from header */ 09200 if (user && ast_apply_ha(user->ha, sin)) { 09201 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09202 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09203 /* copy channel vars */ 09204 for (v = user->chanvars ; v ; v = v->next) { 09205 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09206 tmpvar->next = p->chanvars; 09207 p->chanvars = tmpvar; 09208 } 09209 } 09210 p->prefs = user->prefs; 09211 /* Set Frame packetization */ 09212 if (p->rtp) { 09213 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09214 p->autoframing = user->autoframing; 09215 } 09216 /* replace callerid if rpid found, and not restricted */ 09217 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09218 char *tmp; 09219 if (*calleridname) 09220 ast_string_field_set(p, cid_name, calleridname); 09221 tmp = ast_strdupa(rpid_num); 09222 if (ast_is_shrinkable_phonenumber(tmp)) 09223 ast_shrink_phone_number(tmp); 09224 ast_string_field_set(p, cid_num, tmp); 09225 } 09226 09227 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09228 09229 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09230 sip_cancel_destroy(p); 09231 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09232 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09233 /* Copy SIP extensions profile from INVITE */ 09234 if (p->sipoptions) 09235 user->sipoptions = p->sipoptions; 09236 09237 /* If we have a call limit, set flag */ 09238 if (user->call_limit) 09239 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09240 if (!ast_strlen_zero(user->context)) 09241 ast_string_field_set(p, context, user->context); 09242 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09243 char *tmp = ast_strdupa(user->cid_num); 09244 if (ast_is_shrinkable_phonenumber(tmp)) 09245 ast_shrink_phone_number(tmp); 09246 ast_string_field_set(p, cid_num, tmp); 09247 } 09248 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09249 ast_string_field_set(p, cid_name, user->cid_name); 09250 ast_string_field_set(p, username, user->name); 09251 ast_string_field_set(p, peername, user->name); 09252 ast_string_field_set(p, peersecret, user->secret); 09253 ast_string_field_set(p, peermd5secret, user->md5secret); 09254 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09255 ast_string_field_set(p, accountcode, user->accountcode); 09256 ast_string_field_set(p, language, user->language); 09257 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09258 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09259 p->allowtransfer = user->allowtransfer; 09260 p->amaflags = user->amaflags; 09261 p->callgroup = user->callgroup; 09262 p->pickupgroup = user->pickupgroup; 09263 if (user->callingpres) /* User callingpres setting will override RPID header */ 09264 p->callingpres = user->callingpres; 09265 09266 /* Set default codec settings for this call */ 09267 p->capability = user->capability; /* User codec choice */ 09268 p->jointcapability = user->capability; /* Our codecs */ 09269 if (p->peercapability) /* AND with peer's codecs */ 09270 p->jointcapability &= p->peercapability; 09271 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09272 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09273 p->noncodeccapability |= AST_RTP_DTMF; 09274 else 09275 p->noncodeccapability &= ~AST_RTP_DTMF; 09276 p->jointnoncodeccapability = p->noncodeccapability; 09277 if (p->t38.peercapability) 09278 p->t38.jointcapability &= p->t38.peercapability; 09279 p->maxcallbitrate = user->maxcallbitrate; 09280 /* If we do not support video, remove video from call structure */ 09281 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09282 ast_rtp_destroy(p->vrtp); 09283 p->vrtp = NULL; 09284 } 09285 } 09286 if (user && debug) 09287 ast_verbose("Found user '%s'\n", user->name); 09288 } else { 09289 if (user) { 09290 if (!authpeer && debug) 09291 ast_verbose("Found user '%s', but fails host access\n", user->name); 09292 ASTOBJ_UNREF(user,sip_destroy_user); 09293 } 09294 user = NULL; 09295 } 09296 09297 if (!user) { 09298 /* If we didn't find a user match, check for peers */ 09299 if (sipmethod == SIP_SUBSCRIBE) 09300 /* For subscribes, match on peer name only */ 09301 peer = find_peer(of, NULL, 1); 09302 else 09303 /* Look for peer based on the IP address we received data from */ 09304 /* If peer is registered from this IP address or have this as a default 09305 IP address, this call is from the peer 09306 */ 09307 peer = find_peer(NULL, &p->recv, 1); 09308 09309 if (peer) { 09310 /* Set Frame packetization */ 09311 if (p->rtp) { 09312 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09313 p->autoframing = peer->autoframing; 09314 } 09315 if (debug) 09316 ast_verbose("Found peer '%s'\n", peer->name); 09317 09318 /* Take the peer */ 09319 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09320 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09321 09322 /* Copy SIP extensions profile to peer */ 09323 if (p->sipoptions) 09324 peer->sipoptions = p->sipoptions; 09325 09326 /* replace callerid if rpid found, and not restricted */ 09327 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09328 char *tmp = ast_strdupa(rpid_num); 09329 if (*calleridname) 09330 ast_string_field_set(p, cid_name, calleridname); 09331 if (ast_is_shrinkable_phonenumber(tmp)) 09332 ast_shrink_phone_number(tmp); 09333 ast_string_field_set(p, cid_num, tmp); 09334 } 09335 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09336 09337 ast_string_field_set(p, peersecret, peer->secret); 09338 ast_string_field_set(p, peermd5secret, peer->md5secret); 09339 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09340 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09341 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09342 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09343 p->callingpres = peer->callingpres; 09344 if (peer->maxms && peer->lastms) 09345 p->timer_t1 = peer->lastms; 09346 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09347 /* Pretend there is no required authentication */ 09348 ast_string_field_free(p, peersecret); 09349 ast_string_field_free(p, peermd5secret); 09350 } 09351 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09352 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09353 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09354 /* If we have a call limit, set flag */ 09355 if (peer->call_limit) 09356 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09357 ast_string_field_set(p, peername, peer->name); 09358 ast_string_field_set(p, authname, peer->name); 09359 09360 /* copy channel vars */ 09361 for (v = peer->chanvars ; v ; v = v->next) { 09362 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09363 tmpvar->next = p->chanvars; 09364 p->chanvars = tmpvar; 09365 } 09366 } 09367 if (authpeer) { 09368 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09369 } 09370 09371 if (!ast_strlen_zero(peer->username)) { 09372 ast_string_field_set(p, username, peer->username); 09373 /* Use the default username for authentication on outbound calls */ 09374 /* XXX this takes the name from the caller... can we override ? */ 09375 ast_string_field_set(p, authname, peer->username); 09376 } 09377 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09378 char *tmp = ast_strdupa(peer->cid_num); 09379 if (ast_is_shrinkable_phonenumber(tmp)) 09380 ast_shrink_phone_number(tmp); 09381 ast_string_field_set(p, cid_num, tmp); 09382 } 09383 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09384 ast_string_field_set(p, cid_name, peer->cid_name); 09385 ast_string_field_set(p, fullcontact, peer->fullcontact); 09386 if (!ast_strlen_zero(peer->context)) 09387 ast_string_field_set(p, context, peer->context); 09388 ast_string_field_set(p, peersecret, peer->secret); 09389 ast_string_field_set(p, peermd5secret, peer->md5secret); 09390 ast_string_field_set(p, language, peer->language); 09391 ast_string_field_set(p, accountcode, peer->accountcode); 09392 p->amaflags = peer->amaflags; 09393 p->callgroup = peer->callgroup; 09394 p->pickupgroup = peer->pickupgroup; 09395 p->capability = peer->capability; 09396 p->prefs = peer->prefs; 09397 p->jointcapability = peer->capability; 09398 if (p->peercapability) 09399 p->jointcapability &= p->peercapability; 09400 p->maxcallbitrate = peer->maxcallbitrate; 09401 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09402 ast_rtp_destroy(p->vrtp); 09403 p->vrtp = NULL; 09404 } 09405 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09406 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09407 p->noncodeccapability |= AST_RTP_DTMF; 09408 else 09409 p->noncodeccapability &= ~AST_RTP_DTMF; 09410 p->jointnoncodeccapability = p->noncodeccapability; 09411 if (p->t38.peercapability) 09412 p->t38.jointcapability &= p->t38.peercapability; 09413 } 09414 ASTOBJ_UNREF(peer, sip_destroy_peer); 09415 } else { 09416 if (debug) 09417 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09418 09419 /* do we allow guests? */ 09420 if (!global_allowguest) { 09421 if (global_alwaysauthreject) 09422 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09423 else 09424 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09425 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09426 char *tmp = ast_strdupa(rpid_num); 09427 if (*calleridname) 09428 ast_string_field_set(p, cid_name, calleridname); 09429 if (ast_is_shrinkable_phonenumber(tmp)) 09430 ast_shrink_phone_number(tmp); 09431 ast_string_field_set(p, cid_num, tmp); 09432 } 09433 } 09434 09435 } 09436 09437 if (user) 09438 ASTOBJ_UNREF(user, sip_destroy_user); 09439 return res; 09440 }
static void check_via | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 8992 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(), and handle_request_subscribe().
08993 { 08994 char via[256]; 08995 char *c, *pt; 08996 struct hostent *hp; 08997 struct ast_hostent ahp; 08998 08999 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09000 09001 /* Work on the leftmost value of the topmost Via header */ 09002 c = strchr(via, ','); 09003 if (c) 09004 *c = '\0'; 09005 09006 /* Check for rport */ 09007 c = strstr(via, ";rport"); 09008 if (c && (c[6] != '=')) /* rport query, not answer */ 09009 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09010 09011 c = strchr(via, ';'); 09012 if (c) 09013 *c = '\0'; 09014 09015 c = strchr(via, ' '); 09016 if (c) { 09017 *c = '\0'; 09018 c = ast_skip_blanks(c+1); 09019 if (strcasecmp(via, "SIP/2.0/UDP")) { 09020 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09021 return; 09022 } 09023 pt = strchr(c, ':'); 09024 if (pt) 09025 *pt++ = '\0'; /* remember port pointer */ 09026 hp = ast_gethostbyname(c, &ahp); 09027 if (!hp) { 09028 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09029 return; 09030 } 09031 memset(&p->sa, 0, sizeof(p->sa)); 09032 p->sa.sin_family = AF_INET; 09033 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09034 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09035 09036 if (sip_debug_test_pvt(p)) { 09037 const struct sockaddr_in *dst = sip_real_dst(p); 09038 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09039 } 09040 } 09041 }
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 9887 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
09888 { 09889 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 09890 09891 while ((oldcontext = strsep(&old, "&"))) { 09892 stalecontext = '\0'; 09893 ast_copy_string(newlist, new, sizeof(newlist)); 09894 stringp = newlist; 09895 while ((newcontext = strsep(&stringp, "&"))) { 09896 if (strcmp(newcontext, oldcontext) == 0) { 09897 /* This is not the context you're looking for */ 09898 stalecontext = '\0'; 09899 break; 09900 } else if (strcmp(newcontext, oldcontext)) { 09901 stalecontext = oldcontext; 09902 } 09903 09904 } 09905 if (stalecontext) 09906 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 09907 } 09908 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 16012 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), sip_destroy_peer(), sip_do_reload(), and unload_module().
16013 { 16014 struct sip_auth *a = authlist; 16015 struct sip_auth *b; 16016 16017 while (a) { 16018 b = a; 16019 a = a->next; 16020 free(b); 16021 } 16022 16023 return 1; 16024 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 15941 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by sip_do_reload(), and unload_module().
15942 { 15943 struct domain *d; 15944 15945 AST_LIST_LOCK(&domain_list); 15946 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 15947 free(d); 15948 AST_LIST_UNLOCK(&domain_list); 15949 }
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 10700 of file chan_sip.c.
References complete_sip_peer().
10701 { 10702 if (pos == 3) 10703 return complete_sip_peer(word, state, 0); 10704 10705 return NULL; 10706 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10674 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, and result.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10675 { 10676 char *result = NULL; 10677 int wordlen = strlen(word); 10678 int which = 0; 10679 10680 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10681 /* locking of the object is not required because only the name and flags are being compared */ 10682 if (!strncasecmp(word, iterator->name, wordlen) && 10683 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10684 ++which > state) 10685 result = ast_strdup(iterator->name); 10686 } while(0) ); 10687 return result; 10688 }
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 10768 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10769 { 10770 if (pos == 4) 10771 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10772 return NULL; 10773 }
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 10776 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10777 { 10778 if (pos == 4) 10779 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10780 10781 return NULL; 10782 }
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 10691 of file chan_sip.c.
References complete_sip_peer().
10692 { 10693 if (pos == 3) 10694 return complete_sip_peer(word, state, 0); 10695 10696 return NULL; 10697 }
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 10729 of file chan_sip.c.
References complete_sip_user().
10730 { 10731 if (pos == 3) 10732 return complete_sip_user(word, state, 0); 10733 10734 return NULL; 10735 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10709 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10710 { 10711 char *result = NULL; 10712 int wordlen = strlen(word); 10713 int which = 0; 10714 10715 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10716 /* locking of the object is not required because only the name and flags are being compared */ 10717 if (!strncasecmp(word, iterator->name, wordlen)) { 10718 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10719 continue; 10720 if (++which > state) { 10721 result = ast_strdup(iterator->name); 10722 } 10723 } 10724 } while(0) ); 10725 return result; 10726 }
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 10655 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10656 { 10657 int which=0; 10658 struct sip_pvt *cur; 10659 char *c = NULL; 10660 int wordlen = strlen(word); 10661 10662 ast_mutex_lock(&iflock); 10663 for (cur = iflist; cur; cur = cur->next) { 10664 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10665 c = ast_strdup(cur->callid); 10666 break; 10667 } 10668 } 10669 ast_mutex_unlock(&iflock); 10670 return c; 10671 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10738 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10739 { 10740 char *c = NULL; 10741 10742 if (pos == 2) { 10743 int which = 0; 10744 char *cat = NULL; 10745 int wordlen = strlen(word); 10746 10747 /* do completion for notify type */ 10748 10749 if (!notify_types) 10750 return NULL; 10751 10752 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10753 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10754 c = ast_strdup(cat); 10755 break; 10756 } 10757 } 10758 return c; 10759 } 10760 10761 if (pos > 2) 10762 return complete_sip_peer(word, state, 0); 10763 10764 return NULL; 10765 }
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 5516 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05517 { 05518 int start = 0; 05519 int copied = 0; 05520 for (;;) { 05521 const char *tmp = __get_header(orig, field, &start); 05522 05523 if (ast_strlen_zero(tmp)) 05524 break; 05525 /* Add what we're responding to */ 05526 add_header(req, field, tmp); 05527 copied++; 05528 } 05529 return copied ? 0 : -1; 05530 }
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 5505 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05506 { 05507 const char *tmp = get_header(orig, field); 05508 05509 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05510 return add_header(req, field, tmp); 05511 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05512 return -1; 05513 }
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 6553 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().
06554 { 06555 long offset; 06556 int x; 06557 offset = ((void *)dst) - ((void *)src); 06558 /* First copy stuff */ 06559 memcpy(dst, src, sizeof(*dst)); 06560 /* Now fix pointer arithmetic */ 06561 for (x=0; x < src->headers; x++) 06562 dst->header[x] += offset; 06563 for (x=0; x < src->lines; x++) 06564 dst->line[x] += offset; 06565 dst->rlPart1 += offset; 06566 dst->rlPart2 += offset; 06567 }
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 5538 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().
05539 { 05540 int copied = 0; 05541 int start = 0; 05542 05543 for (;;) { 05544 char new[256]; 05545 const char *oh = __get_header(orig, field, &start); 05546 05547 if (ast_strlen_zero(oh)) 05548 break; 05549 05550 if (!copied) { /* Only check for empty rport in topmost via header */ 05551 char leftmost[256], *others, *rport; 05552 05553 /* Only work on leftmost value */ 05554 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05555 others = strchr(leftmost, ','); 05556 if (others) 05557 *others++ = '\0'; 05558 05559 /* Find ;rport; (empty request) */ 05560 rport = strstr(leftmost, ";rport"); 05561 if (rport && *(rport+6) == '=') 05562 rport = NULL; /* We already have a parameter to rport */ 05563 05564 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05565 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05566 /* We need to add received port - rport */ 05567 char *end; 05568 05569 rport = strstr(leftmost, ";rport"); 05570 05571 if (rport) { 05572 end = strchr(rport + 1, ';'); 05573 if (end) 05574 memmove(rport, end, strlen(end) + 1); 05575 else 05576 *rport = '\0'; 05577 } 05578 05579 /* Add rport to first VIA header if requested */ 05580 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05581 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05582 ntohs(p->recv.sin_port), 05583 others ? "," : "", others ? others : ""); 05584 } else { 05585 /* We should *always* add a received to the topmost via */ 05586 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05587 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05588 others ? "," : "", others ? others : ""); 05589 } 05590 oh = new; /* the header to copy */ 05591 } /* else add the following via headers untouched */ 05592 add_header(req, field, oh); 05593 copied++; 05594 } 05595 if (!copied) { 05596 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05597 return -1; 05598 } 05599 return 0; 05600 }
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 2821 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.
02822 { 02823 struct hostent *hp; 02824 struct ast_hostent ahp; 02825 struct sip_peer *p; 02826 char *port; 02827 int portno; 02828 char host[MAXHOSTNAMELEN], *hostn; 02829 char peer[256]; 02830 02831 ast_copy_string(peer, opeer, sizeof(peer)); 02832 port = strchr(peer, ':'); 02833 if (port) 02834 *port++ = '\0'; 02835 dialog->sa.sin_family = AF_INET; 02836 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02837 p = find_peer(peer, NULL, 1); 02838 02839 if (p) { 02840 int res = create_addr_from_peer(dialog, p); 02841 ASTOBJ_UNREF(p, sip_destroy_peer); 02842 return res; 02843 } 02844 hostn = peer; 02845 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02846 if (srvlookup) { 02847 char service[MAXHOSTNAMELEN]; 02848 int tportno; 02849 int ret; 02850 02851 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02852 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02853 if (ret > 0) { 02854 hostn = host; 02855 portno = tportno; 02856 } 02857 } 02858 hp = ast_gethostbyname(hostn, &ahp); 02859 if (!hp) { 02860 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02861 return -1; 02862 } 02863 ast_string_field_set(dialog, tohost, peer); 02864 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02865 dialog->sa.sin_port = htons(portno); 02866 dialog->recv = dialog->sa; 02867 return 0; 02868 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2713 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02714 { 02715 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02716 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02717 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02718 dialog->recv = dialog->sa; 02719 } else 02720 return -1; 02721 02722 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02723 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02724 dialog->capability = peer->capability; 02725 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02726 ast_rtp_destroy(dialog->vrtp); 02727 dialog->vrtp = NULL; 02728 } 02729 dialog->prefs = peer->prefs; 02730 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02731 dialog->t38.capability = global_t38_capability; 02732 if (dialog->udptl) { 02733 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02734 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02735 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02736 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02737 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02738 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02739 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02740 if (option_debug > 1) 02741 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02742 } 02743 dialog->t38.jointcapability = dialog->t38.capability; 02744 } else if (dialog->udptl) { 02745 ast_udptl_destroy(dialog->udptl); 02746 dialog->udptl = NULL; 02747 } 02748 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02749 02750 if (dialog->rtp) { 02751 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02752 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02753 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02754 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02755 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02756 /* Set Frame packetization */ 02757 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02758 dialog->autoframing = peer->autoframing; 02759 } 02760 if (dialog->vrtp) { 02761 ast_rtp_setdtmf(dialog->vrtp, 0); 02762 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02763 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02764 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02765 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02766 } 02767 02768 ast_string_field_set(dialog, peername, peer->name); 02769 ast_string_field_set(dialog, authname, peer->username); 02770 ast_string_field_set(dialog, username, peer->username); 02771 ast_string_field_set(dialog, peersecret, peer->secret); 02772 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02773 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02774 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02775 ast_string_field_set(dialog, tohost, peer->tohost); 02776 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02777 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02778 char *tmpcall; 02779 char *c; 02780 tmpcall = ast_strdupa(dialog->callid); 02781 c = strchr(tmpcall, '@'); 02782 if (c) { 02783 *c = '\0'; 02784 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02785 } 02786 } 02787 if (ast_strlen_zero(dialog->tohost)) 02788 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02789 if (!ast_strlen_zero(peer->fromdomain)) 02790 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02791 if (!ast_strlen_zero(peer->fromuser)) 02792 ast_string_field_set(dialog, fromuser, peer->fromuser); 02793 if (!ast_strlen_zero(peer->language)) 02794 ast_string_field_set(dialog, language, peer->language); 02795 dialog->maxtime = peer->maxms; 02796 dialog->callgroup = peer->callgroup; 02797 dialog->pickupgroup = peer->pickupgroup; 02798 dialog->allowtransfer = peer->allowtransfer; 02799 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02800 /* Minimum is settable or default to 100 ms */ 02801 if (peer->maxms && peer->lastms) 02802 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02803 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02804 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02805 dialog->noncodeccapability |= AST_RTP_DTMF; 02806 else 02807 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02808 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02809 ast_string_field_set(dialog, context, peer->context); 02810 dialog->rtptimeout = peer->rtptimeout; 02811 if (peer->call_limit) 02812 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02813 dialog->maxcallbitrate = peer->maxcallbitrate; 02814 02815 return 0; 02816 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7714 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().
07715 { 07716 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07717 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07718 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07719 else 07720 ast_db_del("SIP/Registry", peer->name); 07721 } 07722 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6597 of file chan_sip.c.
References ast_log(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06598 { 06599 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06600 06601 if (!*e) 06602 return -1; 06603 req->rlPart1 = e; /* method or protocol */ 06604 e = ast_skip_nonblanks(e); 06605 if (*e) 06606 *e++ = '\0'; 06607 /* Get URI or status code */ 06608 e = ast_skip_blanks(e); 06609 if ( !*e ) 06610 return -1; 06611 ast_trim_blanks(e); 06612 06613 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06614 if (strlen(e) < 3) /* status code is 3 digits */ 06615 return -1; 06616 req->rlPart2 = e; 06617 } else { /* We have a request */ 06618 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06619 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06620 e++; 06621 if (!*e) 06622 return -1; 06623 } 06624 req->rlPart2 = e; /* URI */ 06625 e = ast_skip_nonblanks(e); 06626 if (*e) 06627 *e++ = '\0'; 06628 e = ast_skip_blanks(e); 06629 if (strcasecmp(e, "SIP/2.0") ) { 06630 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06631 return -1; 06632 } 06633 } 06634 return 1; 06635 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15263 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_bridged(), 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(), 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(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
15264 { 15265 int res; 15266 struct sip_pvt *sip; 15267 struct sip_peer *peer = NULL; 15268 time_t t; 15269 int fastrestart = FALSE; 15270 int lastpeernum = -1; 15271 int curpeernum; 15272 int reloading; 15273 15274 /* Add an I/O event to our SIP UDP socket */ 15275 if (sipsock > -1) 15276 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15277 15278 /* From here on out, we die whenever asked */ 15279 for(;;) { 15280 /* Check for a reload request */ 15281 ast_mutex_lock(&sip_reload_lock); 15282 reloading = sip_reloading; 15283 sip_reloading = FALSE; 15284 ast_mutex_unlock(&sip_reload_lock); 15285 if (reloading) { 15286 if (option_verbose > 0) 15287 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15288 sip_do_reload(sip_reloadreason); 15289 15290 /* Change the I/O fd of our UDP socket */ 15291 if (sipsock > -1) { 15292 if (sipsock_read_id) 15293 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15294 else 15295 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15296 } 15297 } 15298 /* Check for interfaces needing to be killed */ 15299 ast_mutex_lock(&iflock); 15300 restartsearch: 15301 t = time(NULL); 15302 /* don't scan the interface list if it hasn't been a reasonable period 15303 of time since the last time we did it (when MWI is being sent, we can 15304 get back to this point every millisecond or less) 15305 */ 15306 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15307 ast_mutex_lock(&sip->lock); 15308 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15309 if (sip->rtp && sip->owner && 15310 (sip->owner->_state == AST_STATE_UP) && 15311 !sip->redirip.sin_addr.s_addr && 15312 sip->t38.state != T38_ENABLED) { 15313 if (sip->lastrtptx && 15314 ast_rtp_get_rtpkeepalive(sip->rtp) && 15315 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15316 /* Need to send an empty RTP packet */ 15317 sip->lastrtptx = time(NULL); 15318 ast_rtp_sendcng(sip->rtp, 0); 15319 } 15320 if (sip->lastrtprx && 15321 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15322 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15323 /* Might be a timeout now -- see if we're on hold */ 15324 struct sockaddr_in sin; 15325 ast_rtp_get_peer(sip->rtp, &sin); 15326 if (sin.sin_addr.s_addr || 15327 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15328 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15329 /* Needs a hangup */ 15330 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15331 while (sip->owner && ast_channel_trylock(sip->owner)) { 15332 ast_mutex_unlock(&sip->lock); 15333 usleep(1); 15334 ast_mutex_lock(&sip->lock); 15335 } 15336 if (sip->owner) { 15337 if (!(ast_rtp_get_bridged(sip->rtp))) { 15338 ast_log(LOG_NOTICE, 15339 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15340 sip->owner->name, 15341 (long) (t - sip->lastrtprx)); 15342 /* Issue a softhangup */ 15343 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15344 } else 15345 ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx)); 15346 ast_channel_unlock(sip->owner); 15347 /* forget the timeouts for this call, since a hangup 15348 has already been requested and we don't want to 15349 repeatedly request hangups 15350 */ 15351 ast_rtp_set_rtptimeout(sip->rtp, 0); 15352 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15353 if (sip->vrtp) { 15354 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15355 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15356 } 15357 } 15358 } 15359 } 15360 } 15361 } 15362 /* If we have sessions that needs to be destroyed, do it now */ 15363 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15364 !sip->owner) { 15365 ast_mutex_unlock(&sip->lock); 15366 __sip_destroy(sip, 1); 15367 goto restartsearch; 15368 } 15369 ast_mutex_unlock(&sip->lock); 15370 } 15371 ast_mutex_unlock(&iflock); 15372 15373 pthread_testcancel(); 15374 /* Wait for sched or io */ 15375 res = ast_sched_wait(sched); 15376 if ((res < 0) || (res > 1000)) 15377 res = 1000; 15378 /* If we might need to send more mailboxes, don't wait long at all.*/ 15379 if (fastrestart) 15380 res = 1; 15381 res = ast_io_wait(io, res); 15382 if (option_debug && res > 20) 15383 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15384 ast_mutex_lock(&monlock); 15385 if (res >= 0) { 15386 res = ast_sched_runq(sched); 15387 if (option_debug && res >= 20) 15388 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15389 } 15390 15391 /* Send MWI notifications to peers - static and cached realtime peers */ 15392 t = time(NULL); 15393 fastrestart = FALSE; 15394 curpeernum = 0; 15395 peer = NULL; 15396 /* Find next peer that needs mwi */ 15397 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15398 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15399 fastrestart = TRUE; 15400 lastpeernum = curpeernum; 15401 peer = ASTOBJ_REF(iterator); 15402 }; 15403 curpeernum++; 15404 } while (0) 15405 ); 15406 /* Send MWI to the peer */ 15407 if (peer) { 15408 ASTOBJ_WRLOCK(peer); 15409 sip_send_mwi_to_peer(peer); 15410 ASTOBJ_UNLOCK(peer); 15411 ASTOBJ_UNREF(peer,sip_destroy_peer); 15412 } else { 15413 /* Reset where we come from */ 15414 lastpeernum = -1; 15415 } 15416 ast_mutex_unlock(&monlock); 15417 } 15418 /* Never reached */ 15419 return NULL; 15420 15421 }
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 11236 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().
11237 { 11238 char digest[1024]; 11239 11240 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11241 return -2; 11242 11243 p->authtries++; 11244 if (option_debug > 1) 11245 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11246 memset(digest, 0, sizeof(digest)); 11247 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11248 /* No way to authenticate */ 11249 return -1; 11250 } 11251 /* Now we have a reply digest */ 11252 p->options->auth = digest; 11253 p->options->authheader = respheader; 11254 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11255 }
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 11215 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().
11216 { 11217 char digest[1024]; 11218 p->authtries++; 11219 memset(digest,0,sizeof(digest)); 11220 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11221 /* There's nothing to use for authentication */ 11222 /* No digest challenge in request */ 11223 if (sip_debug_test_pvt(p) && p->registry) 11224 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11225 /* No old challenge */ 11226 return -1; 11227 } 11228 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11229 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11230 if (sip_debug_test_pvt(p) && p->registry) 11231 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11232 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11233 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2689 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().
02690 { 02691 const char *mode = natflags ? "On" : "Off"; 02692 02693 if (p->rtp) { 02694 if (option_debug) 02695 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02696 ast_rtp_setnat(p->rtp, natflags); 02697 } 02698 if (p->vrtp) { 02699 if (option_debug) 02700 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02701 ast_rtp_setnat(p->vrtp, natflags); 02702 } 02703 if (p->udptl) { 02704 if (option_debug) 02705 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02706 ast_udptl_setnat(p->udptl, natflags); 02707 } 02708 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15242 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.
15243 { 15244 time_t t = time(NULL); 15245 15246 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15247 !peer->mwipvt) { /* We don't have a subscription */ 15248 peer->lastmsgcheck = t; /* Reset timer */ 15249 return FALSE; 15250 } 15251 15252 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15253 return TRUE; 15254 15255 return FALSE; 15256 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10076 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10077 { 10078 switch (mode) { 10079 case SIP_DOMAIN_AUTO: 10080 return "[Automatic]"; 10081 case SIP_DOMAIN_CONFIG: 10082 return "[Configured]"; 10083 } 10084 10085 return ""; 10086 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 9856 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().
09857 { 09858 switch (mode) { 09859 case SIP_DTMF_RFC2833: 09860 return "rfc2833"; 09861 case SIP_DTMF_INFO: 09862 return "info"; 09863 case SIP_DTMF_INBAND: 09864 return "inband"; 09865 case SIP_DTMF_AUTO: 09866 return "auto"; 09867 } 09868 return "<error>"; 09869 }
static int expire_register | ( | void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7725 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
07726 { 07727 struct sip_peer *peer = data; 07728 07729 if (!peer) /* Hmmm. We have no peer. Weird. */ 07730 return 0; 07731 07732 memset(&peer->addr, 0, sizeof(peer->addr)); 07733 07734 destroy_association(peer); /* remove registration data from storage */ 07735 07736 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07737 register_peer_exten(peer, FALSE); /* Remove regexten */ 07738 peer->expire = -1; 07739 ast_device_state_changed("SIP/%s", peer->name); 07740 07741 /* Do we need to release this peer from memory? 07742 Only for realtime peers and autocreated peers 07743 */ 07744 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07745 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07746 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07747 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07748 } 07749 07750 return 0; 07751 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6687 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and strsep().
Referenced by handle_request(), and handle_request_invite().
06688 { 06689 char stripped[BUFSIZ]; 06690 char *c; 06691 06692 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06693 c = get_in_brackets(stripped); 06694 c = strsep(&c, ";"); /* trim ; and beyond */ 06695 if (!ast_strlen_zero(c)) 06696 ast_string_field_set(p, uri, c); 06697 }
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 4107 of file chan_sip.c.
References aliases.
04108 { 04109 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04110 static const struct cfalias { 04111 char * const fullname; 04112 char * const shortname; 04113 } aliases[] = { 04114 { "Content-Type", "c" }, 04115 { "Content-Encoding", "e" }, 04116 { "From", "f" }, 04117 { "Call-ID", "i" }, 04118 { "Contact", "m" }, 04119 { "Content-Length", "l" }, 04120 { "Subject", "s" }, 04121 { "To", "t" }, 04122 { "Supported", "k" }, 04123 { "Refer-To", "r" }, 04124 { "Referred-By", "b" }, 04125 { "Allow-Events", "u" }, 04126 { "Event", "o" }, 04127 { "Via", "v" }, 04128 { "Accept-Contact", "a" }, 04129 { "Reject-Contact", "j" }, 04130 { "Request-Disposition", "d" }, 04131 { "Session-Expires", "x" }, 04132 { "Identity", "y" }, 04133 { "Identity-Info", "n" }, 04134 }; 04135 int x; 04136 04137 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04138 if (!strcasecmp(aliases[x].fullname, name)) 04139 return aliases[x].shortname; 04140 04141 return _default; 04142 }
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 4466 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), FALSE, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.
Referenced by sipsock_read().
04467 { 04468 struct sip_pvt *p = NULL; 04469 char *tag = ""; /* note, tag is never NULL */ 04470 char totag[128]; 04471 char fromtag[128]; 04472 const char *callid = get_header(req, "Call-ID"); 04473 const char *from = get_header(req, "From"); 04474 const char *to = get_header(req, "To"); 04475 const char *cseq = get_header(req, "Cseq"); 04476 04477 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04478 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04479 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04480 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04481 return NULL; /* Invalid packet */ 04482 04483 if (pedanticsipchecking) { 04484 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04485 we need more to identify a branch - so we have to check branch, from 04486 and to tags to identify a call leg. 04487 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04488 in sip.conf 04489 */ 04490 if (gettag(req, "To", totag, sizeof(totag))) 04491 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04492 gettag(req, "From", fromtag, sizeof(fromtag)); 04493 04494 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04495 04496 if (option_debug > 4 ) 04497 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); 04498 } 04499 04500 ast_mutex_lock(&iflock); 04501 for (p = iflist; p; p = p->next) { 04502 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04503 int found = FALSE; 04504 if (ast_strlen_zero(p->callid)) 04505 continue; 04506 if (req->method == SIP_REGISTER) 04507 found = (!strcmp(p->callid, callid)); 04508 else 04509 found = (!strcmp(p->callid, callid) && 04510 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04511 04512 if (option_debug > 4) 04513 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); 04514 04515 /* If we get a new request within an existing to-tag - check the to tag as well */ 04516 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04517 if (p->tag[0] == '\0' && totag[0]) { 04518 /* We have no to tag, but they have. Wrong dialog */ 04519 found = FALSE; 04520 } else if (totag[0]) { /* Both have tags, compare them */ 04521 if (strcmp(totag, p->tag)) { 04522 found = FALSE; /* This is not our packet */ 04523 } 04524 } 04525 if (!found && option_debug > 4) 04526 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); 04527 } 04528 04529 04530 if (found) { 04531 /* Found the call */ 04532 ast_mutex_unlock(&iflock); 04533 ast_mutex_lock(&p->lock); 04534 return p; 04535 } 04536 } 04537 ast_mutex_unlock(&iflock); 04538 04539 /* See if the method is capable of creating a dialog */ 04540 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04541 if (intended_method == SIP_REFER) { 04542 /* We do support REFER, but not outside of a dialog yet */ 04543 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04544 } else if (intended_method == SIP_NOTIFY) { 04545 /* We do not support out-of-dialog NOTIFY either, 04546 like voicemail notification, so cancel that early */ 04547 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04548 } else { 04549 /* Ok, time to create a new SIP dialog object, a pvt */ 04550 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04551 /* Ok, we've created a dialog, let's go and process it */ 04552 ast_mutex_lock(&p->lock); 04553 } else { 04554 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04555 getting a dialog from sip_alloc. 04556 04557 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04558 send an error message. 04559 04560 Sorry, we apologize for the inconvienience 04561 */ 04562 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04563 if (option_debug > 3) 04564 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04565 } 04566 } 04567 return p; 04568 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04569 /* A method we do not support, let's take it on the volley */ 04570 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04571 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04572 /* This is a request outside of a dialog that we don't know about 04573 ...never reply to an ACK! 04574 */ 04575 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04576 } 04577 /* We do not respond to responses for dialogs that we don't know about, we just drop 04578 the session quickly */ 04579 04580 return p; 04581 }
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 2279 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02280 { 02281 char last_char = '\0'; 02282 const char *s; 02283 for (s = start; *s && s != lim; last_char = *s++) { 02284 if (*s == '"' && last_char != '\\') 02285 break; 02286 } 02287 return s; 02288 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [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 2601 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02602 { 02603 struct sip_peer *p = NULL; 02604 02605 if (peer) 02606 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02607 else 02608 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02609 02610 if (!p && realtime) 02611 p = realtime_peer(peer, sin); 02612 02613 return p; 02614 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 16027 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
16028 { 16029 struct sip_auth *a; 16030 16031 for (a = authlist; a; a = a->next) { 16032 if (!strcasecmp(a->realm, realm)) 16033 break; 16034 } 16035 16036 return a; 16037 }
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 4787 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
04788 { 04789 const char *content_type; 04790 const char *search; 04791 char *boundary; 04792 unsigned int x; 04793 int boundaryisquoted = FALSE; 04794 04795 content_type = get_header(req, "Content-Type"); 04796 04797 /* if the body contains only SDP, this is easy */ 04798 if (!strcasecmp(content_type, "application/sdp")) { 04799 req->sdp_start = 0; 04800 req->sdp_end = req->lines; 04801 return req->lines ? 1 : 0; 04802 } 04803 04804 /* if it's not multipart/mixed, there cannot be an SDP */ 04805 if (strncasecmp(content_type, "multipart/mixed", 15)) 04806 return 0; 04807 04808 /* if there is no boundary marker, it's invalid */ 04809 if (!(search = strcasestr(content_type, ";boundary="))) 04810 return 0; 04811 04812 search += 10; 04813 if (ast_strlen_zero(search)) 04814 return 0; 04815 04816 /* If the boundary is quoted with ", remove quote */ 04817 if (*search == '\"') { 04818 search++; 04819 boundaryisquoted = TRUE; 04820 } 04821 04822 /* make a duplicate of the string, with two extra characters 04823 at the beginning */ 04824 boundary = ast_strdupa(search - 2); 04825 boundary[0] = boundary[1] = '-'; 04826 04827 /* Remove final quote */ 04828 if (boundaryisquoted) 04829 boundary[strlen(boundary) - 1] = '\0'; 04830 04831 /* search for the boundary marker, but stop when there are not enough 04832 lines left for it, the Content-Type header and at least one line of 04833 body */ 04834 for (x = 0; x < (req->lines - 2); x++) { 04835 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 04836 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 04837 x += 2; 04838 req->sdp_start = x; 04839 04840 /* search for the end of the body part */ 04841 for ( ; x < req->lines; x++) { 04842 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 04843 break; 04844 } 04845 req->sdp_end = x; 04846 return 1; 04847 } 04848 } 04849 04850 return 0; 04851 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1667 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01668 { 01669 int i, res = 0; 01670 01671 if (ast_strlen_zero(msg)) 01672 return 0; 01673 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01674 if (method_match(i, msg)) 01675 res = sip_methods[i].id; 01676 } 01677 return res; 01678 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10570 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10571 { 10572 int i; 10573 10574 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10575 if (subscription_types[i].type == subtype) { 10576 return &subscription_types[i]; 10577 } 10578 } 10579 return &subscription_types[0]; 10580 }
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 2680 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02681 { 02682 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02683 if (!u && realtime) 02684 u = realtime_user(name); 02685 return u; 02686 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8056 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08057 { 08058 struct sip_route *next; 08059 08060 while (route) { 08061 next = route->next; 08062 free(route); 08063 route = next; 08064 } 08065 }
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 11562 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), and check_sip_domain().
11563 { 11564 if (ast_strlen_zero(data)) { 11565 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11566 return -1; 11567 } 11568 if (check_sip_domain(data, NULL, 0)) 11569 ast_copy_string(buf, data, len); 11570 else 11571 buf[0] = '\0'; 11572 return 0; 11573 }
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 11498 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.
11499 { 11500 struct sip_pvt *p; 11501 const char *content = NULL; 11502 AST_DECLARE_APP_ARGS(args, 11503 AST_APP_ARG(header); 11504 AST_APP_ARG(number); 11505 ); 11506 int i, number, start = 0; 11507 11508 if (ast_strlen_zero(data)) { 11509 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11510 return -1; 11511 } 11512 11513 ast_channel_lock(chan); 11514 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11515 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11516 ast_channel_unlock(chan); 11517 return -1; 11518 } 11519 11520 AST_STANDARD_APP_ARGS(args, data); 11521 if (!args.number) { 11522 number = 1; 11523 } else { 11524 sscanf(args.number, "%d", &number); 11525 if (number < 1) 11526 number = 1; 11527 } 11528 11529 p = chan->tech_pvt; 11530 11531 /* If there is no private structure, this channel is no longer alive */ 11532 if (!p) { 11533 ast_channel_unlock(chan); 11534 return -1; 11535 } 11536 11537 for (i = 0; i < number; i++) 11538 content = __get_header(&p->initreq, args.header, &start); 11539 11540 if (ast_strlen_zero(content)) { 11541 ast_channel_unlock(chan); 11542 return -1; 11543 } 11544 11545 ast_copy_string(buf, content, len); 11546 ast_channel_unlock(chan); 11547 11548 return 0; 11549 }
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 11677 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.
11678 { 11679 struct sip_pvt *p; 11680 11681 *buf = 0; 11682 11683 if (!data) { 11684 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11685 return -1; 11686 } 11687 11688 ast_channel_lock(chan); 11689 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11690 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11691 ast_channel_unlock(chan); 11692 return -1; 11693 } 11694 11695 p = chan->tech_pvt; 11696 11697 /* If there is no private structure, this channel is no longer alive */ 11698 if (!p) { 11699 ast_channel_unlock(chan); 11700 return -1; 11701 } 11702 11703 if (!strcasecmp(data, "peerip")) { 11704 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11705 } else if (!strcasecmp(data, "recvip")) { 11706 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11707 } else if (!strcasecmp(data, "from")) { 11708 ast_copy_string(buf, p->from, len); 11709 } else if (!strcasecmp(data, "uri")) { 11710 ast_copy_string(buf, p->uri, len); 11711 } else if (!strcasecmp(data, "useragent")) { 11712 ast_copy_string(buf, p->useragent, len); 11713 } else if (!strcasecmp(data, "peername")) { 11714 ast_copy_string(buf, p->peername, len); 11715 } else if (!strcasecmp(data, "t38passthrough")) { 11716 if (p->t38.state == T38_DISABLED) 11717 ast_copy_string(buf, "0", sizeof("0")); 11718 else /* T38 is offered or enabled in this call */ 11719 ast_copy_string(buf, "1", sizeof("1")); 11720 } else { 11721 ast_channel_unlock(chan); 11722 return -1; 11723 } 11724 ast_channel_unlock(chan); 11725 11726 return 0; 11727 }
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 11587 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.
11588 { 11589 struct sip_peer *peer; 11590 char *colname; 11591 11592 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11593 *colname++ = '\0'; 11594 else if ((colname = strchr(data, '|'))) 11595 *colname++ = '\0'; 11596 else 11597 colname = "ip"; 11598 11599 if (!(peer = find_peer(data, NULL, 1))) 11600 return -1; 11601 11602 if (!strcasecmp(colname, "ip")) { 11603 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11604 } else if (!strcasecmp(colname, "status")) { 11605 peer_status(peer, buf, len); 11606 } else if (!strcasecmp(colname, "language")) { 11607 ast_copy_string(buf, peer->language, len); 11608 } else if (!strcasecmp(colname, "regexten")) { 11609 ast_copy_string(buf, peer->regexten, len); 11610 } else if (!strcasecmp(colname, "limit")) { 11611 snprintf(buf, len, "%d", peer->call_limit); 11612 } else if (!strcasecmp(colname, "curcalls")) { 11613 snprintf(buf, len, "%d", peer->inUse); 11614 } else if (!strcasecmp(colname, "accountcode")) { 11615 ast_copy_string(buf, peer->accountcode, len); 11616 } else if (!strcasecmp(colname, "useragent")) { 11617 ast_copy_string(buf, peer->useragent, len); 11618 } else if (!strcasecmp(colname, "mailbox")) { 11619 ast_copy_string(buf, peer->mailbox, len); 11620 } else if (!strcasecmp(colname, "context")) { 11621 ast_copy_string(buf, peer->context, len); 11622 } else if (!strcasecmp(colname, "expire")) { 11623 snprintf(buf, len, "%d", peer->expire); 11624 } else if (!strcasecmp(colname, "dynamic")) { 11625 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11626 } else if (!strcasecmp(colname, "callerid_name")) { 11627 ast_copy_string(buf, peer->cid_name, len); 11628 } else if (!strcasecmp(colname, "callerid_num")) { 11629 ast_copy_string(buf, peer->cid_num, len); 11630 } else if (!strcasecmp(colname, "codecs")) { 11631 ast_getformatname_multiple(buf, len -1, peer->capability); 11632 } else if (!strncasecmp(colname, "codec[", 6)) { 11633 char *codecnum; 11634 int index = 0, codec = 0; 11635 11636 codecnum = colname + 6; /* move past the '[' */ 11637 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11638 index = atoi(codecnum); 11639 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11640 ast_copy_string(buf, ast_getformatname(codec), len); 11641 } 11642 } 11643 11644 ASTOBJ_UNREF(peer, sip_destroy_peer); 11645 11646 return 0; 11647 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4300 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04301 { 04302 long val[4]; 04303 int x; 04304 04305 for (x=0; x<4; x++) 04306 val[x] = ast_random(); 04307 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04308 04309 return buf; 04310 }
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 8937 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, and sip_debug_test_pvt().
Referenced by handle_request_bye().
08938 { 08939 char tmp[256] = "", *c, *a; 08940 struct sip_request *req = oreq ? oreq : &p->initreq; 08941 struct sip_refer *referdata = p->refer; 08942 const char *transfer_context = NULL; 08943 08944 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 08945 c = get_in_brackets(tmp); 08946 08947 if (pedanticsipchecking) 08948 ast_uri_decode(c); 08949 08950 if (strncasecmp(c, "sip:", 4)) { 08951 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 08952 return -1; 08953 } 08954 c += 4; 08955 if ((a = strchr(c, ';'))) /* Remove arguments */ 08956 *a = '\0'; 08957 08958 if ((a = strchr(c, '@'))) { /* Separate Domain */ 08959 *a++ = '\0'; 08960 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 08961 } 08962 08963 if (sip_debug_test_pvt(p)) 08964 ast_verbose("Looking for %s in %s\n", c, p->context); 08965 08966 if (p->owner) /* Mimic behaviour in res_features.c */ 08967 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 08968 08969 /* By default, use the context in the channel sending the REFER */ 08970 if (ast_strlen_zero(transfer_context)) { 08971 transfer_context = S_OR(p->owner->macrocontext, 08972 S_OR(p->context, default_context)); 08973 } 08974 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 08975 /* This is a blind transfer */ 08976 if (option_debug) 08977 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 08978 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 08979 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 08980 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 08981 referdata->refer_call = NULL; 08982 /* Set new context */ 08983 ast_string_field_set(p, context, transfer_context); 08984 return 0; 08985 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 08986 return 1; 08987 } 08988 08989 return -1; 08990 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4091 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04092 { 04093 int x; 04094 int len = strlen(name); 04095 char *r; 04096 04097 for (x = 0; x < req->lines; x++) { 04098 r = get_body_by_line(req->line[x], name, len); 04099 if (r[0] != '\0') 04100 return r; 04101 } 04102 04103 return ""; 04104 }
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 4057 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04058 { 04059 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04060 return ast_skip_blanks(line + nameLen + 1); 04061 04062 return ""; 04063 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9044 of file chan_sip.c.
Referenced by check_user_full().
09045 { 09046 const char *end = strchr(input,'<'); /* first_bracket */ 09047 const char *tmp = strchr(input,'"'); /* first quote */ 09048 int bytes = 0; 09049 int maxbytes = outputsize - 1; 09050 09051 if (!end || end == input) /* we require a part in brackets */ 09052 return NULL; 09053 09054 end--; /* move just before "<" */ 09055 09056 if (tmp && tmp <= end) { 09057 /* The quote (tmp) precedes the bracket (end+1). 09058 * Find the matching quote and return the content. 09059 */ 09060 end = strchr(tmp+1, '"'); 09061 if (!end) 09062 return NULL; 09063 bytes = (int) (end - tmp); 09064 /* protect the output buffer */ 09065 if (bytes > maxbytes) 09066 bytes = maxbytes; 09067 ast_copy_string(output, tmp + 1, bytes); 09068 } else { 09069 /* No quoted string, or it is inside brackets. */ 09070 /* clear the empty characters in the begining*/ 09071 input = ast_skip_blanks(input); 09072 /* clear the empty characters in the end */ 09073 while(*end && *end < 33 && end > input) 09074 end--; 09075 if (end >= input) { 09076 bytes = (int) (end - input) + 2; 09077 /* protect the output buffer */ 09078 if (bytes > maxbytes) 09079 bytes = maxbytes; 09080 ast_copy_string(output, input, bytes); 09081 } else 09082 return NULL; 09083 } 09084 return output; 09085 }
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 8611 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), 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, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, strsep(), and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08612 { 08613 char tmp[256] = "", *uri, *a; 08614 char tmpf[256] = "", *from; 08615 struct sip_request *req; 08616 char *colon; 08617 08618 req = oreq; 08619 if (!req) 08620 req = &p->initreq; 08621 08622 /* Find the request URI */ 08623 if (req->rlPart2) 08624 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08625 08626 if (pedanticsipchecking) 08627 ast_uri_decode(tmp); 08628 08629 uri = get_in_brackets(tmp); 08630 08631 if (strncasecmp(uri, "sip:", 4)) { 08632 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08633 return -1; 08634 } 08635 uri += 4; 08636 08637 /* Now find the From: caller ID and name */ 08638 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08639 if (!ast_strlen_zero(tmpf)) { 08640 if (pedanticsipchecking) 08641 ast_uri_decode(tmpf); 08642 from = get_in_brackets(tmpf); 08643 } else { 08644 from = NULL; 08645 } 08646 08647 if (!ast_strlen_zero(from)) { 08648 if (strncasecmp(from, "sip:", 4)) { 08649 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08650 return -1; 08651 } 08652 from += 4; 08653 if ((a = strchr(from, '@'))) 08654 *a++ = '\0'; 08655 else 08656 a = from; /* just a domain */ 08657 from = strsep(&from, ";"); /* Remove userinfo options */ 08658 a = strsep(&a, ";"); /* Remove URI options */ 08659 ast_string_field_set(p, fromdomain, a); 08660 } 08661 08662 /* Skip any options and find the domain */ 08663 08664 /* Get the target domain */ 08665 if ((a = strchr(uri, '@'))) { 08666 *a++ = '\0'; 08667 } else { /* No username part */ 08668 a = uri; 08669 uri = "s"; /* Set extension to "s" */ 08670 } 08671 colon = strchr(a, ':'); /* Remove :port */ 08672 if (colon) 08673 *colon = '\0'; 08674 08675 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08676 a = strsep(&a, ";"); /* Remove URI options */ 08677 08678 ast_string_field_set(p, domain, a); 08679 08680 if (!AST_LIST_EMPTY(&domain_list)) { 08681 char domain_context[AST_MAX_EXTENSION]; 08682 08683 domain_context[0] = '\0'; 08684 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08685 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08686 if (option_debug) 08687 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08688 return -2; 08689 } 08690 } 08691 /* If we have a context defined, overwrite the original context */ 08692 if (!ast_strlen_zero(domain_context)) 08693 ast_string_field_set(p, context, domain_context); 08694 } 08695 08696 if (sip_debug_test_pvt(p)) 08697 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08698 08699 /* Check the dialplan for the username part of the request URI, 08700 the domain will be stored in the SIPDOMAIN variable 08701 Return 0 if we have a matching extension */ 08702 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 08703 !strcmp(uri, ast_pickup_ext())) { 08704 if (!oreq) 08705 ast_string_field_set(p, exten, uri); 08706 return 0; 08707 } 08708 08709 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08710 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08711 ast_canmatch_extension(NULL, p->context, uri, 1, from)) || 08712 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08713 return 1; 08714 } 08715 08716 return -1; 08717 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4180 of file chan_sip.c.
References __get_header().
04181 { 04182 int start = 0; 04183 return __get_header(req, name, &start); 04184 }
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 2301 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().
02302 { 02303 const char *parse = tmp; 02304 char *first_bracket; 02305 02306 /* 02307 * Skip any quoted text until we find the part in brackets. 02308 * On any error give up and return the full string. 02309 */ 02310 while ( (first_bracket = strchr(parse, '<')) ) { 02311 char *first_quote = strchr(parse, '"'); 02312 02313 if (!first_quote || first_quote > first_bracket) 02314 break; /* no need to look at quoted part */ 02315 /* the bracket is within quotes, so ignore it */ 02316 parse = find_closing_quote(first_quote + 1, NULL); 02317 if (!*parse) { /* not found, return full string ? */ 02318 /* XXX or be robust and return in-bracket part ? */ 02319 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02320 break; 02321 } 02322 parse++; 02323 } 02324 if (first_bracket) { 02325 char *second_bracket = strchr(first_bracket + 1, '>'); 02326 if (second_bracket) { 02327 *second_bracket = '\0'; 02328 tmp = first_bracket + 1; 02329 } else { 02330 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02331 } 02332 } 02333 return tmp; 02334 }
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 9451 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09452 { 09453 int x; 09454 int y; 09455 09456 buf[0] = '\0'; 09457 y = len - strlen(buf) - 5; 09458 if (y < 0) 09459 y = 0; 09460 for (x=0;x<req->lines;x++) { 09461 strncat(buf, req->line[x], y); /* safe */ 09462 y -= strlen(req->line[x]) + 1; 09463 if (y < 0) 09464 y = 0; 09465 if (y != 0) 09466 strcat(buf, "\n"); /* safe */ 09467 } 09468 return 0; 09469 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8582 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().
08583 { 08584 char tmp[256], *c, *a; 08585 struct sip_request *req; 08586 08587 req = oreq; 08588 if (!req) 08589 req = &p->initreq; 08590 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08591 if (ast_strlen_zero(tmp)) 08592 return 0; 08593 c = get_in_brackets(tmp); 08594 if (strncasecmp(c, "sip:", 4)) { 08595 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08596 return -1; 08597 } 08598 c += 4; 08599 a = c; 08600 strsep(&a, "@;"); /* trim anything after @ or ; */ 08601 if (sip_debug_test_pvt(p)) 08602 ast_verbose("RDNIS is %s\n", c); 08603 ast_string_field_set(p, rdnis, c); 08604 08605 return 0; 08606 }
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 8776 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().
08777 { 08778 08779 const char *p_referred_by = NULL; 08780 char *h_refer_to = NULL; 08781 char *h_referred_by = NULL; 08782 char *refer_to; 08783 const char *p_refer_to; 08784 char *referred_by_uri = NULL; 08785 char *ptr; 08786 struct sip_request *req = NULL; 08787 const char *transfer_context = NULL; 08788 struct sip_refer *referdata; 08789 08790 08791 req = outgoing_req; 08792 referdata = transferer->refer; 08793 08794 if (!req) 08795 req = &transferer->initreq; 08796 08797 p_refer_to = get_header(req, "Refer-To"); 08798 if (ast_strlen_zero(p_refer_to)) { 08799 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 08800 return -2; /* Syntax error */ 08801 } 08802 h_refer_to = ast_strdupa(p_refer_to); 08803 refer_to = get_in_brackets(h_refer_to); 08804 if (pedanticsipchecking) 08805 ast_uri_decode(refer_to); 08806 08807 if (strncasecmp(refer_to, "sip:", 4)) { 08808 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 08809 return -3; 08810 } 08811 refer_to += 4; /* Skip sip: */ 08812 08813 /* Get referred by header if it exists */ 08814 p_referred_by = get_header(req, "Referred-By"); 08815 if (!ast_strlen_zero(p_referred_by)) { 08816 char *lessthan; 08817 h_referred_by = ast_strdupa(p_referred_by); 08818 if (pedanticsipchecking) 08819 ast_uri_decode(h_referred_by); 08820 08821 /* Store referrer's caller ID name */ 08822 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 08823 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 08824 *(lessthan - 1) = '\0'; /* Space */ 08825 } 08826 08827 referred_by_uri = get_in_brackets(h_referred_by); 08828 if(strncasecmp(referred_by_uri, "sip:", 4)) { 08829 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 08830 referred_by_uri = (char *) NULL; 08831 } else { 08832 referred_by_uri += 4; /* Skip sip: */ 08833 } 08834 } 08835 08836 /* Check for arguments in the refer_to header */ 08837 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 08838 *ptr++ = '\0'; 08839 if (!strncasecmp(ptr, "REPLACES=", 9)) { 08840 char *to = NULL, *from = NULL; 08841 08842 /* This is an attended transfer */ 08843 referdata->attendedtransfer = 1; 08844 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 08845 ast_uri_decode(referdata->replaces_callid); 08846 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 08847 *ptr++ = '\0'; 08848 } 08849 08850 if (ptr) { 08851 /* Find the different tags before we destroy the string */ 08852 to = strcasestr(ptr, "to-tag="); 08853 from = strcasestr(ptr, "from-tag="); 08854 } 08855 08856 /* Grab the to header */ 08857 if (to) { 08858 ptr = to + 7; 08859 if ((to = strchr(ptr, '&'))) 08860 *to = '\0'; 08861 if ((to = strchr(ptr, ';'))) 08862 *to = '\0'; 08863 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 08864 } 08865 08866 if (from) { 08867 ptr = from + 9; 08868 if ((to = strchr(ptr, '&'))) 08869 *to = '\0'; 08870 if ((to = strchr(ptr, ';'))) 08871 *to = '\0'; 08872 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 08873 } 08874 08875 if (option_debug > 1) { 08876 if (!pedanticsipchecking) 08877 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 08878 else 08879 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>" ); 08880 } 08881 } 08882 } 08883 08884 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 08885 char *urioption; 08886 08887 *ptr++ = '\0'; 08888 if ((urioption = strchr(ptr, ';'))) 08889 *urioption++ = '\0'; 08890 /* Save the domain for the dial plan */ 08891 ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain)); 08892 if (urioption) 08893 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 08894 } 08895 08896 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 08897 *ptr = '\0'; 08898 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 08899 08900 if (referred_by_uri) { 08901 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 08902 *ptr = '\0'; 08903 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 08904 } else { 08905 referdata->referred_by[0] = '\0'; 08906 } 08907 08908 /* Determine transfer context */ 08909 if (transferer->owner) /* Mimic behaviour in res_features.c */ 08910 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 08911 08912 /* By default, use the context in the channel sending the REFER */ 08913 if (ast_strlen_zero(transfer_context)) { 08914 transfer_context = S_OR(transferer->owner->macrocontext, 08915 S_OR(transferer->context, default_context)); 08916 } 08917 08918 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 08919 08920 /* Either an existing extension or the parking extension */ 08921 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 08922 if (sip_debug_test_pvt(transferer)) { 08923 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 08924 } 08925 /* We are ready to transfer to the extension */ 08926 return 0; 08927 } 08928 if (sip_debug_test_pvt(transferer)) 08929 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 08930 08931 /* Failure, we can't find this extension */ 08932 return -1; 08933 }
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 9091 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09092 { 09093 char *start; 09094 char *end; 09095 09096 start = strchr(input,':'); 09097 if (!start) { 09098 output[0] = '\0'; 09099 return 0; 09100 } 09101 start++; 09102 09103 /* we found "number" */ 09104 ast_copy_string(output,start,maxlen); 09105 output[maxlen-1] = '\0'; 09106 09107 end = strchr(output,'@'); 09108 if (end) 09109 *end = '\0'; 09110 else 09111 output[0] = '\0'; 09112 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09113 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09114 09115 return 0; 09116 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4083 of file chan_sip.c.
References get_sdp_iterate().
04084 { 04085 int dummy = 0; 04086 04087 return get_sdp_iterate(&dummy, req, name); 04088 }
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 4069 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04070 { 04071 int len = strlen(name); 04072 04073 while (*start < req->sdp_end) { 04074 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04075 if (r[0] != '\0') 04076 return r; 04077 } 04078 04079 return ""; 04080 }
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 8724 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, iflist, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_OUTGOING, and sip_pvt::tag.
Referenced by handle_request_invite(), and local_attended_transfer().
08725 { 08726 struct sip_pvt *sip_pvt_ptr; 08727 08728 ast_mutex_lock(&iflock); 08729 08730 if (option_debug > 3 && totag) 08731 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08732 08733 /* Search interfaces and find the match */ 08734 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08735 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08736 int match = 1; 08737 char *ourtag = sip_pvt_ptr->tag; 08738 08739 /* Go ahead and lock it (and its owner) before returning */ 08740 ast_mutex_lock(&sip_pvt_ptr->lock); 08741 08742 /* Check if tags match. If not, this is not the call we want 08743 (With a forking SIP proxy, several call legs share the 08744 call id, but have different tags) 08745 */ 08746 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 08747 match = 0; 08748 08749 if (!match) { 08750 ast_mutex_unlock(&sip_pvt_ptr->lock); 08751 continue; 08752 } 08753 08754 if (option_debug > 3 && totag) 08755 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08756 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08757 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08758 08759 /* deadlock avoidance... */ 08760 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08761 ast_mutex_unlock(&sip_pvt_ptr->lock); 08762 usleep(1); 08763 ast_mutex_lock(&sip_pvt_ptr->lock); 08764 } 08765 break; 08766 } 08767 } 08768 ast_mutex_unlock(&iflock); 08769 if (option_debug > 3 && !sip_pvt_ptr) 08770 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08771 return sip_pvt_ptr; 08772 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13047 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
13048 { 13049 const char *thetag; 13050 13051 if (!tagbuf) 13052 return NULL; 13053 tagbuf[0] = '\0'; /* reset the buffer */ 13054 thetag = get_header(req, header); 13055 thetag = strcasestr(thetag, ";tag="); 13056 if (thetag) { 13057 thetag += 5; 13058 ast_copy_string(tagbuf, thetag, tagbufsize); 13059 return strsep(&tagbuf, ";"); 13060 } 13061 return NULL; 13062 }
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 15779 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_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
15780 { 15781 int res = 1; 15782 15783 if (!strcasecmp(v->name, "trustrpid")) { 15784 ast_set_flag(&mask[0], SIP_TRUSTRPID); 15785 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 15786 } else if (!strcasecmp(v->name, "sendrpid")) { 15787 ast_set_flag(&mask[0], SIP_SENDRPID); 15788 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 15789 } else if (!strcasecmp(v->name, "g726nonstandard")) { 15790 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 15791 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 15792 } else if (!strcasecmp(v->name, "useclientcode")) { 15793 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 15794 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 15795 } else if (!strcasecmp(v->name, "dtmfmode")) { 15796 ast_set_flag(&mask[0], SIP_DTMF); 15797 ast_clear_flag(&flags[0], SIP_DTMF); 15798 if (!strcasecmp(v->value, "inband")) 15799 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 15800 else if (!strcasecmp(v->value, "rfc2833")) 15801 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15802 else if (!strcasecmp(v->value, "info")) 15803 ast_set_flag(&flags[0], SIP_DTMF_INFO); 15804 else if (!strcasecmp(v->value, "auto")) 15805 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 15806 else { 15807 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 15808 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15809 } 15810 } else if (!strcasecmp(v->name, "nat")) { 15811 ast_set_flag(&mask[0], SIP_NAT); 15812 ast_clear_flag(&flags[0], SIP_NAT); 15813 if (!strcasecmp(v->value, "never")) 15814 ast_set_flag(&flags[0], SIP_NAT_NEVER); 15815 else if (!strcasecmp(v->value, "route")) 15816 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 15817 else if (ast_true(v->value)) 15818 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 15819 else 15820 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 15821 } else if (!strcasecmp(v->name, "canreinvite")) { 15822 ast_set_flag(&mask[0], SIP_REINVITE); 15823 ast_clear_flag(&flags[0], SIP_REINVITE); 15824 if(ast_true(v->value)) { 15825 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 15826 } else if (!ast_false(v->value)) { 15827 char buf[64]; 15828 char *word, *next = buf; 15829 15830 ast_copy_string(buf, v->value, sizeof(buf)); 15831 while ((word = strsep(&next, ","))) { 15832 if(!strcasecmp(word, "update")) { 15833 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 15834 } else if(!strcasecmp(word, "nonat")) { 15835 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 15836 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 15837 } else { 15838 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 15839 } 15840 } 15841 } 15842 } else if (!strcasecmp(v->name, "insecure")) { 15843 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15844 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15845 set_insecure_flags(flags, v->value, v->lineno); 15846 } else if (!strcasecmp(v->name, "progressinband")) { 15847 ast_set_flag(&mask[0], SIP_PROG_INBAND); 15848 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 15849 if (ast_true(v->value)) 15850 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 15851 else if (strcasecmp(v->value, "never")) 15852 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 15853 } else if (!strcasecmp(v->name, "promiscredir")) { 15854 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 15855 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 15856 } else if (!strcasecmp(v->name, "videosupport")) { 15857 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 15858 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 15859 } else if (!strcasecmp(v->name, "allowoverlap")) { 15860 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 15861 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 15862 } else if (!strcasecmp(v->name, "allowsubscribe")) { 15863 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 15864 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 15865 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 15866 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 15867 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 15868 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 15869 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 15870 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 15871 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 15872 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 15873 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 15874 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 15875 #endif 15876 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 15877 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 15878 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 15879 } else if (!strcasecmp(v->name, "buggymwi")) { 15880 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 15881 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 15882 } else 15883 res = 0; 15884 15885 return res; 15886 }
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 13220 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree(), ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13221 { 13222 struct ast_frame *f; 13223 int earlyreplace = 0; 13224 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13225 struct ast_channel *c = p->owner; /* Our incoming call */ 13226 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13227 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13228 13229 /* Check if we're in ring state */ 13230 if (replacecall->_state == AST_STATE_RING) 13231 earlyreplace = 1; 13232 13233 /* Check if we have a bridge */ 13234 if (!(targetcall = ast_bridged_channel(replacecall))) { 13235 /* We have no bridge */ 13236 if (!earlyreplace) { 13237 if (option_debug > 1) 13238 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13239 oneleggedreplace = 1; 13240 } 13241 } 13242 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13243 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13244 13245 if (option_debug > 3) { 13246 if (targetcall) 13247 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); 13248 else 13249 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13250 } 13251 13252 if (ignore) { 13253 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13254 /* We should answer something here. If we are here, the 13255 call we are replacing exists, so an accepted 13256 can't harm */ 13257 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13258 /* Do something more clever here */ 13259 ast_channel_unlock(c); 13260 ast_mutex_unlock(&p->refer->refer_call->lock); 13261 return 1; 13262 } 13263 if (!c) { 13264 /* What to do if no channel ??? */ 13265 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13266 transmit_response_reliable(p, "503 Service Unavailable", req); 13267 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13268 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13269 ast_mutex_unlock(&p->refer->refer_call->lock); 13270 return 1; 13271 } 13272 append_history(p, "Xfer", "INVITE/Replace received"); 13273 /* We have three channels to play with 13274 channel c: New incoming call 13275 targetcall: Call from PBX to target 13276 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13277 replacecall: The owner of the previous 13278 We need to masq C into refer_call to connect to 13279 targetcall; 13280 If we are talking to internal audio stream, target call is null. 13281 */ 13282 13283 /* Fake call progress */ 13284 transmit_response(p, "100 Trying", req); 13285 ast_setstate(c, AST_STATE_RING); 13286 13287 /* Masquerade the new call into the referred call to connect to target call 13288 Targetcall is not touched by the masq */ 13289 13290 /* Answer the incoming call and set channel to UP state */ 13291 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13292 13293 ast_setstate(c, AST_STATE_UP); 13294 13295 /* Stop music on hold and other generators */ 13296 ast_quiet_chan(replacecall); 13297 ast_quiet_chan(targetcall); 13298 if (option_debug > 3) 13299 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13300 /* Unlock clone, but not original (replacecall) */ 13301 ast_channel_unlock(c); 13302 13303 /* Unlock PVT */ 13304 ast_mutex_unlock(&p->refer->refer_call->lock); 13305 13306 /* Make sure that the masq does not free our PVT for the old call */ 13307 if (! earlyreplace && ! oneleggedreplace ) 13308 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13309 13310 /* Prepare the masquerade - if this does not happen, we will be gone */ 13311 if(ast_channel_masquerade(replacecall, c)) 13312 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13313 else if (option_debug > 3) 13314 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13315 13316 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13317 13318 /* C should now be in place of replacecall */ 13319 /* ast_read needs to lock channel */ 13320 ast_channel_unlock(c); 13321 13322 if (earlyreplace || oneleggedreplace ) { 13323 /* Force the masq to happen */ 13324 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13325 ast_frfree(f); 13326 f = NULL; 13327 if (option_debug > 3) 13328 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13329 } else { 13330 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13331 } 13332 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13333 ast_channel_unlock(replacecall); 13334 } else { /* Bridged call, UP channel */ 13335 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13336 /* Masq ok */ 13337 ast_frfree(f); 13338 f = NULL; 13339 if (option_debug > 2) 13340 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13341 } else { 13342 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13343 } 13344 ast_channel_unlock(replacecall); 13345 } 13346 ast_mutex_unlock(&p->refer->refer_call->lock); 13347 13348 ast_setstate(c, AST_STATE_DOWN); 13349 if (option_debug > 3) { 13350 struct ast_channel *test; 13351 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13352 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13353 if (replacecall) 13354 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13355 if (p->owner) { 13356 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13357 test = ast_bridged_channel(p->owner); 13358 if (test) 13359 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13360 else 13361 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13362 } else 13363 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13364 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13365 } 13366 13367 ast_channel_unlock(p->owner); /* Unlock new owner */ 13368 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13369 13370 /* The call should be down with no ast_channel, so hang it up */ 13371 c->tech_pvt = NULL; 13372 ast_hangup(c); 13373 return 0; 13374 }
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 14873 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, 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.
14874 { 14875 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 14876 relatively static */ 14877 const char *cmd; 14878 const char *cseq; 14879 const char *useragent; 14880 int seqno; 14881 int len; 14882 int ignore = FALSE; 14883 int respid; 14884 int res = 0; 14885 int debug = sip_debug_test_pvt(p); 14886 char *e; 14887 int error = 0; 14888 14889 /* Get Method and Cseq */ 14890 cseq = get_header(req, "Cseq"); 14891 cmd = req->header[0]; 14892 14893 /* Must have Cseq */ 14894 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 14895 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 14896 error = 1; 14897 } 14898 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 14899 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 14900 error = 1; 14901 } 14902 if (error) { 14903 if (!p->initreq.headers) /* New call */ 14904 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 14905 return -1; 14906 } 14907 /* Get the command XXX */ 14908 14909 cmd = req->rlPart1; 14910 e = req->rlPart2; 14911 14912 /* Save useragent of the client */ 14913 useragent = get_header(req, "User-Agent"); 14914 if (!ast_strlen_zero(useragent)) 14915 ast_string_field_set(p, useragent, useragent); 14916 14917 /* Find out SIP method for incoming request */ 14918 if (req->method == SIP_RESPONSE) { /* Response to our request */ 14919 /* Response to our request -- Do some sanity checks */ 14920 if (!p->initreq.headers) { 14921 if (option_debug) 14922 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 14923 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14924 return 0; 14925 } else if (p->ocseq && (p->ocseq < seqno)) { 14926 if (option_debug) 14927 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 14928 return -1; 14929 } else if (p->ocseq && (p->ocseq != seqno)) { 14930 /* ignore means "don't do anything with it" but still have to 14931 respond appropriately */ 14932 ignore = TRUE; 14933 ast_set_flag(req, SIP_PKT_IGNORE); 14934 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 14935 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14936 } else if (e) { 14937 e = ast_skip_blanks(e); 14938 if (sscanf(e, "%d %n", &respid, &len) != 1) { 14939 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 14940 } else { 14941 if (respid <= 0) { 14942 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 14943 return 0; 14944 } 14945 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 14946 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 14947 extract_uri(p, req); 14948 handle_response(p, respid, e + len, req, ignore, seqno); 14949 } 14950 } 14951 return 0; 14952 } 14953 14954 /* New SIP request coming in 14955 (could be new request in existing SIP dialog as well...) 14956 */ 14957 14958 p->method = req->method; /* Find out which SIP method they are using */ 14959 if (option_debug > 3) 14960 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 14961 14962 if (p->icseq && (p->icseq > seqno)) { 14963 if (option_debug) 14964 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 14965 if (req->method != SIP_ACK) 14966 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 14967 return -1; 14968 } else if (p->icseq && 14969 p->icseq == seqno && 14970 req->method != SIP_ACK && 14971 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 14972 /* ignore means "don't do anything with it" but still have to 14973 respond appropriately. We do this if we receive a repeat of 14974 the last sequence number */ 14975 ignore = 2; 14976 ast_set_flag(req, SIP_PKT_IGNORE); 14977 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 14978 if (option_debug > 2) 14979 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 14980 } 14981 14982 if (seqno >= p->icseq) 14983 /* Next should follow monotonically (but not necessarily 14984 incrementally -- thanks again to the genius authors of SIP -- 14985 increasing */ 14986 p->icseq = seqno; 14987 14988 /* Find their tag if we haven't got it */ 14989 if (ast_strlen_zero(p->theirtag)) { 14990 char tag[128]; 14991 14992 gettag(req, "From", tag, sizeof(tag)); 14993 ast_string_field_set(p, theirtag, tag); 14994 } 14995 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 14996 14997 if (pedanticsipchecking) { 14998 /* If this is a request packet without a from tag, it's not 14999 correct according to RFC 3261 */ 15000 /* Check if this a new request in a new dialog with a totag already attached to it, 15001 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15002 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15003 /* If this is a first request and it got a to-tag, it is not for us */ 15004 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15005 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15006 /* Will cease to exist after ACK */ 15007 } else if (req->method != SIP_ACK) { 15008 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15009 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15010 } 15011 return res; 15012 } 15013 } 15014 15015 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15016 transmit_response(p, "400 Bad request", req); 15017 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15018 return -1; 15019 } 15020 15021 /* Handle various incoming SIP methods in requests */ 15022 switch (p->method) { 15023 case SIP_OPTIONS: 15024 res = handle_request_options(p, req); 15025 break; 15026 case SIP_INVITE: 15027 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15028 break; 15029 case SIP_REFER: 15030 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15031 break; 15032 case SIP_CANCEL: 15033 res = handle_request_cancel(p, req); 15034 break; 15035 case SIP_BYE: 15036 res = handle_request_bye(p, req); 15037 break; 15038 case SIP_MESSAGE: 15039 res = handle_request_message(p, req); 15040 break; 15041 case SIP_SUBSCRIBE: 15042 res = handle_request_subscribe(p, req, sin, seqno, e); 15043 break; 15044 case SIP_REGISTER: 15045 res = handle_request_register(p, req, sin, e); 15046 break; 15047 case SIP_INFO: 15048 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15049 ast_verbose("Receiving INFO!\n"); 15050 if (!ignore) 15051 handle_request_info(p, req); 15052 else /* if ignoring, transmit response */ 15053 transmit_response(p, "200 OK", req); 15054 break; 15055 case SIP_NOTIFY: 15056 res = handle_request_notify(p, req, sin, seqno, e); 15057 break; 15058 case SIP_ACK: 15059 /* Make sure we don't ignore this */ 15060 if (seqno == p->pendinginvite) { 15061 p->invitestate = INV_TERMINATED; 15062 p->pendinginvite = 0; 15063 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15064 if (find_sdp(req)) { 15065 if (process_sdp(p, req)) 15066 return -1; 15067 } 15068 check_pendings(p); 15069 } 15070 /* Got an ACK that we did not match. Ignore silently */ 15071 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15072 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15073 break; 15074 default: 15075 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15076 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15077 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15078 /* If this is some new method, and we don't have a call, destroy it now */ 15079 if (!p->initreq.headers) 15080 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15081 break; 15082 } 15083 return res; 15084 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14440 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
14441 { 14442 struct ast_channel *c=NULL; 14443 int res; 14444 struct ast_channel *bridged_to; 14445 14446 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14447 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14448 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14449 14450 p->invitestate = INV_TERMINATED; 14451 14452 copy_request(&p->initreq, req); 14453 check_via(p, req); 14454 sip_alreadygone(p); 14455 14456 /* Get RTCP quality before end of call */ 14457 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14458 char *audioqos, *videoqos; 14459 if (p->rtp) { 14460 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14461 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14462 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14463 if (p->owner) 14464 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14465 } 14466 if (p->vrtp) { 14467 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14468 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14469 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14470 if (p->owner) 14471 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14472 } 14473 } 14474 14475 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14476 14477 if (!ast_strlen_zero(get_header(req, "Also"))) { 14478 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14479 ast_inet_ntoa(p->recv.sin_addr)); 14480 if (ast_strlen_zero(p->context)) 14481 ast_string_field_set(p, context, default_context); 14482 res = get_also_info(p, req); 14483 if (!res) { 14484 c = p->owner; 14485 if (c) { 14486 bridged_to = ast_bridged_channel(c); 14487 if (bridged_to) { 14488 /* Don't actually hangup here... */ 14489 ast_queue_control(c, AST_CONTROL_UNHOLD); 14490 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14491 } else 14492 ast_queue_hangup(p->owner); 14493 } 14494 } else { 14495 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14496 if (p->owner) 14497 ast_queue_hangup(p->owner); 14498 } 14499 } else if (p->owner) { 14500 ast_queue_hangup(p->owner); 14501 if (option_debug > 2) 14502 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14503 } else { 14504 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14505 if (option_debug > 2) 14506 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14507 } 14508 transmit_response(p, "200 OK", req); 14509 14510 return 1; 14511 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14342 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, INV_CANCELLED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::owner, 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().
14343 { 14344 14345 check_via(p, req); 14346 sip_alreadygone(p); 14347 p->invitestate = INV_CANCELLED; 14348 14349 if (p->owner && p->owner->_state == AST_STATE_UP) { 14350 /* This call is up, cancel is ignored, we need a bye */ 14351 transmit_response(p, "200 OK", req); 14352 if (option_debug) 14353 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14354 return 0; 14355 } 14356 14357 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14358 update_call_counter(p, DEC_CALL_LIMIT); 14359 14360 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14361 14362 if (p->owner) 14363 ast_queue_hangup(p->owner); 14364 else 14365 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14366 if (p->initreq.len > 0) { 14367 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14368 transmit_response(p, "200 OK", req); 14369 return 1; 14370 } else { 14371 transmit_response(p, "481 Call Leg Does Not Exist", req); 14372 return 0; 14373 } 14374 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 10923 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().
10924 { 10925 char buf[1024]; 10926 unsigned int event; 10927 const char *c = get_header(req, "Content-Type"); 10928 10929 /* Need to check the media/type */ 10930 if (!strcasecmp(c, "application/dtmf-relay") || 10931 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 10932 unsigned int duration = 0; 10933 10934 /* Try getting the "signal=" part */ 10935 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 10936 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 10937 transmit_response(p, "200 OK", req); /* Should return error */ 10938 return; 10939 } else { 10940 ast_copy_string(buf, c, sizeof(buf)); 10941 } 10942 10943 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 10944 duration = atoi(c); 10945 if (!duration) 10946 duration = 100; /* 100 ms */ 10947 10948 if (!p->owner) { /* not a PBX call */ 10949 transmit_response(p, "481 Call leg/transaction does not exist", req); 10950 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10951 return; 10952 } 10953 10954 if (ast_strlen_zero(buf)) { 10955 transmit_response(p, "200 OK", req); 10956 return; 10957 } 10958 10959 if (buf[0] == '*') 10960 event = 10; 10961 else if (buf[0] == '#') 10962 event = 11; 10963 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 10964 event = 12 + buf[0] - 'A'; 10965 else 10966 event = atoi(buf); 10967 if (event == 16) { 10968 /* send a FLASH event */ 10969 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 10970 ast_queue_frame(p->owner, &f); 10971 if (sipdebug) 10972 ast_verbose("* DTMF-relay event received: FLASH\n"); 10973 } else { 10974 /* send a DTMF event */ 10975 struct ast_frame f = { AST_FRAME_DTMF, }; 10976 if (event < 10) { 10977 f.subclass = '0' + event; 10978 } else if (event < 11) { 10979 f.subclass = '*'; 10980 } else if (event < 12) { 10981 f.subclass = '#'; 10982 } else if (event < 16) { 10983 f.subclass = 'A' + (event - 12); 10984 } 10985 f.len = duration; 10986 ast_queue_frame(p->owner, &f); 10987 if (sipdebug) 10988 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 10989 } 10990 transmit_response(p, "200 OK", req); 10991 return; 10992 } else if (!strcasecmp(c, "application/media_control+xml")) { 10993 /* Eh, we'll just assume it's a fast picture update for now */ 10994 if (p->owner) 10995 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 10996 transmit_response(p, "200 OK", req); 10997 return; 10998 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 10999 /* Client code (from SNOM phone) */ 11000 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11001 if (p->owner && p->owner->cdr) 11002 ast_cdr_setuserfield(p->owner, c); 11003 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11004 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11005 transmit_response(p, "200 OK", req); 11006 } else { 11007 transmit_response(p, "403 Unauthorized", req); 11008 } 11009 return; 11010 } 11011 /* Other type of INFO message, not really understood by Asterisk */ 11012 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11013 11014 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11015 transmit_response(p, "415 Unsupported media type", req); 11016 return; 11017 }
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 13383 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
13384 { 13385 int res = 1; 13386 int gotdest; 13387 const char *p_replaces; 13388 char *replace_id = NULL; 13389 const char *required; 13390 unsigned int required_profile = 0; 13391 struct ast_channel *c = NULL; /* New channel */ 13392 int reinvite = 0; 13393 13394 /* Find out what they support */ 13395 if (!p->sipoptions) { 13396 const char *supported = get_header(req, "Supported"); 13397 if (!ast_strlen_zero(supported)) 13398 parse_sip_options(p, supported); 13399 } 13400 13401 /* Find out what they require */ 13402 required = get_header(req, "Require"); 13403 if (!ast_strlen_zero(required)) { 13404 required_profile = parse_sip_options(NULL, required); 13405 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13406 /* At this point we only support REPLACES */ 13407 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13408 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13409 p->invitestate = INV_COMPLETED; 13410 if (!p->lastinvite) 13411 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13412 return -1; 13413 } 13414 } 13415 13416 /* Check if this is a loop */ 13417 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13418 /* This is a call to ourself. Send ourselves an error code and stop 13419 processing immediately, as SIP really has no good mechanism for 13420 being able to call yourself */ 13421 /* If pedantic is on, we need to check the tags. If they're different, this is 13422 in fact a forked call through a SIP proxy somewhere. */ 13423 transmit_response(p, "482 Loop Detected", req); 13424 p->invitestate = INV_COMPLETED; 13425 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13426 return 0; 13427 } 13428 13429 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13430 /* We already have a pending invite. Sorry. You are on hold. */ 13431 transmit_response(p, "491 Request Pending", req); 13432 if (option_debug) 13433 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13434 /* Don't destroy dialog here */ 13435 return 0; 13436 } 13437 13438 p_replaces = get_header(req, "Replaces"); 13439 if (!ast_strlen_zero(p_replaces)) { 13440 /* We have a replaces header */ 13441 char *ptr; 13442 char *fromtag = NULL; 13443 char *totag = NULL; 13444 char *start, *to; 13445 int error = 0; 13446 13447 if (p->owner) { 13448 if (option_debug > 2) 13449 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13450 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13451 /* Do not destroy existing call */ 13452 return -1; 13453 } 13454 13455 if (sipdebug && option_debug > 2) 13456 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13457 /* Create a buffer we can manipulate */ 13458 replace_id = ast_strdupa(p_replaces); 13459 ast_uri_decode(replace_id); 13460 13461 if (!p->refer && !sip_refer_allocate(p)) { 13462 transmit_response(p, "500 Server Internal Error", req); 13463 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13464 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13465 p->invitestate = INV_COMPLETED; 13466 return -1; 13467 } 13468 13469 /* Todo: (When we find phones that support this) 13470 if the replaces header contains ";early-only" 13471 we can only replace the call in early 13472 stage, not after it's up. 13473 13474 If it's not in early mode, 486 Busy. 13475 */ 13476 13477 /* Skip leading whitespace */ 13478 replace_id = ast_skip_blanks(replace_id); 13479 13480 start = replace_id; 13481 while ( (ptr = strsep(&start, ";")) ) { 13482 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13483 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13484 totag = to + 7; /* skip the keyword */ 13485 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13486 fromtag = to + 9; /* skip the keyword */ 13487 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13488 } 13489 } 13490 13491 if (sipdebug && option_debug > 3) 13492 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>"); 13493 13494 13495 /* Try to find call that we are replacing 13496 If we have a Replaces header, we need to cancel that call if we succeed with this call 13497 */ 13498 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13499 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13500 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13501 error = 1; 13502 } 13503 13504 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13505 13506 /* The matched call is the call from the transferer to Asterisk . 13507 We want to bridge the bridged part of the call to the 13508 incoming invite, thus taking over the refered call */ 13509 13510 if (p->refer->refer_call == p) { 13511 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13512 p->refer->refer_call = NULL; 13513 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13514 error = 1; 13515 } 13516 13517 if (!error && !p->refer->refer_call->owner) { 13518 /* Oops, someting wrong anyway, no owner, no call */ 13519 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13520 /* Check for better return code */ 13521 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13522 error = 1; 13523 } 13524 13525 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 ) { 13526 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13527 transmit_response(p, "603 Declined (Replaces)", req); 13528 error = 1; 13529 } 13530 13531 if (error) { /* Give up this dialog */ 13532 append_history(p, "Xfer", "INVITE/Replace Failed."); 13533 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13534 ast_mutex_unlock(&p->lock); 13535 if (p->refer->refer_call) { 13536 ast_mutex_unlock(&p->refer->refer_call->lock); 13537 ast_channel_unlock(p->refer->refer_call->owner); 13538 } 13539 p->invitestate = INV_COMPLETED; 13540 return -1; 13541 } 13542 } 13543 13544 13545 /* Check if this is an INVITE that sets up a new dialog or 13546 a re-invite in an existing dialog */ 13547 13548 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13549 int newcall = (p->initreq.headers ? TRUE : FALSE); 13550 13551 sip_cancel_destroy(p); 13552 /* This also counts as a pending invite */ 13553 p->pendinginvite = seqno; 13554 check_via(p, req); 13555 13556 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13557 if (!p->owner) { /* Not a re-invite */ 13558 if (debug) 13559 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13560 if (newcall) 13561 append_history(p, "Invite", "New call: %s", p->callid); 13562 parse_ok_contact(p, req); 13563 } else { /* Re-invite on existing call */ 13564 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13565 /* Handle SDP here if we already have an owner */ 13566 if (find_sdp(req)) { 13567 if (process_sdp(p, req)) { 13568 transmit_response(p, "488 Not acceptable here", req); 13569 if (!p->lastinvite) 13570 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13571 return -1; 13572 } 13573 } else { 13574 p->jointcapability = p->capability; 13575 if (option_debug > 2) 13576 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13577 /* Some devices signal they want to be put off hold by sending a re-invite 13578 *without* an SDP, which is supposed to mean "Go back to your state" 13579 and since they put os on remote hold, we go back to off hold */ 13580 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13581 change_hold_state(p, req, FALSE, 0); 13582 } 13583 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13584 append_history(p, "ReInv", "Re-invite received"); 13585 } 13586 } else if (debug) 13587 ast_verbose("Ignoring this INVITE request\n"); 13588 13589 13590 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13591 /* This is a new invite */ 13592 /* Handle authentication if this is our first invite */ 13593 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13594 if (res == AUTH_CHALLENGE_SENT) { 13595 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13596 return 0; 13597 } 13598 if (res < 0) { /* Something failed in authentication */ 13599 if (res == AUTH_FAKE_AUTH) { 13600 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13601 transmit_fake_auth_response(p, req, 1); 13602 } else { 13603 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13604 transmit_response_reliable(p, "403 Forbidden", req); 13605 } 13606 p->invitestate = INV_COMPLETED; 13607 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13608 ast_string_field_free(p, theirtag); 13609 return 0; 13610 } 13611 13612 /* We have a succesful authentication, process the SDP portion if there is one */ 13613 if (find_sdp(req)) { 13614 if (process_sdp(p, req)) { 13615 /* Unacceptable codecs */ 13616 transmit_response_reliable(p, "488 Not acceptable here", req); 13617 p->invitestate = INV_COMPLETED; 13618 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13619 if (option_debug) 13620 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13621 return -1; 13622 } 13623 } else { /* No SDP in invite, call control session */ 13624 p->jointcapability = p->capability; 13625 if (option_debug > 1) 13626 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13627 } 13628 13629 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13630 /* This seems redundant ... see !p-owner above */ 13631 if (p->owner) 13632 ast_queue_frame(p->owner, &ast_null_frame); 13633 13634 13635 /* Initialize the context if it hasn't been already */ 13636 if (ast_strlen_zero(p->context)) 13637 ast_string_field_set(p, context, default_context); 13638 13639 13640 /* Check number of concurrent calls -vs- incoming limit HERE */ 13641 if (option_debug) 13642 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13643 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13644 if (res < 0) { 13645 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13646 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13647 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13648 p->invitestate = INV_COMPLETED; 13649 } 13650 return 0; 13651 } 13652 gotdest = get_destination(p, NULL); /* Get destination right away */ 13653 get_rdnis(p, NULL); /* Get redirect information */ 13654 extract_uri(p, req); /* Get the Contact URI */ 13655 build_contact(p); /* Build our contact header */ 13656 13657 if (p->rtp) { 13658 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13659 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13660 } 13661 13662 if (!replace_id && gotdest) { /* No matching extension found */ 13663 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13664 transmit_response_reliable(p, "484 Address Incomplete", req); 13665 else 13666 transmit_response_reliable(p, "404 Not Found", req); 13667 p->invitestate = INV_COMPLETED; 13668 update_call_counter(p, DEC_CALL_LIMIT); 13669 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13670 return 0; 13671 } else { 13672 /* If no extension was specified, use the s one */ 13673 /* Basically for calling to IP/Host name only */ 13674 if (ast_strlen_zero(p->exten)) 13675 ast_string_field_set(p, exten, "s"); 13676 /* Initialize our tag */ 13677 13678 make_our_tag(p->tag, sizeof(p->tag)); 13679 /* First invitation - create the channel */ 13680 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13681 *recount = 1; 13682 13683 /* Save Record-Route for any later requests we make on this dialogue */ 13684 build_route(p, req, 0); 13685 13686 if (c) { 13687 /* Pre-lock the call */ 13688 ast_channel_lock(c); 13689 } 13690 } 13691 } else { 13692 if (option_debug > 1 && sipdebug) { 13693 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13694 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13695 else 13696 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13697 } 13698 reinvite = 1; 13699 c = p->owner; 13700 } 13701 13702 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 13703 p->lastinvite = seqno; 13704 13705 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 13706 /* Go and take over the target call */ 13707 if (sipdebug && option_debug > 3) 13708 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 13709 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 13710 } 13711 13712 13713 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 13714 switch(c->_state) { 13715 case AST_STATE_DOWN: 13716 if (option_debug > 1) 13717 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 13718 transmit_response(p, "100 Trying", req); 13719 p->invitestate = INV_PROCEEDING; 13720 ast_setstate(c, AST_STATE_RING); 13721 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 13722 enum ast_pbx_result res; 13723 13724 res = ast_pbx_start(c); 13725 13726 switch(res) { 13727 case AST_PBX_FAILED: 13728 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 13729 p->invitestate = INV_COMPLETED; 13730 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13731 transmit_response(p, "503 Unavailable", req); 13732 else 13733 transmit_response_reliable(p, "503 Unavailable", req); 13734 break; 13735 case AST_PBX_CALL_LIMIT: 13736 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 13737 p->invitestate = INV_COMPLETED; 13738 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13739 transmit_response(p, "480 Temporarily Unavailable", req); 13740 else 13741 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 13742 break; 13743 case AST_PBX_SUCCESS: 13744 /* nothing to do */ 13745 break; 13746 } 13747 13748 if (res) { 13749 13750 /* Unlock locks so ast_hangup can do its magic */ 13751 ast_mutex_unlock(&c->lock); 13752 ast_mutex_unlock(&p->lock); 13753 ast_hangup(c); 13754 ast_mutex_lock(&p->lock); 13755 c = NULL; 13756 } 13757 } else { /* Pickup call in call group */ 13758 ast_channel_unlock(c); 13759 *nounlock = 1; 13760 if (ast_pickup_call(c)) { 13761 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 13762 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13763 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 13764 else 13765 transmit_response_reliable(p, "503 Unavailable", req); 13766 sip_alreadygone(p); 13767 /* Unlock locks so ast_hangup can do its magic */ 13768 ast_mutex_unlock(&p->lock); 13769 c->hangupcause = AST_CAUSE_CALL_REJECTED; 13770 } else { 13771 ast_mutex_unlock(&p->lock); 13772 ast_setstate(c, AST_STATE_DOWN); 13773 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13774 } 13775 p->invitestate = INV_COMPLETED; 13776 ast_hangup(c); 13777 ast_mutex_lock(&p->lock); 13778 c = NULL; 13779 } 13780 break; 13781 case AST_STATE_RING: 13782 transmit_response(p, "100 Trying", req); 13783 p->invitestate = INV_PROCEEDING; 13784 break; 13785 case AST_STATE_RINGING: 13786 transmit_response(p, "180 Ringing", req); 13787 p->invitestate = INV_PROCEEDING; 13788 break; 13789 case AST_STATE_UP: 13790 if (option_debug > 1) 13791 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 13792 13793 transmit_response(p, "100 Trying", req); 13794 13795 if (p->t38.state == T38_PEER_REINVITE) { 13796 struct ast_channel *bridgepeer = NULL; 13797 struct sip_pvt *bridgepvt = NULL; 13798 13799 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13800 /* 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*/ 13801 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 13802 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13803 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13804 if (bridgepvt->t38.state == T38_DISABLED) { 13805 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 13806 /* Send re-invite to the bridged channel */ 13807 sip_handle_t38_reinvite(bridgepeer, p, 1); 13808 } else { /* Something is wrong with peers udptl struct */ 13809 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 13810 ast_mutex_lock(&bridgepvt->lock); 13811 bridgepvt->t38.state = T38_DISABLED; 13812 ast_mutex_unlock(&bridgepvt->lock); 13813 if (option_debug > 1) 13814 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 13815 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13816 transmit_response(p, "488 Not acceptable here", req); 13817 else 13818 transmit_response_reliable(p, "488 Not acceptable here", req); 13819 13820 } 13821 } else { 13822 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 13823 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13824 p->t38.state = T38_ENABLED; 13825 if (option_debug) 13826 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13827 } 13828 } else { 13829 /* Other side is not a SIP channel */ 13830 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13831 transmit_response(p, "488 Not acceptable here", req); 13832 else 13833 transmit_response_reliable(p, "488 Not acceptable here", req); 13834 p->t38.state = T38_DISABLED; 13835 if (option_debug > 1) 13836 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13837 13838 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 13839 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13840 } 13841 } else { 13842 /* we are not bridged in a call */ 13843 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13844 p->t38.state = T38_ENABLED; 13845 if (option_debug) 13846 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13847 } 13848 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 13849 int sendok = TRUE; 13850 13851 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 13852 /* so handle it here (re-invite other party to RTP) */ 13853 struct ast_channel *bridgepeer = NULL; 13854 struct sip_pvt *bridgepvt = NULL; 13855 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13856 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13857 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13858 /* Does the bridged peer have T38 ? */ 13859 if (bridgepvt->t38.state == T38_ENABLED) { 13860 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 13861 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 13862 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13863 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 13864 else 13865 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 13866 sendok = FALSE; 13867 } 13868 /* No bridged peer with T38 enabled*/ 13869 } 13870 } 13871 /* Respond to normal re-invite */ 13872 if (sendok) 13873 /* If this is not a re-invite or something to ignore - it's critical */ 13874 transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ? XMIT_UNRELIABLE : XMIT_CRITICAL); 13875 } 13876 p->invitestate = INV_TERMINATED; 13877 break; 13878 default: 13879 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 13880 transmit_response(p, "100 Trying", req); 13881 break; 13882 } 13883 } else { 13884 if (p && (p->autokillid == -1)) { 13885 const char *msg; 13886 13887 if (!p->jointcapability) 13888 msg = "488 Not Acceptable Here (codec error)"; 13889 else { 13890 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 13891 msg = "503 Unavailable"; 13892 } 13893 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13894 transmit_response(p, msg, req); 13895 else 13896 transmit_response_reliable(p, msg, req); 13897 p->invitestate = INV_COMPLETED; 13898 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13899 } 13900 } 13901 return res; 13902 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14514 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().
14515 { 14516 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14517 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14518 ast_verbose("Receiving message!\n"); 14519 receive_message(p, req); 14520 } else 14521 transmit_response(p, "202 Accepted", req); 14522 return 1; 14523 }
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 13065 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().
13066 { 13067 /* This is mostly a skeleton for future improvements */ 13068 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13069 int res = 0; 13070 const char *event = get_header(req, "Event"); 13071 char *eventid = NULL; 13072 char *sep; 13073 13074 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13075 *sep++ = '\0'; 13076 eventid = sep; 13077 } 13078 13079 if (option_debug > 1 && sipdebug) 13080 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13081 13082 if (strcmp(event, "refer")) { 13083 /* We don't understand this event. */ 13084 /* Here's room to implement incoming voicemail notifications :-) */ 13085 transmit_response(p, "489 Bad event", req); 13086 res = -1; 13087 } else { 13088 /* Save nesting depth for now, since there might be other events we will 13089 support in the future */ 13090 13091 /* Handle REFER notifications */ 13092 13093 char buf[1024]; 13094 char *cmd, *code; 13095 int respcode; 13096 int success = TRUE; 13097 13098 /* EventID for each transfer... EventID is basically the REFER cseq 13099 13100 We are getting notifications on a call that we transfered 13101 We should hangup when we are getting a 200 OK in a sipfrag 13102 Check if we have an owner of this event */ 13103 13104 /* Check the content type */ 13105 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13106 /* We need a sipfrag */ 13107 transmit_response(p, "400 Bad request", req); 13108 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13109 return -1; 13110 } 13111 13112 /* Get the text of the attachment */ 13113 if (get_msg_text(buf, sizeof(buf), req)) { 13114 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13115 transmit_response(p, "400 Bad request", req); 13116 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13117 return -1; 13118 } 13119 13120 /* 13121 From the RFC... 13122 A minimal, but complete, implementation can respond with a single 13123 NOTIFY containing either the body: 13124 SIP/2.0 100 Trying 13125 13126 if the subscription is pending, the body: 13127 SIP/2.0 200 OK 13128 if the reference was successful, the body: 13129 SIP/2.0 503 Service Unavailable 13130 if the reference failed, or the body: 13131 SIP/2.0 603 Declined 13132 13133 if the REFER request was accepted before approval to follow the 13134 reference could be obtained and that approval was subsequently denied 13135 (see Section 2.4.7). 13136 13137 If there are several REFERs in the same dialog, we need to 13138 match the ID of the event header... 13139 */ 13140 if (option_debug > 2) 13141 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13142 cmd = ast_skip_blanks(buf); 13143 code = cmd; 13144 /* We are at SIP/2.0 */ 13145 while(*code && (*code > 32)) { /* Search white space */ 13146 code++; 13147 } 13148 *code++ = '\0'; 13149 code = ast_skip_blanks(code); 13150 sep = code; 13151 sep++; 13152 while(*sep && (*sep > 32)) { /* Search white space */ 13153 sep++; 13154 } 13155 *sep++ = '\0'; /* Response string */ 13156 respcode = atoi(code); 13157 switch (respcode) { 13158 case 100: /* Trying: */ 13159 case 101: /* dialog establishment */ 13160 /* Don't do anything yet */ 13161 break; 13162 case 183: /* Ringing: */ 13163 /* Don't do anything yet */ 13164 break; 13165 case 200: /* OK: The new call is up, hangup this call */ 13166 /* Hangup the call that we are replacing */ 13167 break; 13168 case 301: /* Moved permenantly */ 13169 case 302: /* Moved temporarily */ 13170 /* Do we get the header in the packet in this case? */ 13171 success = FALSE; 13172 break; 13173 case 503: /* Service Unavailable: The new call failed */ 13174 /* Cancel transfer, continue the call */ 13175 success = FALSE; 13176 break; 13177 case 603: /* Declined: Not accepted */ 13178 /* Cancel transfer, continue the current call */ 13179 success = FALSE; 13180 break; 13181 } 13182 if (!success) { 13183 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13184 } 13185 13186 /* Confirm that we received this packet */ 13187 transmit_response(p, "200 OK", req); 13188 }; 13189 13190 if (!p->lastinvite) 13191 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13192 13193 return res; 13194 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13197 of file chan_sip.c.
References 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().
13198 { 13199 int res; 13200 13201 res = get_destination(p, req); 13202 build_contact(p); 13203 /* XXX Should we authenticate OPTIONS? XXX */ 13204 if (ast_strlen_zero(p->context)) 13205 ast_string_field_set(p, context, default_context); 13206 if (res < 0) 13207 transmit_response_with_allow(p, "404 Not Found", req, 0); 13208 else 13209 transmit_response_with_allow(p, "200 OK", req, 0); 13210 /* Destroy if this OPTIONS was the opening request, but not if 13211 it's in the middle of a normal call flow. */ 13212 if (!p->lastinvite) 13213 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13214 13215 return res; 13216 }
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 14070 of file chan_sip.c.
References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
14071 { 14072 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14073 /* Chan2: Call between asterisk and transferee */ 14074 14075 int res = 0; 14076 14077 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14078 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"); 14079 14080 if (!p->owner) { 14081 /* This is a REFER outside of an existing SIP dialog */ 14082 /* We can't handle that, so decline it */ 14083 if (option_debug > 2) 14084 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14085 transmit_response(p, "603 Declined (No dialog)", req); 14086 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14087 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14088 sip_alreadygone(p); 14089 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14090 } 14091 return 0; 14092 } 14093 14094 14095 /* Check if transfer is allowed from this device */ 14096 if (p->allowtransfer == TRANSFER_CLOSED ) { 14097 /* Transfer not allowed, decline */ 14098 transmit_response(p, "603 Declined (policy)", req); 14099 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14100 /* Do not destroy SIP session */ 14101 return 0; 14102 } 14103 14104 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14105 /* Already have a pending REFER */ 14106 transmit_response(p, "491 Request pending", req); 14107 append_history(p, "Xfer", "Refer failed. Request pending."); 14108 return 0; 14109 } 14110 14111 /* Allocate memory for call transfer data */ 14112 if (!p->refer && !sip_refer_allocate(p)) { 14113 transmit_response(p, "500 Internal Server Error", req); 14114 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14115 return -3; 14116 } 14117 14118 res = get_refer_info(p, req); /* Extract headers */ 14119 14120 p->refer->status = REFER_SENT; 14121 14122 if (res != 0) { 14123 switch (res) { 14124 case -2: /* Syntax error */ 14125 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14126 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14127 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14128 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14129 break; 14130 case -3: 14131 transmit_response(p, "603 Declined (Non sip: uri)", req); 14132 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14133 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14134 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14135 break; 14136 default: 14137 /* Refer-to extension not found, fake a failed transfer */ 14138 transmit_response(p, "202 Accepted", req); 14139 append_history(p, "Xfer", "Refer failed. Bad extension."); 14140 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14141 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14142 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14143 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14144 break; 14145 } 14146 return 0; 14147 } 14148 if (ast_strlen_zero(p->context)) 14149 ast_string_field_set(p, context, default_context); 14150 14151 /* If we do not support SIP domains, all transfers are local */ 14152 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14153 p->refer->localtransfer = 1; 14154 if (sipdebug && option_debug > 2) 14155 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14156 } else if (AST_LIST_EMPTY(&domain_list)) { 14157 /* This PBX don't bother with SIP domains, so all transfers are local */ 14158 p->refer->localtransfer = 1; 14159 } else 14160 if (sipdebug && option_debug > 2) 14161 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14162 14163 /* Is this a repeat of a current request? Ignore it */ 14164 /* Don't know what else to do right now. */ 14165 if (ignore) 14166 return res; 14167 14168 /* If this is a blind transfer, we have the following 14169 channels to work with: 14170 - chan1, chan2: The current call between transferer and transferee (2 channels) 14171 - target_channel: A new call from the transferee to the target (1 channel) 14172 We need to stay tuned to what happens in order to be able 14173 to bring back the call to the transferer */ 14174 14175 /* If this is a attended transfer, we should have all call legs within reach: 14176 - chan1, chan2: The call between the transferer and transferee (2 channels) 14177 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14178 We want to bridge chan2 with targetcall_pvt! 14179 14180 The replaces call id in the refer message points 14181 to the call leg between Asterisk and the transferer. 14182 So we need to connect the target and the transferee channel 14183 and hangup the two other channels silently 14184 14185 If the target is non-local, the call ID could be on a remote 14186 machine and we need to send an INVITE with replaces to the 14187 target. We basically handle this as a blind transfer 14188 and let the sip_call function catch that we need replaces 14189 header in the INVITE. 14190 */ 14191 14192 14193 /* Get the transferer's channel */ 14194 current.chan1 = p->owner; 14195 14196 /* Find the other part of the bridge (2) - transferee */ 14197 current.chan2 = ast_bridged_channel(current.chan1); 14198 14199 if (sipdebug && option_debug > 2) 14200 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>"); 14201 14202 if (!current.chan2 && !p->refer->attendedtransfer) { 14203 /* No bridged channel, propably IVR or echo or similar... */ 14204 /* Guess we should masquerade or something here */ 14205 /* Until we figure it out, refuse transfer of such calls */ 14206 if (sipdebug && option_debug > 2) 14207 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14208 p->refer->status = REFER_FAILED; 14209 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14210 transmit_response(p, "603 Declined", req); 14211 return -1; 14212 } 14213 14214 if (current.chan2) { 14215 if (sipdebug && option_debug > 3) 14216 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14217 14218 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14219 } 14220 14221 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14222 14223 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14224 if (p->refer->attendedtransfer) { 14225 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14226 return res; /* We're done with the transfer */ 14227 /* Fall through for remote transfers that we did not find locally */ 14228 if (sipdebug && option_debug > 3) 14229 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14230 /* Fallthrough if we can't find the call leg internally */ 14231 } 14232 14233 14234 /* Parking a call */ 14235 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14236 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14237 *nounlock = 1; 14238 ast_channel_unlock(current.chan1); 14239 copy_request(¤t.req, req); 14240 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14241 p->refer->status = REFER_200OK; 14242 append_history(p, "Xfer", "REFER to call parking."); 14243 if (sipdebug && option_debug > 3) 14244 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14245 sip_park(current.chan2, current.chan1, req, seqno); 14246 return res; 14247 } 14248 14249 /* Blind transfers and remote attended xfers */ 14250 transmit_response(p, "202 Accepted", req); 14251 14252 if (current.chan1 && current.chan2) { 14253 if (option_debug > 2) 14254 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14255 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14256 } 14257 if (current.chan2) { 14258 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14259 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14260 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14261 /* One for the new channel */ 14262 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14263 /* Attended transfer to remote host, prepare headers for the INVITE */ 14264 if (p->refer->referred_by) 14265 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14266 } 14267 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14268 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14269 char tempheader[BUFSIZ]; 14270 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14271 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14272 p->refer->replaces_callid_totag, 14273 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14274 p->refer->replaces_callid_fromtag); 14275 if (current.chan2) 14276 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14277 } 14278 /* Must release lock now, because it will not longer 14279 be accessible after the transfer! */ 14280 *nounlock = 1; 14281 ast_channel_unlock(current.chan1); 14282 14283 /* Connect the call */ 14284 14285 /* FAKE ringing if not attended transfer */ 14286 if (!p->refer->attendedtransfer) 14287 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14288 14289 /* For blind transfer, this will lead to a new call */ 14290 /* For attended transfer to remote host, this will lead to 14291 a new SIP call with a replaces header, if the dial plan allows it 14292 */ 14293 if (!current.chan2) { 14294 /* We have no bridge, so we're talking with Asterisk somehow */ 14295 /* We need to masquerade this call */ 14296 /* What to do to fix this situation: 14297 * Set up the new call in a new channel 14298 * Let the new channel masq into this channel 14299 Please add that code here :-) 14300 */ 14301 p->refer->status = REFER_FAILED; 14302 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14303 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14304 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14305 return -1; 14306 } 14307 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14308 14309 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14310 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14311 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14312 14313 if (!res) { 14314 /* Success - we have a new channel */ 14315 if (option_debug > 2) 14316 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14317 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14318 if (p->refer->localtransfer) 14319 p->refer->status = REFER_200OK; 14320 if (p->owner) 14321 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14322 append_history(p, "Xfer", "Refer succeeded."); 14323 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14324 /* Do not hangup call, the other side do that when we say 200 OK */ 14325 /* We could possibly implement a timer here, auto congestion */ 14326 res = 0; 14327 } else { 14328 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14329 if (option_debug > 2) 14330 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14331 append_history(p, "Xfer", "Refer failed."); 14332 /* Failure of some kind */ 14333 p->refer->status = REFER_FAILED; 14334 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14335 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14336 res = -1; 14337 } 14338 return res; 14339 }
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 14820 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().
14821 { 14822 enum check_auth_result res; 14823 14824 /* Use this as the basis */ 14825 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14826 ast_verbose("Using latest REGISTER request as basis request\n"); 14827 copy_request(&p->initreq, req); 14828 check_via(p, req); 14829 if ((res = register_verify(p, sin, req, e)) < 0) { 14830 const char *reason; 14831 14832 switch (res) { 14833 case AUTH_SECRET_FAILED: 14834 reason = "Wrong password"; 14835 break; 14836 case AUTH_USERNAME_MISMATCH: 14837 reason = "Username/auth name mismatch"; 14838 break; 14839 case AUTH_NOT_FOUND: 14840 reason = "No matching peer found"; 14841 break; 14842 case AUTH_UNKNOWN_DOMAIN: 14843 reason = "Not a local domain"; 14844 break; 14845 case AUTH_PEER_NOT_DYNAMIC: 14846 reason = "Peer is not supposed to register"; 14847 break; 14848 case AUTH_ACL_FAILED: 14849 reason = "Device does not match ACL"; 14850 break; 14851 default: 14852 reason = "Unknown failure"; 14853 break; 14854 } 14855 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 14856 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 14857 reason); 14858 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 14859 } else 14860 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 14861 14862 if (res < 1) { 14863 /* Destroy the session, but keep us around for just a bit in case they don't 14864 get our 200 OK */ 14865 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14866 } 14867 return res; 14868 }
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 14526 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, 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_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().
14527 { 14528 int gotdest; 14529 int res = 0; 14530 int firststate = AST_EXTENSION_REMOVED; 14531 struct sip_peer *authpeer = NULL; 14532 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14533 const char *accept = get_header(req, "Accept"); 14534 int resubscribe = (p->subscribed != NONE); 14535 char *temp, *event; 14536 14537 if (p->initreq.headers) { 14538 /* We already have a dialog */ 14539 if (p->initreq.method != SIP_SUBSCRIBE) { 14540 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14541 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14542 transmit_response(p, "403 Forbidden (within dialog)", req); 14543 /* Do not destroy session, since we will break the call if we do */ 14544 if (option_debug) 14545 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); 14546 return 0; 14547 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14548 if (option_debug) { 14549 if (resubscribe) 14550 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14551 else 14552 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14553 } 14554 } 14555 } 14556 14557 /* Check if we have a global disallow setting on subscriptions. 14558 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14559 */ 14560 if (!global_allowsubscribe) { 14561 transmit_response(p, "403 Forbidden (policy)", req); 14562 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14563 return 0; 14564 } 14565 14566 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14567 /* Use this as the basis */ 14568 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14569 ast_verbose("Creating new subscription\n"); 14570 14571 copy_request(&p->initreq, req); 14572 check_via(p, req); 14573 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14574 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14575 14576 /* Find parameters to Event: header value and remove them for now */ 14577 if (ast_strlen_zero(eventheader)) { 14578 transmit_response(p, "489 Bad Event", req); 14579 if (option_debug > 1) 14580 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14581 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14582 return 0; 14583 } 14584 14585 if ( (strchr(eventheader, ';'))) { 14586 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14587 temp = strchr(event, ';'); 14588 *temp = '\0'; /* Remove any options for now */ 14589 /* We might need to use them later :-) */ 14590 } else 14591 event = (char *) eventheader; /* XXX is this legal ? */ 14592 14593 /* Handle authentication */ 14594 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14595 /* if an authentication response was sent, we are done here */ 14596 if (res == AUTH_CHALLENGE_SENT) { 14597 if (authpeer) 14598 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14599 return 0; 14600 } 14601 if (res < 0) { 14602 if (res == AUTH_FAKE_AUTH) { 14603 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14604 transmit_fake_auth_response(p, req, 1); 14605 } else { 14606 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14607 transmit_response_reliable(p, "403 Forbidden", req); 14608 } 14609 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14610 if (authpeer) 14611 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14612 return 0; 14613 } 14614 14615 /* Check if this user/peer is allowed to subscribe at all */ 14616 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14617 transmit_response(p, "403 Forbidden (policy)", req); 14618 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14619 if (authpeer) 14620 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14621 return 0; 14622 } 14623 14624 /* Get destination right away */ 14625 gotdest = get_destination(p, NULL); 14626 14627 /* Initialize the context if it hasn't been already; 14628 note this is done _after_ handling any domain lookups, 14629 because the context specified there is for calls, not 14630 subscriptions 14631 */ 14632 if (!ast_strlen_zero(p->subscribecontext)) 14633 ast_string_field_set(p, context, p->subscribecontext); 14634 else if (ast_strlen_zero(p->context)) 14635 ast_string_field_set(p, context, default_context); 14636 14637 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14638 parse_ok_contact(p, req); 14639 14640 build_contact(p); 14641 if (gotdest) { 14642 transmit_response(p, "404 Not Found", req); 14643 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14644 if (authpeer) 14645 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14646 return 0; 14647 } 14648 14649 /* Initialize tag for new subscriptions */ 14650 if (ast_strlen_zero(p->tag)) 14651 make_our_tag(p->tag, sizeof(p->tag)); 14652 14653 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14654 if (authpeer) /* No need for authpeer here */ 14655 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14656 14657 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14658 /* Polycom phones only handle xpidf+xml, even if they say they can 14659 handle pidf+xml as well 14660 */ 14661 if (strstr(p->useragent, "Polycom")) { 14662 p->subscribed = XPIDF_XML; 14663 } else if (strstr(accept, "application/pidf+xml")) { 14664 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14665 } else if (strstr(accept, "application/dialog-info+xml")) { 14666 p->subscribed = DIALOG_INFO_XML; 14667 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14668 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14669 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14670 } else if (strstr(accept, "application/xpidf+xml")) { 14671 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14672 } else if (ast_strlen_zero(accept)) { 14673 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14674 transmit_response(p, "489 Bad Event", req); 14675 14676 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14677 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14678 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14679 return 0; 14680 } 14681 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14682 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14683 } else { 14684 /* Can't find a format for events that we know about */ 14685 char mybuf[200]; 14686 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14687 transmit_response(p, mybuf, req); 14688 14689 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14690 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14691 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14692 return 0; 14693 } 14694 } else if (!strcmp(event, "message-summary")) { 14695 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14696 /* Format requested that we do not support */ 14697 transmit_response(p, "406 Not Acceptable", req); 14698 if (option_debug > 1) 14699 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 14700 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14701 if (authpeer) /* No need for authpeer here */ 14702 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14703 return 0; 14704 } 14705 /* Looks like they actually want a mailbox status 14706 This version of Asterisk supports mailbox subscriptions 14707 The subscribed URI needs to exist in the dial plan 14708 In most devices, this is configurable to the voicemailmain extension you use 14709 */ 14710 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 14711 transmit_response(p, "404 Not found (no mailbox)", req); 14712 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14713 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 14714 if (authpeer) /* No need for authpeer here */ 14715 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14716 return 0; 14717 } 14718 14719 p->subscribed = MWI_NOTIFICATION; 14720 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 14721 /* We only allow one subscription per peer */ 14722 sip_destroy(authpeer->mwipvt); 14723 authpeer->mwipvt = p; /* Link from peer to pvt */ 14724 p->relatedpeer = authpeer; /* Link from pvt to peer */ 14725 } else { /* At this point, Asterisk does not understand the specified event */ 14726 transmit_response(p, "489 Bad Event", req); 14727 if (option_debug > 1) 14728 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 14729 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14730 if (authpeer) /* No need for authpeer here */ 14731 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14732 return 0; 14733 } 14734 14735 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 14736 if (p->stateid > -1) 14737 ast_extension_state_del(p->stateid, cb_extensionstate); 14738 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 14739 } 14740 14741 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14742 p->lastinvite = seqno; 14743 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 14744 p->expiry = atoi(get_header(req, "Expires")); 14745 14746 /* check if the requested expiry-time is within the approved limits from sip.conf */ 14747 if (p->expiry > max_expiry) 14748 p->expiry = max_expiry; 14749 if (p->expiry < min_expiry && p->expiry > 0) 14750 p->expiry = min_expiry; 14751 14752 if (sipdebug || option_debug > 1) { 14753 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 14754 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 14755 else 14756 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 14757 } 14758 if (p->autokillid > -1) 14759 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 14760 if (p->expiry > 0) 14761 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 14762 14763 if (p->subscribed == MWI_NOTIFICATION) { 14764 transmit_response(p, "200 OK", req); 14765 if (p->relatedpeer) { /* Send first notification */ 14766 ASTOBJ_WRLOCK(p->relatedpeer); 14767 sip_send_mwi_to_peer(p->relatedpeer); 14768 ASTOBJ_UNLOCK(p->relatedpeer); 14769 } 14770 } else { 14771 struct sip_pvt *p_old; 14772 14773 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 14774 14775 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)); 14776 transmit_response(p, "404 Not found", req); 14777 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14778 return 0; 14779 } 14780 14781 transmit_response(p, "200 OK", req); 14782 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 14783 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 14784 /* hide the 'complete' exten/context in the refer_to field for later display */ 14785 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 14786 14787 /* remove any old subscription from this peer for the same exten/context, 14788 as the peer has obviously forgotten about it and it's wasteful to wait 14789 for it to expire and send NOTIFY messages to the peer only to have them 14790 ignored (or generate errors) 14791 */ 14792 ast_mutex_lock(&iflock); 14793 for (p_old = iflist; p_old; p_old = p_old->next) { 14794 if (p_old == p) 14795 continue; 14796 if (p_old->initreq.method != SIP_SUBSCRIBE) 14797 continue; 14798 if (p_old->subscribed == NONE) 14799 continue; 14800 ast_mutex_lock(&p_old->lock); 14801 if (!strcmp(p_old->username, p->username)) { 14802 if (!strcmp(p_old->exten, p->exten) && 14803 !strcmp(p_old->context, p->context)) { 14804 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 14805 ast_mutex_unlock(&p_old->lock); 14806 break; 14807 } 14808 } 14809 ast_mutex_unlock(&p_old->lock); 14810 } 14811 ast_mutex_unlock(&iflock); 14812 } 14813 if (!p->expiry) 14814 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14815 } 14816 return 1; 14817 }
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 12379 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), 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, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), 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_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12380 { 12381 struct ast_channel *owner; 12382 int sipmethod; 12383 int res = 1; 12384 const char *c = get_header(req, "Cseq"); 12385 const char *msg = strchr(c, ' '); 12386 12387 if (!msg) 12388 msg = ""; 12389 else 12390 msg++; 12391 sipmethod = find_sip_method(msg); 12392 12393 owner = p->owner; 12394 if (owner) 12395 owner->hangupcause = hangup_sip2cause(resp); 12396 12397 /* Acknowledge whatever it is destined for */ 12398 if ((resp >= 100) && (resp <= 199)) 12399 __sip_semi_ack(p, seqno, 0, sipmethod); 12400 else 12401 __sip_ack(p, seqno, 0, sipmethod); 12402 12403 /* Get their tag if we haven't already */ 12404 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12405 char tag[128]; 12406 12407 gettag(req, "To", tag, sizeof(tag)); 12408 ast_string_field_set(p, theirtag, tag); 12409 } 12410 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12411 /* We don't really care what the response is, just that it replied back. 12412 Well, as long as it's not a 100 response... since we might 12413 need to hang around for something more "definitive" */ 12414 if (resp != 100) 12415 handle_response_peerpoke(p, resp, req); 12416 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12417 switch(resp) { 12418 case 100: /* 100 Trying */ 12419 case 101: /* 101 Dialog establishment */ 12420 if (sipmethod == SIP_INVITE) 12421 handle_response_invite(p, resp, rest, req, seqno); 12422 break; 12423 case 183: /* 183 Session Progress */ 12424 if (sipmethod == SIP_INVITE) 12425 handle_response_invite(p, resp, rest, req, seqno); 12426 break; 12427 case 180: /* 180 Ringing */ 12428 if (sipmethod == SIP_INVITE) 12429 handle_response_invite(p, resp, rest, req, seqno); 12430 break; 12431 case 200: /* 200 OK */ 12432 p->authtries = 0; /* Reset authentication counter */ 12433 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12434 /* We successfully transmitted a message 12435 or a video update request in INFO */ 12436 /* Nothing happens here - the message is inside a dialog */ 12437 } else if (sipmethod == SIP_INVITE) { 12438 handle_response_invite(p, resp, rest, req, seqno); 12439 } else if (sipmethod == SIP_NOTIFY) { 12440 /* They got the notify, this is the end */ 12441 if (p->owner) { 12442 if (!p->refer) { 12443 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12444 ast_queue_hangup(p->owner); 12445 } else if (option_debug > 3) 12446 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12447 } else { 12448 if (p->subscribed == NONE) 12449 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12450 } 12451 } else if (sipmethod == SIP_REGISTER) 12452 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12453 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12454 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12455 break; 12456 case 202: /* Transfer accepted */ 12457 if (sipmethod == SIP_REFER) 12458 handle_response_refer(p, resp, rest, req, seqno); 12459 break; 12460 case 401: /* Not www-authorized on SIP method */ 12461 if (sipmethod == SIP_INVITE) 12462 handle_response_invite(p, resp, rest, req, seqno); 12463 else if (sipmethod == SIP_REFER) 12464 handle_response_refer(p, resp, rest, req, seqno); 12465 else if (p->registry && sipmethod == SIP_REGISTER) 12466 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12467 else if (sipmethod == SIP_BYE) { 12468 if (ast_strlen_zero(p->authname)) { 12469 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12470 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12471 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12472 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12473 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12474 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12475 /* We fail to auth bye on our own call, but still needs to tear down the call. 12476 Life, they call it. */ 12477 } 12478 } else { 12479 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12480 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12481 } 12482 break; 12483 case 403: /* Forbidden - we failed authentication */ 12484 if (sipmethod == SIP_INVITE) 12485 handle_response_invite(p, resp, rest, req, seqno); 12486 else if (p->registry && sipmethod == SIP_REGISTER) 12487 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12488 else { 12489 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12490 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12491 } 12492 break; 12493 case 404: /* Not found */ 12494 if (p->registry && sipmethod == SIP_REGISTER) 12495 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12496 else if (sipmethod == SIP_INVITE) 12497 handle_response_invite(p, resp, rest, req, seqno); 12498 else if (owner) 12499 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12500 break; 12501 case 407: /* Proxy auth required */ 12502 if (sipmethod == SIP_INVITE) 12503 handle_response_invite(p, resp, rest, req, seqno); 12504 else if (sipmethod == SIP_REFER) 12505 handle_response_refer(p, resp, rest, req, seqno); 12506 else if (p->registry && sipmethod == SIP_REGISTER) 12507 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12508 else if (sipmethod == SIP_BYE) { 12509 if (ast_strlen_zero(p->authname)) { 12510 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12511 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12512 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12513 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12514 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12515 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12516 } 12517 } else /* We can't handle this, giving up in a bad way */ 12518 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12519 12520 break; 12521 case 408: /* Request timeout - terminate dialog */ 12522 if (sipmethod == SIP_INVITE) 12523 handle_response_invite(p, resp, rest, req, seqno); 12524 else if (sipmethod == SIP_REGISTER) 12525 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12526 else if (sipmethod == SIP_BYE) { 12527 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12528 if (option_debug) 12529 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12530 } else { 12531 if (owner) 12532 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12533 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12534 } 12535 break; 12536 case 481: /* Call leg does not exist */ 12537 if (sipmethod == SIP_INVITE) { 12538 handle_response_invite(p, resp, rest, req, seqno); 12539 } else if (sipmethod == SIP_REFER) { 12540 handle_response_refer(p, resp, rest, req, seqno); 12541 } else if (sipmethod == SIP_BYE) { 12542 /* The other side has no transaction to bye, 12543 just assume it's all right then */ 12544 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12545 } else if (sipmethod == SIP_CANCEL) { 12546 /* The other side has no transaction to cancel, 12547 just assume it's all right then */ 12548 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12549 } else { 12550 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12551 /* Guessing that this is not an important request */ 12552 } 12553 break; 12554 case 487: 12555 if (sipmethod == SIP_INVITE) 12556 handle_response_invite(p, resp, rest, req, seqno); 12557 break; 12558 case 488: /* Not acceptable here - codec error */ 12559 if (sipmethod == SIP_INVITE) 12560 handle_response_invite(p, resp, rest, req, seqno); 12561 break; 12562 case 491: /* Pending */ 12563 if (sipmethod == SIP_INVITE) 12564 handle_response_invite(p, resp, rest, req, seqno); 12565 else { 12566 if (option_debug) 12567 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12568 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12569 } 12570 break; 12571 case 501: /* Not Implemented */ 12572 if (sipmethod == SIP_INVITE) 12573 handle_response_invite(p, resp, rest, req, seqno); 12574 else if (sipmethod == SIP_REFER) 12575 handle_response_refer(p, resp, rest, req, seqno); 12576 else 12577 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12578 break; 12579 case 603: /* Declined transfer */ 12580 if (sipmethod == SIP_REFER) { 12581 handle_response_refer(p, resp, rest, req, seqno); 12582 break; 12583 } 12584 /* Fallthrough */ 12585 default: 12586 if ((resp >= 300) && (resp < 700)) { 12587 /* Fatal response */ 12588 if ((option_verbose > 2) && (resp != 487)) 12589 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12590 12591 if (sipmethod == SIP_INVITE) 12592 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12593 12594 /* XXX Locking issues?? XXX */ 12595 switch(resp) { 12596 case 300: /* Multiple Choices */ 12597 case 301: /* Moved permenantly */ 12598 case 302: /* Moved temporarily */ 12599 case 305: /* Use Proxy */ 12600 parse_moved_contact(p, req); 12601 /* Fall through */ 12602 case 486: /* Busy here */ 12603 case 600: /* Busy everywhere */ 12604 case 603: /* Decline */ 12605 if (p->owner) 12606 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12607 break; 12608 case 482: /* 12609 \note SIP is incapable of performing a hairpin call, which 12610 is yet another failure of not having a layer 2 (again, YAY 12611 IETF for thinking ahead). So we treat this as a call 12612 forward and hope we end up at the right place... */ 12613 if (option_debug) 12614 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12615 if (p->owner) 12616 ast_string_field_build(p->owner, call_forward, 12617 "Local/%s@%s", p->username, p->context); 12618 /* Fall through */ 12619 case 480: /* Temporarily Unavailable */ 12620 case 404: /* Not Found */ 12621 case 410: /* Gone */ 12622 case 400: /* Bad Request */ 12623 case 500: /* Server error */ 12624 if (sipmethod == SIP_REFER) { 12625 handle_response_refer(p, resp, rest, req, seqno); 12626 break; 12627 } 12628 /* Fall through */ 12629 case 503: /* Service Unavailable */ 12630 case 504: /* Server Timeout */ 12631 if (owner) 12632 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12633 break; 12634 default: 12635 /* Send hangup */ 12636 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12637 ast_queue_hangup(p->owner); 12638 break; 12639 } 12640 /* ACK on invite */ 12641 if (sipmethod == SIP_INVITE) 12642 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12643 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12644 sip_alreadygone(p); 12645 if (!p->owner) 12646 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12647 } else if ((resp >= 100) && (resp < 200)) { 12648 if (sipmethod == SIP_INVITE) { 12649 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12650 sip_cancel_destroy(p); 12651 if (find_sdp(req)) 12652 process_sdp(p, req); 12653 if (p->owner) { 12654 /* Queue a progress frame */ 12655 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12656 } 12657 } 12658 } else 12659 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)); 12660 } 12661 } else { 12662 /* Responses to OUTGOING SIP requests on INCOMING calls 12663 get handled here. As well as out-of-call message responses */ 12664 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12665 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12666 12667 if (sipmethod == SIP_INVITE && resp == 200) { 12668 /* Tags in early session is replaced by the tag in 200 OK, which is 12669 the final reply to our INVITE */ 12670 char tag[128]; 12671 12672 gettag(req, "To", tag, sizeof(tag)); 12673 ast_string_field_set(p, theirtag, tag); 12674 } 12675 12676 switch(resp) { 12677 case 200: 12678 if (sipmethod == SIP_INVITE) { 12679 handle_response_invite(p, resp, rest, req, seqno); 12680 } else if (sipmethod == SIP_CANCEL) { 12681 if (option_debug) 12682 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12683 12684 /* Wait for 487, then destroy */ 12685 } else if (sipmethod == SIP_NOTIFY) { 12686 /* They got the notify, this is the end */ 12687 if (p->owner) { 12688 if (p->refer) { 12689 if (option_debug) 12690 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12691 } else 12692 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12693 /* ast_queue_hangup(p->owner); Disabled */ 12694 } else { 12695 if (!p->subscribed && !p->refer) 12696 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12697 } 12698 } else if (sipmethod == SIP_BYE) 12699 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12700 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12701 /* We successfully transmitted a message or 12702 a video update request in INFO */ 12703 ; 12704 else if (sipmethod == SIP_BYE) 12705 /* Ok, we're ready to go */ 12706 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12707 break; 12708 case 202: /* Transfer accepted */ 12709 if (sipmethod == SIP_REFER) 12710 handle_response_refer(p, resp, rest, req, seqno); 12711 break; 12712 case 401: /* www-auth */ 12713 case 407: 12714 if (sipmethod == SIP_REFER) 12715 handle_response_refer(p, resp, rest, req, seqno); 12716 else if (sipmethod == SIP_INVITE) 12717 handle_response_invite(p, resp, rest, req, seqno); 12718 else if (sipmethod == SIP_BYE) { 12719 char *auth, *auth2; 12720 12721 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 12722 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 12723 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 12724 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12725 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12726 } 12727 } 12728 break; 12729 case 481: /* Call leg does not exist */ 12730 if (sipmethod == SIP_INVITE) { 12731 /* Re-invite failed */ 12732 handle_response_invite(p, resp, rest, req, seqno); 12733 } else if (sipmethod == SIP_BYE) { 12734 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12735 } else if (sipdebug) { 12736 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 12737 } 12738 break; 12739 case 501: /* Not Implemented */ 12740 if (sipmethod == SIP_INVITE) 12741 handle_response_invite(p, resp, rest, req, seqno); 12742 else if (sipmethod == SIP_REFER) 12743 handle_response_refer(p, resp, rest, req, seqno); 12744 break; 12745 case 603: /* Declined transfer */ 12746 if (sipmethod == SIP_REFER) { 12747 handle_response_refer(p, resp, rest, req, seqno); 12748 break; 12749 } 12750 /* Fallthrough */ 12751 default: /* Errors without handlers */ 12752 if ((resp >= 100) && (resp < 200)) { 12753 if (sipmethod == SIP_INVITE) { /* re-invite */ 12754 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12755 sip_cancel_destroy(p); 12756 } 12757 } 12758 if ((resp >= 300) && (resp < 700)) { 12759 if ((option_verbose > 2) && (resp != 487)) 12760 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)); 12761 switch(resp) { 12762 case 488: /* Not acceptable here - codec error */ 12763 case 603: /* Decline */ 12764 case 500: /* Server error */ 12765 case 503: /* Service Unavailable */ 12766 case 504: /* Server timeout */ 12767 12768 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 12769 sip_cancel_destroy(p); 12770 } 12771 break; 12772 } 12773 } 12774 break; 12775 } 12776 } 12777 }
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 11818 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_rtp_set_rtptimers_onhold(), ast_sched_del(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, authenticate(), 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, INV_CALLING, 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::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, 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_PENDINGBYE, SIP_PKT_IGNORE, 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(), WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
11819 { 11820 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 11821 int res = 0; 11822 int xmitres = 0; 11823 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 11824 struct ast_channel *bridgepeer = NULL; 11825 11826 if (option_debug > 3) { 11827 if (reinvite) 11828 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 11829 else 11830 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 11831 } 11832 11833 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 11834 if (option_debug) 11835 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 11836 return; 11837 } 11838 11839 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 11840 if (p->initid > -1) { 11841 /* Don't auto congest anymore since we've gotten something useful back */ 11842 ast_sched_del(sched, p->initid); 11843 p->initid = -1; 11844 } 11845 11846 /* RFC3261 says we must treat every 1xx response (but not 100) 11847 that we don't recognize as if it was 183. 11848 */ 11849 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183) 11850 resp = 183; 11851 11852 /* Any response between 100 and 199 is PROCEEDING */ 11853 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 11854 p->invitestate = INV_PROCEEDING; 11855 11856 /* Final response, not 200 ? */ 11857 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 11858 p->invitestate = INV_COMPLETED; 11859 11860 11861 switch (resp) { 11862 case 100: /* Trying */ 11863 case 101: /* Dialog establishment */ 11864 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11865 sip_cancel_destroy(p); 11866 check_pendings(p); 11867 break; 11868 11869 case 180: /* 180 Ringing */ 11870 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11871 sip_cancel_destroy(p); 11872 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11873 ast_queue_control(p->owner, AST_CONTROL_RINGING); 11874 if (p->owner->_state != AST_STATE_UP) { 11875 ast_setstate(p->owner, AST_STATE_RINGING); 11876 } 11877 } 11878 if (find_sdp(req)) { 11879 p->invitestate = INV_EARLY_MEDIA; 11880 res = process_sdp(p, req); 11881 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11882 /* Queue a progress frame only if we have SDP in 180 */ 11883 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11884 } 11885 } 11886 check_pendings(p); 11887 break; 11888 11889 case 183: /* Session progress */ 11890 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11891 sip_cancel_destroy(p); 11892 /* Ignore 183 Session progress without SDP */ 11893 if (find_sdp(req)) { 11894 p->invitestate = INV_EARLY_MEDIA; 11895 res = process_sdp(p, req); 11896 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11897 /* Queue a progress frame */ 11898 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11899 } 11900 } 11901 check_pendings(p); 11902 break; 11903 11904 case 200: /* 200 OK on invite - someone's answering our call */ 11905 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11906 sip_cancel_destroy(p); 11907 p->authtries = 0; 11908 if (find_sdp(req)) { 11909 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 11910 if (!reinvite) 11911 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 11912 /* For re-invites, we try to recover */ 11913 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11914 } 11915 11916 /* Parse contact header for continued conversation */ 11917 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 11918 /* This is important when we have a SIP proxy between us and the phone */ 11919 if (outgoing) { 11920 update_call_counter(p, DEC_CALL_RINGING); 11921 parse_ok_contact(p, req); 11922 if(set_address_from_contact(p)) { 11923 /* Bad contact - we don't know how to reach this device */ 11924 /* We need to ACK, but then send a bye */ 11925 /* OEJ: Possible issue that may need a check: 11926 If we have a proxy route between us and the device, 11927 should we care about resolving the contact 11928 or should we just send it? 11929 */ 11930 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11931 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11932 } 11933 11934 /* Save Record-Route for any later requests we make on this dialogue */ 11935 build_route(p, req, 1); 11936 } 11937 11938 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 11939 struct sip_pvt *bridgepvt = NULL; 11940 11941 if (!bridgepeer->tech) { 11942 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 11943 break; 11944 } 11945 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 11946 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 11947 if (bridgepvt->udptl) { 11948 if (p->t38.state == T38_PEER_REINVITE) { 11949 sip_handle_t38_reinvite(bridgepeer, p, 0); 11950 ast_rtp_set_rtptimers_onhold(p->rtp); 11951 if (p->vrtp) 11952 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 11953 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 11954 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 11955 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 11956 /* XXXX Should we really destroy this session here, without any response at all??? */ 11957 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11958 } 11959 } else { 11960 if (option_debug > 1) 11961 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 11962 ast_mutex_lock(&bridgepvt->lock); 11963 bridgepvt->t38.state = T38_DISABLED; 11964 ast_mutex_unlock(&bridgepvt->lock); 11965 if (option_debug) 11966 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 11967 p->t38.state = T38_DISABLED; 11968 if (option_debug > 1) 11969 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11970 } 11971 } else { 11972 /* Other side is not a SIP channel */ 11973 if (option_debug > 1) 11974 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 11975 p->t38.state = T38_DISABLED; 11976 if (option_debug > 1) 11977 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11978 } 11979 } 11980 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 11981 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 11982 p->t38.state = T38_ENABLED; 11983 if (option_debug) 11984 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11985 } 11986 11987 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11988 if (!reinvite) { 11989 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 11990 } else { /* RE-invite */ 11991 ast_queue_frame(p->owner, &ast_null_frame); 11992 } 11993 } else { 11994 /* It's possible we're getting an 200 OK after we've tried to disconnect 11995 by sending CANCEL */ 11996 /* First send ACK, then send bye */ 11997 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11998 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11999 } 12000 /* If I understand this right, the branch is different for a non-200 ACK only */ 12001 p->invitestate = INV_TERMINATED; 12002 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12003 check_pendings(p); 12004 break; 12005 case 407: /* Proxy authentication */ 12006 case 401: /* Www auth */ 12007 /* First we ACK */ 12008 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12009 if (p->options) 12010 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12011 12012 /* Then we AUTH */ 12013 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12014 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12015 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12016 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12017 if (p->authtries < MAX_AUTHTRIES) 12018 p->invitestate = INV_CALLING; 12019 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12020 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12021 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12022 sip_alreadygone(p); 12023 if (p->owner) 12024 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12025 } 12026 } 12027 break; 12028 12029 case 403: /* Forbidden */ 12030 /* First we ACK */ 12031 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12032 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12033 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12034 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12035 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12036 sip_alreadygone(p); 12037 break; 12038 12039 case 404: /* Not found */ 12040 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12041 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12042 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12043 sip_alreadygone(p); 12044 break; 12045 12046 case 408: /* Request timeout */ 12047 case 481: /* Call leg does not exist */ 12048 /* Could be REFER caused INVITE with replaces */ 12049 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12050 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12051 if (p->owner) 12052 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12053 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12054 break; 12055 case 487: /* Cancelled transaction */ 12056 /* We have sent CANCEL on an outbound INVITE 12057 This transaction is already scheduled to be killed by sip_hangup(). 12058 */ 12059 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12060 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12061 ast_queue_hangup(p->owner); 12062 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12063 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12064 update_call_counter(p, DEC_CALL_LIMIT); 12065 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12066 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12067 sip_alreadygone(p); 12068 } 12069 break; 12070 case 488: /* Not acceptable here */ 12071 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12072 if (reinvite && p->udptl) { 12073 /* If this is a T.38 call, we should go back to 12074 audio. If this is an audio call - something went 12075 terribly wrong since we don't renegotiate codecs, 12076 only IP/port . 12077 */ 12078 p->t38.state = T38_DISABLED; 12079 /* Try to reset RTP timers */ 12080 ast_rtp_set_rtptimers_onhold(p->rtp); 12081 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12082 12083 /*! \bug Is there any way we can go back to the audio call on both 12084 sides here? 12085 */ 12086 /* While figuring that out, hangup the call */ 12087 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12088 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12089 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12090 } else { 12091 /* We can't set up this call, so give up */ 12092 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12093 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12094 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12095 } 12096 break; 12097 case 491: /* Pending */ 12098 /* we really should have to wait a while, then retransmit */ 12099 /* We should support the retry-after at some point */ 12100 /* At this point, we treat this as a congestion */ 12101 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12102 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12103 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12104 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12105 break; 12106 12107 case 501: /* Not implemented */ 12108 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12109 if (p->owner) 12110 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12111 break; 12112 } 12113 if (xmitres == XMIT_ERROR) 12114 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12115 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12319 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12320 { 12321 struct sip_peer *peer = p->relatedpeer; 12322 int statechanged, is_reachable, was_reachable; 12323 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12324 12325 /* 12326 * Compute the response time to a ping (goes in peer->lastms.) 12327 * -1 means did not respond, 0 means unknown, 12328 * 1..maxms is a valid response, >maxms means late response. 12329 */ 12330 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12331 pingtime = 1; 12332 12333 /* Now determine new state and whether it has changed. 12334 * Use some helper variables to simplify the writing 12335 * of the expressions. 12336 */ 12337 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12338 is_reachable = pingtime <= peer->maxms; 12339 statechanged = peer->lastms == 0 /* yes, unknown before */ 12340 || was_reachable != is_reachable; 12341 12342 peer->lastms = pingtime; 12343 peer->call = NULL; 12344 if (statechanged) { 12345 const char *s = is_reachable ? "Reachable" : "Lagged"; 12346 12347 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12348 peer->name, s, pingtime, peer->maxms); 12349 ast_device_state_changed("SIP/%s", peer->name); 12350 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12351 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12352 peer->name, s, pingtime); 12353 } 12354 12355 if (peer->pokeexpire > -1) 12356 ast_sched_del(sched, peer->pokeexpire); 12357 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12358 12359 /* Try again eventually */ 12360 peer->pokeexpire = ast_sched_add(sched, 12361 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12362 sip_poke_peer_s, peer); 12363 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12120 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().
12121 { 12122 char *auth = "Proxy-Authenticate"; 12123 char *auth2 = "Proxy-Authorization"; 12124 12125 /* If no refer structure exists, then do nothing */ 12126 if (!p->refer) 12127 return; 12128 12129 switch (resp) { 12130 case 202: /* Transfer accepted */ 12131 /* We need to do something here */ 12132 /* The transferee is now sending INVITE to target */ 12133 p->refer->status = REFER_ACCEPTED; 12134 /* Now wait for next message */ 12135 if (option_debug > 2) 12136 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12137 /* We should hang along, waiting for NOTIFY's here */ 12138 break; 12139 12140 case 401: /* Not www-authorized on SIP method */ 12141 case 407: /* Proxy auth */ 12142 if (ast_strlen_zero(p->authname)) { 12143 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12144 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12145 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12146 } 12147 if (resp == 401) { 12148 auth = "WWW-Authenticate"; 12149 auth2 = "Authorization"; 12150 } 12151 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12152 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12153 p->refer->status = REFER_NOAUTH; 12154 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12155 } 12156 break; 12157 case 481: /* Call leg does not exist */ 12158 12159 /* A transfer with Replaces did not work */ 12160 /* OEJ: We should Set flag, cancel the REFER, go back 12161 to original call - but right now we can't */ 12162 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12163 if (p->owner) 12164 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12165 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12166 break; 12167 12168 case 500: /* Server error */ 12169 case 501: /* Method not implemented */ 12170 /* Return to the current call onhold */ 12171 /* Status flag needed to be reset */ 12172 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12173 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12174 p->refer->status = REFER_FAILED; 12175 break; 12176 case 603: /* Transfer declined */ 12177 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12178 p->refer->status = REFER_FAILED; 12179 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12180 break; 12181 } 12182 }
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 12185 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().
12186 { 12187 int expires, expires_ms; 12188 struct sip_registry *r; 12189 r=p->registry; 12190 12191 switch (resp) { 12192 case 401: /* Unauthorized */ 12193 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12194 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12195 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12196 } 12197 break; 12198 case 403: /* Forbidden */ 12199 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12200 if (global_regattempts_max) 12201 p->registry->regattempts = global_regattempts_max+1; 12202 ast_sched_del(sched, r->timeout); 12203 r->timeout = -1; 12204 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12205 break; 12206 case 404: /* Not found */ 12207 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12208 if (global_regattempts_max) 12209 p->registry->regattempts = global_regattempts_max+1; 12210 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12211 r->call = NULL; 12212 ast_sched_del(sched, r->timeout); 12213 r->timeout = -1; 12214 break; 12215 case 407: /* Proxy auth */ 12216 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12217 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12218 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12219 } 12220 break; 12221 case 408: /* Request timeout */ 12222 if (global_regattempts_max) 12223 p->registry->regattempts = global_regattempts_max+1; 12224 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12225 r->call = NULL; 12226 ast_sched_del(sched, r->timeout); 12227 r->timeout = -1; 12228 break; 12229 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12230 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12231 if (global_regattempts_max) 12232 p->registry->regattempts = global_regattempts_max+1; 12233 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12234 r->call = NULL; 12235 ast_sched_del(sched, r->timeout); 12236 r->timeout = -1; 12237 break; 12238 case 200: /* 200 OK */ 12239 if (!r) { 12240 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12241 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12242 return 0; 12243 } 12244 12245 r->regstate = REG_STATE_REGISTERED; 12246 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12247 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12248 r->regattempts = 0; 12249 if (option_debug) 12250 ast_log(LOG_DEBUG, "Registration successful\n"); 12251 if (r->timeout > -1) { 12252 if (option_debug) 12253 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12254 ast_sched_del(sched, r->timeout); 12255 } 12256 r->timeout=-1; 12257 r->call = NULL; 12258 p->registry = NULL; 12259 /* Let this one hang around until we have all the responses */ 12260 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12261 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12262 12263 /* set us up for re-registering */ 12264 /* figure out how long we got registered for */ 12265 if (r->expire > -1) 12266 ast_sched_del(sched, r->expire); 12267 /* according to section 6.13 of RFC, contact headers override 12268 expires headers, so check those first */ 12269 expires = 0; 12270 12271 /* XXX todo: try to save the extra call */ 12272 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12273 const char *contact = NULL; 12274 const char *tmptmp = NULL; 12275 int start = 0; 12276 for(;;) { 12277 contact = __get_header(req, "Contact", &start); 12278 /* this loop ensures we get a contact header about our register request */ 12279 if(!ast_strlen_zero(contact)) { 12280 if( (tmptmp=strstr(contact, p->our_contact))) { 12281 contact=tmptmp; 12282 break; 12283 } 12284 } else 12285 break; 12286 } 12287 tmptmp = strcasestr(contact, "expires="); 12288 if (tmptmp) { 12289 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12290 expires = 0; 12291 } 12292 12293 } 12294 if (!expires) 12295 expires=atoi(get_header(req, "expires")); 12296 if (!expires) 12297 expires=default_expiry; 12298 12299 expires_ms = expires * 1000; 12300 if (expires <= EXPIRY_GUARD_LIMIT) 12301 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12302 else 12303 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12304 if (sipdebug) 12305 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12306 12307 r->refresh= (int) expires_ms / 1000; 12308 12309 /* Schedule re-registration before we expire */ 12310 if (r->expire > -1) 12311 ast_sched_del(sched, r->expire); 12312 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12313 ASTOBJ_UNREF(r, sip_registry_destroy); 12314 } 12315 return 1; 12316 }
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 3360 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03361 { 03362 switch (cause) { 03363 case AST_CAUSE_UNALLOCATED: /* 1 */ 03364 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03365 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03366 return "404 Not Found"; 03367 case AST_CAUSE_CONGESTION: /* 34 */ 03368 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03369 return "503 Service Unavailable"; 03370 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03371 return "408 Request Timeout"; 03372 case AST_CAUSE_NO_ANSWER: /* 19 */ 03373 return "480 Temporarily unavailable"; 03374 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03375 return "403 Forbidden"; 03376 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03377 return "410 Gone"; 03378 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03379 return "480 Temporarily unavailable"; 03380 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03381 return "484 Address incomplete"; 03382 case AST_CAUSE_USER_BUSY: 03383 return "486 Busy here"; 03384 case AST_CAUSE_FAILURE: 03385 return "500 Server internal failure"; 03386 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03387 return "501 Not Implemented"; 03388 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03389 return "503 Service Unavailable"; 03390 /* Used in chan_iax2 */ 03391 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03392 return "502 Bad Gateway"; 03393 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03394 return "488 Not Acceptable Here"; 03395 03396 case AST_CAUSE_NOTDEFINED: 03397 default: 03398 if (option_debug) 03399 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03400 return NULL; 03401 } 03402 03403 /* Never reached */ 03404 return 0; 03405 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3248 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().
03249 { 03250 /* Possible values taken from causes.h */ 03251 03252 switch(cause) { 03253 case 401: /* Unauthorized */ 03254 return AST_CAUSE_CALL_REJECTED; 03255 case 403: /* Not found */ 03256 return AST_CAUSE_CALL_REJECTED; 03257 case 404: /* Not found */ 03258 return AST_CAUSE_UNALLOCATED; 03259 case 405: /* Method not allowed */ 03260 return AST_CAUSE_INTERWORKING; 03261 case 407: /* Proxy authentication required */ 03262 return AST_CAUSE_CALL_REJECTED; 03263 case 408: /* No reaction */ 03264 return AST_CAUSE_NO_USER_RESPONSE; 03265 case 409: /* Conflict */ 03266 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03267 case 410: /* Gone */ 03268 return AST_CAUSE_UNALLOCATED; 03269 case 411: /* Length required */ 03270 return AST_CAUSE_INTERWORKING; 03271 case 413: /* Request entity too large */ 03272 return AST_CAUSE_INTERWORKING; 03273 case 414: /* Request URI too large */ 03274 return AST_CAUSE_INTERWORKING; 03275 case 415: /* Unsupported media type */ 03276 return AST_CAUSE_INTERWORKING; 03277 case 420: /* Bad extension */ 03278 return AST_CAUSE_NO_ROUTE_DESTINATION; 03279 case 480: /* No answer */ 03280 return AST_CAUSE_NO_ANSWER; 03281 case 481: /* No answer */ 03282 return AST_CAUSE_INTERWORKING; 03283 case 482: /* Loop detected */ 03284 return AST_CAUSE_INTERWORKING; 03285 case 483: /* Too many hops */ 03286 return AST_CAUSE_NO_ANSWER; 03287 case 484: /* Address incomplete */ 03288 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03289 case 485: /* Ambigous */ 03290 return AST_CAUSE_UNALLOCATED; 03291 case 486: /* Busy everywhere */ 03292 return AST_CAUSE_BUSY; 03293 case 487: /* Request terminated */ 03294 return AST_CAUSE_INTERWORKING; 03295 case 488: /* No codecs approved */ 03296 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03297 case 491: /* Request pending */ 03298 return AST_CAUSE_INTERWORKING; 03299 case 493: /* Undecipherable */ 03300 return AST_CAUSE_INTERWORKING; 03301 case 500: /* Server internal failure */ 03302 return AST_CAUSE_FAILURE; 03303 case 501: /* Call rejected */ 03304 return AST_CAUSE_FACILITY_REJECTED; 03305 case 502: 03306 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03307 case 503: /* Service unavailable */ 03308 return AST_CAUSE_CONGESTION; 03309 case 504: /* Gateway timeout */ 03310 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03311 case 505: /* SIP version not supported */ 03312 return AST_CAUSE_INTERWORKING; 03313 case 600: /* Busy everywhere */ 03314 return AST_CAUSE_USER_BUSY; 03315 case 603: /* Decline */ 03316 return AST_CAUSE_CALL_REJECTED; 03317 case 604: /* Does not exist anywhere */ 03318 return AST_CAUSE_UNALLOCATED; 03319 case 606: /* Not acceptable */ 03320 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03321 default: 03322 return AST_CAUSE_NORMAL; 03323 } 03324 /* Never reached */ 03325 return 0; 03326 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5708 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05709 { 05710 /* Initialize a request */ 05711 memset(req, 0, sizeof(*req)); 05712 req->method = sipmethod; 05713 req->header[0] = req->data; 05714 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05715 req->len = strlen(req->header[0]); 05716 req->headers++; 05717 return 0; 05718 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5695 of file chan_sip.c.
References SIP_RESPONSE.
05696 { 05697 /* Initialize a response */ 05698 memset(resp, 0, sizeof(*resp)); 05699 resp->method = SIP_RESPONSE; 05700 resp->header[0] = resp->data; 05701 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05702 resp->len = strlen(resp->header[0]); 05703 resp->headers++; 05704 return 0; 05705 }
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 1631 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().
01632 { 01633 if (p->initreq.headers && option_debug) { 01634 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01635 } 01636 /* Use this as the basis */ 01637 copy_request(&p->initreq, req); 01638 parse_request(&p->initreq); 01639 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01640 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01641 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6789 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::ourip, ourport, sip_pvt::owner, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_invite_param::uri_options, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
06790 { 06791 char invite_buf[256] = ""; 06792 char *invite = invite_buf; 06793 size_t invite_max = sizeof(invite_buf); 06794 char from[256]; 06795 char to[256]; 06796 char tmp[BUFSIZ/2]; 06797 char tmp2[BUFSIZ/2]; 06798 const char *l = NULL, *n = NULL; 06799 const char *urioptions = ""; 06800 06801 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06802 const char *s = p->username; /* being a string field, cannot be NULL */ 06803 06804 /* Test p->username against allowed characters in AST_DIGIT_ANY 06805 If it matches the allowed characters list, then sipuser = ";user=phone" 06806 If not, then sipuser = "" 06807 */ 06808 /* + is allowed in first position in a tel: uri */ 06809 if (*s == '+') 06810 s++; 06811 for (; *s; s++) { 06812 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06813 break; 06814 } 06815 /* If we have only digits, add ;user=phone to the uri */ 06816 if (*s) 06817 urioptions = ";user=phone"; 06818 } 06819 06820 06821 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06822 06823 if (p->owner) { 06824 l = p->owner->cid.cid_num; 06825 n = p->owner->cid.cid_name; 06826 } 06827 /* if we are not sending RPID and user wants his callerid restricted */ 06828 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06829 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06830 l = CALLERID_UNKNOWN; 06831 n = l; 06832 } 06833 if (ast_strlen_zero(l)) 06834 l = default_callerid; 06835 if (ast_strlen_zero(n)) 06836 n = l; 06837 /* Allow user to be overridden */ 06838 if (!ast_strlen_zero(p->fromuser)) 06839 l = p->fromuser; 06840 else /* Save for any further attempts */ 06841 ast_string_field_set(p, fromuser, l); 06842 06843 /* Allow user to be overridden */ 06844 if (!ast_strlen_zero(p->fromname)) 06845 n = p->fromname; 06846 else /* Save for any further attempts */ 06847 ast_string_field_set(p, fromname, n); 06848 06849 if (pedanticsipchecking) { 06850 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06851 n = tmp; 06852 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06853 l = tmp2; 06854 } 06855 06856 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06857 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); 06858 else 06859 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06860 06861 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06862 if (!ast_strlen_zero(p->fullcontact)) { 06863 /* If we have full contact, trust it */ 06864 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06865 } else { 06866 /* Otherwise, use the username while waiting for registration */ 06867 ast_build_string(&invite, &invite_max, "sip:"); 06868 if (!ast_strlen_zero(p->username)) { 06869 n = p->username; 06870 if (pedanticsipchecking) { 06871 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06872 n = tmp; 06873 } 06874 ast_build_string(&invite, &invite_max, "%s@", n); 06875 } 06876 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06877 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06878 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06879 ast_build_string(&invite, &invite_max, "%s", urioptions); 06880 } 06881 06882 /* If custom URI options have been provided, append them */ 06883 if (p->options && p->options->uri_options) 06884 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06885 06886 ast_string_field_set(p, uri, invite_buf); 06887 06888 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06889 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06890 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 06891 } else if (p->options && p->options->vxml_url) { 06892 /* If there is a VXML URL append it to the SIP URL */ 06893 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06894 } else 06895 snprintf(to, sizeof(to), "<%s>", p->uri); 06896 06897 init_req(req, sipmethod, p->uri); 06898 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06899 06900 add_header(req, "Via", p->via); 06901 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06902 * OTOH, then we won't have anything in p->route anyway */ 06903 /* Build Remote Party-ID and From */ 06904 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06905 build_rpid(p); 06906 add_header(req, "From", p->rpid_from); 06907 } else 06908 add_header(req, "From", from); 06909 add_header(req, "To", to); 06910 ast_string_field_set(p, exten, l); 06911 build_contact(p); 06912 add_header(req, "Contact", p->our_contact); 06913 add_header(req, "Call-ID", p->callid); 06914 add_header(req, "CSeq", tmp); 06915 if (!ast_strlen_zero(global_useragent)) 06916 add_header(req, "User-Agent", global_useragent); 06917 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06918 if (!ast_strlen_zero(p->rpid)) 06919 add_header(req, "Remote-Party-ID", p->rpid); 06920 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 9872 of file chan_sip.c.
Referenced by _sip_show_peer().
09873 { 09874 if (port && invite) 09875 return "port,invite"; 09876 else if (port) 09877 return "port"; 09878 else if (invite) 09879 return "invite"; 09880 else 09881 return "no"; 09882 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8068 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08069 { 08070 if (!route) 08071 ast_verbose("list_route: no route\n"); 08072 else { 08073 for (;route; route = route->next) 08074 ast_verbose("list_route: hop: <%s>\n", route->hop); 08075 } 08076 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17688 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.
17689 { 17690 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 17691 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 17692 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 17693 17694 if (!(sched = sched_context_create())) { 17695 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 17696 return AST_MODULE_LOAD_FAILURE; 17697 } 17698 17699 if (!(io = io_context_create())) { 17700 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 17701 sched_context_destroy(sched); 17702 return AST_MODULE_LOAD_FAILURE; 17703 } 17704 17705 sip_reloadreason = CHANNEL_MODULE_LOAD; 17706 17707 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 17708 return AST_MODULE_LOAD_DECLINE; 17709 17710 /* Make sure we can register our sip channel type */ 17711 if (ast_channel_register(&sip_tech)) { 17712 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 17713 io_context_destroy(io); 17714 sched_context_destroy(sched); 17715 return AST_MODULE_LOAD_FAILURE; 17716 } 17717 17718 /* Register all CLI functions for SIP */ 17719 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 17720 17721 /* Tell the RTP subdriver that we're here */ 17722 ast_rtp_proto_register(&sip_rtp); 17723 17724 /* Tell the UDPTL subdriver that we're here */ 17725 ast_udptl_proto_register(&sip_udptl); 17726 17727 /* Register dialplan applications */ 17728 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 17729 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 17730 17731 /* Register dialplan functions */ 17732 ast_custom_function_register(&sip_header_function); 17733 ast_custom_function_register(&sippeer_function); 17734 ast_custom_function_register(&sipchaninfo_function); 17735 ast_custom_function_register(&checksipdomain_function); 17736 17737 /* Register manager commands */ 17738 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 17739 "List SIP peers (text format)", mandescr_show_peers); 17740 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 17741 "Show SIP peer (text format)", mandescr_show_peer); 17742 17743 sip_poke_all_peers(); 17744 sip_send_all_registers(); 17745 17746 /* And start the monitor for the first time */ 17747 restart_monitor(); 17748 17749 return AST_MODULE_LOAD_SUCCESS; 17750 }
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 13906 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().
13907 { 13908 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 13909 /* Chan 2: Call from Asterisk to target */ 13910 int res = 0; 13911 struct sip_pvt *targetcall_pvt; 13912 13913 /* Check if the call ID of the replaces header does exist locally */ 13914 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 13915 transferer->refer->replaces_callid_fromtag))) { 13916 if (transferer->refer->localtransfer) { 13917 /* We did not find the refered call. Sorry, can't accept then */ 13918 transmit_response(transferer, "202 Accepted", req); 13919 /* Let's fake a response from someone else in order 13920 to follow the standard */ 13921 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 13922 append_history(transferer, "Xfer", "Refer failed"); 13923 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13924 transferer->refer->status = REFER_FAILED; 13925 return -1; 13926 } 13927 /* Fall through for remote transfers that we did not find locally */ 13928 if (option_debug > 2) 13929 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 13930 return 0; 13931 } 13932 13933 /* Ok, we can accept this transfer */ 13934 transmit_response(transferer, "202 Accepted", req); 13935 append_history(transferer, "Xfer", "Refer accepted"); 13936 if (!targetcall_pvt->owner) { /* No active channel */ 13937 if (option_debug > 3) 13938 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 13939 /* Cancel transfer */ 13940 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 13941 append_history(transferer, "Xfer", "Refer failed"); 13942 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13943 transferer->refer->status = REFER_FAILED; 13944 ast_mutex_unlock(&targetcall_pvt->lock); 13945 ast_channel_unlock(current->chan1); 13946 return -1; 13947 } 13948 13949 /* We have a channel, find the bridge */ 13950 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 13951 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 13952 13953 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 13954 /* Wrong state of new channel */ 13955 if (option_debug > 3) { 13956 if (target.chan2) 13957 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 13958 else if (target.chan1->_state != AST_STATE_RING) 13959 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 13960 else 13961 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 13962 } 13963 } 13964 13965 /* Transfer */ 13966 if (option_debug > 3 && sipdebug) { 13967 if (current->chan2) /* We have two bridges */ 13968 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 13969 else /* One bridge, propably transfer of IVR/voicemail etc */ 13970 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 13971 } 13972 13973 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13974 13975 /* Perform the transfer */ 13976 res = attempt_transfer(current, &target); 13977 ast_mutex_unlock(&targetcall_pvt->lock); 13978 if (res) { 13979 /* Failed transfer */ 13980 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 13981 append_history(transferer, "Xfer", "Refer failed"); 13982 transferer->refer->status = REFER_FAILED; 13983 if (targetcall_pvt->owner) 13984 ast_channel_unlock(targetcall_pvt->owner); 13985 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 13986 if (res != -2) 13987 ast_hangup(transferer->owner); 13988 else 13989 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 13990 } else { 13991 /* Transfer succeeded! */ 13992 13993 /* Tell transferer that we're done. */ 13994 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 13995 append_history(transferer, "Xfer", "Refer succeeded"); 13996 transferer->refer->status = REFER_200OK; 13997 if (targetcall_pvt->owner) { 13998 if (option_debug) 13999 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14000 ast_channel_unlock(targetcall_pvt->owner); 14001 } 14002 } 14003 return 1; 14004 }
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 4662 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04663 { 04664 int h = 0, t = 0; 04665 int lws = 0; 04666 04667 for (; h < len;) { 04668 /* Eliminate all CRs */ 04669 if (msgbuf[h] == '\r') { 04670 h++; 04671 continue; 04672 } 04673 /* Check for end-of-line */ 04674 if (msgbuf[h] == '\n') { 04675 /* Check for end-of-message */ 04676 if (h + 1 == len) 04677 break; 04678 /* Check for a continuation line */ 04679 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04680 /* Merge continuation line */ 04681 h++; 04682 continue; 04683 } 04684 /* Propagate LF and start new line */ 04685 msgbuf[t++] = msgbuf[h++]; 04686 lws = 0; 04687 continue; 04688 } 04689 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04690 if (lws) { 04691 h++; 04692 continue; 04693 } 04694 msgbuf[t++] = msgbuf[h++]; 04695 lws = 1; 04696 continue; 04697 } 04698 msgbuf[t++] = msgbuf[h++]; 04699 if (lws) 04700 lws = 0; 04701 } 04702 msgbuf[t] = '\0'; 04703 return t; 04704 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4334 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().
04335 { 04336 snprintf(tagbuf, len, "as%08lx", ast_random()); 04337 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10117 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().
10118 { 10119 const char *a[4]; 10120 const char *peer; 10121 int ret; 10122 10123 peer = astman_get_header(m,"Peer"); 10124 if (ast_strlen_zero(peer)) { 10125 astman_send_error(s, m, "Peer: <name> missing.\n"); 10126 return 0; 10127 } 10128 a[0] = "sip"; 10129 a[1] = "show"; 10130 a[2] = "peer"; 10131 a[3] = peer; 10132 10133 ret = _sip_show_peer(1, -1, s, m, 4, a); 10134 astman_append(s, "\r\n\r\n" ); 10135 return ret; 10136 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9668 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().
09669 { 09670 const char *id = astman_get_header(m,"ActionID"); 09671 const char *a[] = {"sip", "show", "peers"}; 09672 char idtext[256] = ""; 09673 int total = 0; 09674 09675 if (!ast_strlen_zero(id)) 09676 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09677 09678 astman_send_ack(s, m, "Peer status list will follow"); 09679 /* List the peers in separate manager events */ 09680 _sip_show_peers(-1, &total, s, m, 3, a); 09681 /* Send final confirmation */ 09682 astman_append(s, 09683 "Event: PeerlistComplete\r\n" 09684 "ListItems: %d\r\n" 09685 "%s" 09686 "\r\n", total, idtext); 09687 return 0; 09688 }
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 1657 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01658 { 01659 int len = strlen(sip_methods[id].text); 01660 int l_name = name ? strlen(name) : 0; 01661 /* true if the string is long enough, and ends with whitespace, and matches */ 01662 return (l_name >= len && name[len] < 33 && 01663 !strncasecmp(sip_methods[id].text, name, len)); 01664 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9571 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().
09572 { 09573 switch(nat) { 09574 case SIP_NAT_NEVER: 09575 return "No"; 09576 case SIP_NAT_ROUTE: 09577 return "Route"; 09578 case SIP_NAT_ALWAYS: 09579 return "Always"; 09580 case SIP_NAT_RFC3581: 09581 return "RFC3581"; 09582 default: 09583 return "Unknown"; 09584 } 09585 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2206 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02207 { 02208 memset(dst, 0, sizeof(*dst)); 02209 memcpy(dst->data, src->data, sizeof(dst->data)); 02210 dst->len = src->len; 02211 parse_request(dst); 02212 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11746 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, and t.
Referenced by handle_response().
11747 { 11748 char tmp[BUFSIZ]; 11749 char *s, *e, *uri, *t; 11750 char *domain; 11751 11752 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11753 if ((t = strchr(tmp, ','))) 11754 *t = '\0'; 11755 s = get_in_brackets(tmp); 11756 uri = ast_strdupa(s); 11757 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11758 if (!strncasecmp(s, "sip:", 4)) 11759 s += 4; 11760 e = strchr(s, ';'); 11761 if (e) 11762 *e = '\0'; 11763 if (option_debug) 11764 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11765 if (p->owner) 11766 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11767 } else { 11768 e = strchr(tmp, '@'); 11769 if (e) { 11770 *e++ = '\0'; 11771 domain = e; 11772 } else { 11773 /* No username part */ 11774 domain = tmp; 11775 } 11776 e = strchr(s, ';'); /* Strip of parameters in the username part */ 11777 if (e) 11778 *e = '\0'; 11779 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 11780 if (e) 11781 *e = '\0'; 11782 11783 if (!strncasecmp(s, "sip:", 4)) 11784 s += 4; 11785 if (option_debug > 1) 11786 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 11787 if (p->owner) { 11788 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 11789 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 11790 ast_string_field_set(p->owner, call_forward, s); 11791 } 11792 } 11793 }
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 7824 of file chan_sip.c.
References ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
07825 { 07826 char contact[BUFSIZ]; 07827 char *c; 07828 07829 /* Look for brackets */ 07830 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07831 c = get_in_brackets(contact); 07832 07833 /* Save full contact to call pvt for later bye or re-invite */ 07834 ast_string_field_set(pvt, fullcontact, c); 07835 07836 /* Save URI for later ACKs, BYE or RE-invites */ 07837 ast_string_field_set(pvt, okcontacturi, c); 07838 07839 /* We should return false for URI:s we can't handle, 07840 like sips:, tel:, mailto:,ldap: etc */ 07841 return TRUE; 07842 }
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 7908 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_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
07909 { 07910 char contact[BUFSIZ]; 07911 char data[BUFSIZ]; 07912 const char *expires = get_header(req, "Expires"); 07913 int expiry = atoi(expires); 07914 char *curi, *n, *pt; 07915 int port; 07916 const char *useragent; 07917 struct hostent *hp; 07918 struct ast_hostent ahp; 07919 struct sockaddr_in oldsin; 07920 07921 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07922 07923 if (ast_strlen_zero(expires)) { /* No expires header */ 07924 expires = strcasestr(contact, ";expires="); 07925 if (expires) { 07926 /* XXX bug here, we overwrite the string */ 07927 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 07928 if (sscanf(expires + 9, "%d", &expiry) != 1) 07929 expiry = default_expiry; 07930 } else { 07931 /* Nothing has been specified */ 07932 expiry = default_expiry; 07933 } 07934 } 07935 07936 /* Look for brackets */ 07937 curi = contact; 07938 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 07939 strsep(&curi, ";"); /* This is Header options, not URI options */ 07940 curi = get_in_brackets(contact); 07941 07942 /* if they did not specify Contact: or Expires:, they are querying 07943 what we currently have stored as their contact address, so return 07944 it 07945 */ 07946 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 07947 /* If we have an active registration, tell them when the registration is going to expire */ 07948 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 07949 pvt->expiry = ast_sched_when(sched, peer->expire); 07950 return PARSE_REGISTER_QUERY; 07951 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 07952 /* This means remove all registrations and return OK */ 07953 memset(&peer->addr, 0, sizeof(peer->addr)); 07954 if (peer->expire > -1) 07955 ast_sched_del(sched, peer->expire); 07956 peer->expire = -1; 07957 07958 destroy_association(peer); 07959 07960 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 07961 peer->fullcontact[0] = '\0'; 07962 peer->useragent[0] = '\0'; 07963 peer->sipoptions = 0; 07964 peer->lastms = 0; 07965 07966 if (option_verbose > 2) 07967 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 07968 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 07969 return PARSE_REGISTER_UPDATE; 07970 } 07971 07972 /* Store whatever we got as a contact from the client */ 07973 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 07974 07975 /* For the 200 OK, we should use the received contact */ 07976 ast_string_field_build(pvt, our_contact, "<%s>", curi); 07977 07978 /* Make sure it's a SIP URL */ 07979 if (strncasecmp(curi, "sip:", 4)) { 07980 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 07981 } else 07982 curi += 4; 07983 /* Ditch q */ 07984 curi = strsep(&curi, ";"); 07985 /* Grab host */ 07986 n = strchr(curi, '@'); 07987 if (!n) { 07988 n = curi; 07989 curi = NULL; 07990 } else 07991 *n++ = '\0'; 07992 pt = strchr(n, ':'); 07993 if (pt) { 07994 *pt++ = '\0'; 07995 port = atoi(pt); 07996 } else 07997 port = STANDARD_SIP_PORT; 07998 oldsin = peer->addr; 07999 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08000 /* XXX This could block for a long time XXX */ 08001 hp = ast_gethostbyname(n, &ahp); 08002 if (!hp) { 08003 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08004 return PARSE_REGISTER_FAILED; 08005 } 08006 peer->addr.sin_family = AF_INET; 08007 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08008 peer->addr.sin_port = htons(port); 08009 } else { 08010 /* Don't trust the contact field. Just use what they came to us 08011 with */ 08012 peer->addr = pvt->recv; 08013 } 08014 08015 /* Save SIP options profile */ 08016 peer->sipoptions = pvt->sipoptions; 08017 08018 if (curi && ast_strlen_zero(peer->username)) 08019 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08020 08021 if (peer->expire > -1) { 08022 ast_sched_del(sched, peer->expire); 08023 peer->expire = -1; 08024 } 08025 if (expiry > max_expiry) 08026 expiry = max_expiry; 08027 if (expiry < min_expiry) 08028 expiry = min_expiry; 08029 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 08030 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 08031 pvt->expiry = expiry; 08032 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); 08033 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08034 ast_db_put("SIP/Registry", peer->name, data); 08035 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08036 08037 /* Is this a new IP address for us? */ 08038 if (inaddrcmp(&peer->addr, &oldsin)) { 08039 sip_poke_peer(peer); 08040 if (option_verbose > 2) 08041 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); 08042 register_peer_exten(peer, 1); 08043 } 08044 08045 /* Save User agent */ 08046 useragent = get_header(req, "User-Agent"); 08047 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08048 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08049 if (option_verbose > 3) 08050 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08051 } 08052 return PARSE_REGISTER_UPDATE; 08053 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4709 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().
04710 { 04711 /* Divide fields by NULL's */ 04712 char *c; 04713 int f = 0; 04714 04715 c = req->data; 04716 04717 /* First header starts immediately */ 04718 req->header[f] = c; 04719 while(*c) { 04720 if (*c == '\n') { 04721 /* We've got a new header */ 04722 *c = 0; 04723 04724 if (sipdebug && option_debug > 3) 04725 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04726 if (ast_strlen_zero(req->header[f])) { 04727 /* Line by itself means we're now in content */ 04728 c++; 04729 break; 04730 } 04731 if (f >= SIP_MAX_HEADERS - 1) { 04732 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04733 } else 04734 f++; 04735 req->header[f] = c + 1; 04736 } else if (*c == '\r') { 04737 /* Ignore but eliminate \r's */ 04738 *c = 0; 04739 } 04740 c++; 04741 } 04742 /* Check for last header */ 04743 if (!ast_strlen_zero(req->header[f])) { 04744 if (sipdebug && option_debug > 3) 04745 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04746 f++; 04747 } 04748 req->headers = f; 04749 /* Now we process any mime content */ 04750 f = 0; 04751 req->line[f] = c; 04752 while(*c) { 04753 if (*c == '\n') { 04754 /* We've got a new line */ 04755 *c = 0; 04756 if (sipdebug && option_debug > 3) 04757 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04758 if (f >= SIP_MAX_LINES - 1) { 04759 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04760 } else 04761 f++; 04762 req->line[f] = c + 1; 04763 } else if (*c == '\r') { 04764 /* Ignore and eliminate \r's */ 04765 *c = 0; 04766 } 04767 c++; 04768 } 04769 /* Check for last line */ 04770 if (!ast_strlen_zero(req->line[f])) 04771 f++; 04772 req->lines = f; 04773 if (*c) 04774 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04775 /* Split up the first line parts */ 04776 determine_firstline_parts(req); 04777 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1681 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().
01682 { 01683 char *next, *sep; 01684 char *temp; 01685 unsigned int profile = 0; 01686 int i, found; 01687 01688 if (ast_strlen_zero(supported) ) 01689 return 0; 01690 temp = ast_strdupa(supported); 01691 01692 if (option_debug > 2 && sipdebug) 01693 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01694 01695 for (next = temp; next; next = sep) { 01696 found = FALSE; 01697 if ( (sep = strchr(next, ',')) != NULL) 01698 *sep++ = '\0'; 01699 next = ast_skip_blanks(next); 01700 if (option_debug > 2 && sipdebug) 01701 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01702 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01703 if (!strcasecmp(next, sip_options[i].text)) { 01704 profile |= sip_options[i].id; 01705 found = TRUE; 01706 if (option_debug > 2 && sipdebug) 01707 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01708 break; 01709 } 01710 } 01711 if (!found && option_debug > 2 && sipdebug) { 01712 if (!strncasecmp(next, "x-", 2)) 01713 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01714 else 01715 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01716 } 01717 } 01718 01719 if (pvt) 01720 pvt->sipoptions = profile; 01721 return profile; 01722 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9590 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09591 { 09592 int res = 0; 09593 if (peer->maxms) { 09594 if (peer->lastms < 0) { 09595 ast_copy_string(status, "UNREACHABLE", statuslen); 09596 } else if (peer->lastms > peer->maxms) { 09597 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09598 res = 1; 09599 } else if (peer->lastms) { 09600 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09601 res = 1; 09602 } else { 09603 ast_copy_string(status, "UNKNOWN", statuslen); 09604 } 09605 } else { 09606 ast_copy_string(status, "Unmonitored", statuslen); 09607 /* Checking if port is 0 */ 09608 res = -1; 09609 } 09610 return res; 09611 }
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 10058 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().
10059 { 10060 int x, codec; 10061 10062 for(x = 0; x < 32 ; x++) { 10063 codec = ast_codec_pref_index(pref, x); 10064 if (!codec) 10065 break; 10066 ast_cli(fd, "%s", ast_getformatname(codec)); 10067 ast_cli(fd, ":%d", pref->framing[x]); 10068 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10069 ast_cli(fd, ","); 10070 } 10071 if (!x) 10072 ast_cli(fd, "none"); 10073 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 9849 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
09850 { 09851 char buf[256]; 09852 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 09853 }
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 4885 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_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, 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, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
04886 { 04887 const char *m; /* SDP media offer */ 04888 const char *c; 04889 const char *a; 04890 char host[258]; 04891 int len = -1; 04892 int portno = -1; /*!< RTP Audio port number */ 04893 int vportno = -1; /*!< RTP Video port number */ 04894 int udptlportno = -1; 04895 int peert38capability = 0; 04896 char s[256]; 04897 int old = 0; 04898 04899 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04900 int peercapability = 0, peernoncodeccapability = 0; 04901 int vpeercapability = 0, vpeernoncodeccapability = 0; 04902 struct sockaddr_in sin; /*!< media socket address */ 04903 struct sockaddr_in vsin; /*!< Video socket address */ 04904 04905 const char *codecs; 04906 struct hostent *hp; /*!< RTP Audio host IP */ 04907 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04908 struct ast_hostent audiohp; 04909 struct ast_hostent videohp; 04910 int codec; 04911 int destiterator = 0; 04912 int iterator; 04913 int sendonly = -1; 04914 int numberofports; 04915 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04916 int newjointcapability; /* Negotiated capability */ 04917 int newpeercapability; 04918 int newnoncodeccapability; 04919 int numberofmediastreams = 0; 04920 int debug = sip_debug_test_pvt(p); 04921 04922 int found_rtpmap_codecs[32]; 04923 int last_rtpmap_codec=0; 04924 04925 if (!p->rtp) { 04926 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04927 return -1; 04928 } 04929 04930 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04931 newaudiortp = alloca(ast_rtp_alloc_size()); 04932 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04933 ast_rtp_new_init(newaudiortp); 04934 ast_rtp_pt_clear(newaudiortp); 04935 04936 newvideortp = alloca(ast_rtp_alloc_size()); 04937 memset(newvideortp, 0, ast_rtp_alloc_size()); 04938 ast_rtp_new_init(newvideortp); 04939 ast_rtp_pt_clear(newvideortp); 04940 04941 /* Update our last rtprx when we receive an SDP, too */ 04942 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 04943 04944 04945 /* Try to find first media stream */ 04946 m = get_sdp(req, "m"); 04947 destiterator = req->sdp_start; 04948 c = get_sdp_iterate(&destiterator, req, "c"); 04949 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 04950 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 04951 return -1; 04952 } 04953 04954 /* Check for IPv4 address (not IPv6 yet) */ 04955 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04956 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 04957 return -1; 04958 } 04959 04960 /* XXX This could block for a long time, and block the main thread! XXX */ 04961 hp = ast_gethostbyname(host, &audiohp); 04962 if (!hp) { 04963 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 04964 return -1; 04965 } 04966 vhp = hp; /* Copy to video address as default too */ 04967 04968 iterator = req->sdp_start; 04969 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 04970 04971 04972 /* Find media streams in this SDP offer */ 04973 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 04974 int x; 04975 int audio = FALSE; 04976 04977 numberofports = 1; 04978 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04979 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 04980 audio = TRUE; 04981 numberofmediastreams++; 04982 /* Found audio stream in this media definition */ 04983 portno = x; 04984 /* Scan through the RTP payload types specified in a "m=" line: */ 04985 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04986 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04987 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04988 return -1; 04989 } 04990 if (debug) 04991 ast_verbose("Found RTP audio format %d\n", codec); 04992 ast_rtp_set_m_type(newaudiortp, codec); 04993 } 04994 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04995 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 04996 /* If it is not audio - is it video ? */ 04997 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 04998 numberofmediastreams++; 04999 vportno = x; 05000 /* Scan through the RTP payload types specified in a "m=" line: */ 05001 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05002 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05003 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05004 return -1; 05005 } 05006 if (debug) 05007 ast_verbose("Found RTP video format %d\n", codec); 05008 ast_rtp_set_m_type(newvideortp, codec); 05009 } 05010 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 05011 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 05012 if (debug) 05013 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05014 udptlportno = x; 05015 numberofmediastreams++; 05016 05017 if (p->owner && p->lastinvite) { 05018 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05019 if (option_debug > 1) 05020 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05021 } else { 05022 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05023 if (option_debug > 1) 05024 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05025 } 05026 } else 05027 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05028 if (numberofports > 1) 05029 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05030 05031 05032 /* Check for Media-description-level-address for audio */ 05033 c = get_sdp_iterate(&destiterator, req, "c"); 05034 if (!ast_strlen_zero(c)) { 05035 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05036 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05037 } else { 05038 /* XXX This could block for a long time, and block the main thread! XXX */ 05039 if (audio) { 05040 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05041 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05042 return -2; 05043 } 05044 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05045 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05046 return -2; 05047 } 05048 } 05049 05050 } 05051 } 05052 if (portno == -1 && vportno == -1 && udptlportno == -1) 05053 /* No acceptable offer found in SDP - we have no ports */ 05054 /* Do not change RTP or VRTP if this is a re-invite */ 05055 return -2; 05056 05057 if (numberofmediastreams > 2) 05058 /* We have too many fax, audio and/or video media streams, fail this offer */ 05059 return -3; 05060 05061 /* RTP addresses and ports for audio and video */ 05062 sin.sin_family = AF_INET; 05063 vsin.sin_family = AF_INET; 05064 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05065 if (vhp) 05066 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05067 05068 /* Setup UDPTL port number */ 05069 if (p->udptl) { 05070 if (udptlportno > 0) { 05071 sin.sin_port = htons(udptlportno); 05072 ast_udptl_set_peer(p->udptl, &sin); 05073 if (debug) 05074 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05075 } else { 05076 ast_udptl_stop(p->udptl); 05077 if (debug) 05078 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05079 } 05080 } 05081 05082 05083 if (p->rtp) { 05084 if (portno > 0) { 05085 sin.sin_port = htons(portno); 05086 ast_rtp_set_peer(p->rtp, &sin); 05087 if (debug) 05088 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05089 } else { 05090 if (udptlportno > 0) { 05091 if (debug) 05092 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05093 } else { 05094 ast_rtp_stop(p->rtp); 05095 if (debug) 05096 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05097 } 05098 } 05099 } 05100 /* Setup video port number */ 05101 if (vportno != -1) 05102 vsin.sin_port = htons(vportno); 05103 05104 /* Next, scan through each "a=rtpmap:" line, noting each 05105 * specified RTP payload type (with corresponding MIME subtype): 05106 */ 05107 /* XXX This needs to be done per media stream, since it's media stream specific */ 05108 iterator = req->sdp_start; 05109 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05110 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05111 if (option_debug > 1) { 05112 int breakout = FALSE; 05113 05114 /* If we're debugging, check for unsupported sdp options */ 05115 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05116 if (debug) 05117 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05118 breakout = TRUE; 05119 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05120 /* Format parameters: Not supported */ 05121 /* Note: This is used for codec parameters, like bitrate for 05122 G722 and video formats for H263 and H264 05123 See RFC2327 for an example */ 05124 if (debug) 05125 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05126 breakout = TRUE; 05127 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05128 /* Video stuff: Not supported */ 05129 if (debug) 05130 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05131 breakout = TRUE; 05132 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05133 /* Video stuff: Not supported */ 05134 if (debug) 05135 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05136 breakout = TRUE; 05137 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05138 /* SRTP stuff, not yet supported */ 05139 if (debug) 05140 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05141 breakout = TRUE; 05142 } 05143 if (breakout) /* We have a match, skip to next header */ 05144 continue; 05145 } 05146 if (!strcasecmp(a, "sendonly")) { 05147 if (sendonly == -1) 05148 sendonly = 1; 05149 continue; 05150 } else if (!strcasecmp(a, "inactive")) { 05151 if (sendonly == -1) 05152 sendonly = 2; 05153 continue; 05154 } else if (!strcasecmp(a, "sendrecv")) { 05155 if (sendonly == -1) 05156 sendonly = 0; 05157 continue; 05158 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05159 char *tmp = strrchr(a, ':'); 05160 long int framing = 0; 05161 if (tmp) { 05162 tmp++; 05163 framing = strtol(tmp, NULL, 10); 05164 if (framing == LONG_MIN || framing == LONG_MAX) { 05165 framing = 0; 05166 if (option_debug) 05167 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05168 } 05169 } 05170 if (framing && last_rtpmap_codec) { 05171 if (p->autoframing) { 05172 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05173 int codec_n; 05174 int format = 0; 05175 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05176 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05177 if (!format) /* non-codec or not found */ 05178 continue; 05179 if (option_debug) 05180 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05181 ast_codec_pref_setsize(pref, format, framing); 05182 } 05183 ast_rtp_codec_setpref(p->rtp, pref); 05184 } 05185 } 05186 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05187 last_rtpmap_codec = 0; 05188 continue; 05189 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05190 /* We have a rtpmap to handle */ 05191 if (debug) 05192 ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec); 05193 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05194 last_rtpmap_codec++; 05195 05196 /* Note: should really look at the 'freq' and '#chans' params too */ 05197 ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05198 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0); 05199 if (p->vrtp) 05200 ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0); 05201 } 05202 } 05203 05204 if (udptlportno != -1) { 05205 int found = 0, x; 05206 05207 old = 0; 05208 05209 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05210 iterator = req->sdp_start; 05211 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05212 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05213 found = 1; 05214 if (option_debug > 2) 05215 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05216 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05217 found = 1; 05218 if (option_debug > 2) 05219 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05220 switch (x) { 05221 case 14400: 05222 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05223 break; 05224 case 12000: 05225 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05226 break; 05227 case 9600: 05228 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05229 break; 05230 case 7200: 05231 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05232 break; 05233 case 4800: 05234 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05235 break; 05236 case 2400: 05237 peert38capability |= T38FAX_RATE_2400; 05238 break; 05239 } 05240 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05241 found = 1; 05242 if (option_debug > 2) 05243 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05244 if (x == 0) 05245 peert38capability |= T38FAX_VERSION_0; 05246 else if (x == 1) 05247 peert38capability |= T38FAX_VERSION_1; 05248 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05249 found = 1; 05250 if (option_debug > 2) 05251 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05252 ast_udptl_set_far_max_datagram(p->udptl, x); 05253 ast_udptl_set_local_max_datagram(p->udptl, x); 05254 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05255 found = 1; 05256 if (option_debug > 2) 05257 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05258 if (x == 1) 05259 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05260 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05261 found = 1; 05262 if (option_debug > 2) 05263 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05264 if (x == 1) 05265 peert38capability |= T38FAX_TRANSCODING_MMR; 05266 } 05267 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05268 found = 1; 05269 if (option_debug > 2) 05270 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05271 if (x == 1) 05272 peert38capability |= T38FAX_TRANSCODING_JBIG; 05273 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05274 found = 1; 05275 if (option_debug > 2) 05276 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05277 if (!strcasecmp(s, "localTCF")) 05278 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05279 else if (!strcasecmp(s, "transferredTCF")) 05280 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05281 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05282 found = 1; 05283 if (option_debug > 2) 05284 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05285 if (!strcasecmp(s, "t38UDPRedundancy")) { 05286 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05287 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05288 } else if (!strcasecmp(s, "t38UDPFEC")) { 05289 peert38capability |= T38FAX_UDP_EC_FEC; 05290 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05291 } else { 05292 peert38capability |= T38FAX_UDP_EC_NONE; 05293 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05294 } 05295 } 05296 } 05297 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05298 p->t38.peercapability = peert38capability; 05299 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05300 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05301 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05302 } 05303 if (debug) 05304 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05305 p->t38.capability, 05306 p->t38.peercapability, 05307 p->t38.jointcapability); 05308 } else { 05309 p->t38.state = T38_DISABLED; 05310 if (option_debug > 2) 05311 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05312 } 05313 05314 /* Now gather all of the codecs that we are asked for: */ 05315 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05316 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05317 05318 newjointcapability = p->capability & (peercapability | vpeercapability); 05319 newpeercapability = (peercapability | vpeercapability); 05320 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05321 05322 05323 if (debug) { 05324 /* shame on whoever coded this.... */ 05325 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05326 05327 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05328 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05329 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05330 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05331 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05332 05333 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05334 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05335 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05336 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05337 } 05338 if (!newjointcapability) { 05339 /* If T.38 was not negotiated either, totally bail out... */ 05340 if (!p->t38.jointcapability) { 05341 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05342 /* Do NOT Change current setting */ 05343 return -1; 05344 } else { 05345 if (option_debug > 2) 05346 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05347 return 0; 05348 } 05349 } 05350 05351 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05352 they are acceptable */ 05353 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05354 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05355 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05356 05357 ast_rtp_pt_copy(p->rtp, newaudiortp); 05358 if (p->vrtp) 05359 ast_rtp_pt_copy(p->vrtp, newvideortp); 05360 05361 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05362 ast_clear_flag(&p->flags[0], SIP_DTMF); 05363 if (newnoncodeccapability & AST_RTP_DTMF) { 05364 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05365 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05366 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05367 ast_rtp_setdtmf(p->rtp, 1); 05368 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05369 } else { 05370 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05371 } 05372 } 05373 05374 /* Setup audio port number */ 05375 if (p->rtp && sin.sin_port) { 05376 ast_rtp_set_peer(p->rtp, &sin); 05377 if (debug) 05378 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05379 } 05380 05381 /* Setup video port number */ 05382 if (p->vrtp && vsin.sin_port) { 05383 ast_rtp_set_peer(p->vrtp, &vsin); 05384 if (debug) 05385 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05386 } 05387 05388 /* Ok, we're going with this offer */ 05389 if (option_debug > 1) { 05390 char buf[BUFSIZ]; 05391 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05392 } 05393 05394 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05395 return 0; 05396 05397 if (option_debug > 3) 05398 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05399 05400 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05401 if (debug) { 05402 char s1[BUFSIZ], s2[BUFSIZ]; 05403 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05404 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05405 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05406 } 05407 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05408 ast_set_read_format(p->owner, p->owner->readformat); 05409 ast_set_write_format(p->owner, p->owner->writeformat); 05410 } 05411 05412 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05413 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05414 /* Activate a re-invite */ 05415 ast_queue_frame(p->owner, &ast_null_frame); 05416 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05417 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05418 S_OR(p->mohsuggest, NULL), 05419 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05420 if (sendonly) 05421 ast_rtp_stop(p->rtp); 05422 /* RTCP needs to go ahead, even if we're on hold!!! */ 05423 /* Activate a re-invite */ 05424 ast_queue_frame(p->owner, &ast_null_frame); 05425 } 05426 05427 /* Manager Hold and Unhold events must be generated, if necessary */ 05428 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05429 change_hold_state(p, req, FALSE, sendonly); 05430 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05431 change_hold_state(p, req, TRUE, sendonly); 05432 return 0; 05433 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2475 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ast_flags::flags, ast_variable::name, ast_variable::next, set_insecure_flags(), SIP_INSECURE_PORT, ast_variable::value, and var.
02476 { 02477 struct sip_peer *peer=NULL; 02478 struct ast_variable *var; 02479 struct ast_config *peerlist = NULL; 02480 struct ast_variable *tmp; 02481 struct ast_flags flags = {0}; 02482 const char *iabuf = NULL; 02483 char portstring[6]; /*up to five digits plus null terminator*/ 02484 const char *insecure; 02485 char *cat = NULL; 02486 unsigned short portnum; 02487 02488 /* First check on peer name */ 02489 if (newpeername) 02490 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02491 else if (sin) { /* Then check on IP address */ 02492 iabuf = ast_inet_ntoa(sin->sin_addr); 02493 portnum = ntohs(sin->sin_port); 02494 sprintf(portstring, "%d", portnum); 02495 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02496 if (!var) 02497 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02498 if (!var) { 02499 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02500 if(peerlist){ 02501 while((cat = ast_category_browse(peerlist, cat))) 02502 { 02503 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02504 set_insecure_flags(&flags, insecure, -1); 02505 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02506 var = ast_category_root(peerlist, cat); 02507 break; 02508 } 02509 } 02510 } 02511 if(!var) { 02512 ast_config_destroy(peerlist); 02513 peerlist = NULL; /*for safety's sake*/ 02514 cat = NULL; 02515 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02516 if(peerlist) { 02517 while((cat = ast_category_browse(peerlist, cat))) 02518 { 02519 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02520 set_insecure_flags(&flags, insecure, -1); 02521 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02522 var = ast_category_root(peerlist, cat); 02523 break; 02524 } 02525 } 02526 } 02527 } 02528 } 02529 } else 02530 return NULL; 02531 02532 if (!var) { 02533 if(peerlist) 02534 ast_config_destroy(peerlist); 02535 return NULL; 02536 } 02537 02538 for (tmp = var; tmp; tmp = tmp->next) { 02539 /* If this is type=user, then skip this object. */ 02540 if (!strcasecmp(tmp->name, "type") && 02541 !strcasecmp(tmp->value, "user")) { 02542 ast_variables_destroy(var); 02543 return NULL; 02544 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02545 newpeername = tmp->value; 02546 } 02547 } 02548 02549 if (!newpeername) { /* Did not find peer in realtime */ 02550 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02551 if(peerlist) 02552 ast_config_destroy(peerlist); 02553 else 02554 ast_variables_destroy(var); 02555 return NULL; 02556 } 02557 02558 /* Peer found in realtime, now build it in memory */ 02559 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02560 if (!peer) { 02561 if(peerlist) 02562 ast_config_destroy(peerlist); 02563 else 02564 ast_variables_destroy(var); 02565 return NULL; 02566 } 02567 02568 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02569 /* Cache peer */ 02570 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02571 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02572 if (peer->expire > -1) { 02573 ast_sched_del(sched, peer->expire); 02574 } 02575 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02576 } 02577 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02578 } else { 02579 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02580 } 02581 if(peerlist) 02582 ast_config_destroy(peerlist); 02583 else 02584 ast_variables_destroy(var); 02585 return peer; 02586 }
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 2360 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.
02361 { 02362 char port[10]; 02363 char ipaddr[INET_ADDRSTRLEN]; 02364 char regseconds[20]; 02365 02366 char *sysname = ast_config_AST_SYSTEM_NAME; 02367 char *syslabel = NULL; 02368 02369 time_t nowtime = time(NULL) + expirey; 02370 const char *fc = fullcontact ? "fullcontact" : NULL; 02371 02372 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02373 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02374 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02375 02376 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02377 sysname = NULL; 02378 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02379 syslabel = "regserver"; 02380 02381 if (fc) 02382 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02383 "port", port, "regseconds", regseconds, 02384 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02385 else 02386 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02387 "port", port, "regseconds", regseconds, 02388 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02389 }
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 2636 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02637 { 02638 struct ast_variable *var; 02639 struct ast_variable *tmp; 02640 struct sip_user *user = NULL; 02641 02642 var = ast_load_realtime("sipusers", "name", username, NULL); 02643 02644 if (!var) 02645 return NULL; 02646 02647 for (tmp = var; tmp; tmp = tmp->next) { 02648 if (!strcasecmp(tmp->name, "type") && 02649 !strcasecmp(tmp->value, "peer")) { 02650 ast_variables_destroy(var); 02651 return NULL; 02652 } 02653 } 02654 02655 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02656 02657 if (!user) { /* No user found */ 02658 ast_variables_destroy(var); 02659 return NULL; 02660 } 02661 02662 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02663 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02664 suserobjs++; 02665 ASTOBJ_CONTAINER_LINK(&userl,user); 02666 } else { 02667 /* Move counter from s to r... */ 02668 suserobjs--; 02669 ruserobjs++; 02670 ast_set_flag(&user->flags[0], SIP_REALTIME); 02671 } 02672 ast_variables_destroy(var); 02673 return user; 02674 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9475 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().
09476 { 09477 char buf[1024]; 09478 struct ast_frame f; 09479 const char *content_type = get_header(req, "Content-Type"); 09480 09481 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09482 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09483 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09484 return; 09485 } 09486 09487 if (get_msg_text(buf, sizeof(buf), req)) { 09488 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09489 transmit_response(p, "202 Accepted", req); 09490 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09491 return; 09492 } 09493 09494 if (p->owner) { 09495 if (sip_debug_test_pvt(p)) 09496 ast_verbose("Message received: '%s'\n", buf); 09497 memset(&f, 0, sizeof(f)); 09498 f.frametype = AST_FRAME_TEXT; 09499 f.subclass = 0; 09500 f.offset = 0; 09501 f.data = buf; 09502 f.datalen = strlen(buf); 09503 ast_queue_frame(p->owner, &f); 09504 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09505 } else { /* Message outside of a call, we do not support that */ 09506 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); 09507 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09508 } 09509 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09510 return; 09511 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1616 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01617 { 01618 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01619 int x; 01620 01621 for (x = 0; x < i; x++) { 01622 if (referstatusstrings[x].status == rstatus) 01623 return (char *) referstatusstrings[x].text; 01624 } 01625 return ""; 01626 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7764 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_test_flag, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07765 { 07766 char data[256]; 07767 struct in_addr in; 07768 int expiry; 07769 int port; 07770 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07771 07772 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07773 return; 07774 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07775 return; 07776 07777 scan = data; 07778 addr = strsep(&scan, ":"); 07779 port_str = strsep(&scan, ":"); 07780 expiry_str = strsep(&scan, ":"); 07781 username = strsep(&scan, ":"); 07782 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07783 07784 if (!inet_aton(addr, &in)) 07785 return; 07786 07787 if (port_str) 07788 port = atoi(port_str); 07789 else 07790 return; 07791 07792 if (expiry_str) 07793 expiry = atoi(expiry_str); 07794 else 07795 return; 07796 07797 if (username) 07798 ast_copy_string(peer->username, username, sizeof(peer->username)); 07799 if (contact) 07800 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07801 07802 if (option_debug > 1) 07803 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07804 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07805 07806 memset(&peer->addr, 0, sizeof(peer->addr)); 07807 peer->addr.sin_family = AF_INET; 07808 peer->addr.sin_addr = in; 07809 peer->addr.sin_port = htons(port); 07810 if (sipsock < 0) { 07811 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07812 if (peer->pokeexpire > -1) 07813 ast_sched_del(sched, peer->pokeexpire); 07814 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07815 } else 07816 sip_poke_peer(peer); 07817 if (peer->expire > -1) 07818 ast_sched_del(sched, peer->expire); 07819 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07820 register_peer_exten(peer, TRUE); 07821 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2392 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().
02393 { 02394 char multi[256]; 02395 char *stringp, *ext, *context; 02396 02397 /* XXX note that global_regcontext is both a global 'enable' flag and 02398 * the name of the global regexten context, if not specified 02399 * individually. 02400 */ 02401 if (ast_strlen_zero(global_regcontext)) 02402 return; 02403 02404 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02405 stringp = multi; 02406 while ((ext = strsep(&stringp, "&"))) { 02407 if ((context = strchr(ext, '@'))) { 02408 *context++ = '\0'; /* split ext@context */ 02409 if (!ast_context_find(context)) { 02410 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02411 continue; 02412 } 02413 } else { 02414 context = global_regcontext; 02415 } 02416 if (onoff) 02417 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02418 ast_strdup(peer->name), ast_free, "SIP"); 02419 else 02420 ast_context_remove_extension(context, ext, 1, NULL); 02421 } 02422 }
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 8417 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.
08419 { 08420 enum check_auth_result res = AUTH_NOT_FOUND; 08421 struct sip_peer *peer; 08422 char tmp[256]; 08423 char *name, *c; 08424 char *t; 08425 char *domain; 08426 08427 /* Terminate URI */ 08428 t = uri; 08429 while(*t && (*t > 32) && (*t != ';')) 08430 t++; 08431 *t = '\0'; 08432 08433 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08434 if (pedanticsipchecking) 08435 ast_uri_decode(tmp); 08436 08437 c = get_in_brackets(tmp); 08438 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08439 08440 if (!strncasecmp(c, "sip:", 4)) { 08441 name = c + 4; 08442 } else { 08443 name = c; 08444 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08445 } 08446 08447 /* Strip off the domain name */ 08448 if ((c = strchr(name, '@'))) { 08449 *c++ = '\0'; 08450 domain = c; 08451 if ((c = strchr(domain, ':'))) /* Remove :port */ 08452 *c = '\0'; 08453 if (!AST_LIST_EMPTY(&domain_list)) { 08454 if (!check_sip_domain(domain, NULL, 0)) { 08455 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08456 return AUTH_UNKNOWN_DOMAIN; 08457 } 08458 } 08459 } 08460 08461 ast_string_field_set(p, exten, name); 08462 build_contact(p); 08463 peer = find_peer(name, NULL, 1); 08464 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08465 /* Peer fails ACL check */ 08466 if (peer) { 08467 ASTOBJ_UNREF(peer, sip_destroy_peer); 08468 peer = NULL; 08469 res = AUTH_ACL_FAILED; 08470 } else 08471 res = AUTH_NOT_FOUND; 08472 } 08473 if (peer) { 08474 /* Set Frame packetization */ 08475 if (p->rtp) { 08476 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08477 p->autoframing = peer->autoframing; 08478 } 08479 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08480 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08481 res = AUTH_PEER_NOT_DYNAMIC; 08482 } else { 08483 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08484 transmit_response(p, "100 Trying", req); 08485 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08486 sip_cancel_destroy(p); 08487 08488 /* We have a succesful registration attemp with proper authentication, 08489 now, update the peer */ 08490 switch (parse_register_contact(p, peer, req)) { 08491 case PARSE_REGISTER_FAILED: 08492 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08493 transmit_response_with_date(p, "400 Bad Request", req); 08494 peer->lastmsgssent = -1; 08495 res = 0; 08496 break; 08497 case PARSE_REGISTER_QUERY: 08498 transmit_response_with_date(p, "200 OK", req); 08499 peer->lastmsgssent = -1; 08500 res = 0; 08501 break; 08502 case PARSE_REGISTER_UPDATE: 08503 update_peer(peer, p->expiry); 08504 /* Say OK and ask subsystem to retransmit msg counter */ 08505 transmit_response_with_date(p, "200 OK", req); 08506 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08507 peer->lastmsgssent = -1; 08508 res = 0; 08509 break; 08510 } 08511 } 08512 } 08513 } 08514 if (!peer && autocreatepeer) { 08515 /* Create peer if we have autocreate mode enabled */ 08516 peer = temp_peer(name); 08517 if (peer) { 08518 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08519 sip_cancel_destroy(p); 08520 switch (parse_register_contact(p, peer, req)) { 08521 case PARSE_REGISTER_FAILED: 08522 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08523 transmit_response_with_date(p, "400 Bad Request", req); 08524 peer->lastmsgssent = -1; 08525 res = 0; 08526 break; 08527 case PARSE_REGISTER_QUERY: 08528 transmit_response_with_date(p, "200 OK", req); 08529 peer->lastmsgssent = -1; 08530 res = 0; 08531 break; 08532 case PARSE_REGISTER_UPDATE: 08533 /* Say OK and ask subsystem to retransmit msg counter */ 08534 transmit_response_with_date(p, "200 OK", req); 08535 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08536 peer->lastmsgssent = -1; 08537 res = 0; 08538 break; 08539 } 08540 } 08541 } 08542 if (!res) { 08543 ast_device_state_changed("SIP/%s", peer->name); 08544 } 08545 if (res < 0) { 08546 switch (res) { 08547 case AUTH_SECRET_FAILED: 08548 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08549 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08550 break; 08551 case AUTH_USERNAME_MISMATCH: 08552 /* Username and digest username does not match. 08553 Asterisk uses the From: username for authentication. We need the 08554 users to use the same authentication user name until we support 08555 proper authentication by digest auth name */ 08556 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08557 break; 08558 case AUTH_NOT_FOUND: 08559 case AUTH_PEER_NOT_DYNAMIC: 08560 case AUTH_ACL_FAILED: 08561 if (global_alwaysauthreject) { 08562 transmit_fake_auth_response(p, &p->initreq, 1); 08563 } else { 08564 /* URI not found */ 08565 if (res == AUTH_UNKNOWN_DOMAIN || res == AUTH_PEER_NOT_DYNAMIC) 08566 transmit_response(p, "403 Forbidden", &p->initreq); 08567 else 08568 transmit_response(p, "404 Not found", &p->initreq); 08569 } 08570 break; 08571 default: 08572 break; 08573 } 08574 } 08575 if (peer) 08576 ASTOBJ_UNREF(peer, sip_destroy_peer); 08577 08578 return res; 08579 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7263 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.
07264 { 07265 switch(regstate) { 07266 case REG_STATE_FAILED: 07267 return "Failed"; 07268 case REG_STATE_UNREGISTERED: 07269 return "Unregistered"; 07270 case REG_STATE_REGSENT: 07271 return "Request Sent"; 07272 case REG_STATE_AUTHSENT: 07273 return "Auth. Sent"; 07274 case REG_STATE_REGISTERED: 07275 return "Registered"; 07276 case REG_STATE_REJECTED: 07277 return "Rejected"; 07278 case REG_STATE_TIMEOUT: 07279 return "Timeout"; 07280 case REG_STATE_NOAUTH: 07281 return "No Authentication"; 07282 default: 07283 return "Unknown"; 07284 } 07285 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17574 of file chan_sip.c.
References sip_reload().
17575 { 17576 return sip_reload(0, 0, NULL); 17577 }
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 16475 of file chan_sip.c.
References ahp, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_load(), ast_copy_flags, AST_FLAGS_ALL, ast_free_ha(), ast_jb_read_conf(), ast_log(), AST_MAX_CONTEXT, ast_set_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), bindaddr, context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_EXPIRY, default_jbconf, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, externexpire, externhost, externip, externrefresh, FALSE, global_flags, global_jbconf, handle_common_options(), hp, localaddr, LOG_NOTICE, ast_variable::name, ast_variable::next, ourport, outboundproxyip, SIP_CAN_REINVITE, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, STANDARD_SIP_PORT, TRANSFER_OPENFORALL, and ast_variable::value.
16476 { 16477 struct ast_config *cfg, *ucfg; 16478 struct ast_variable *v; 16479 struct sip_peer *peer; 16480 struct sip_user *user; 16481 struct ast_hostent ahp; 16482 char *cat, *stringp, *context, *oldregcontext; 16483 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16484 struct hostent *hp; 16485 int format; 16486 struct ast_flags dummy[2]; 16487 int auto_sip_domains = FALSE; 16488 struct sockaddr_in old_bindaddr = bindaddr; 16489 int registry_count = 0, peer_count = 0, user_count = 0; 16490 unsigned int temp_tos = 0; 16491 struct ast_flags debugflag = {0}; 16492 16493 cfg = ast_config_load(config); 16494 16495 /* We *must* have a config file otherwise stop immediately */ 16496 if (!cfg) { 16497 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16498 return -1; 16499 } 16500 16501 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16502 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16503 oldregcontext = oldcontexts; 16504 16505 /* Clear all flags before setting default values */ 16506 /* Preserve debugging settings for console */ 16507 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16508 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16509 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16510 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16511 16512 /* Reset IP addresses */ 16513 memset(&bindaddr, 0, sizeof(bindaddr)); 16514 ast_free_ha(localaddr); 16515 memset(&localaddr, 0, sizeof(localaddr)); 16516 memset(&externip, 0, sizeof(externip)); 16517 memset(&default_prefs, 0 , sizeof(default_prefs)); 16518 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16519 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16520 ourport = STANDARD_SIP_PORT; 16521 srvlookup = DEFAULT_SRVLOOKUP; 16522 global_tos_sip = DEFAULT_TOS_SIP; 16523 global_tos_audio = DEFAULT_TOS_AUDIO; 16524 global_tos_video = DEFAULT_TOS_VIDEO; 16525 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16526 externexpire = 0; /* Expiration for DNS re-issuing */ 16527 externrefresh = 10; 16528 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16529 16530 /* Reset channel settings to default before re-configuring */ 16531 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16532 global_regcontext[0] = '\0'; 16533 expiry = DEFAULT_EXPIRY; 16534 global_notifyringing = DEFAULT_NOTIFYRINGING; 16535 global_limitonpeers = FALSE; 16536 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16537 global_notifyhold = FALSE; 16538 global_alwaysauthreject = 0; 16539 global_allowsubscribe = FALSE; 16540 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16541 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16542 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16543 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16544 else 16545 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16546 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16547 compactheaders = DEFAULT_COMPACTHEADERS; 16548 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16549 global_regattempts_max = 0; 16550 pedanticsipchecking = DEFAULT_PEDANTIC; 16551 global_mwitime = DEFAULT_MWITIME; 16552 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16553 global_autoframing = 0; 16554 global_allowguest = DEFAULT_ALLOWGUEST; 16555 global_rtptimeout = 0; 16556 global_rtpholdtimeout = 0; 16557 global_rtpkeepalive = 0; 16558 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16559 global_rtautoclear = 120; 16560 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16561 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16562 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16563 16564 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16565 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16566 default_subscribecontext[0] = '\0'; 16567 default_language[0] = '\0'; 16568 default_fromdomain[0] = '\0'; 16569 default_qualify = DEFAULT_QUALIFY; 16570 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16571 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16572 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16573 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16574 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16575 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16576 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16577 16578 /* Debugging settings, always default to off */ 16579 dumphistory = FALSE; 16580 recordhistory = FALSE; 16581 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16582 16583 /* Misc settings for the channel */ 16584 global_relaxdtmf = FALSE; 16585 global_callevents = FALSE; 16586 global_t1min = DEFAULT_T1MIN; 16587 16588 global_matchexterniplocally = FALSE; 16589 16590 /* Copy the default jb config over global_jbconf */ 16591 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16592 16593 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16594 16595 /* Read the [general] config section of sip.conf (or from realtime config) */ 16596 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16597 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16598 continue; 16599 /* handle jb conf */ 16600 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16601 continue; 16602 16603 /* Create the interface list */ 16604 if (!strcasecmp(v->name, "context")) { 16605 ast_copy_string(default_context, v->value, sizeof(default_context)); 16606 } else if (!strcasecmp(v->name, "allowguest")) { 16607 global_allowguest = ast_true(v->value) ? 1 : 0; 16608 } else if (!strcasecmp(v->name, "realm")) { 16609 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16610 } else if (!strcasecmp(v->name, "useragent")) { 16611 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16612 if (option_debug) 16613 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16614 } else if (!strcasecmp(v->name, "allowtransfer")) { 16615 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16616 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16617 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16618 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16619 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16620 } else if (!strcasecmp(v->name, "rtupdate")) { 16621 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16622 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16623 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16624 } else if (!strcasecmp(v->name, "t1min")) { 16625 global_t1min = atoi(v->value); 16626 } else if (!strcasecmp(v->name, "rtautoclear")) { 16627 int i = atoi(v->value); 16628 if (i > 0) 16629 global_rtautoclear = i; 16630 else 16631 i = 0; 16632 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16633 } else if (!strcasecmp(v->name, "usereqphone")) { 16634 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16635 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16636 global_relaxdtmf = ast_true(v->value); 16637 } else if (!strcasecmp(v->name, "checkmwi")) { 16638 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16639 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16640 global_mwitime = DEFAULT_MWITIME; 16641 } 16642 } else if (!strcasecmp(v->name, "vmexten")) { 16643 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16644 } else if (!strcasecmp(v->name, "rtptimeout")) { 16645 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16646 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16647 global_rtptimeout = 0; 16648 } 16649 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16650 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16651 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16652 global_rtpholdtimeout = 0; 16653 } 16654 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16655 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16656 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16657 global_rtpkeepalive = 0; 16658 } 16659 } else if (!strcasecmp(v->name, "compactheaders")) { 16660 compactheaders = ast_true(v->value); 16661 } else if (!strcasecmp(v->name, "notifymimetype")) { 16662 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 16663 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 16664 global_limitonpeers = ast_true(v->value); 16665 } else if (!strcasecmp(v->name, "directrtpsetup")) { 16666 global_directrtpsetup = ast_true(v->value); 16667 } else if (!strcasecmp(v->name, "notifyringing")) { 16668 global_notifyringing = ast_true(v->value); 16669 } else if (!strcasecmp(v->name, "notifyhold")) { 16670 global_notifyhold = ast_true(v->value); 16671 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 16672 global_alwaysauthreject = ast_true(v->value); 16673 } else if (!strcasecmp(v->name, "mohinterpret") 16674 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16675 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 16676 } else if (!strcasecmp(v->name, "mohsuggest")) { 16677 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 16678 } else if (!strcasecmp(v->name, "language")) { 16679 ast_copy_string(default_language, v->value, sizeof(default_language)); 16680 } else if (!strcasecmp(v->name, "regcontext")) { 16681 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 16682 stringp = newcontexts; 16683 /* Let's remove any contexts that are no longer defined in regcontext */ 16684 cleanup_stale_contexts(stringp, oldregcontext); 16685 /* Create contexts if they don't exist already */ 16686 while ((context = strsep(&stringp, "&"))) { 16687 if (!ast_context_find(context)) 16688 ast_context_create(NULL, context,"SIP"); 16689 } 16690 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 16691 } else if (!strcasecmp(v->name, "callerid")) { 16692 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 16693 } else if (!strcasecmp(v->name, "fromdomain")) { 16694 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 16695 } else if (!strcasecmp(v->name, "outboundproxy")) { 16696 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 16697 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 16698 } else if (!strcasecmp(v->name, "outboundproxyport")) { 16699 /* Port needs to be after IP */ 16700 sscanf(v->value, "%d", &format); 16701 outboundproxyip.sin_port = htons(format); 16702 } else if (!strcasecmp(v->name, "autocreatepeer")) { 16703 autocreatepeer = ast_true(v->value); 16704 } else if (!strcasecmp(v->name, "srvlookup")) { 16705 srvlookup = ast_true(v->value); 16706 } else if (!strcasecmp(v->name, "pedantic")) { 16707 pedanticsipchecking = ast_true(v->value); 16708 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 16709 max_expiry = atoi(v->value); 16710 if (max_expiry < 1) 16711 max_expiry = DEFAULT_MAX_EXPIRY; 16712 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 16713 min_expiry = atoi(v->value); 16714 if (min_expiry < 1) 16715 min_expiry = DEFAULT_MIN_EXPIRY; 16716 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 16717 default_expiry = atoi(v->value); 16718 if (default_expiry < 1) 16719 default_expiry = DEFAULT_DEFAULT_EXPIRY; 16720 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 16721 if (ast_true(v->value)) 16722 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16723 } else if (!strcasecmp(v->name, "dumphistory")) { 16724 dumphistory = ast_true(v->value); 16725 } else if (!strcasecmp(v->name, "recordhistory")) { 16726 recordhistory = ast_true(v->value); 16727 } else if (!strcasecmp(v->name, "registertimeout")) { 16728 global_reg_timeout = atoi(v->value); 16729 if (global_reg_timeout < 1) 16730 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16731 } else if (!strcasecmp(v->name, "registerattempts")) { 16732 global_regattempts_max = atoi(v->value); 16733 } else if (!strcasecmp(v->name, "bindaddr")) { 16734 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 16735 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 16736 } else { 16737 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 16738 } 16739 } else if (!strcasecmp(v->name, "localnet")) { 16740 struct ast_ha *na; 16741 if (!(na = ast_append_ha("d", v->value, localaddr))) 16742 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 16743 else 16744 localaddr = na; 16745 } else if (!strcasecmp(v->name, "localmask")) { 16746 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 16747 } else if (!strcasecmp(v->name, "externip")) { 16748 if (!(hp = ast_gethostbyname(v->value, &ahp))) 16749 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 16750 else 16751 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16752 externexpire = 0; 16753 } else if (!strcasecmp(v->name, "externhost")) { 16754 ast_copy_string(externhost, v->value, sizeof(externhost)); 16755 if (!(hp = ast_gethostbyname(externhost, &ahp))) 16756 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 16757 else 16758 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16759 externexpire = time(NULL); 16760 } else if (!strcasecmp(v->name, "externrefresh")) { 16761 if (sscanf(v->value, "%d", &externrefresh) != 1) { 16762 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 16763 externrefresh = 10; 16764 } 16765 } else if (!strcasecmp(v->name, "allow")) { 16766 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 16767 } else if (!strcasecmp(v->name, "disallow")) { 16768 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 16769 } else if (!strcasecmp(v->name, "autoframing")) { 16770 global_autoframing = ast_true(v->value); 16771 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 16772 allow_external_domains = ast_true(v->value); 16773 } else if (!strcasecmp(v->name, "autodomain")) { 16774 auto_sip_domains = ast_true(v->value); 16775 } else if (!strcasecmp(v->name, "domain")) { 16776 char *domain = ast_strdupa(v->value); 16777 char *context = strchr(domain, ','); 16778 16779 if (context) 16780 *context++ = '\0'; 16781 16782 if (option_debug && ast_strlen_zero(context)) 16783 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 16784 if (ast_strlen_zero(domain)) 16785 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 16786 else 16787 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 16788 } else if (!strcasecmp(v->name, "register")) { 16789 if (sip_register(v->value, v->lineno) == 0) 16790 registry_count++; 16791 } else if (!strcasecmp(v->name, "tos")) { 16792 if (!ast_str2tos(v->value, &temp_tos)) { 16793 global_tos_sip = temp_tos; 16794 global_tos_audio = temp_tos; 16795 global_tos_video = temp_tos; 16796 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 16797 } else 16798 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 16799 } else if (!strcasecmp(v->name, "tos_sip")) { 16800 if (ast_str2tos(v->value, &global_tos_sip)) 16801 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 16802 } else if (!strcasecmp(v->name, "tos_audio")) { 16803 if (ast_str2tos(v->value, &global_tos_audio)) 16804 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 16805 } else if (!strcasecmp(v->name, "tos_video")) { 16806 if (ast_str2tos(v->value, &global_tos_video)) 16807 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 16808 } else if (!strcasecmp(v->name, "bindport")) { 16809 if (sscanf(v->value, "%d", &ourport) == 1) { 16810 bindaddr.sin_port = htons(ourport); 16811 } else { 16812 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 16813 } 16814 } else if (!strcasecmp(v->name, "qualify")) { 16815 if (!strcasecmp(v->value, "no")) { 16816 default_qualify = 0; 16817 } else if (!strcasecmp(v->value, "yes")) { 16818 default_qualify = DEFAULT_MAXMS; 16819 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 16820 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 16821 default_qualify = 0; 16822 } 16823 } else if (!strcasecmp(v->name, "callevents")) { 16824 global_callevents = ast_true(v->value); 16825 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16826 default_maxcallbitrate = atoi(v->value); 16827 if (default_maxcallbitrate < 0) 16828 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16829 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 16830 global_matchexterniplocally = ast_true(v->value); 16831 } 16832 } 16833 16834 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 16835 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 16836 allow_external_domains = 1; 16837 } 16838 16839 /* Build list of authentication to various SIP realms, i.e. service providers */ 16840 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 16841 /* Format for authentication is auth = username:password@realm */ 16842 if (!strcasecmp(v->name, "auth")) 16843 authl = add_realm_authentication(authl, v->value, v->lineno); 16844 } 16845 16846 ucfg = ast_config_load("users.conf"); 16847 if (ucfg) { 16848 struct ast_variable *gen; 16849 int genhassip, genregistersip; 16850 const char *hassip, *registersip; 16851 16852 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 16853 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 16854 gen = ast_variable_browse(ucfg, "general"); 16855 cat = ast_category_browse(ucfg, NULL); 16856 while (cat) { 16857 if (strcasecmp(cat, "general")) { 16858 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 16859 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 16860 if (ast_true(hassip) || (!hassip && genhassip)) { 16861 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 16862 if (peer) { 16863 ast_device_state_changed("SIP/%s", peer->name); 16864 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16865 ASTOBJ_UNREF(peer, sip_destroy_peer); 16866 peer_count++; 16867 } 16868 } 16869 if (ast_true(registersip) || (!registersip && genregistersip)) { 16870 char tmp[256]; 16871 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 16872 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 16873 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 16874 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 16875 if (!host) 16876 host = ast_variable_retrieve(ucfg, "general", "host"); 16877 if (!username) 16878 username = ast_variable_retrieve(ucfg, "general", "username"); 16879 if (!secret) 16880 secret = ast_variable_retrieve(ucfg, "general", "secret"); 16881 if (!contact) 16882 contact = "s"; 16883 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 16884 if (!ast_strlen_zero(secret)) 16885 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 16886 else 16887 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 16888 if (sip_register(tmp, 0) == 0) 16889 registry_count++; 16890 } 16891 } 16892 } 16893 cat = ast_category_browse(ucfg, cat); 16894 } 16895 ast_config_destroy(ucfg); 16896 } 16897 16898 16899 /* Load peers, users and friends */ 16900 cat = NULL; 16901 while ( (cat = ast_category_browse(cfg, cat)) ) { 16902 const char *utype; 16903 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 16904 continue; 16905 utype = ast_variable_retrieve(cfg, cat, "type"); 16906 if (!utype) { 16907 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 16908 continue; 16909 } else { 16910 int is_user = 0, is_peer = 0; 16911 if (!strcasecmp(utype, "user")) 16912 is_user = 1; 16913 else if (!strcasecmp(utype, "friend")) 16914 is_user = is_peer = 1; 16915 else if (!strcasecmp(utype, "peer")) 16916 is_peer = 1; 16917 else { 16918 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 16919 continue; 16920 } 16921 if (is_user) { 16922 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 16923 if (user) { 16924 ASTOBJ_CONTAINER_LINK(&userl,user); 16925 ASTOBJ_UNREF(user, sip_destroy_user); 16926 user_count++; 16927 } 16928 } 16929 if (is_peer) { 16930 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 16931 if (peer) { 16932 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16933 ASTOBJ_UNREF(peer, sip_destroy_peer); 16934 peer_count++; 16935 } 16936 } 16937 } 16938 } 16939 if (ast_find_ourip(&__ourip, bindaddr)) { 16940 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 16941 return 0; 16942 } 16943 if (!ntohs(bindaddr.sin_port)) 16944 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 16945 bindaddr.sin_family = AF_INET; 16946 ast_mutex_lock(&netlock); 16947 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 16948 close(sipsock); 16949 sipsock = -1; 16950 } 16951 if (sipsock < 0) { 16952 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 16953 if (sipsock < 0) { 16954 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 16955 return -1; 16956 } else { 16957 /* Allow SIP clients on the same host to access us: */ 16958 const int reuseFlag = 1; 16959 16960 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 16961 (const char*)&reuseFlag, 16962 sizeof reuseFlag); 16963 16964 ast_enable_packet_fragmentation(sipsock); 16965 16966 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 16967 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 16968 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 16969 strerror(errno)); 16970 close(sipsock); 16971 sipsock = -1; 16972 } else { 16973 if (option_verbose > 1) { 16974 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 16975 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 16976 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 16977 } 16978 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 16979 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 16980 } 16981 } 16982 } 16983 ast_mutex_unlock(&netlock); 16984 16985 /* Add default domains - host name, IP address and IP:port */ 16986 /* Only do this if user added any sip domain with "localdomains" */ 16987 /* In order to *not* break backwards compatibility */ 16988 /* Some phones address us at IP only, some with additional port number */ 16989 if (auto_sip_domains) { 16990 char temp[MAXHOSTNAMELEN]; 16991 16992 /* First our default IP address */ 16993 if (bindaddr.sin_addr.s_addr) 16994 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 16995 else 16996 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 16997 16998 /* Our extern IP address, if configured */ 16999 if (externip.sin_addr.s_addr) 17000 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 17001 17002 /* Extern host name (NAT traversal support) */ 17003 if (!ast_strlen_zero(externhost)) 17004 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 17005 17006 /* Our host name */ 17007 if (!gethostname(temp, sizeof(temp))) 17008 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 17009 } 17010 17011 /* Release configuration from memory */ 17012 ast_config_destroy(cfg); 17013 17014 /* Load the list of manual NOTIFY types to support */ 17015 if (notify_types) 17016 ast_config_destroy(notify_types); 17017 notify_types = ast_config_load(notify_config); 17018 17019 /* Done, tell the manager */ 17020 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\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count); 17021 17022 return 0; 17023 }
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 11261 of file chan_sip.c.
References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), key(), keys, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11262 { 11263 char tmp[512]; 11264 char *c; 11265 char oldnonce[256]; 11266 11267 /* table of recognised keywords, and places where they should be copied */ 11268 const struct x { 11269 const char *key; 11270 int field_index; 11271 } *i, keys[] = { 11272 { "realm=", ast_string_field_index(p, realm) }, 11273 { "nonce=", ast_string_field_index(p, nonce) }, 11274 { "opaque=", ast_string_field_index(p, opaque) }, 11275 { "qop=", ast_string_field_index(p, qop) }, 11276 { "domain=", ast_string_field_index(p, domain) }, 11277 { NULL, 0 }, 11278 }; 11279 11280 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11281 if (ast_strlen_zero(tmp)) 11282 return -1; 11283 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11284 ast_log(LOG_WARNING, "missing Digest.\n"); 11285 return -1; 11286 } 11287 c = tmp + strlen("Digest "); 11288 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11289 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11290 for (i = keys; i->key != NULL; i++) { 11291 char *src, *separator; 11292 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11293 continue; 11294 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11295 c += strlen(i->key); 11296 if (*c == '"') { 11297 src = ++c; 11298 separator = "\""; 11299 } else { 11300 src = c; 11301 separator = ","; 11302 } 11303 strsep(&c, separator); /* clear separator and move ptr */ 11304 ast_string_field_index_set(p, i->field_index, src); 11305 break; 11306 } 11307 if (i->key == NULL) /* not found, try ',' */ 11308 strsep(&c, ","); 11309 } 11310 /* Reset nonce count */ 11311 if (strcmp(p->nonce, oldnonce)) 11312 p->noncecount = 0; 11313 11314 /* Save auth data for following registrations */ 11315 if (p->registry) { 11316 struct sip_registry *r = p->registry; 11317 11318 if (strcmp(r->nonce, p->nonce)) { 11319 ast_string_field_set(r, realm, p->realm); 11320 ast_string_field_set(r, nonce, p->nonce); 11321 ast_string_field_set(r, domain, p->domain); 11322 ast_string_field_set(r, opaque, p->opaque); 11323 ast_string_field_set(r, qop, p->qop); 11324 r->noncecount = 0; 11325 } 11326 } 11327 return build_reply_digest(p, sipmethod, digest, digest_len); 11328 }
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 5770 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.
05771 { 05772 struct sip_request *orig = &p->initreq; 05773 char stripped[80]; 05774 char tmp[80]; 05775 char newto[256]; 05776 const char *c; 05777 const char *ot, *of; 05778 int is_strict = FALSE; /*!< Strict routing flag */ 05779 05780 memset(req, 0, sizeof(struct sip_request)); 05781 05782 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05783 05784 if (!seqno) { 05785 p->ocseq++; 05786 seqno = p->ocseq; 05787 } 05788 05789 if (newbranch) { 05790 p->branch ^= ast_random(); 05791 build_via(p); 05792 } 05793 05794 /* Check for strict or loose router */ 05795 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05796 is_strict = TRUE; 05797 if (sipdebug) 05798 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05799 } 05800 05801 if (sipmethod == SIP_CANCEL) 05802 c = p->initreq.rlPart2; /* Use original URI */ 05803 else if (sipmethod == SIP_ACK) { 05804 /* Use URI from Contact: in 200 OK (if INVITE) 05805 (we only have the contacturi on INVITEs) */ 05806 if (!ast_strlen_zero(p->okcontacturi)) 05807 c = is_strict ? p->route->hop : p->okcontacturi; 05808 else 05809 c = p->initreq.rlPart2; 05810 } else if (!ast_strlen_zero(p->okcontacturi)) 05811 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05812 else if (!ast_strlen_zero(p->uri)) 05813 c = p->uri; 05814 else { 05815 char *n; 05816 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05817 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05818 sizeof(stripped)); 05819 n = get_in_brackets(stripped); 05820 c = strsep(&n, ";"); /* trim ; and beyond */ 05821 } 05822 init_req(req, sipmethod, c); 05823 05824 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05825 05826 add_header(req, "Via", p->via); 05827 if (p->route) { 05828 set_destination(p, p->route->hop); 05829 add_route(req, is_strict ? p->route->next : p->route); 05830 } 05831 05832 ot = get_header(orig, "To"); 05833 of = get_header(orig, "From"); 05834 05835 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05836 as our original request, including tag (or presumably lack thereof) */ 05837 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05838 /* Add the proper tag if we don't have it already. If they have specified 05839 their tag, use it. Otherwise, use our own tag */ 05840 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05841 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05842 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05843 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05844 else 05845 snprintf(newto, sizeof(newto), "%s", ot); 05846 ot = newto; 05847 } 05848 05849 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05850 add_header(req, "From", of); 05851 add_header(req, "To", ot); 05852 } else { 05853 add_header(req, "From", ot); 05854 add_header(req, "To", of); 05855 } 05856 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05857 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05858 add_header(req, "Contact", p->our_contact); 05859 05860 copy_header(req, orig, "Call-ID"); 05861 add_header(req, "CSeq", tmp); 05862 05863 if (!ast_strlen_zero(global_useragent)) 05864 add_header(req, "User-Agent", global_useragent); 05865 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05866 05867 if (!ast_strlen_zero(p->rpid)) 05868 add_header(req, "Remote-Party-ID", p->rpid); 05869 05870 return 0; 05871 }
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 5722 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.
05723 { 05724 char newto[256]; 05725 const char *ot; 05726 05727 init_resp(resp, msg); 05728 copy_via_headers(p, resp, req, "Via"); 05729 if (msg[0] == '2') 05730 copy_all_header(resp, req, "Record-Route"); 05731 copy_header(resp, req, "From"); 05732 ot = get_header(req, "To"); 05733 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05734 /* Add the proper tag if we don't have it already. If they have specified 05735 their tag, use it. Otherwise, use our own tag */ 05736 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05737 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05738 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05739 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05740 else 05741 ast_copy_string(newto, ot, sizeof(newto)); 05742 ot = newto; 05743 } 05744 add_header(resp, "To", ot); 05745 copy_header(resp, req, "Call-ID"); 05746 copy_header(resp, req, "CSeq"); 05747 if (!ast_strlen_zero(global_useragent)) 05748 add_header(resp, "User-Agent", global_useragent); 05749 add_header(resp, "Allow", ALLOWED_METHODS); 05750 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05751 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05752 /* For registration responses, we also need expiry and 05753 contact info */ 05754 char tmp[256]; 05755 05756 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05757 add_header(resp, "Expires", tmp); 05758 if (p->expiry) { /* Only add contact if we have an expiry time */ 05759 char contact[BUFSIZ]; 05760 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05761 add_header(resp, "Contact", contact); /* Not when we unregister */ 05762 } 05763 } else if (msg[0] != '4' && p->our_contact[0]) { 05764 add_header(resp, "Contact", p->our_contact); 05765 } 05766 return 0; 05767 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15424 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.
15425 { 15426 /* If we're supposed to be stopped -- stay stopped */ 15427 if (monitor_thread == AST_PTHREADT_STOP) 15428 return 0; 15429 ast_mutex_lock(&monlock); 15430 if (monitor_thread == pthread_self()) { 15431 ast_mutex_unlock(&monlock); 15432 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15433 return -1; 15434 } 15435 if (monitor_thread != AST_PTHREADT_NULL) { 15436 /* Wake up the thread */ 15437 pthread_kill(monitor_thread, SIGURG); 15438 } else { 15439 /* Start a new monitor */ 15440 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15441 ast_mutex_unlock(&monlock); 15442 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15443 return -1; 15444 } 15445 } 15446 ast_mutex_unlock(&monlock); 15447 return 0; 15448 }
static int retrans_pkt | ( | void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1884 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01885 { 01886 struct sip_pkt *pkt = data, *prev, *cur = NULL; 01887 int reschedule = DEFAULT_RETRANS; 01888 int xmitres = 0; 01889 01890 /* Lock channel PVT */ 01891 ast_mutex_lock(&pkt->owner->lock); 01892 01893 if (pkt->retrans < MAX_RETRANS) { 01894 pkt->retrans++; 01895 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01896 if (sipdebug && option_debug > 3) 01897 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); 01898 } else { 01899 int siptimer_a; 01900 01901 if (sipdebug && option_debug > 3) 01902 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01903 if (!pkt->timer_a) 01904 pkt->timer_a = 2 ; 01905 else 01906 pkt->timer_a = 2 * pkt->timer_a; 01907 01908 /* For non-invites, a maximum of 4 secs */ 01909 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01910 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01911 siptimer_a = 4000; 01912 01913 /* Reschedule re-transmit */ 01914 reschedule = siptimer_a; 01915 if (option_debug > 3) 01916 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); 01917 } 01918 01919 if (sip_debug_test_pvt(pkt->owner)) { 01920 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01921 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01922 pkt->retrans, sip_nat_mode(pkt->owner), 01923 ast_inet_ntoa(dst->sin_addr), 01924 ntohs(dst->sin_port), pkt->data); 01925 } 01926 01927 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01928 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01929 ast_mutex_unlock(&pkt->owner->lock); 01930 if (xmitres == XMIT_ERROR) 01931 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01932 else 01933 return reschedule; 01934 } 01935 /* Too many retries */ 01936 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01937 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01938 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request"); 01939 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01940 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01941 } 01942 if (xmitres == XMIT_ERROR) { 01943 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01944 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01945 } else 01946 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01947 01948 pkt->retransid = -1; 01949 01950 if (ast_test_flag(pkt, FLAG_FATAL)) { 01951 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01952 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01953 usleep(1); 01954 ast_mutex_lock(&pkt->owner->lock); 01955 } 01956 01957 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01958 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01959 01960 if (pkt->owner->owner) { 01961 sip_alreadygone(pkt->owner); 01962 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01963 ast_queue_hangup(pkt->owner->owner); 01964 ast_channel_unlock(pkt->owner->owner); 01965 } else { 01966 /* If no channel owner, destroy now */ 01967 01968 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01969 if (pkt->method != SIP_OPTIONS) { 01970 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01971 sip_alreadygone(pkt->owner); 01972 if (option_debug) 01973 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01974 } 01975 } 01976 } 01977 01978 if (pkt->method == SIP_BYE) { 01979 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01980 if (pkt->owner->owner) 01981 ast_channel_unlock(pkt->owner->owner); 01982 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01983 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01984 } 01985 01986 /* In any case, go ahead and remove the packet */ 01987 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01988 if (cur == pkt) 01989 break; 01990 } 01991 if (cur) { 01992 if (prev) 01993 prev->next = cur->next; 01994 else 01995 pkt->owner->packets = cur->next; 01996 ast_mutex_unlock(&pkt->owner->lock); 01997 free(cur); 01998 pkt = NULL; 01999 } else 02000 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02001 if (pkt) 02002 ast_mutex_unlock(&pkt->owner->lock); 02003 return 0; 02004 }
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 2253 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.
02254 { 02255 int res; 02256 02257 add_blank(req); 02258 if (sip_debug_test_pvt(p)) { 02259 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02260 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); 02261 else 02262 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); 02263 } 02264 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02265 struct sip_request tmp; 02266 parse_copy(&tmp, req); 02267 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02268 } 02269 res = (reliable) ? 02270 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02271 __sip_xmit(p, req->data, req->len); 02272 return res; 02273 }
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 2225 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.
02226 { 02227 int res; 02228 02229 add_blank(req); 02230 if (sip_debug_test_pvt(p)) { 02231 const struct sockaddr_in *dst = sip_real_dst(p); 02232 02233 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02234 reliable ? "Reliably " : "", sip_nat_mode(p), 02235 ast_inet_ntoa(dst->sin_addr), 02236 ntohs(dst->sin_port), req->data); 02237 } 02238 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02239 struct sip_request tmp; 02240 parse_copy(&tmp, req); 02241 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02242 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02243 } 02244 res = (reliable) ? 02245 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02246 __sip_xmit(p, req->data, req->len); 02247 if (res > 0) 02248 return 0; 02249 return res; 02250 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7845 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
07846 { 07847 struct hostent *hp; 07848 struct ast_hostent ahp; 07849 int port; 07850 char *c, *host, *pt; 07851 char *contact; 07852 07853 07854 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07855 /* NAT: Don't trust the contact field. Just use what they came to us 07856 with. */ 07857 pvt->sa = pvt->recv; 07858 return 0; 07859 } 07860 07861 07862 /* Work on a copy */ 07863 contact = ast_strdupa(pvt->fullcontact); 07864 07865 /* Make sure it's a SIP URL */ 07866 if (strncasecmp(contact, "sip:", 4)) { 07867 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07868 } else 07869 contact += 4; 07870 07871 /* Ditch arguments */ 07872 /* XXX this code is replicated also shortly below */ 07873 07874 /* Grab host */ 07875 host = strchr(contact, '@'); 07876 if (!host) { /* No username part */ 07877 host = contact; 07878 c = NULL; 07879 } else { 07880 *host++ = '\0'; 07881 } 07882 pt = strchr(host, ':'); 07883 if (pt) { 07884 *pt++ = '\0'; 07885 port = atoi(pt); 07886 } else 07887 port = STANDARD_SIP_PORT; 07888 07889 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 07890 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 07891 07892 /* XXX This could block for a long time XXX */ 07893 /* We should only do this if it's a name, not an IP */ 07894 hp = ast_gethostbyname(host, &ahp); 07895 if (!hp) { 07896 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07897 return -1; 07898 } 07899 pvt->sa.sin_family = AF_INET; 07900 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 07901 pvt->sa.sin_port = htons(port); 07902 07903 return 0; 07904 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5631 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().
05632 { 05633 char *h, *maddr, hostname[256]; 05634 int port, hn; 05635 struct hostent *hp; 05636 struct ast_hostent ahp; 05637 int debug=sip_debug_test_pvt(p); 05638 05639 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05640 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05641 05642 if (debug) 05643 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05644 05645 /* Find and parse hostname */ 05646 h = strchr(uri, '@'); 05647 if (h) 05648 ++h; 05649 else { 05650 h = uri; 05651 if (strncasecmp(h, "sip:", 4) == 0) 05652 h += 4; 05653 else if (strncasecmp(h, "sips:", 5) == 0) 05654 h += 5; 05655 } 05656 hn = strcspn(h, ":;>") + 1; 05657 if (hn > sizeof(hostname)) 05658 hn = sizeof(hostname); 05659 ast_copy_string(hostname, h, hn); 05660 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05661 h += hn - 1; 05662 05663 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05664 if (*h == ':') { 05665 /* Parse port */ 05666 ++h; 05667 port = strtol(h, &h, 10); 05668 } 05669 else 05670 port = STANDARD_SIP_PORT; 05671 05672 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05673 maddr = strstr(h, "maddr="); 05674 if (maddr) { 05675 maddr += 6; 05676 hn = strspn(maddr, "0123456789.") + 1; 05677 if (hn > sizeof(hostname)) 05678 hn = sizeof(hostname); 05679 ast_copy_string(hostname, maddr, hn); 05680 } 05681 05682 hp = ast_gethostbyname(hostname, &ahp); 05683 if (hp == NULL) { 05684 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05685 return; 05686 } 05687 p->sa.sin_family = AF_INET; 05688 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05689 p->sa.sin_port = htons(port); 05690 if (debug) 05691 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05692 }
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 15728 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(), and realtime_peer().
15729 { 15730 static int dep_insecure_very = 0; 15731 static int dep_insecure_yes = 0; 15732 15733 if (ast_strlen_zero(value)) 15734 return; 15735 15736 if (!strcasecmp(value, "very")) { 15737 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15738 if(!dep_insecure_very) { 15739 if(lineno != -1) 15740 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 15741 else 15742 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 15743 dep_insecure_very = 1; 15744 } 15745 } 15746 else if (ast_true(value)) { 15747 ast_set_flag(flags, SIP_INSECURE_PORT); 15748 if(!dep_insecure_yes) { 15749 if(lineno != -1) 15750 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 15751 else 15752 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 15753 dep_insecure_yes = 1; 15754 } 15755 } 15756 else if (!ast_false(value)) { 15757 char buf[64]; 15758 char *word, *next; 15759 ast_copy_string(buf, value, sizeof(buf)); 15760 next = buf; 15761 while ((word = strsep(&next, ","))) { 15762 if (!strcasecmp(word, "port")) 15763 ast_set_flag(flags, SIP_INSECURE_PORT); 15764 else if (!strcasecmp(word, "invite")) 15765 ast_set_flag(flags, SIP_INSECURE_INVITE); 15766 else 15767 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 15768 } 15769 } 15770 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16155 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().
16156 { 16157 if (peer->expire == 0) { 16158 /* Don't reset expire or port time during reload 16159 if we have an active registration 16160 */ 16161 peer->expire = -1; 16162 peer->pokeexpire = -1; 16163 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16164 } 16165 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16166 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16167 strcpy(peer->context, default_context); 16168 strcpy(peer->subscribecontext, default_subscribecontext); 16169 strcpy(peer->language, default_language); 16170 strcpy(peer->mohinterpret, default_mohinterpret); 16171 strcpy(peer->mohsuggest, default_mohsuggest); 16172 peer->addr.sin_family = AF_INET; 16173 peer->defaddr.sin_family = AF_INET; 16174 peer->capability = global_capability; 16175 peer->maxcallbitrate = default_maxcallbitrate; 16176 peer->rtptimeout = global_rtptimeout; 16177 peer->rtpholdtimeout = global_rtpholdtimeout; 16178 peer->rtpkeepalive = global_rtpkeepalive; 16179 peer->allowtransfer = global_allowtransfer; 16180 peer->autoframing = global_autoframing; 16181 strcpy(peer->vmexten, default_vmexten); 16182 peer->secret[0] = '\0'; 16183 peer->md5secret[0] = '\0'; 16184 peer->cid_num[0] = '\0'; 16185 peer->cid_name[0] = '\0'; 16186 peer->fromdomain[0] = '\0'; 16187 peer->fromuser[0] = '\0'; 16188 peer->regexten[0] = '\0'; 16189 peer->mailbox[0] = '\0'; 16190 peer->callgroup = 0; 16191 peer->pickupgroup = 0; 16192 peer->maxms = default_qualify; 16193 peer->prefs = default_prefs; 16194 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17362 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().
17363 { 17364 int no = 0; 17365 int ok = FALSE; 17366 char varbuf[30]; 17367 char *inbuf = (char *) data; 17368 17369 if (ast_strlen_zero(inbuf)) { 17370 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17371 return 0; 17372 } 17373 ast_channel_lock(chan); 17374 17375 /* Check for headers */ 17376 while (!ok && no <= 50) { 17377 no++; 17378 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17379 17380 /* Compare without the leading underscore */ 17381 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17382 ok = TRUE; 17383 } 17384 if (ok) { 17385 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17386 if (sipdebug) 17387 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17388 } else { 17389 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17390 } 17391 ast_channel_unlock(chan); 17392 return 0; 17393 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2589 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02590 { 02591 /* We know name is the first field, so we can cast */ 02592 struct sip_peer *p = (struct sip_peer *) name; 02593 return !(!inaddrcmp(&p->addr, sin) || 02594 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02595 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02596 }
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 4340 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_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(), 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().
04342 { 04343 struct sip_pvt *p; 04344 04345 if (!(p = ast_calloc(1, sizeof(*p)))) 04346 return NULL; 04347 04348 if (ast_string_field_init(p, 512)) { 04349 free(p); 04350 return NULL; 04351 } 04352 04353 ast_mutex_init(&p->lock); 04354 04355 p->method = intended_method; 04356 p->initid = -1; 04357 p->autokillid = -1; 04358 p->subscribed = NONE; 04359 p->stateid = -1; 04360 p->prefs = default_prefs; /* Set default codecs for this call */ 04361 04362 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04363 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04364 04365 if (sin) { 04366 p->sa = *sin; 04367 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04368 p->ourip = __ourip; 04369 } else 04370 p->ourip = __ourip; 04371 04372 /* Copy global flags to this PVT at setup. */ 04373 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04374 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04375 04376 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04377 04378 p->branch = ast_random(); 04379 make_our_tag(p->tag, sizeof(p->tag)); 04380 p->ocseq = INITIAL_CSEQ; 04381 04382 if (sip_methods[intended_method].need_rtp) { 04383 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04384 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04385 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04386 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04387 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04388 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04389 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04390 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04391 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04392 ast_mutex_destroy(&p->lock); 04393 if (p->chanvars) { 04394 ast_variables_destroy(p->chanvars); 04395 p->chanvars = NULL; 04396 } 04397 free(p); 04398 return NULL; 04399 } 04400 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04401 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04402 ast_rtp_settos(p->rtp, global_tos_audio); 04403 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04404 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04405 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04406 if (p->vrtp) { 04407 ast_rtp_settos(p->vrtp, global_tos_video); 04408 ast_rtp_setdtmf(p->vrtp, 0); 04409 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04410 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04411 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04412 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04413 } 04414 if (p->udptl) 04415 ast_udptl_settos(p->udptl, global_tos_audio); 04416 p->maxcallbitrate = default_maxcallbitrate; 04417 } 04418 04419 if (useglobal_nat && sin) { 04420 /* Setup NAT structure according to global settings if we have an address */ 04421 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04422 p->recv = *sin; 04423 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04424 } 04425 04426 if (p->method != SIP_REGISTER) 04427 ast_string_field_set(p, fromdomain, default_fromdomain); 04428 build_via(p); 04429 if (!callid) 04430 build_callid_pvt(p); 04431 else 04432 ast_string_field_set(p, callid, callid); 04433 /* Assign default music on hold class */ 04434 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04435 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04436 p->capability = global_capability; 04437 p->allowtransfer = global_allowtransfer; 04438 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04439 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04440 p->noncodeccapability |= AST_RTP_DTMF; 04441 if (p->udptl) { 04442 p->t38.capability = global_t38_capability; 04443 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04444 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04445 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04446 p->t38.capability |= T38FAX_UDP_EC_FEC; 04447 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04448 p->t38.capability |= T38FAX_UDP_EC_NONE; 04449 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04450 p->t38.jointcapability = p->t38.capability; 04451 } 04452 ast_string_field_set(p, context, default_context); 04453 04454 /* Add to active dialog list */ 04455 ast_mutex_lock(&iflock); 04456 p->next = iflist; 04457 iflist = p; 04458 ast_mutex_unlock(&iflock); 04459 if (option_debug) 04460 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"); 04461 return p; 04462 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1643 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().
01644 { 01645 if (option_debug > 2) 01646 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01647 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01648 }
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 3591 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, option_debug, 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.
03592 { 03593 int res = 0; 03594 struct sip_pvt *p = ast->tech_pvt; 03595 03596 ast_mutex_lock(&p->lock); 03597 if (ast->_state != AST_STATE_UP) { 03598 try_suggested_sip_codec(p); 03599 03600 ast_setstate(ast, AST_STATE_UP); 03601 if (option_debug) 03602 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03603 if (p->t38.state == T38_PEER_DIRECT) { 03604 p->t38.state = T38_ENABLED; 03605 if (option_debug > 1) 03606 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03607 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03608 } else 03609 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03610 } 03611 ast_mutex_unlock(&p->lock); 03612 return res; 03613 }
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 2893 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, 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.
02894 { 02895 int res, xmitres = 0; 02896 struct sip_pvt *p; 02897 struct varshead *headp; 02898 struct ast_var_t *current; 02899 const char *referer = NULL; /* SIP refererer */ 02900 02901 p = ast->tech_pvt; 02902 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02903 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02904 return -1; 02905 } 02906 02907 /* Check whether there is vxml_url, distinctive ring variables */ 02908 headp=&ast->varshead; 02909 AST_LIST_TRAVERSE(headp,current,entries) { 02910 /* Check whether there is a VXML_URL variable */ 02911 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02912 p->options->vxml_url = ast_var_value(current); 02913 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02914 p->options->uri_options = ast_var_value(current); 02915 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02916 /* Check whether there is a ALERT_INFO variable */ 02917 p->options->distinctive_ring = ast_var_value(current); 02918 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02919 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02920 p->options->addsipheaders = 1; 02921 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02922 /* This is a transfered call */ 02923 p->options->transfer = 1; 02924 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02925 /* This is the referer */ 02926 referer = ast_var_value(current); 02927 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02928 /* We're replacing a call. */ 02929 p->options->replaces = ast_var_value(current); 02930 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02931 p->t38.state = T38_LOCAL_DIRECT; 02932 if (option_debug) 02933 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02934 } 02935 02936 } 02937 02938 res = 0; 02939 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02940 02941 if (p->options->transfer) { 02942 char buf[BUFSIZ/2]; 02943 02944 if (referer) { 02945 if (sipdebug && option_debug > 2) 02946 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02947 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02948 } else 02949 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02950 ast_string_field_set(p, cid_name, buf); 02951 } 02952 if (option_debug) 02953 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02954 02955 res = update_call_counter(p, INC_CALL_RINGING); 02956 if ( res != -1 ) { 02957 p->callingpres = ast->cid.cid_pres; 02958 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 02959 p->jointnoncodeccapability = p->noncodeccapability; 02960 02961 /* If there are no audio formats left to offer, punt */ 02962 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 02963 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 02964 res = -1; 02965 } else { 02966 p->t38.jointcapability = p->t38.capability; 02967 if (option_debug > 1) 02968 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 02969 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 02970 if (xmitres == XMIT_ERROR) 02971 return -1; /* Transmission error */ 02972 02973 p->invitestate = INV_CALLING; 02974 02975 /* Initialize auto-congest time */ 02976 if (p->initid > -1) 02977 ast_sched_del(sched, p->initid); 02978 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 02979 } 02980 } 02981 return res; 02982 }
static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2113 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().
02114 { 02115 if (p->autokillid > -1) { 02116 ast_sched_del(sched, p->autokillid); 02117 append_history(p, "CancelDestroy", ""); 02118 p->autokillid = -1; 02119 } 02120 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1725 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01726 { 01727 if (!sipdebug) 01728 return 0; 01729 if (debugaddr.sin_addr.s_addr) { 01730 if (((ntohs(debugaddr.sin_port) != 0) 01731 && (debugaddr.sin_port != addr->sin_port)) 01732 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01733 return 0; 01734 } 01735 return 1; 01736 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1751 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().
01752 { 01753 if (!sipdebug) 01754 return 0; 01755 return sip_debug_test_addr(sip_real_dst(p)); 01756 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3238 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(), sip_destroy_peer(), sip_do_reload(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03239 { 03240 ast_mutex_lock(&iflock); 03241 if (option_debug > 2) 03242 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03243 __sip_destroy(p, 1); 03244 ast_mutex_unlock(&iflock); 03245 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2425 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().
02426 { 02427 if (option_debug > 2) 02428 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02429 02430 /* Delete it, it needs to disappear */ 02431 if (peer->call) 02432 sip_destroy(peer->call); 02433 02434 if (peer->mwipvt) /* We have an active subscription, delete it */ 02435 sip_destroy(peer->mwipvt); 02436 02437 if (peer->chanvars) { 02438 ast_variables_destroy(peer->chanvars); 02439 peer->chanvars = NULL; 02440 } 02441 if (peer->expire > -1) 02442 ast_sched_del(sched, peer->expire); 02443 02444 if (peer->pokeexpire > -1) 02445 ast_sched_del(sched, peer->pokeexpire); 02446 register_peer_exten(peer, FALSE); 02447 ast_free_ha(peer->ha); 02448 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02449 apeerobjs--; 02450 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02451 rpeerobjs--; 02452 else 02453 speerobjs--; 02454 clear_realm_authentication(peer->auth); 02455 peer->auth = NULL; 02456 free(peer); 02457 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2617 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().
02618 { 02619 if (option_debug > 2) 02620 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02621 ast_free_ha(user->ha); 02622 if (user->chanvars) { 02623 ast_variables_destroy(user->chanvars); 02624 user->chanvars = NULL; 02625 } 02626 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02627 ruserobjs--; 02628 else 02629 suserobjs--; 02630 free(user); 02631 }
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 15573 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().
15574 { 15575 char *host; 15576 char *tmp; 15577 15578 struct hostent *hp; 15579 struct ast_hostent ahp; 15580 struct sip_peer *p; 15581 15582 int res = AST_DEVICE_INVALID; 15583 15584 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15585 host = ast_strdupa(data ? data : ""); 15586 if ((tmp = strchr(host, '@'))) 15587 host = tmp + 1; 15588 15589 if (option_debug > 2) 15590 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15591 15592 if ((p = find_peer(host, NULL, 1))) { 15593 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15594 /* we have an address for the peer */ 15595 15596 /* Check status in this order 15597 - Hold 15598 - Ringing 15599 - Busy (enforced only by call limit) 15600 - Inuse (we have a call) 15601 - Unreachable (qualify) 15602 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15603 for registered devices */ 15604 15605 if (p->onHold) 15606 /* First check for hold or ring states */ 15607 res = AST_DEVICE_ONHOLD; 15608 else if (p->inRinging) { 15609 if (p->inRinging == p->inUse) 15610 res = AST_DEVICE_RINGING; 15611 else 15612 res = AST_DEVICE_RINGINUSE; 15613 } else if (p->call_limit && (p->inUse == p->call_limit)) 15614 /* check call limit */ 15615 res = AST_DEVICE_BUSY; 15616 else if (p->call_limit && p->inUse) 15617 /* Not busy, but we do have a call */ 15618 res = AST_DEVICE_INUSE; 15619 else if (p->maxms && (p->lastms > p->maxms)) 15620 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15621 res = AST_DEVICE_UNAVAILABLE; 15622 else /* Default reply if we're registered and have no other data */ 15623 res = AST_DEVICE_NOT_INUSE; 15624 } else { 15625 /* there is no address, it's unavailable */ 15626 res = AST_DEVICE_UNAVAILABLE; 15627 } 15628 ASTOBJ_UNREF(p,sip_destroy_peer); 15629 } else { 15630 hp = ast_gethostbyname(host, &ahp); 15631 if (hp) 15632 res = AST_DEVICE_UNKNOWN; 15633 } 15634 15635 return res; 15636 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11074 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.
11075 { 11076 int oldsipdebug = sipdebug_console; 11077 if (argc != 3) { 11078 if (argc != 5) 11079 return RESULT_SHOWUSAGE; 11080 else if (strcmp(argv[3], "ip") == 0) 11081 return sip_do_debug_ip(fd, argc, argv); 11082 else if (strcmp(argv[3], "peer") == 0) 11083 return sip_do_debug_peer(fd, argc, argv); 11084 else 11085 return RESULT_SHOWUSAGE; 11086 } 11087 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11088 memset(&debugaddr, 0, sizeof(debugaddr)); 11089 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11090 return RESULT_SUCCESS; 11091 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11093 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.
11094 { 11095 int oldsipdebug = sipdebug_console; 11096 char *newargv[6] = { "sip", "set", "debug", NULL }; 11097 if (argc != 2) { 11098 if (argc != 4) 11099 return RESULT_SHOWUSAGE; 11100 else if (strcmp(argv[2], "ip") == 0) { 11101 newargv[3] = argv[2]; 11102 newargv[4] = argv[3]; 11103 return sip_do_debug_ip(fd, argc + 1, newargv); 11104 } else if (strcmp(argv[2], "peer") == 0) { 11105 newargv[3] = argv[2]; 11106 newargv[4] = argv[3]; 11107 return sip_do_debug_peer(fd, argc + 1, newargv); 11108 } else 11109 return RESULT_SHOWUSAGE; 11110 } 11111 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11112 memset(&debugaddr, 0, sizeof(debugaddr)); 11113 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11114 return RESULT_SUCCESS; 11115 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11020 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().
11021 { 11022 struct hostent *hp; 11023 struct ast_hostent ahp; 11024 int port = 0; 11025 char *p, *arg; 11026 11027 /* sip set debug ip <ip> */ 11028 if (argc != 5) 11029 return RESULT_SHOWUSAGE; 11030 p = arg = argv[4]; 11031 strsep(&p, ":"); 11032 if (p) 11033 port = atoi(p); 11034 hp = ast_gethostbyname(arg, &ahp); 11035 if (hp == NULL) 11036 return RESULT_SHOWUSAGE; 11037 11038 debugaddr.sin_family = AF_INET; 11039 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11040 debugaddr.sin_port = htons(port); 11041 if (port == 0) 11042 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11043 else 11044 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11045 11046 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11047 11048 return RESULT_SUCCESS; 11049 }
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 11052 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().
11053 { 11054 struct sip_peer *peer; 11055 if (argc != 5) 11056 return RESULT_SHOWUSAGE; 11057 peer = find_peer(argv[4], NULL, 1); 11058 if (peer) { 11059 if (peer->addr.sin_addr.s_addr) { 11060 debugaddr.sin_family = AF_INET; 11061 debugaddr.sin_addr = peer->addr.sin_addr; 11062 debugaddr.sin_port = peer->addr.sin_port; 11063 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11064 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11065 } else 11066 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11067 ASTOBJ_UNREF(peer,sip_destroy_peer); 11068 } else 11069 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11070 return RESULT_SUCCESS; 11071 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11193 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11194 { 11195 if (argc != 2) { 11196 return RESULT_SHOWUSAGE; 11197 } 11198 recordhistory = TRUE; 11199 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11200 return RESULT_SUCCESS; 11201 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17504 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, regl, and sip_destroy().
Referenced by do_monitor().
17505 { 17506 if (option_debug > 3) 17507 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17508 17509 clear_realm_authentication(authl); 17510 clear_sip_domains(); 17511 authl = NULL; 17512 17513 /* First, destroy all outstanding registry calls */ 17514 /* This is needed, since otherwise active registry entries will not be destroyed */ 17515 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17516 ASTOBJ_RDLOCK(iterator); 17517 if (iterator->call) { 17518 if (option_debug > 2) 17519 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17520 /* This will also remove references to the registry */ 17521 sip_destroy(iterator->call); 17522 } 17523 ASTOBJ_UNLOCK(iterator); 17524 17525 } while(0)); 17526 17527 /* Then, actually destroy users and registry */ 17528 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17529 if (option_debug > 3) 17530 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17531 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17532 if (option_debug > 3) 17533 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17534 ASTOBJ_CONTAINER_MARKALL(&peerl); 17535 reload_config(reason); 17536 17537 /* Prune peers who still are supposed to be deleted */ 17538 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17539 if (option_debug > 3) 17540 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17541 17542 /* Send qualify (OPTIONS) to all peers */ 17543 sip_poke_all_peers(); 17544 17545 /* Register with all services */ 17546 sip_send_all_registers(); 17547 17548 if (option_debug > 3) 17549 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17550 17551 return 0; 17552 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17307 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().
17308 { 17309 struct sip_pvt *p; 17310 char *mode; 17311 if (data) 17312 mode = (char *)data; 17313 else { 17314 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17315 return 0; 17316 } 17317 ast_channel_lock(chan); 17318 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17319 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17320 ast_channel_unlock(chan); 17321 return 0; 17322 } 17323 p = chan->tech_pvt; 17324 if (!p) { 17325 ast_channel_unlock(chan); 17326 return 0; 17327 } 17328 ast_mutex_lock(&p->lock); 17329 if (!strcasecmp(mode,"info")) { 17330 ast_clear_flag(&p->flags[0], SIP_DTMF); 17331 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17332 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17333 } else if (!strcasecmp(mode,"rfc2833")) { 17334 ast_clear_flag(&p->flags[0], SIP_DTMF); 17335 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17336 p->jointnoncodeccapability |= AST_RTP_DTMF; 17337 } else if (!strcasecmp(mode,"inband")) { 17338 ast_clear_flag(&p->flags[0], SIP_DTMF); 17339 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17340 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17341 } else 17342 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17343 if (p->rtp) 17344 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17345 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17346 if (!p->vad) { 17347 p->vad = ast_dsp_new(); 17348 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17349 } 17350 } else { 17351 if (p->vad) { 17352 ast_dsp_free(p->vad); 17353 p->vad = NULL; 17354 } 17355 } 17356 ast_mutex_unlock(&p->lock); 17357 ast_channel_unlock(chan); 17358 return 0; 17359 }
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 10890 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().
10891 { 10892 int x = 0; 10893 struct sip_history *hist; 10894 static int errmsg = 0; 10895 10896 if (!dialog) 10897 return; 10898 10899 if (!option_debug && !sipdebug) { 10900 if (!errmsg) { 10901 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 10902 errmsg = 1; 10903 } 10904 return; 10905 } 10906 10907 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 10908 if (dialog->subscribed) 10909 ast_log(LOG_DEBUG, " * Subscription\n"); 10910 else 10911 ast_log(LOG_DEBUG, " * SIP Call\n"); 10912 if (dialog->history) 10913 AST_LIST_TRAVERSE(dialog->history, hist, list) 10914 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 10915 if (!x) 10916 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 10917 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 10918 }
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 3695 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, and ast_channel::tech_pvt.
03696 { 03697 int ret = -1; 03698 struct sip_pvt *p; 03699 03700 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03701 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03702 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03703 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03704 03705 if (!newchan || !newchan->tech_pvt) { 03706 if (!newchan) 03707 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03708 else 03709 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03710 return -1; 03711 } 03712 p = newchan->tech_pvt; 03713 03714 if (!p) { 03715 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03716 return -1; 03717 } 03718 03719 ast_mutex_lock(&p->lock); 03720 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03721 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03722 if (p->owner != oldchan) 03723 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03724 else { 03725 p->owner = newchan; 03726 ret = 0; 03727 } 03728 if (option_debug > 2) 03729 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03730 03731 ast_mutex_unlock(&p->lock); 03732 return ret; 03733 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17453 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17454 { 17455 struct sip_pvt *p = chan->tech_pvt; 17456 return p->peercapability ? p->peercapability : p->capability; 17457 }
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 17160 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.
17161 { 17162 struct sip_pvt *p = NULL; 17163 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17164 17165 if (!(p = chan->tech_pvt)) 17166 return AST_RTP_GET_FAILED; 17167 17168 ast_mutex_lock(&p->lock); 17169 if (!(p->rtp)) { 17170 ast_mutex_unlock(&p->lock); 17171 return AST_RTP_GET_FAILED; 17172 } 17173 17174 *rtp = p->rtp; 17175 17176 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17177 res = AST_RTP_TRY_PARTIAL; 17178 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17179 res = AST_RTP_TRY_NATIVE; 17180 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17181 res = AST_RTP_GET_FAILED; 17182 17183 ast_mutex_unlock(&p->lock); 17184 17185 return res; 17186 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 17025 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.
17026 { 17027 struct sip_pvt *p; 17028 struct ast_udptl *udptl = NULL; 17029 17030 p = chan->tech_pvt; 17031 if (!p) 17032 return NULL; 17033 17034 ast_mutex_lock(&p->lock); 17035 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17036 udptl = p->udptl; 17037 ast_mutex_unlock(&p->lock); 17038 return udptl; 17039 }
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 17189 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.
17190 { 17191 struct sip_pvt *p = NULL; 17192 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17193 17194 if (!(p = chan->tech_pvt)) 17195 return AST_RTP_GET_FAILED; 17196 17197 ast_mutex_lock(&p->lock); 17198 if (!(p->vrtp)) { 17199 ast_mutex_unlock(&p->lock); 17200 return AST_RTP_GET_FAILED; 17201 } 17202 17203 *rtp = p->vrtp; 17204 17205 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17206 res = AST_RTP_TRY_NATIVE; 17207 17208 ast_mutex_unlock(&p->lock); 17209 17210 return res; 17211 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 17077 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().
17078 { 17079 struct sip_pvt *p; 17080 int flag = 0; 17081 17082 p = chan->tech_pvt; 17083 if (!p || !pvt->udptl) 17084 return -1; 17085 17086 /* Setup everything on the other side like offered/responded from first side */ 17087 ast_mutex_lock(&p->lock); 17088 17089 /*! \todo check if this is not set earlier when setting up the PVT. If not 17090 maybe it should move there. */ 17091 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17092 17093 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17094 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17095 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17096 17097 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17098 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17099 not really T38 re-invites which are different. In this 17100 case it's used properly, to see if we can reinvite over 17101 NAT 17102 */ 17103 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17104 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17105 flag =1; 17106 } else { 17107 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17108 } 17109 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17110 if (!p->pendinginvite) { 17111 if (option_debug > 2) { 17112 if (flag) 17113 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)); 17114 else 17115 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)); 17116 } 17117 transmit_reinvite_with_t38_sdp(p); 17118 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17119 if (option_debug > 2) { 17120 if (flag) 17121 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)); 17122 else 17123 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)); 17124 } 17125 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17126 } 17127 } 17128 /* Reset lastrtprx timer */ 17129 p->lastrtprx = p->lastrtptx = time(NULL); 17130 ast_mutex_unlock(&p->lock); 17131 return 0; 17132 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17133 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17134 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17135 flag = 1; 17136 } else { 17137 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17138 } 17139 if (option_debug > 2) { 17140 if (flag) 17141 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)); 17142 else 17143 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)); 17144 } 17145 pvt->t38.state = T38_ENABLED; 17146 p->t38.state = T38_ENABLED; 17147 if (option_debug > 1) { 17148 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17149 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17150 } 17151 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17152 p->lastrtprx = p->lastrtptx = time(NULL); 17153 ast_mutex_unlock(&p->lock); 17154 return 0; 17155 } 17156 }
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 3410 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_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_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, 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.
03411 { 03412 struct sip_pvt *p = ast->tech_pvt; 03413 int needcancel = FALSE; 03414 int needdestroy = 0; 03415 struct ast_channel *oldowner = ast; 03416 03417 if (!p) { 03418 if (option_debug) 03419 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03420 return 0; 03421 } 03422 03423 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03424 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03425 if (option_debug && sipdebug) 03426 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03427 update_call_counter(p, DEC_CALL_LIMIT); 03428 } 03429 if (option_debug >3) 03430 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03431 if (p->autokillid > -1) 03432 sip_cancel_destroy(p); 03433 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03434 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03435 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03436 p->owner->tech_pvt = NULL; 03437 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03438 return 0; 03439 } 03440 if (option_debug) { 03441 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03442 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03443 else { 03444 if (option_debug) 03445 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03446 } 03447 } 03448 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03449 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03450 03451 ast_mutex_lock(&p->lock); 03452 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03453 if (option_debug && sipdebug) 03454 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03455 update_call_counter(p, DEC_CALL_LIMIT); 03456 } 03457 03458 /* Determine how to disconnect */ 03459 if (p->owner != ast) { 03460 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03461 ast_mutex_unlock(&p->lock); 03462 return 0; 03463 } 03464 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03465 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03466 needcancel = TRUE; 03467 if (option_debug > 3) 03468 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03469 } 03470 03471 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03472 03473 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03474 03475 /* Disconnect */ 03476 if (p->vad) 03477 ast_dsp_free(p->vad); 03478 03479 p->owner = NULL; 03480 ast->tech_pvt = NULL; 03481 03482 ast_module_unref(ast_module_info->self); 03483 03484 /* Do not destroy this pvt until we have timeout or 03485 get an answer to the BYE or INVITE/CANCEL 03486 If we get no answer during retransmit period, drop the call anyway. 03487 (Sorry, mother-in-law, you can't deny a hangup by sending 03488 603 declined to BYE...) 03489 */ 03490 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03491 needdestroy = 1; /* Set destroy flag at end of this function */ 03492 else if (p->invitestate != INV_CALLING) 03493 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03494 03495 /* Start the process if it's not already started */ 03496 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03497 if (needcancel) { /* Outgoing call, not up */ 03498 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03499 /* stop retransmitting an INVITE that has not received a response */ 03500 __sip_pretend_ack(p); 03501 03502 /* if we can't send right now, mark it pending */ 03503 if (p->invitestate == INV_CALLING) { 03504 /* We can't send anything in CALLING state */ 03505 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03506 /* 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. */ 03507 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03508 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03509 } else { 03510 /* Send a new request: CANCEL */ 03511 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03512 /* Actually don't destroy us yet, wait for the 487 on our original 03513 INVITE, but do set an autodestruct just in case we never get it. */ 03514 needdestroy = 0; 03515 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03516 } 03517 if ( p->initid != -1 ) { 03518 /* channel still up - reverse dec of inUse counter 03519 only if the channel is not auto-congested */ 03520 update_call_counter(p, INC_CALL_LIMIT); 03521 } 03522 } else { /* Incoming call, not up */ 03523 const char *res; 03524 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03525 transmit_response_reliable(p, res, &p->initreq); 03526 else 03527 transmit_response_reliable(p, "603 Declined", &p->initreq); 03528 } 03529 } else { /* Call is in UP state, send BYE */ 03530 if (!p->pendinginvite) { 03531 char *audioqos = ""; 03532 char *videoqos = ""; 03533 if (p->rtp) 03534 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03535 if (p->vrtp) 03536 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03537 /* Send a hangup */ 03538 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03539 03540 /* Get RTCP quality before end of call */ 03541 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03542 if (p->rtp) 03543 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03544 if (p->vrtp) 03545 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03546 } 03547 if (p->rtp && oldowner) 03548 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03549 if (p->vrtp && oldowner) 03550 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03551 } else { 03552 /* Note we will need a BYE when this all settles out 03553 but we can't send one while we have "INVITE" outstanding. */ 03554 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03555 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03556 sip_cancel_destroy(p); 03557 } 03558 } 03559 } 03560 if (needdestroy) 03561 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03562 ast_mutex_unlock(&p->lock); 03563 return 0; 03564 }
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 3804 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03805 { 03806 struct sip_pvt *p = ast->tech_pvt; 03807 int res = 0; 03808 03809 ast_mutex_lock(&p->lock); 03810 switch(condition) { 03811 case AST_CONTROL_RINGING: 03812 if (ast->_state == AST_STATE_RING) { 03813 p->invitestate = INV_EARLY_MEDIA; 03814 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03815 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03816 /* Send 180 ringing if out-of-band seems reasonable */ 03817 transmit_response(p, "180 Ringing", &p->initreq); 03818 ast_set_flag(&p->flags[0], SIP_RINGING); 03819 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03820 break; 03821 } else { 03822 /* Well, if it's not reasonable, just send in-band */ 03823 } 03824 } 03825 res = -1; 03826 break; 03827 case AST_CONTROL_BUSY: 03828 if (ast->_state != AST_STATE_UP) { 03829 transmit_response(p, "486 Busy Here", &p->initreq); 03830 p->invitestate = INV_COMPLETED; 03831 sip_alreadygone(p); 03832 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03833 break; 03834 } 03835 res = -1; 03836 break; 03837 case AST_CONTROL_CONGESTION: 03838 if (ast->_state != AST_STATE_UP) { 03839 transmit_response(p, "503 Service Unavailable", &p->initreq); 03840 p->invitestate = INV_COMPLETED; 03841 sip_alreadygone(p); 03842 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03843 break; 03844 } 03845 res = -1; 03846 break; 03847 case AST_CONTROL_PROCEEDING: 03848 if ((ast->_state != AST_STATE_UP) && 03849 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03850 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03851 transmit_response(p, "100 Trying", &p->initreq); 03852 p->invitestate = INV_PROCEEDING; 03853 break; 03854 } 03855 res = -1; 03856 break; 03857 case AST_CONTROL_PROGRESS: 03858 if ((ast->_state != AST_STATE_UP) && 03859 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03860 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03861 p->invitestate = INV_EARLY_MEDIA; 03862 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03863 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03864 break; 03865 } 03866 res = -1; 03867 break; 03868 case AST_CONTROL_HOLD: 03869 ast_moh_start(ast, data, p->mohinterpret); 03870 break; 03871 case AST_CONTROL_UNHOLD: 03872 ast_moh_stop(ast); 03873 break; 03874 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03875 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03876 transmit_info_with_vidupdate(p); 03877 /* ast_rtcp_send_h261fur(p->vrtp); */ 03878 } else 03879 res = -1; 03880 break; 03881 case -1: 03882 res = -1; 03883 break; 03884 default: 03885 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03886 res = -1; 03887 break; 03888 } 03889 ast_mutex_unlock(&p->lock); 03890 return res; 03891 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1745 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().
01746 { 01747 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01748 }
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 3900 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, 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, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
03901 { 03902 struct ast_channel *tmp; 03903 struct ast_variable *v = NULL; 03904 int fmt; 03905 int what; 03906 int needvideo = 0; 03907 { 03908 const char *my_name; /* pick a good name */ 03909 03910 if (title) 03911 my_name = title; 03912 else if ( (my_name = strchr(i->fromdomain,':')) ) 03913 my_name++; /* skip ':' */ 03914 else 03915 my_name = i->fromdomain; 03916 03917 ast_mutex_unlock(&i->lock); 03918 /* Don't hold a sip pvt lock while we allocate a channel */ 03919 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); 03920 03921 } 03922 if (!tmp) { 03923 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03924 return NULL; 03925 } 03926 ast_mutex_lock(&i->lock); 03927 03928 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03929 tmp->tech = &sip_tech_info; 03930 else 03931 tmp->tech = &sip_tech; 03932 03933 /* Select our native format based on codec preference until we receive 03934 something from another device to the contrary. */ 03935 if (i->jointcapability) /* The joint capabilities of us and peer */ 03936 what = i->jointcapability; 03937 else if (i->capability) /* Our configured capability for this peer */ 03938 what = i->capability; 03939 else 03940 what = global_capability; /* Global codec support */ 03941 03942 /* Set the native formats for audio and merge in video */ 03943 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK); 03944 if (option_debug > 2) { 03945 char buf[BUFSIZ]; 03946 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03947 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03948 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03949 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 03950 if (i->prefcodec) 03951 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 03952 } 03953 03954 /* XXX Why are we choosing a codec from the native formats?? */ 03955 fmt = ast_best_codec(tmp->nativeformats); 03956 03957 /* If we have a prefcodec setting, we have an inbound channel that set a 03958 preferred format for this call. Otherwise, we check the jointcapability 03959 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 03960 */ 03961 if (i->vrtp) { 03962 if (i->prefcodec) 03963 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 03964 else 03965 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 03966 } 03967 03968 if (option_debug > 2) { 03969 if (needvideo) 03970 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 03971 else 03972 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 03973 } 03974 03975 03976 03977 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 03978 i->vad = ast_dsp_new(); 03979 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 03980 if (global_relaxdtmf) 03981 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 03982 } 03983 if (i->rtp) { 03984 tmp->fds[0] = ast_rtp_fd(i->rtp); 03985 tmp->fds[1] = ast_rtcp_fd(i->rtp); 03986 } 03987 if (needvideo && i->vrtp) { 03988 tmp->fds[2] = ast_rtp_fd(i->vrtp); 03989 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 03990 } 03991 if (i->udptl) { 03992 tmp->fds[5] = ast_udptl_fd(i->udptl); 03993 } 03994 if (state == AST_STATE_RING) 03995 tmp->rings = 1; 03996 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03997 tmp->writeformat = fmt; 03998 tmp->rawwriteformat = fmt; 03999 tmp->readformat = fmt; 04000 tmp->rawreadformat = fmt; 04001 tmp->tech_pvt = i; 04002 04003 tmp->callgroup = i->callgroup; 04004 tmp->pickupgroup = i->pickupgroup; 04005 tmp->cid.cid_pres = i->callingpres; 04006 if (!ast_strlen_zero(i->accountcode)) 04007 ast_string_field_set(tmp, accountcode, i->accountcode); 04008 if (i->amaflags) 04009 tmp->amaflags = i->amaflags; 04010 if (!ast_strlen_zero(i->language)) 04011 ast_string_field_set(tmp, language, i->language); 04012 i->owner = tmp; 04013 ast_module_ref(ast_module_info->self); 04014 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04015 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04016 04017 04018 /* Don't use ast_set_callerid() here because it will 04019 * generate an unnecessary NewCallerID event */ 04020 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04021 if (!ast_strlen_zero(i->rdnis)) 04022 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04023 04024 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04025 tmp->cid.cid_dnid = ast_strdup(i->exten); 04026 04027 tmp->priority = 1; 04028 if (!ast_strlen_zero(i->uri)) 04029 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04030 if (!ast_strlen_zero(i->domain)) 04031 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04032 if (!ast_strlen_zero(i->useragent)) 04033 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04034 if (!ast_strlen_zero(i->callid)) 04035 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04036 if (i->rtp) 04037 ast_jb_configure(tmp, &global_jbconf); 04038 04039 /* Set channel variables for this call from configuration */ 04040 for (v = i->chanvars ; v ; v = v->next) 04041 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04042 04043 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04044 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04045 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04046 ast_hangup(tmp); 04047 tmp = NULL; 04048 } 04049 04050 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04051 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04052 04053 return tmp; 04054 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11174 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11175 { 11176 if (argc != 4) 11177 return RESULT_SHOWUSAGE; 11178 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11179 ast_cli(fd, "SIP Debugging Disabled\n"); 11180 return RESULT_SUCCESS; 11181 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11183 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11184 { 11185 if (argc != 3) 11186 return RESULT_SHOWUSAGE; 11187 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11188 ast_cli(fd, "SIP Debugging Disabled\n"); 11189 return RESULT_SUCCESS; 11190 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11204 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11205 { 11206 if (argc != 3) { 11207 return RESULT_SHOWUSAGE; 11208 } 11209 recordhistory = FALSE; 11210 ast_cli(fd, "SIP History Recording Disabled\n"); 11211 return RESULT_SUCCESS; 11212 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11118 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.
11119 { 11120 struct ast_variable *varlist; 11121 int i; 11122 11123 if (argc < 4) 11124 return RESULT_SHOWUSAGE; 11125 11126 if (!notify_types) { 11127 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11128 return RESULT_FAILURE; 11129 } 11130 11131 varlist = ast_variable_browse(notify_types, argv[2]); 11132 11133 if (!varlist) { 11134 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11135 return RESULT_FAILURE; 11136 } 11137 11138 for (i = 3; i < argc; i++) { 11139 struct sip_pvt *p; 11140 struct sip_request req; 11141 struct ast_variable *var; 11142 11143 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11144 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11145 return RESULT_FAILURE; 11146 } 11147 11148 if (create_addr(p, argv[i])) { 11149 /* Maybe they're not registered, etc. */ 11150 sip_destroy(p); 11151 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11152 continue; 11153 } 11154 11155 initreqprep(&req, p, SIP_NOTIFY); 11156 11157 for (var = varlist; var; var = var->next) 11158 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11159 11160 /* Recalculate our side, and recalculate Call ID */ 11161 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11162 p->ourip = __ourip; 11163 build_via(p); 11164 build_callid_pvt(p); 11165 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11166 transmit_sip_request(p, &req); 11167 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11168 } 11169 11170 return RESULT_SUCCESS; 11171 }
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 12852 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_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
12853 { 12854 struct sip_dual *d; 12855 struct ast_channel *transferee, *transferer; 12856 /* Chan2m: The transferer, chan1m: The transferee */ 12857 pthread_t th; 12858 12859 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 12860 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 12861 if ((!transferer) || (!transferee)) { 12862 if (transferee) { 12863 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12864 ast_hangup(transferee); 12865 } 12866 if (transferer) { 12867 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12868 ast_hangup(transferer); 12869 } 12870 return -1; 12871 } 12872 12873 /* Make formats okay */ 12874 transferee->readformat = chan1->readformat; 12875 transferee->writeformat = chan1->writeformat; 12876 12877 /* Prepare for taking over the channel */ 12878 ast_channel_masquerade(transferee, chan1); 12879 12880 /* Setup the extensions and such */ 12881 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 12882 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 12883 transferee->priority = chan1->priority; 12884 12885 /* We make a clone of the peer channel too, so we can play 12886 back the announcement */ 12887 12888 /* Make formats okay */ 12889 transferer->readformat = chan2->readformat; 12890 transferer->writeformat = chan2->writeformat; 12891 12892 /* Prepare for taking over the channel */ 12893 ast_channel_masquerade(transferer, chan2); 12894 12895 /* Setup the extensions and such */ 12896 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 12897 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 12898 transferer->priority = chan2->priority; 12899 12900 ast_channel_lock(transferer); 12901 if (ast_do_masquerade(transferer)) { 12902 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 12903 ast_channel_unlock(transferer); 12904 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12905 ast_hangup(transferer); 12906 return -1; 12907 } 12908 ast_channel_unlock(transferer); 12909 if (!transferer || !transferee) { 12910 if (!transferer) { 12911 if (option_debug) 12912 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 12913 } 12914 if (!transferee) { 12915 if (option_debug) 12916 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 12917 } 12918 return -1; 12919 } 12920 if ((d = ast_calloc(1, sizeof(*d)))) { 12921 pthread_attr_t attr; 12922 12923 pthread_attr_init(&attr); 12924 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 12925 12926 /* Save original request for followup */ 12927 copy_request(&d->req, req); 12928 d->chan1 = transferee; /* Transferee */ 12929 d->chan2 = transferer; /* Transferer */ 12930 d->seqno = seqno; 12931 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 12932 /* Could not start thread */ 12933 free(d); /* We don't need it anymore. If thread is created, d will be free'd 12934 by sip_park_thread() */ 12935 pthread_attr_destroy(&attr); 12936 return 0; 12937 } 12938 pthread_attr_destroy(&attr); 12939 } 12940 return -1; 12941 }
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 12785 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().
12786 { 12787 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 12788 struct sip_dual *d; 12789 struct sip_request req; 12790 int ext; 12791 int res; 12792 12793 d = stuff; 12794 transferee = d->chan1; 12795 transferer = d->chan2; 12796 copy_request(&req, &d->req); 12797 free(d); 12798 12799 if (!transferee || !transferer) { 12800 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 12801 return NULL; 12802 } 12803 if (option_debug > 3) 12804 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 12805 12806 ast_channel_lock(transferee); 12807 if (ast_do_masquerade(transferee)) { 12808 ast_log(LOG_WARNING, "Masquerade failed.\n"); 12809 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 12810 ast_channel_unlock(transferee); 12811 return NULL; 12812 } 12813 ast_channel_unlock(transferee); 12814 12815 res = ast_park_call(transferee, transferer, 0, &ext); 12816 12817 12818 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 12819 if (!res) { 12820 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 12821 } else { 12822 /* Then tell the transferer what happened */ 12823 sprintf(buf, "Call parked on extension '%d'", ext); 12824 transmit_message_with_text(transferer->tech_pvt, buf); 12825 } 12826 #endif 12827 12828 /* Any way back to the current call??? */ 12829 /* Transmit response to the REFER request */ 12830 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 12831 if (!res) { 12832 /* Transfer succeeded */ 12833 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 12834 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 12835 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 12836 ast_hangup(transferer); /* This will cause a BYE */ 12837 if (option_debug) 12838 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 12839 } else { 12840 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 12841 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 12842 if (option_debug) 12843 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 12844 /* Do not hangup call */ 12845 } 12846 return NULL; 12847 }
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 8349 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().
08350 { 08351 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08352 08353 if (!peer) 08354 return; 08355 08356 /* If they put someone on hold, increment the value... otherwise decrement it */ 08357 if (hold) 08358 peer->onHold++; 08359 else 08360 peer->onHold--; 08361 08362 /* Request device state update */ 08363 ast_device_state_changed("SIP/%s", peer->name); 08364 08365 return; 08366 }
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 17463 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, sched, and sip_poke_peer_s().
Referenced by load_module().
17464 { 17465 int ms = 0; 17466 17467 if (!speerobjs) /* No peers, just give up */ 17468 return; 17469 17470 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17471 ASTOBJ_WRLOCK(iterator); 17472 if (iterator->pokeexpire > -1) 17473 ast_sched_del(sched, iterator->pokeexpire); 17474 ms += 100; 17475 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17476 ASTOBJ_UNLOCK(iterator); 17477 } while (0) 17478 ); 17479 }
static int sip_poke_noanswer | ( | void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15451 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sched, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15452 { 15453 struct sip_peer *peer = data; 15454 15455 peer->pokeexpire = -1; 15456 if (peer->lastms > -1) { 15457 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15458 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15459 } 15460 if (peer->call) 15461 sip_destroy(peer->call); 15462 peer->call = NULL; 15463 peer->lastms = -1; 15464 ast_device_state_changed("SIP/%s", peer->name); 15465 /* Try again quickly */ 15466 if (peer->pokeexpire > -1) 15467 ast_sched_del(sched, peer->pokeexpire); 15468 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15469 return 0; 15470 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15475 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_peer::call, DEFAULT_MAXMS, 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_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15476 { 15477 struct sip_pvt *p; 15478 int xmitres = 0; 15479 15480 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15481 /* IF we have no IP, or this isn't to be monitored, return 15482 imeediately after clearing things out */ 15483 if (peer->pokeexpire > -1) 15484 ast_sched_del(sched, peer->pokeexpire); 15485 peer->lastms = 0; 15486 peer->pokeexpire = -1; 15487 peer->call = NULL; 15488 return 0; 15489 } 15490 if (peer->call) { 15491 if (sipdebug) 15492 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15493 sip_destroy(peer->call); 15494 } 15495 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15496 return -1; 15497 15498 p->sa = peer->addr; 15499 p->recv = peer->addr; 15500 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15501 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15502 15503 /* Send OPTIONs to peer's fullcontact */ 15504 if (!ast_strlen_zero(peer->fullcontact)) 15505 ast_string_field_set(p, fullcontact, peer->fullcontact); 15506 15507 if (!ast_strlen_zero(peer->tohost)) 15508 ast_string_field_set(p, tohost, peer->tohost); 15509 else 15510 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15511 15512 /* Recalculate our side, and recalculate Call ID */ 15513 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15514 p->ourip = __ourip; 15515 build_via(p); 15516 build_callid_pvt(p); 15517 15518 if (peer->pokeexpire > -1) 15519 ast_sched_del(sched, peer->pokeexpire); 15520 p->relatedpeer = peer; 15521 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15522 #ifdef VOCAL_DATA_HACK 15523 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15524 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15525 #else 15526 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15527 #endif 15528 gettimeofday(&peer->ps, NULL); 15529 if (xmitres == XMIT_ERROR) 15530 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 15531 else { 15532 if (peer->pokeexpire > -1) 15533 ast_sched_del(sched, peer->pokeexpire); 15534 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 15535 } 15536 15537 return 0; 15538 }
static int sip_poke_peer_s | ( | void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 7754 of file chan_sip.c.
References sip_peer::pokeexpire, and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
07755 { 07756 struct sip_peer *peer = data; 07757 07758 peer->pokeexpire = -1; 07759 sip_poke_peer(peer); 07760 return 0; 07761 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 9911 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.
09912 { 09913 struct sip_peer *peer; 09914 struct sip_user *user; 09915 int pruneuser = FALSE; 09916 int prunepeer = FALSE; 09917 int multi = FALSE; 09918 char *name = NULL; 09919 regex_t regexbuf; 09920 09921 switch (argc) { 09922 case 4: 09923 if (!strcasecmp(argv[3], "user")) 09924 return RESULT_SHOWUSAGE; 09925 if (!strcasecmp(argv[3], "peer")) 09926 return RESULT_SHOWUSAGE; 09927 if (!strcasecmp(argv[3], "like")) 09928 return RESULT_SHOWUSAGE; 09929 if (!strcasecmp(argv[3], "all")) { 09930 multi = TRUE; 09931 pruneuser = prunepeer = TRUE; 09932 } else { 09933 pruneuser = prunepeer = TRUE; 09934 name = argv[3]; 09935 } 09936 break; 09937 case 5: 09938 if (!strcasecmp(argv[4], "like")) 09939 return RESULT_SHOWUSAGE; 09940 if (!strcasecmp(argv[3], "all")) 09941 return RESULT_SHOWUSAGE; 09942 if (!strcasecmp(argv[3], "like")) { 09943 multi = TRUE; 09944 name = argv[4]; 09945 pruneuser = prunepeer = TRUE; 09946 } else if (!strcasecmp(argv[3], "user")) { 09947 pruneuser = TRUE; 09948 if (!strcasecmp(argv[4], "all")) 09949 multi = TRUE; 09950 else 09951 name = argv[4]; 09952 } else if (!strcasecmp(argv[3], "peer")) { 09953 prunepeer = TRUE; 09954 if (!strcasecmp(argv[4], "all")) 09955 multi = TRUE; 09956 else 09957 name = argv[4]; 09958 } else 09959 return RESULT_SHOWUSAGE; 09960 break; 09961 case 6: 09962 if (strcasecmp(argv[4], "like")) 09963 return RESULT_SHOWUSAGE; 09964 if (!strcasecmp(argv[3], "user")) { 09965 pruneuser = TRUE; 09966 name = argv[5]; 09967 } else if (!strcasecmp(argv[3], "peer")) { 09968 prunepeer = TRUE; 09969 name = argv[5]; 09970 } else 09971 return RESULT_SHOWUSAGE; 09972 break; 09973 default: 09974 return RESULT_SHOWUSAGE; 09975 } 09976 09977 if (multi && name) { 09978 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 09979 return RESULT_SHOWUSAGE; 09980 } 09981 09982 if (multi) { 09983 if (prunepeer) { 09984 int pruned = 0; 09985 09986 ASTOBJ_CONTAINER_WRLOCK(&peerl); 09987 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09988 ASTOBJ_RDLOCK(iterator); 09989 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09990 ASTOBJ_UNLOCK(iterator); 09991 continue; 09992 }; 09993 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09994 ASTOBJ_MARK(iterator); 09995 pruned++; 09996 } 09997 ASTOBJ_UNLOCK(iterator); 09998 } while (0) ); 09999 if (pruned) { 10000 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10001 ast_cli(fd, "%d peers pruned.\n", pruned); 10002 } else 10003 ast_cli(fd, "No peers found to prune.\n"); 10004 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10005 } 10006 if (pruneuser) { 10007 int pruned = 0; 10008 10009 ASTOBJ_CONTAINER_WRLOCK(&userl); 10010 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10011 ASTOBJ_RDLOCK(iterator); 10012 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10013 ASTOBJ_UNLOCK(iterator); 10014 continue; 10015 }; 10016 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10017 ASTOBJ_MARK(iterator); 10018 pruned++; 10019 } 10020 ASTOBJ_UNLOCK(iterator); 10021 } while (0) ); 10022 if (pruned) { 10023 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10024 ast_cli(fd, "%d users pruned.\n", pruned); 10025 } else 10026 ast_cli(fd, "No users found to prune.\n"); 10027 ASTOBJ_CONTAINER_UNLOCK(&userl); 10028 } 10029 } else { 10030 if (prunepeer) { 10031 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10032 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10033 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10034 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10035 } else 10036 ast_cli(fd, "Peer '%s' pruned.\n", name); 10037 ASTOBJ_UNREF(peer, sip_destroy_peer); 10038 } else 10039 ast_cli(fd, "Peer '%s' not found.\n", name); 10040 } 10041 if (pruneuser) { 10042 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10043 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10044 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10045 ASTOBJ_CONTAINER_LINK(&userl, user); 10046 } else 10047 ast_cli(fd, "User '%s' pruned.\n", name); 10048 ASTOBJ_UNREF(user, sip_destroy_user); 10049 } else 10050 ast_cli(fd, "User '%s' not found.\n", name); 10051 } 10052 } 10053 10054 return RESULT_SUCCESS; 10055 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4257 of file chan_sip.c.
References ast_bridged_channel(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().
04258 { 04259 struct ast_frame *fr; 04260 struct sip_pvt *p; 04261 04262 if( ast == NULL ) 04263 return NULL; 04264 04265 p = ast->tech_pvt; 04266 int faxdetected = FALSE; 04267 04268 if( p == NULL ) 04269 return NULL; 04270 04271 ast_mutex_lock(&p->lock); 04272 fr = sip_rtp_read(ast, p, &faxdetected); 04273 p->lastrtprx = time(NULL); 04274 04275 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04276 /* 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 */ 04277 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04278 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04279 if (!p->pendinginvite) { 04280 if (option_debug > 2) 04281 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04282 p->t38.state = T38_LOCAL_REINVITE; 04283 transmit_reinvite_with_t38_sdp(p); 04284 if (option_debug > 1) 04285 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04286 } 04287 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04288 if (option_debug > 2) 04289 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04290 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04291 } 04292 } 04293 04294 ast_mutex_unlock(&p->lock); 04295 return fr; 04296 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1739 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().
01740 { 01741 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01742 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7563 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by handle_request_invite(), handle_request_refer(), and transmit_refer().
07564 { 07565 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07566 return p->refer ? 1 : 0; 07567 }
static int sip_reg_timeout | ( | void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7320 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, and transmit_register().
Referenced by transmit_register().
07321 { 07322 07323 /* if we are here, our registration timed out, so we'll just do it over */ 07324 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07325 struct sip_pvt *p; 07326 int res; 07327 07328 /* if we couldn't get a reference to the registry object, punt */ 07329 if (!r) 07330 return 0; 07331 07332 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07333 if (r->call) { 07334 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07335 in the single SIP manager thread. */ 07336 p = r->call; 07337 if (p->registry) 07338 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07339 r->call = NULL; 07340 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07341 /* Pretend to ACK anything just in case */ 07342 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07343 } 07344 /* If we have a limit, stop registration and give up */ 07345 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07346 /* Ok, enough is enough. Don't try any more */ 07347 /* We could add an external notification here... 07348 steal it from app_voicemail :-) */ 07349 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07350 r->regstate = REG_STATE_FAILED; 07351 } else { 07352 r->regstate = REG_STATE_UNREGISTERED; 07353 r->timeout = -1; 07354 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07355 } 07356 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)); 07357 ASTOBJ_UNREF(r, sip_registry_destroy); 07358 return 0; 07359 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4584 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.
04585 { 04586 struct sip_registry *reg; 04587 int portnum = 0; 04588 char username[256] = ""; 04589 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04590 char *porta=NULL; 04591 char *contact=NULL; 04592 04593 if (!value) 04594 return -1; 04595 ast_copy_string(username, value, sizeof(username)); 04596 /* First split around the last '@' then parse the two components. */ 04597 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04598 if (hostname) 04599 *hostname++ = '\0'; 04600 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04601 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04602 return -1; 04603 } 04604 /* split user[:secret[:authuser]] */ 04605 secret = strchr(username, ':'); 04606 if (secret) { 04607 *secret++ = '\0'; 04608 authuser = strchr(secret, ':'); 04609 if (authuser) 04610 *authuser++ = '\0'; 04611 } 04612 /* split host[:port][/contact] */ 04613 contact = strchr(hostname, '/'); 04614 if (contact) 04615 *contact++ = '\0'; 04616 if (ast_strlen_zero(contact)) 04617 contact = "s"; 04618 porta = strchr(hostname, ':'); 04619 if (porta) { 04620 *porta++ = '\0'; 04621 portnum = atoi(porta); 04622 if (portnum == 0) { 04623 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04624 return -1; 04625 } 04626 } 04627 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04628 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04629 return -1; 04630 } 04631 04632 if (ast_string_field_init(reg, 256)) { 04633 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04634 free(reg); 04635 return -1; 04636 } 04637 04638 regobjs++; 04639 ASTOBJ_INIT(reg); 04640 ast_string_field_set(reg, contact, contact); 04641 if (!ast_strlen_zero(username)) 04642 ast_string_field_set(reg, username, username); 04643 if (hostname) 04644 ast_string_field_set(reg, hostname, hostname); 04645 if (authuser) 04646 ast_string_field_set(reg, authuser, authuser); 04647 if (secret) 04648 ast_string_field_set(reg, secret, secret); 04649 reg->expire = -1; 04650 reg->timeout = -1; 04651 reg->refresh = default_expiry; 04652 reg->portno = portnum; 04653 reg->callid_valid = FALSE; 04654 reg->ocseq = INITIAL_CSEQ; 04655 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04656 ASTOBJ_UNREF(reg,sip_registry_destroy); 04657 return 0; 04658 }
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 2986 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_string_field_free_pools, 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().
02987 { 02988 /* Really delete */ 02989 if (option_debug > 2) 02990 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 02991 02992 if (reg->call) { 02993 /* Clear registry before destroying to ensure 02994 we don't get reentered trying to grab the registry lock */ 02995 reg->call->registry = NULL; 02996 if (option_debug > 2) 02997 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 02998 sip_destroy(reg->call); 02999 } 03000 if (reg->expire > -1) 03001 ast_sched_del(sched, reg->expire); 03002 if (reg->timeout > -1) 03003 ast_sched_del(sched, reg->timeout); 03004 ast_string_field_free_pools(reg); 03005 regobjs--; 03006 free(reg); 03007 03008 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17555 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().
17556 { 17557 ast_mutex_lock(&sip_reload_lock); 17558 if (sip_reloading) 17559 ast_verbose("Previous SIP reload not yet done\n"); 17560 else { 17561 sip_reloading = TRUE; 17562 if (fd) 17563 sip_reloadreason = CHANNEL_CLI_RELOAD; 17564 else 17565 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17566 } 17567 ast_mutex_unlock(&sip_reload_lock); 17568 restart_monitor(); 17569 17570 return 0; 17571 }
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 15640 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.
15641 { 15642 int oldformat; 15643 struct sip_pvt *p; 15644 struct ast_channel *tmpc = NULL; 15645 char *ext, *host; 15646 char tmp[256]; 15647 char *dest = data; 15648 15649 oldformat = format; 15650 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15651 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)); 15652 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15653 return NULL; 15654 } 15655 if (option_debug) 15656 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15657 15658 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15659 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15660 *cause = AST_CAUSE_SWITCH_CONGESTION; 15661 return NULL; 15662 } 15663 15664 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15665 15666 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15667 sip_destroy(p); 15668 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15669 *cause = AST_CAUSE_SWITCH_CONGESTION; 15670 return NULL; 15671 } 15672 15673 ast_copy_string(tmp, dest, sizeof(tmp)); 15674 host = strchr(tmp, '@'); 15675 if (host) { 15676 *host++ = '\0'; 15677 ext = tmp; 15678 } else { 15679 ext = strchr(tmp, '/'); 15680 if (ext) 15681 *ext++ = '\0'; 15682 host = tmp; 15683 } 15684 15685 if (create_addr(p, host)) { 15686 *cause = AST_CAUSE_UNREGISTERED; 15687 if (option_debug > 2) 15688 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15689 sip_destroy(p); 15690 return NULL; 15691 } 15692 if (ast_strlen_zero(p->peername) && ext) 15693 ast_string_field_set(p, peername, ext); 15694 /* Recalculate our side, and recalculate Call ID */ 15695 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15696 p->ourip = __ourip; 15697 build_via(p); 15698 build_callid_pvt(p); 15699 15700 /* We have an extension to call, don't use the full contact here */ 15701 /* This to enable dialing registered peers with extension dialling, 15702 like SIP/peername/extension 15703 SIP/peername will still use the full contact */ 15704 if (ext) { 15705 ast_string_field_set(p, username, ext); 15706 ast_string_field_free(p, fullcontact); 15707 } 15708 #if 0 15709 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 15710 #endif 15711 p->prefcodec = oldformat; /* Format for this call */ 15712 ast_mutex_lock(&p->lock); 15713 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 15714 ast_mutex_unlock(&p->lock); 15715 if (!tmpc) 15716 sip_destroy(p); 15717 ast_update_use_count(); 15718 restart_monitor(); 15719 return tmpc; 15720 }
static int sip_reregister | ( | void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7288 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().
07289 { 07290 /* if we are here, we know that we need to reregister. */ 07291 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07292 07293 /* if we couldn't get a reference to the registry object, punt */ 07294 if (!r) 07295 return 0; 07296 07297 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07298 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07299 /* Since registry's are only added/removed by the the monitor thread, this 07300 may be overkill to reference/dereference at all here */ 07301 if (sipdebug) 07302 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07303 07304 r->expire = -1; 07305 __sip_do_register(r); 07306 ASTOBJ_UNREF(r, sip_registry_destroy); 07307 return 0; 07308 }
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 4187 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().
04188 { 04189 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04190 struct ast_frame *f; 04191 04192 if (!p->rtp) { 04193 /* We have no RTP allocated for this channel */ 04194 return &ast_null_frame; 04195 } 04196 04197 switch(ast->fdno) { 04198 case 0: 04199 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04200 break; 04201 case 1: 04202 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04203 break; 04204 case 2: 04205 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04206 break; 04207 case 3: 04208 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04209 break; 04210 case 5: 04211 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04212 break; 04213 default: 04214 f = &ast_null_frame; 04215 } 04216 /* Don't forward RFC2833 if we're not supposed to */ 04217 if (f && (f->frametype == AST_FRAME_DTMF) && 04218 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04219 return &ast_null_frame; 04220 04221 /* We already hold the channel lock */ 04222 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04223 return f; 04224 04225 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04226 if (!(f->subclass & p->jointcapability)) { 04227 if (option_debug) { 04228 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04229 ast_getformatname(f->subclass), p->owner->name); 04230 } 04231 return &ast_null_frame; 04232 } 04233 if (option_debug) 04234 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04235 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04236 ast_set_read_format(p->owner, p->owner->readformat); 04237 ast_set_write_format(p->owner, p->owner->writeformat); 04238 } 04239 04240 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04241 f = ast_dsp_process(p->owner, p->vad, f); 04242 if (f && f->frametype == AST_FRAME_DTMF) { 04243 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04244 if (option_debug) 04245 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04246 *faxdetect = 1; 04247 } else if (option_debug) { 04248 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04249 } 04250 } 04251 } 04252 04253 return f; 04254 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2095 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, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02096 { 02097 if (ms < 0) { 02098 if (p->timer_t1 == 0) 02099 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02100 ms = p->timer_t1 * 64; 02101 } 02102 if (sip_debug_test_pvt(p)) 02103 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02104 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02105 append_history(p, "SchedDestroy", "%d ms", ms); 02106 02107 if (p->autokillid > -1) 02108 ast_sched_del(sched, p->autokillid); 02109 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02110 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17482 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().
17483 { 17484 int ms; 17485 int regspacing; 17486 if (!regobjs) 17487 return; 17488 regspacing = default_expiry * 1000/regobjs; 17489 if (regspacing > 100) 17490 regspacing = 100; 17491 ms = regspacing; 17492 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17493 ASTOBJ_WRLOCK(iterator); 17494 if (iterator->expire > -1) 17495 ast_sched_del(sched, iterator->expire); 17496 ms += regspacing; 17497 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17498 ASTOBJ_UNLOCK(iterator); 17499 } while (0) 17500 ); 17501 }
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 15192 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().
15193 { 15194 /* Called with peerl lock, but releases it */ 15195 struct sip_pvt *p; 15196 int newmsgs, oldmsgs; 15197 15198 /* Do we have an IP address? If not, skip this peer */ 15199 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15200 return 0; 15201 15202 /* Check for messages */ 15203 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15204 15205 peer->lastmsgcheck = time(NULL); 15206 15207 /* Return now if it's the same thing we told them last time */ 15208 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15209 return 0; 15210 } 15211 15212 15213 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15214 15215 if (peer->mwipvt) { 15216 /* Base message on subscription */ 15217 p = peer->mwipvt; 15218 } else { 15219 /* Build temporary dialog for this message */ 15220 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15221 return -1; 15222 if (create_addr_from_peer(p, peer)) { 15223 /* Maybe they're not registered, etc. */ 15224 sip_destroy(p); 15225 return 0; 15226 } 15227 /* Recalculate our side, and recalculate Call ID */ 15228 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15229 p->ourip = __ourip; 15230 build_via(p); 15231 build_callid_pvt(p); 15232 /* Destroy this session after 32 secs */ 15233 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15234 } 15235 /* Send MWI */ 15236 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15237 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15238 return 0; 15239 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3735 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.
03736 { 03737 struct sip_pvt *p = ast->tech_pvt; 03738 int res = 0; 03739 03740 ast_mutex_lock(&p->lock); 03741 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03742 case SIP_DTMF_INBAND: 03743 res = -1; /* Tell Asterisk to generate inband indications */ 03744 break; 03745 case SIP_DTMF_RFC2833: 03746 if (p->rtp) 03747 ast_rtp_senddigit_begin(p->rtp, digit); 03748 break; 03749 default: 03750 break; 03751 } 03752 ast_mutex_unlock(&p->lock); 03753 03754 return res; 03755 }
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 3759 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().
03760 { 03761 struct sip_pvt *p = ast->tech_pvt; 03762 int res = 0; 03763 03764 ast_mutex_lock(&p->lock); 03765 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03766 case SIP_DTMF_INFO: 03767 transmit_info_with_digit(p, digit, duration); 03768 break; 03769 case SIP_DTMF_RFC2833: 03770 if (p->rtp) 03771 ast_rtp_senddigit_end(p->rtp, digit); 03772 break; 03773 case SIP_DTMF_INBAND: 03774 res = -1; /* Tell Asterisk to stop inband indications */ 03775 break; 03776 } 03777 ast_mutex_unlock(&p->lock); 03778 03779 return res; 03780 }
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 2338 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().
02339 { 02340 struct sip_pvt *p = ast->tech_pvt; 02341 int debug = sip_debug_test_pvt(p); 02342 02343 if (debug) 02344 ast_verbose("Sending text %s on %s\n", text, ast->name); 02345 if (!p) 02346 return -1; 02347 if (ast_strlen_zero(text)) 02348 return 0; 02349 if (debug) 02350 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02351 transmit_message_with_text(p, text); 02352 return 0; 02353 }
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 17214 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_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
17215 { 17216 struct sip_pvt *p; 17217 int changed = 0; 17218 17219 p = chan->tech_pvt; 17220 if (!p) 17221 return -1; 17222 17223 /* Disable early RTP bridge */ 17224 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17225 return 0; 17226 17227 ast_mutex_lock(&p->lock); 17228 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17229 /* If we're destroyed, don't bother */ 17230 ast_mutex_unlock(&p->lock); 17231 return 0; 17232 } 17233 17234 /* if this peer cannot handle reinvites of the media stream to devices 17235 that are known to be behind a NAT, then stop the process now 17236 */ 17237 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17238 ast_mutex_unlock(&p->lock); 17239 return 0; 17240 } 17241 17242 if (rtp) { 17243 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17244 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17245 memset(&p->redirip, 0, sizeof(p->redirip)); 17246 changed = 1; 17247 } 17248 if (vrtp) { 17249 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17250 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17251 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17252 changed = 1; 17253 } 17254 if (codecs) { 17255 if ((p->redircodecs != codecs)) { 17256 p->redircodecs = codecs; 17257 changed = 1; 17258 } 17259 if ((p->capability & codecs) != p->capability) { 17260 p->jointcapability &= codecs; 17261 p->capability &= codecs; 17262 changed = 1; 17263 } 17264 } 17265 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17266 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17267 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17268 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17269 if (option_debug) 17270 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)); 17271 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17272 if (option_debug > 2) { 17273 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)); 17274 } 17275 transmit_reinvite_with_sdp(p); 17276 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17277 if (option_debug > 2) { 17278 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)); 17279 } 17280 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17281 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17282 } 17283 } 17284 /* Reset lastrtprx timer */ 17285 p->lastrtprx = p->lastrtptx = time(NULL); 17286 ast_mutex_unlock(&p->lock); 17287 return 0; 17288 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 17041 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.
17042 { 17043 struct sip_pvt *p; 17044 17045 p = chan->tech_pvt; 17046 if (!p) 17047 return -1; 17048 ast_mutex_lock(&p->lock); 17049 if (udptl) 17050 ast_udptl_get_peer(udptl, &p->udptlredirip); 17051 else 17052 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17053 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17054 if (!p->pendinginvite) { 17055 if (option_debug > 2) { 17056 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); 17057 } 17058 transmit_reinvite_with_t38_sdp(p); 17059 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17060 if (option_debug > 2) { 17061 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); 17062 } 17063 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17064 } 17065 } 17066 /* Reset lastrtprx timer */ 17067 p->lastrtprx = p->lastrtptx = time(NULL); 17068 ast_mutex_unlock(&p->lock); 17069 return 0; 17070 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 10785 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, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
10786 { 10787 struct sip_pvt *cur; 10788 size_t len; 10789 int found = 0; 10790 10791 if (argc != 4) 10792 return RESULT_SHOWUSAGE; 10793 len = strlen(argv[3]); 10794 ast_mutex_lock(&iflock); 10795 for (cur = iflist; cur; cur = cur->next) { 10796 if (!strncasecmp(cur->callid, argv[3], len)) { 10797 char formatbuf[BUFSIZ/2]; 10798 ast_cli(fd,"\n"); 10799 if (cur->subscribed != NONE) 10800 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 10801 else 10802 ast_cli(fd, " * SIP Call\n"); 10803 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 10804 ast_cli(fd, " Call-ID: %s\n", cur->callid); 10805 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 10806 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 10807 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 10808 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 10809 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 10810 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 10811 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 10812 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 10813 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 10814 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 10815 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 10816 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)" ); 10817 ast_cli(fd, " Our Tag: %s\n", cur->tag); 10818 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 10819 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 10820 if (!ast_strlen_zero(cur->username)) 10821 ast_cli(fd, " Username: %s\n", cur->username); 10822 if (!ast_strlen_zero(cur->peername)) 10823 ast_cli(fd, " Peername: %s\n", cur->peername); 10824 if (!ast_strlen_zero(cur->uri)) 10825 ast_cli(fd, " Original uri: %s\n", cur->uri); 10826 if (!ast_strlen_zero(cur->cid_num)) 10827 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 10828 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 10829 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 10830 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10831 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 10832 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 10833 ast_cli(fd, " SIP Options: "); 10834 if (cur->sipoptions) { 10835 int x; 10836 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10837 if (cur->sipoptions & sip_options[x].id) 10838 ast_cli(fd, "%s ", sip_options[x].text); 10839 } 10840 } else 10841 ast_cli(fd, "(none)\n"); 10842 ast_cli(fd, "\n\n"); 10843 found++; 10844 } 10845 } 10846 ast_mutex_unlock(&iflock); 10847 if (!found) 10848 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10849 return RESULT_SUCCESS; 10850 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10583 of file chan_sip.c.
References __sip_show_channels().
10584 { 10585 return __sip_show_channels(fd, argc, argv, 0); 10586 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10089 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.
10090 { 10091 struct domain *d; 10092 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10093 10094 if (AST_LIST_EMPTY(&domain_list)) { 10095 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10096 return RESULT_SUCCESS; 10097 } else { 10098 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10099 AST_LIST_LOCK(&domain_list); 10100 AST_LIST_TRAVERSE(&domain_list, d, list) 10101 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10102 domain_mode_to_text(d->mode)); 10103 AST_LIST_UNLOCK(&domain_list); 10104 ast_cli(fd, "\n"); 10105 return RESULT_SUCCESS; 10106 } 10107 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 10853 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.
10854 { 10855 struct sip_pvt *cur; 10856 size_t len; 10857 int found = 0; 10858 10859 if (argc != 4) 10860 return RESULT_SHOWUSAGE; 10861 if (!recordhistory) 10862 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 10863 len = strlen(argv[3]); 10864 ast_mutex_lock(&iflock); 10865 for (cur = iflist; cur; cur = cur->next) { 10866 if (!strncasecmp(cur->callid, argv[3], len)) { 10867 struct sip_history *hist; 10868 int x = 0; 10869 10870 ast_cli(fd,"\n"); 10871 if (cur->subscribed != NONE) 10872 ast_cli(fd, " * Subscription\n"); 10873 else 10874 ast_cli(fd, " * SIP Call\n"); 10875 if (cur->history) 10876 AST_LIST_TRAVERSE(cur->history, hist, list) 10877 ast_cli(fd, "%d. %s\n", ++x, hist->event); 10878 if (x == 0) 10879 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 10880 found++; 10881 } 10882 } 10883 ast_mutex_unlock(&iflock); 10884 if (!found) 10885 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10886 return RESULT_SUCCESS; 10887 }
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 9514 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.
09515 { 09516 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09517 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09518 char ilimits[40]; 09519 char iused[40]; 09520 int showall = FALSE; 09521 09522 if (argc < 3) 09523 return RESULT_SHOWUSAGE; 09524 09525 if (argc == 4 && !strcmp(argv[3],"all")) 09526 showall = TRUE; 09527 09528 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09529 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09530 ASTOBJ_RDLOCK(iterator); 09531 if (iterator->call_limit) 09532 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09533 else 09534 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09535 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09536 if (showall || iterator->call_limit) 09537 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09538 ASTOBJ_UNLOCK(iterator); 09539 } while (0) ); 09540 09541 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09542 09543 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09544 ASTOBJ_RDLOCK(iterator); 09545 if (iterator->call_limit) 09546 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09547 else 09548 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09549 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09550 if (showall || iterator->call_limit) 09551 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09552 ASTOBJ_UNLOCK(iterator); 09553 } while (0) ); 09554 09555 return RESULT_SUCCESS; 09556 #undef FORMAT 09557 #undef FORMAT2 09558 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 9835 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
09836 { 09837 char tmp[256]; 09838 if (argc != 3) 09839 return RESULT_SHOWUSAGE; 09840 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 09841 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 09842 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 09843 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 09844 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 09845 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 09846 return RESULT_SUCCESS; 09847 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10141 of file chan_sip.c.
References _sip_show_peer().
10142 { 10143 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10144 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9691 of file chan_sip.c.
References _sip_show_peers().
09692 { 09693 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09694 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10414 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.
10415 { 10416 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10417 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10418 char host[80]; 10419 char tmpdat[256]; 10420 struct tm tm; 10421 10422 10423 if (argc != 3) 10424 return RESULT_SHOWUSAGE; 10425 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10426 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10427 ASTOBJ_RDLOCK(iterator); 10428 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10429 if (iterator->regtime) { 10430 ast_localtime(&iterator->regtime, &tm, NULL); 10431 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10432 } else { 10433 tmpdat[0] = 0; 10434 } 10435 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10436 ASTOBJ_UNLOCK(iterator); 10437 } while(0)); 10438 return RESULT_SUCCESS; 10439 #undef FORMAT 10440 #undef FORMAT2 10441 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10444 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_jb_conf::resync_threshold, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().
10445 { 10446 int realtimepeers; 10447 int realtimeusers; 10448 char codec_buf[BUFSIZ]; 10449 10450 realtimepeers = ast_check_realtime("sippeers"); 10451 realtimeusers = ast_check_realtime("sipusers"); 10452 10453 if (argc != 3) 10454 return RESULT_SHOWUSAGE; 10455 ast_cli(fd, "\n\nGlobal Settings:\n"); 10456 ast_cli(fd, "----------------\n"); 10457 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10458 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10459 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10460 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10461 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10462 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10463 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10464 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10465 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10466 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10467 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10468 ast_cli(fd, " Our auth realm %s\n", global_realm); 10469 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10470 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10471 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10472 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10473 ast_cli(fd, " User Agent: %s\n", global_useragent); 10474 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10475 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10476 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10477 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10478 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10479 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10480 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10481 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10482 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10483 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10484 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10485 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10486 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10487 #endif 10488 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10489 ast_cli(fd, " Jitterbuffer enabled: %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"); 10490 ast_cli(fd, " Jitterbuffer forced: %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"); 10491 ast_cli(fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 10492 ast_cli(fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 10493 ast_cli(fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 10494 ast_cli(fd, " Jitterbuffer log: %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"); 10495 if (!realtimepeers && !realtimeusers) 10496 ast_cli(fd, " SIP realtime: Disabled\n" ); 10497 else 10498 ast_cli(fd, " SIP realtime: Enabled\n" ); 10499 10500 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10501 ast_cli(fd, "---------------------------\n"); 10502 ast_cli(fd, " Codecs: "); 10503 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10504 ast_cli(fd, "%s\n", codec_buf); 10505 ast_cli(fd, " Codec Order: "); 10506 print_codec_to_cli(fd, &default_prefs); 10507 ast_cli(fd, "\n"); 10508 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10509 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10510 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10511 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10512 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10513 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10514 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10515 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10516 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10517 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10518 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10519 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10520 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10521 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10522 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10523 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10524 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10525 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10526 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10527 ast_cli(fd, "\nDefault Settings:\n"); 10528 ast_cli(fd, "-----------------\n"); 10529 ast_cli(fd, " Context: %s\n", default_context); 10530 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10531 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10532 ast_cli(fd, " Qualify: %d\n", default_qualify); 10533 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10534 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" ); 10535 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10536 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10537 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10538 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10539 10540 10541 if (realtimepeers || realtimeusers) { 10542 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10543 ast_cli(fd, "----------------------\n"); 10544 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10545 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10546 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10547 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10548 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10549 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10550 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10551 } 10552 ast_cli(fd, "\n----\n"); 10553 return RESULT_SUCCESS; 10554 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10589 of file chan_sip.c.
References __sip_show_channels().
10590 { 10591 return __sip_show_channels(fd, argc, argv, 1); 10592 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10359 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.
10360 { 10361 char cbuf[256]; 10362 struct sip_user *user; 10363 struct ast_variable *v; 10364 int load_realtime; 10365 10366 if (argc < 4) 10367 return RESULT_SHOWUSAGE; 10368 10369 /* Load from realtime storage? */ 10370 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10371 10372 user = find_user(argv[3], load_realtime); 10373 if (user) { 10374 ast_cli(fd,"\n\n"); 10375 ast_cli(fd, " * Name : %s\n", user->name); 10376 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10377 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10378 ast_cli(fd, " Context : %s\n", user->context); 10379 ast_cli(fd, " Language : %s\n", user->language); 10380 if (!ast_strlen_zero(user->accountcode)) 10381 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10382 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10383 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10384 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10385 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10386 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10387 ast_cli(fd, " Callgroup : "); 10388 print_group(fd, user->callgroup, 0); 10389 ast_cli(fd, " Pickupgroup : "); 10390 print_group(fd, user->pickupgroup, 0); 10391 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10392 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10393 ast_cli(fd, " Codec Order : ("); 10394 print_codec_to_cli(fd, &user->prefs); 10395 ast_cli(fd, ")\n"); 10396 10397 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10398 if (user->chanvars) { 10399 ast_cli(fd, " Variables :\n"); 10400 for (v = user->chanvars ; v ; v = v->next) 10401 ast_cli(fd, " %s = %s\n", v->name, v->value); 10402 } 10403 ast_cli(fd,"\n"); 10404 ASTOBJ_UNREF(user,sip_destroy_user); 10405 } else { 10406 ast_cli(fd,"User %s not found.\n", argv[3]); 10407 ast_cli(fd,"\n"); 10408 } 10409 10410 return RESULT_SUCCESS; 10411 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9614 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.
09615 { 09616 regex_t regexbuf; 09617 int havepattern = FALSE; 09618 09619 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09620 09621 switch (argc) { 09622 case 5: 09623 if (!strcasecmp(argv[3], "like")) { 09624 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09625 return RESULT_SHOWUSAGE; 09626 havepattern = TRUE; 09627 } else 09628 return RESULT_SHOWUSAGE; 09629 case 3: 09630 break; 09631 default: 09632 return RESULT_SHOWUSAGE; 09633 } 09634 09635 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09636 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09637 ASTOBJ_RDLOCK(iterator); 09638 09639 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09640 ASTOBJ_UNLOCK(iterator); 09641 continue; 09642 } 09643 09644 ast_cli(fd, FORMAT, iterator->name, 09645 iterator->secret, 09646 iterator->accountcode, 09647 iterator->context, 09648 iterator->ha ? "Yes" : "No", 09649 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09650 ASTOBJ_UNLOCK(iterator); 09651 } while (0) 09652 ); 09653 09654 if (havepattern) 09655 regfree(®exbuf); 09656 09657 return RESULT_SUCCESS; 09658 #undef FORMAT 09659 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17401 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().
17402 { 17403 char *cdest; 17404 char *extension, *host, *port; 17405 char tmp[80]; 17406 17407 cdest = ast_strdupa(dest); 17408 17409 extension = strsep(&cdest, "@"); 17410 host = strsep(&cdest, ":"); 17411 port = strsep(&cdest, ":"); 17412 if (ast_strlen_zero(extension)) { 17413 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17414 return 0; 17415 } 17416 17417 /* we'll issue the redirect message here */ 17418 if (!host) { 17419 char *localtmp; 17420 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17421 if (ast_strlen_zero(tmp)) { 17422 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17423 return 0; 17424 } 17425 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17426 char lhost[80], lport[80]; 17427 memset(lhost, 0, sizeof(lhost)); 17428 memset(lport, 0, sizeof(lport)); 17429 localtmp++; 17430 /* This is okey because lhost and lport are as big as tmp */ 17431 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17432 if (ast_strlen_zero(lhost)) { 17433 ast_log(LOG_ERROR, "Can't find the host address\n"); 17434 return 0; 17435 } 17436 host = ast_strdupa(lhost); 17437 if (!ast_strlen_zero(lport)) { 17438 port = ast_strdupa(lport); 17439 } 17440 } 17441 } 17442 17443 sip_alreadygone(p); 17444 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17445 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17446 17447 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 17448 sip_alreadygone(p); 17449 return 0; 17450 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3783 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().
03784 { 03785 struct sip_pvt *p = ast->tech_pvt; 03786 int res; 03787 03788 if (dest == NULL) /* functions below do not take a NULL */ 03789 dest = ""; 03790 ast_mutex_lock(&p->lock); 03791 if (ast->_state == AST_STATE_RING) 03792 res = sip_sipredirect(p, dest); 03793 else 03794 res = transmit_refer(p, dest); 03795 ast_mutex_unlock(&p->lock); 03796 return res; 03797 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3616 of file chan_sip.c.
References ast_channel::_state, ast_backtrace(), AST_FORMAT_AUDIO_MASK, ast_frame_dump(), AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, 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.
03617 { 03618 struct sip_pvt *p = ast->tech_pvt; 03619 int res = 0; 03620 03621 switch (frame->frametype) { 03622 case AST_FRAME_VOICE: 03623 if (!(frame->subclass & ast->nativeformats)) { 03624 char s1[512], s2[512], s3[512]; 03625 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03626 frame->subclass, 03627 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03628 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03629 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03630 ast->readformat, 03631 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03632 ast->writeformat); 03633 ast_frame_dump(ast->name, frame, "<<"); 03634 ast_backtrace(); 03635 return 0; 03636 } 03637 if (p) { 03638 ast_mutex_lock(&p->lock); 03639 if (p->rtp) { 03640 /* If channel is not up, activate early media session */ 03641 if ((ast->_state != AST_STATE_UP) && 03642 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03643 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03644 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03645 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03646 } 03647 p->lastrtptx = time(NULL); 03648 res = ast_rtp_write(p->rtp, frame); 03649 } 03650 ast_mutex_unlock(&p->lock); 03651 } 03652 break; 03653 case AST_FRAME_VIDEO: 03654 if (p) { 03655 ast_mutex_lock(&p->lock); 03656 if (p->vrtp) { 03657 /* Activate video early media */ 03658 if ((ast->_state != AST_STATE_UP) && 03659 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03660 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03661 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03662 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03663 } 03664 p->lastrtptx = time(NULL); 03665 res = ast_rtp_write(p->vrtp, frame); 03666 } 03667 ast_mutex_unlock(&p->lock); 03668 } 03669 break; 03670 case AST_FRAME_IMAGE: 03671 return 0; 03672 break; 03673 case AST_FRAME_MODEM: 03674 if (p) { 03675 ast_mutex_lock(&p->lock); 03676 /* UDPTL requires two-way communication, so early media is not needed here. 03677 we simply forget the frames if we get modem frames before the bridge is up. 03678 Fax will re-transmit. 03679 */ 03680 if (p->udptl && ast->_state == AST_STATE_UP) 03681 res = ast_udptl_write(p->udptl, frame); 03682 ast_mutex_unlock(&p->lock); 03683 } 03684 break; 03685 default: 03686 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03687 return 0; 03688 } 03689 03690 return res; 03691 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15091 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(), 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_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15092 { 15093 struct sip_request req; 15094 struct sockaddr_in sin = { 0, }; 15095 struct sip_pvt *p; 15096 int res; 15097 socklen_t len = sizeof(sin); 15098 int nounlock; 15099 int recount = 0; 15100 int lockretry; 15101 15102 memset(&req, 0, sizeof(req)); 15103 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15104 if (res < 0) { 15105 #if !defined(__FreeBSD__) 15106 if (errno == EAGAIN) 15107 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15108 else 15109 #endif 15110 if (errno != ECONNREFUSED) 15111 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15112 return 1; 15113 } 15114 if (option_debug && res == sizeof(req.data)) { 15115 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15116 req.data[sizeof(req.data) - 1] = '\0'; 15117 } else 15118 req.data[res] = '\0'; 15119 req.len = res; 15120 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15121 ast_set_flag(&req, SIP_PKT_DEBUG); 15122 if (pedanticsipchecking) 15123 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15124 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15125 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15126 15127 parse_request(&req); 15128 req.method = find_sip_method(req.rlPart1); 15129 15130 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15131 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15132 15133 if (req.headers < 2) /* Must have at least two headers */ 15134 return 1; 15135 15136 /* Process request, with netlock held, and with usual deadlock avoidance */ 15137 for (lockretry = 100; lockretry > 0; lockretry--) { 15138 ast_mutex_lock(&netlock); 15139 15140 /* Find the active SIP dialog or create a new one */ 15141 p = find_call(&req, &sin, req.method); /* returns p locked */ 15142 if (p == NULL) { 15143 if (option_debug) 15144 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15145 ast_mutex_unlock(&netlock); 15146 return 1; 15147 } 15148 /* Go ahead and lock the owner if it has one -- we may need it */ 15149 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15150 if (!p->owner || !ast_channel_trylock(p->owner)) 15151 break; /* locking succeeded */ 15152 if (option_debug) 15153 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15154 ast_mutex_unlock(&p->lock); 15155 ast_mutex_unlock(&netlock); 15156 /* Sleep for a very short amount of time */ 15157 usleep(1); 15158 } 15159 p->recv = sin; 15160 15161 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15162 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15163 15164 if (!lockretry) { 15165 if (p->owner) 15166 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15167 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15168 if (req.method != SIP_ACK) 15169 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15170 /* XXX We could add retry-after to make sure they come back */ 15171 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15172 return 1; 15173 } 15174 nounlock = 0; 15175 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15176 /* Request failed */ 15177 if (option_debug) 15178 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15179 } 15180 15181 if (p->owner && !nounlock) 15182 ast_channel_unlock(p->owner); 15183 ast_mutex_unlock(&p->lock); 15184 ast_mutex_unlock(&netlock); 15185 if (recount) 15186 ast_update_use_count(); 15187 15188 return 1; 15189 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12366 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().
12367 { 12368 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12369 if (p->rtp) 12370 ast_rtp_stop(p->rtp); 12371 if (p->vrtp) 12372 ast_rtp_stop(p->vrtp); 12373 if (p->udptl) 12374 ast_udptl_stop(p->udptl); 12375 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10557 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10558 { 10559 int i; 10560 10561 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10562 if (subscription_types[i].type == subtype) { 10563 return subscription_types[i].text; 10564 } 10565 } 10566 return subscription_types[0].text; 10567 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6121 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().
06122 { 06123 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06124 06125 if (maxrate & T38FAX_RATE_14400) { 06126 if (option_debug > 1) 06127 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06128 return 14400; 06129 } else if (maxrate & T38FAX_RATE_12000) { 06130 if (option_debug > 1) 06131 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06132 return 12000; 06133 } else if (maxrate & T38FAX_RATE_9600) { 06134 if (option_debug > 1) 06135 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06136 return 9600; 06137 } else if (maxrate & T38FAX_RATE_7200) { 06138 if (option_debug > 1) 06139 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06140 return 7200; 06141 } else if (maxrate & T38FAX_RATE_4800) { 06142 if (option_debug > 1) 06143 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06144 return 4800; 06145 } else if (maxrate & T38FAX_RATE_2400) { 06146 if (option_debug > 1) 06147 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06148 return 2400; 06149 } else { 06150 if (option_debug > 1) 06151 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06152 return 0; 06153 } 06154 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16197 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().
16198 { 16199 struct sip_peer *peer; 16200 16201 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16202 return NULL; 16203 16204 apeerobjs++; 16205 ASTOBJ_INIT(peer); 16206 set_peer_defaults(peer); 16207 16208 ast_copy_string(peer->name, name, sizeof(peer->name)); 16209 16210 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16211 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16212 peer->prefs = default_prefs; 16213 reg_source_db(peer); 16214 16215 return peer; 16216 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 5897 of file chan_sip.c.
References ast_string_field_free_pools, and free.
05898 { 05899 struct sip_pvt *p = data; 05900 05901 ast_string_field_free_pools(p); 05902 05903 free(data); 05904 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9561 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().
09562 { 09563 if (mode == TRANSFER_OPENFORALL) 09564 return "open"; 09565 else if (mode == TRANSFER_CLOSED) 09566 return "closed"; 09567 return "strict"; 09568 }
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 8406 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().
08407 { 08408 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08409 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08410 }
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 7645 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07646 { 07647 struct sip_request req; 07648 07649 reqprep(&req, p, SIP_INFO, 0, 1); 07650 add_digit(&req, digit, duration); 07651 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07652 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7655 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07656 { 07657 struct sip_request req; 07658 07659 reqprep(&req, p, SIP_INFO, 0, 1); 07660 add_vidupdate(&req); 07661 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07662 }
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 6923 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_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, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
06924 { 06925 struct sip_request req; 06926 06927 req.method = sipmethod; 06928 if (init) { /* Seems like init always is 2 */ 06929 /* Bump branch even on initial requests */ 06930 p->branch ^= ast_random(); 06931 build_via(p); 06932 if (init > 1) 06933 initreqprep(&req, p, sipmethod); 06934 else 06935 reqprep(&req, p, sipmethod, 0, 1); 06936 } else 06937 reqprep(&req, p, sipmethod, 0, 1); 06938 06939 if (p->options && p->options->auth) 06940 add_header(&req, p->options->authheader, p->options->auth); 06941 append_date(&req); 06942 if (sipmethod == SIP_REFER) { /* Call transfer */ 06943 if (p->refer) { 06944 char buf[BUFSIZ]; 06945 if (!ast_strlen_zero(p->refer->refer_to)) 06946 add_header(&req, "Refer-To", p->refer->refer_to); 06947 if (!ast_strlen_zero(p->refer->referred_by)) { 06948 sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 06949 add_header(&req, "Referred-By", buf); 06950 } 06951 } 06952 } 06953 /* This new INVITE is part of an attended transfer. Make sure that the 06954 other end knows and replace the current call with this new call */ 06955 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 06956 add_header(&req, "Replaces", p->options->replaces); 06957 add_header(&req, "Require", "replaces"); 06958 } 06959 06960 add_header(&req, "Allow", ALLOWED_METHODS); 06961 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06962 if (p->options && p->options->addsipheaders && p->owner) { 06963 struct ast_channel *ast = p->owner; /* The owner channel */ 06964 struct varshead *headp = &ast->varshead; 06965 06966 if (!headp) 06967 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 06968 else { 06969 const struct ast_var_t *current; 06970 AST_LIST_TRAVERSE(headp, current, entries) { 06971 /* SIPADDHEADER: Add SIP header to outgoing call */ 06972 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 06973 char *content, *end; 06974 const char *header = ast_var_value(current); 06975 char *headdup = ast_strdupa(header); 06976 06977 /* Strip of the starting " (if it's there) */ 06978 if (*headdup == '"') 06979 headdup++; 06980 if ((content = strchr(headdup, ':'))) { 06981 *content++ = '\0'; 06982 content = ast_skip_blanks(content); /* Skip white space */ 06983 /* Strip the ending " (if it's there) */ 06984 end = content + strlen(content) -1; 06985 if (*end == '"') 06986 *end = '\0'; 06987 06988 add_header(&req, headdup, content); 06989 if (sipdebug) 06990 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 06991 } 06992 } 06993 } 06994 } 06995 } 06996 if (sdp) { 06997 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 06998 ast_udptl_offered_from_local(p->udptl, 1); 06999 if (option_debug) 07000 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07001 add_t38_sdp(&req, p); 07002 } else if (p->rtp) 07003 add_sdp(&req, p); 07004 } else { 07005 add_header_contentLength(&req, 0); 07006 } 07007 07008 if (!p->initreq.headers) 07009 initialize_initreq(p, &req); 07010 p->lastinvite = p->ocseq; 07011 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07012 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7553 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().
07554 { 07555 struct sip_request req; 07556 07557 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07558 add_text(&req, text); 07559 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07560 }
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 7193 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().
07194 { 07195 struct sip_request req; 07196 char tmp[500]; 07197 char *t = tmp; 07198 size_t maxbytes = sizeof(tmp); 07199 07200 initreqprep(&req, p, SIP_NOTIFY); 07201 add_header(&req, "Event", "message-summary"); 07202 add_header(&req, "Content-Type", default_notifymime); 07203 07204 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07205 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07206 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07207 /* Cisco has a bug in the SIP stack where it can't accept the 07208 (0/0) notification. This can temporarily be disabled in 07209 sip.conf with the "buggymwi" option */ 07210 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)")); 07211 07212 if (p->subscribed) { 07213 if (p->expiry) 07214 add_header(&req, "Subscription-State", "active"); 07215 else /* Expired */ 07216 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07217 } 07218 07219 if (t > tmp + sizeof(tmp)) 07220 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07221 07222 add_header_contentLength(&req, strlen(tmp)); 07223 add_line(&req, tmp); 07224 07225 if (!p->initreq.headers) 07226 initialize_initreq(p, &req); 07227 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07228 }
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 7239 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07240 { 07241 struct sip_request req; 07242 char tmp[BUFSIZ/2]; 07243 07244 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07245 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07246 add_header(&req, "Event", tmp); 07247 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07248 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07249 add_header(&req, "Allow", ALLOWED_METHODS); 07250 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07251 07252 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07253 add_header_contentLength(&req, strlen(tmp)); 07254 add_line(&req, tmp); 07255 07256 if (!p->initreq.headers) 07257 initialize_initreq(p, &req); 07258 07259 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07260 }
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 7574 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, DEFAULT_MAX_FORWARDS, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.
Referenced by sip_transfer().
07575 { 07576 struct sip_request req = { 07577 .headers = 0, 07578 }; 07579 char from[256]; 07580 const char *of; 07581 char *c; 07582 char referto[256]; 07583 char *ttag, *ftag; 07584 char *theirtag = ast_strdupa(p->theirtag); 07585 07586 if (option_debug || sipdebug) 07587 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07588 07589 /* Are we transfering an inbound or outbound call ? */ 07590 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07591 of = get_header(&p->initreq, "To"); 07592 ttag = theirtag; 07593 ftag = p->tag; 07594 } else { 07595 of = get_header(&p->initreq, "From"); 07596 ftag = theirtag; 07597 ttag = p->tag; 07598 } 07599 07600 ast_copy_string(from, of, sizeof(from)); 07601 of = get_in_brackets(from); 07602 ast_string_field_set(p, from, of); 07603 if (strncasecmp(of, "sip:", 4)) 07604 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07605 else 07606 of += 4; 07607 /* Get just the username part */ 07608 if ((c = strchr(dest, '@'))) 07609 c = NULL; 07610 else if ((c = strchr(of, '@'))) 07611 *c++ = '\0'; 07612 if (c) 07613 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07614 else 07615 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07616 07617 /* save in case we get 407 challenge */ 07618 sip_refer_allocate(p); 07619 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07620 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07621 p->refer->status = REFER_SENT; /* Set refer status */ 07622 07623 reqprep(&req, p, SIP_REFER, 0, 1); 07624 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07625 07626 add_header(&req, "Refer-To", referto); 07627 add_header(&req, "Allow", ALLOWED_METHODS); 07628 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07629 if (!ast_strlen_zero(p->our_contact)) 07630 add_header(&req, "Referred-By", p->our_contact); 07631 07632 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07633 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07634 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07635 07636 /*! \todo In theory, we should hang around and wait for a reply, before 07637 returning to the dial plan here. Don't know really how that would 07638 affect the transfer() app or the pbx, but, well, to make this 07639 useful we should have a STATUS code on transfer(). 07640 */ 07641 }
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 7362 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().
07363 { 07364 struct sip_request req; 07365 char from[256]; 07366 char to[256]; 07367 char tmp[80]; 07368 char addr[80]; 07369 struct sip_pvt *p; 07370 07371 /* exit if we are already in process with this registrar ?*/ 07372 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07373 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07374 return 0; 07375 } 07376 07377 if (r->call) { /* We have a registration */ 07378 if (!auth) { 07379 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07380 return 0; 07381 } else { 07382 p = r->call; 07383 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07384 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07385 } 07386 } else { 07387 /* Build callid for registration if we haven't registered before */ 07388 if (!r->callid_valid) { 07389 build_callid_registry(r, __ourip, default_fromdomain); 07390 r->callid_valid = TRUE; 07391 } 07392 /* Allocate SIP packet for registration */ 07393 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07394 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07395 return 0; 07396 } 07397 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07398 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07399 /* Find address to hostname */ 07400 if (create_addr(p, r->hostname)) { 07401 /* we have what we hope is a temporary network error, 07402 * probably DNS. We need to reschedule a registration try */ 07403 sip_destroy(p); 07404 if (r->timeout > -1) { 07405 ast_sched_del(sched, r->timeout); 07406 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07407 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07408 } else { 07409 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07410 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); 07411 } 07412 r->regattempts++; 07413 return 0; 07414 } 07415 /* Copy back Call-ID in case create_addr changed it */ 07416 ast_string_field_set(r, callid, p->callid); 07417 if (r->portno) 07418 p->sa.sin_port = htons(r->portno); 07419 else /* Set registry port to the port set from the peer definition/srv or default */ 07420 r->portno = ntohs(p->sa.sin_port); 07421 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07422 r->call=p; /* Save pointer to SIP packet */ 07423 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07424 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07425 ast_string_field_set(p, peersecret, r->secret); 07426 if (!ast_strlen_zero(r->md5secret)) 07427 ast_string_field_set(p, peermd5secret, r->md5secret); 07428 /* User name in this realm 07429 - if authuser is set, use that, otherwise use username */ 07430 if (!ast_strlen_zero(r->authuser)) { 07431 ast_string_field_set(p, peername, r->authuser); 07432 ast_string_field_set(p, authname, r->authuser); 07433 } else if (!ast_strlen_zero(r->username)) { 07434 ast_string_field_set(p, peername, r->username); 07435 ast_string_field_set(p, authname, r->username); 07436 ast_string_field_set(p, fromuser, r->username); 07437 } 07438 if (!ast_strlen_zero(r->username)) 07439 ast_string_field_set(p, username, r->username); 07440 /* Save extension in packet */ 07441 ast_string_field_set(p, exten, r->contact); 07442 07443 /* 07444 check which address we should use in our contact header 07445 based on whether the remote host is on the external or 07446 internal network so we can register through nat 07447 */ 07448 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07449 p->ourip = bindaddr.sin_addr; 07450 build_contact(p); 07451 } 07452 07453 /* set up a timeout */ 07454 if (auth == NULL) { 07455 if (r->timeout > -1) { 07456 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07457 ast_sched_del(sched, r->timeout); 07458 } 07459 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07460 if (option_debug) 07461 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07462 } 07463 07464 if (strchr(r->username, '@')) { 07465 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07466 if (!ast_strlen_zero(p->theirtag)) 07467 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07468 else 07469 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07470 } else { 07471 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07472 if (!ast_strlen_zero(p->theirtag)) 07473 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07474 else 07475 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07476 } 07477 07478 /* Fromdomain is what we are registering to, regardless of actual 07479 host name from SRV */ 07480 if (!ast_strlen_zero(p->fromdomain)) { 07481 if (r->portno && r->portno != STANDARD_SIP_PORT) 07482 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07483 else 07484 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07485 } else { 07486 if (r->portno && r->portno != STANDARD_SIP_PORT) 07487 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07488 else 07489 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07490 } 07491 ast_string_field_set(p, uri, addr); 07492 07493 p->branch ^= ast_random(); 07494 07495 init_req(&req, sipmethod, addr); 07496 07497 /* Add to CSEQ */ 07498 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07499 p->ocseq = r->ocseq; 07500 07501 build_via(p); 07502 add_header(&req, "Via", p->via); 07503 add_header(&req, "From", from); 07504 add_header(&req, "To", to); 07505 add_header(&req, "Call-ID", p->callid); 07506 add_header(&req, "CSeq", tmp); 07507 if (!ast_strlen_zero(global_useragent)) 07508 add_header(&req, "User-Agent", global_useragent); 07509 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07510 07511 07512 if (auth) /* Add auth header */ 07513 add_header(&req, authheader, auth); 07514 else if (!ast_strlen_zero(r->nonce)) { 07515 char digest[1024]; 07516 07517 /* We have auth data to reuse, build a digest header! */ 07518 if (sipdebug) 07519 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07520 ast_string_field_set(p, realm, r->realm); 07521 ast_string_field_set(p, nonce, r->nonce); 07522 ast_string_field_set(p, domain, r->domain); 07523 ast_string_field_set(p, opaque, r->opaque); 07524 ast_string_field_set(p, qop, r->qop); 07525 r->noncecount++; 07526 p->noncecount = r->noncecount; 07527 07528 memset(digest,0,sizeof(digest)); 07529 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07530 add_header(&req, "Authorization", digest); 07531 else 07532 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07533 07534 } 07535 07536 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07537 add_header(&req, "Expires", tmp); 07538 add_header(&req, "Contact", p->our_contact); 07539 add_header(&req, "Event", "registration"); 07540 add_header_contentLength(&req, 0); 07541 07542 initialize_initreq(p, &req); 07543 if (sip_debug_test_pvt(p)) 07544 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07545 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07546 r->regattempts++; /* Another attempt */ 07547 if (option_debug > 3) 07548 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07549 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07550 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6643 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().
06644 { 06645 struct sip_request req; 06646 06647 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06648 06649 add_header(&req, "Allow", ALLOWED_METHODS); 06650 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06651 if (sipdebug) 06652 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06653 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06654 append_history(p, "ReInv", "Re-invite sent"); 06655 add_sdp(&req, p); 06656 /* Use this as the basis */ 06657 initialize_initreq(p, &req); 06658 p->lastinvite = p->ocseq; 06659 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06660 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06661 }
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 6667 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().
06668 { 06669 struct sip_request req; 06670 06671 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06672 06673 add_header(&req, "Allow", ALLOWED_METHODS); 06674 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06675 if (sipdebug) 06676 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06677 ast_udptl_offered_from_local(p->udptl, 1); 06678 add_t38_sdp(&req, p); 06679 /* Use this as the basis */ 06680 initialize_initreq(p, &req); 06681 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06682 p->lastinvite = p->ocseq; 06683 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06684 }
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 7667 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().
07668 { 07669 struct sip_request resp; 07670 07671 if (sipmethod == SIP_ACK) 07672 p->invitestate = INV_CONFIRMED; 07673 07674 reqprep(&resp, p, sipmethod, seqno, newbranch); 07675 add_header_contentLength(&resp, 0); 07676 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07677 }
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 7680 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().
07681 { 07682 struct sip_request resp; 07683 07684 reqprep(&resp, p, sipmethod, seqno, newbranch); 07685 if (!ast_strlen_zero(p->realm)) { 07686 char digest[1024]; 07687 07688 memset(digest, 0, sizeof(digest)); 07689 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07690 if (p->options && p->options->auth_type == PROXY_AUTH) 07691 add_header(&resp, "Proxy-Authorization", digest); 07692 else if (p->options && p->options->auth_type == WWW_AUTH) 07693 add_header(&resp, "Authorization", digest); 07694 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07695 add_header(&resp, "Proxy-Authorization", digest); 07696 } else 07697 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07698 } 07699 /* If we are hanging up and know a cause for that, send it in clear text to make 07700 debugging easier. */ 07701 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07702 char buf[10]; 07703 07704 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07705 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07706 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07707 } 07708 07709 add_header_contentLength(&resp, 0); 07710 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07711 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 5957 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
05958 { 05959 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05960 }
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 5976 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect().
05977 { 05978 return __transmit_response(p, msg, req, XMIT_CRITICAL); 05979 }
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 5907 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_free_all, ast_string_field_init, ast_string_field_set, ast_test_flag, build_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.
05908 { 05909 struct sip_pvt *p = NULL; 05910 05911 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05912 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05913 return -1; 05914 } 05915 05916 /* if the structure was just allocated, initialize it */ 05917 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 05918 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 05919 if (ast_string_field_init(p, 512)) 05920 return -1; 05921 } 05922 05923 /* Initialize the bare minimum */ 05924 p->method = intended_method; 05925 05926 if (sin) { 05927 p->sa = *sin; 05928 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05929 p->ourip = __ourip; 05930 } else 05931 p->ourip = __ourip; 05932 05933 p->branch = ast_random(); 05934 make_our_tag(p->tag, sizeof(p->tag)); 05935 p->ocseq = INITIAL_CSEQ; 05936 05937 if (useglobal_nat && sin) { 05938 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 05939 p->recv = *sin; 05940 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 05941 } 05942 05943 ast_string_field_set(p, fromdomain, default_fromdomain); 05944 build_via(p); 05945 ast_string_field_set(p, callid, callid); 05946 05947 /* Use this temporary pvt structure to send the message */ 05948 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05949 05950 /* Free the string fields, but not the pool space */ 05951 ast_string_field_free_all(p); 05952 05953 return 0; 05954 }
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 6004 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06005 { 06006 struct sip_request resp; 06007 respprep(&resp, p, msg, req); 06008 add_header(&resp, "Accept", "application/sdp"); 06009 add_header_contentLength(&resp, 0); 06010 return send_response(p, &resp, reliable, 0); 06011 }
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 6014 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().
06015 { 06016 struct sip_request resp; 06017 char tmp[512]; 06018 int seqno = 0; 06019 06020 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06021 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06022 return -1; 06023 } 06024 /* Stale means that they sent us correct authentication, but 06025 based it on an old challenge (nonce) */ 06026 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06027 respprep(&resp, p, msg, req); 06028 add_header(&resp, header, tmp); 06029 add_header_contentLength(&resp, 0); 06030 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06031 return send_response(p, &resp, reliable, seqno); 06032 }
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 5994 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
05995 { 05996 struct sip_request resp; 05997 respprep(&resp, p, msg, req); 05998 append_date(&resp); 05999 add_header_contentLength(&resp, 0); 06000 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06001 }
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 6572 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().
06573 { 06574 struct sip_request resp; 06575 int seqno; 06576 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06577 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06578 return -1; 06579 } 06580 respprep(&resp, p, msg, req); 06581 if (p->rtp) { 06582 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06583 if (option_debug) 06584 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06585 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06586 } 06587 try_suggested_sip_codec(p); 06588 add_sdp(&resp, p); 06589 } else 06590 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06591 if (reliable && !p->pendinginvite) 06592 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06593 return send_response(p, &resp, reliable, seqno); 06594 }
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 6532 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().
06533 { 06534 struct sip_request resp; 06535 int seqno; 06536 06537 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06538 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06539 return -1; 06540 } 06541 respprep(&resp, p, msg, req); 06542 if (p->udptl) { 06543 ast_udptl_offered_from_local(p->udptl, 0); 06544 add_t38_sdp(&resp, p); 06545 } else 06546 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06547 if (retrans && !p->pendinginvite) 06548 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06549 return send_response(p, &resp, retrans, seqno); 06550 }
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 5963 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
05964 { 05965 struct sip_request resp; 05966 respprep(&resp, p, msg, req); 05967 append_date(&resp); 05968 add_header(&resp, "Unsupported", unsupported); 05969 add_header_contentLength(&resp, 0); 05970 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05971 }
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 7231 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().
07232 { 07233 if (!p->initreq.headers) /* Initialize first request before sending */ 07234 initialize_initreq(p, req); 07235 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07236 }
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 7015 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, 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().
07016 { 07017 char tmp[4000], from[256], to[256]; 07018 char *t = tmp, *c, *mfrom, *mto; 07019 size_t maxbytes = sizeof(tmp); 07020 struct sip_request req; 07021 char hint[AST_MAX_EXTENSION]; 07022 char *statestring = "terminated"; 07023 const struct cfsubscription_types *subscriptiontype; 07024 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07025 char *pidfstate = "--"; 07026 char *pidfnote= "Ready"; 07027 07028 memset(from, 0, sizeof(from)); 07029 memset(to, 0, sizeof(to)); 07030 memset(tmp, 0, sizeof(tmp)); 07031 07032 switch (state) { 07033 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07034 statestring = (global_notifyringing) ? "early" : "confirmed"; 07035 local_state = NOTIFY_INUSE; 07036 pidfstate = "busy"; 07037 pidfnote = "Ringing"; 07038 break; 07039 case AST_EXTENSION_RINGING: 07040 statestring = "early"; 07041 local_state = NOTIFY_INUSE; 07042 pidfstate = "busy"; 07043 pidfnote = "Ringing"; 07044 break; 07045 case AST_EXTENSION_INUSE: 07046 statestring = "confirmed"; 07047 local_state = NOTIFY_INUSE; 07048 pidfstate = "busy"; 07049 pidfnote = "On the phone"; 07050 break; 07051 case AST_EXTENSION_BUSY: 07052 statestring = "confirmed"; 07053 local_state = NOTIFY_CLOSED; 07054 pidfstate = "busy"; 07055 pidfnote = "On the phone"; 07056 break; 07057 case AST_EXTENSION_UNAVAILABLE: 07058 statestring = "terminated"; 07059 local_state = NOTIFY_CLOSED; 07060 pidfstate = "away"; 07061 pidfnote = "Unavailable"; 07062 break; 07063 case AST_EXTENSION_ONHOLD: 07064 statestring = "confirmed"; 07065 local_state = NOTIFY_INUSE; 07066 pidfstate = "busy"; 07067 pidfnote = "On Hold"; 07068 break; 07069 case AST_EXTENSION_NOT_INUSE: 07070 default: 07071 /* Default setting */ 07072 break; 07073 } 07074 07075 subscriptiontype = find_subscription_type(p->subscribed); 07076 07077 /* Check which device/devices we are watching and if they are registered */ 07078 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07079 char *hint2 = hint, *individual_hint = NULL; 07080 while ((individual_hint = strsep(&hint2, "&"))) { 07081 /* If they are not registered, we will override notification and show no availability */ 07082 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) { 07083 local_state = NOTIFY_CLOSED; 07084 pidfstate = "away"; 07085 pidfnote = "Not online"; 07086 } 07087 } 07088 } 07089 07090 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07091 c = get_in_brackets(from); 07092 if (strncasecmp(c, "sip:", 4)) { 07093 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07094 return -1; 07095 } 07096 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07097 07098 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07099 c = get_in_brackets(to); 07100 if (strncasecmp(c, "sip:", 4)) { 07101 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07102 return -1; 07103 } 07104 mto = strsep(&c, ";"); /* trim ; and beyond */ 07105 07106 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07107 07108 07109 add_header(&req, "Event", subscriptiontype->event); 07110 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07111 switch(state) { 07112 case AST_EXTENSION_DEACTIVATED: 07113 if (timeout) 07114 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07115 else { 07116 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07117 add_header(&req, "Retry-After", "60"); 07118 } 07119 break; 07120 case AST_EXTENSION_REMOVED: 07121 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07122 break; 07123 default: 07124 if (p->expiry) 07125 add_header(&req, "Subscription-State", "active"); 07126 else /* Expired */ 07127 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07128 } 07129 switch (p->subscribed) { 07130 case XPIDF_XML: 07131 case CPIM_PIDF_XML: 07132 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07133 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07134 ast_build_string(&t, &maxbytes, "<presence>\n"); 07135 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07136 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07137 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07138 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07139 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07140 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07141 break; 07142 case PIDF_XML: /* Eyebeam supports this format */ 07143 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07144 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); 07145 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07146 if (pidfstate[0] != '-') 07147 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07148 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07149 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07150 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07151 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07152 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07153 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07154 else 07155 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07156 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07157 break; 07158 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07159 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07160 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); 07161 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07162 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07163 else 07164 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07165 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07166 if (state == AST_EXTENSION_ONHOLD) { 07167 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07168 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07169 "</target>\n</local>\n", mto); 07170 } 07171 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07172 break; 07173 case NONE: 07174 default: 07175 break; 07176 } 07177 07178 if (t > tmp + sizeof(tmp)) 07179 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07180 07181 add_header_contentLength(&req, strlen(tmp)); 07182 add_line(&req, tmp); 07183 07184 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07185 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3567 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().
03568 { 03569 int fmt; 03570 const char *codec; 03571 03572 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03573 if (!codec) 03574 return; 03575 03576 fmt = ast_getformatbyname(codec); 03577 if (fmt) { 03578 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03579 if (p->jointcapability & fmt) { 03580 p->jointcapability &= fmt; 03581 p->capability &= fmt; 03582 } else 03583 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03584 } else 03585 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03586 return; 03587 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 17753 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, TRUE, and userl.
17754 { 17755 struct sip_pvt *p, *pl; 17756 17757 /* First, take us out of the channel type list */ 17758 ast_channel_unregister(&sip_tech); 17759 17760 /* Unregister dial plan functions */ 17761 ast_custom_function_unregister(&sipchaninfo_function); 17762 ast_custom_function_unregister(&sippeer_function); 17763 ast_custom_function_unregister(&sip_header_function); 17764 ast_custom_function_unregister(&checksipdomain_function); 17765 17766 /* Unregister dial plan applications */ 17767 ast_unregister_application(app_dtmfmode); 17768 ast_unregister_application(app_sipaddheader); 17769 17770 /* Unregister CLI commands */ 17771 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 17772 17773 /* Disconnect from the RTP subsystem */ 17774 ast_rtp_proto_unregister(&sip_rtp); 17775 17776 /* Disconnect from UDPTL */ 17777 ast_udptl_proto_unregister(&sip_udptl); 17778 17779 /* Unregister AMI actions */ 17780 ast_manager_unregister("SIPpeers"); 17781 ast_manager_unregister("SIPshowpeer"); 17782 17783 ast_mutex_lock(&iflock); 17784 /* Hangup all interfaces if they have an owner */ 17785 for (p = iflist; p ; p = p->next) { 17786 if (p->owner) 17787 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 17788 } 17789 ast_mutex_unlock(&iflock); 17790 17791 ast_mutex_lock(&monlock); 17792 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 17793 pthread_cancel(monitor_thread); 17794 pthread_kill(monitor_thread, SIGURG); 17795 pthread_join(monitor_thread, NULL); 17796 } 17797 monitor_thread = AST_PTHREADT_STOP; 17798 ast_mutex_unlock(&monlock); 17799 17800 ast_mutex_lock(&iflock); 17801 /* Destroy all the interfaces and free their memory */ 17802 p = iflist; 17803 while (p) { 17804 pl = p; 17805 p = p->next; 17806 __sip_destroy(pl, TRUE); 17807 } 17808 iflist = NULL; 17809 ast_mutex_unlock(&iflock); 17810 17811 /* Free memory for local network address mask */ 17812 ast_free_ha(localaddr); 17813 17814 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17815 ASTOBJ_CONTAINER_DESTROY(&userl); 17816 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 17817 ASTOBJ_CONTAINER_DESTROY(&peerl); 17818 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17819 ASTOBJ_CONTAINER_DESTROY(®l); 17820 17821 clear_realm_authentication(authl); 17822 clear_sip_domains(); 17823 close(sipsock); 17824 sched_context_destroy(sched); 17825 17826 return 0; 17827 }
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 3124 of file chan_sip.c.
References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, 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().
03125 { 03126 char name[256]; 03127 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03128 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03129 struct sip_user *u = NULL; 03130 struct sip_peer *p = NULL; 03131 03132 if (option_debug > 2) 03133 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03134 03135 /* Test if we need to check call limits, in order to avoid 03136 realtime lookups if we do not need it */ 03137 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03138 return 0; 03139 03140 ast_copy_string(name, fup->username, sizeof(name)); 03141 03142 /* Check the list of users only for incoming calls */ 03143 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03144 inuse = &u->inUse; 03145 call_limit = &u->call_limit; 03146 inringing = NULL; 03147 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03148 inuse = &p->inUse; 03149 call_limit = &p->call_limit; 03150 inringing = &p->inRinging; 03151 ast_copy_string(name, fup->peername, sizeof(name)); 03152 } 03153 if (!p && !u) { 03154 if (option_debug > 1) 03155 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03156 return 0; 03157 } 03158 03159 switch(event) { 03160 /* incoming and outgoing affects the inUse counter */ 03161 case DEC_CALL_LIMIT: 03162 if ( *inuse > 0 ) { 03163 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03164 (*inuse)--; 03165 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03166 } 03167 } else { 03168 *inuse = 0; 03169 } 03170 if (inringing) { 03171 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03172 if (*inringing > 0) 03173 (*inringing)--; 03174 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03175 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03176 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03177 } 03178 } 03179 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03180 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03181 sip_peer_hold(fup, 0); 03182 } 03183 if (option_debug > 1 || sipdebug) { 03184 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03185 } 03186 break; 03187 03188 case INC_CALL_RINGING: 03189 case INC_CALL_LIMIT: 03190 if (*call_limit > 0 ) { 03191 if (*inuse >= *call_limit) { 03192 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); 03193 if (u) 03194 ASTOBJ_UNREF(u, sip_destroy_user); 03195 else 03196 ASTOBJ_UNREF(p, sip_destroy_peer); 03197 return -1; 03198 } 03199 } 03200 if (inringing && (event == INC_CALL_RINGING)) { 03201 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03202 (*inringing)++; 03203 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03204 } 03205 } 03206 /* Continue */ 03207 (*inuse)++; 03208 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03209 if (option_debug > 1 || sipdebug) { 03210 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03211 } 03212 break; 03213 03214 case DEC_CALL_RINGING: 03215 if (inringing) { 03216 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03217 if (*inringing > 0) 03218 (*inringing)--; 03219 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03220 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03221 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03222 } 03223 } 03224 break; 03225 03226 default: 03227 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03228 } 03229 if (p) { 03230 ast_device_state_changed("SIP/%s", p->name); 03231 ASTOBJ_UNREF(p, sip_destroy_peer); 03232 } else /* u must be set */ 03233 ASTOBJ_UNREF(u, sip_destroy_user); 03234 return 0; 03235 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2460 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().
02461 { 02462 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02463 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02464 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02465 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02466 } 02467 }
struct in_addr __ourip [static] |
Definition at line 1197 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 558 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 574 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17292 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17294 of file chan_sip.c.
Definition at line 1186 of file chan_sip.c.
Referenced by build_reply_digest(), sip_do_reload(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 538 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1191 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 17579 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 17584 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 552 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 224 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11459 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1200 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 518 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 515 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 187 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 519 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 215 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 517 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 526 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 523 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 524 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 520 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 527 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 521 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 516 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 522 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17291 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17297 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 554 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 1194 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1193 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1192 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1195 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 545 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 546 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 562 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 535 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 561 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 559 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 530 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 577 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), reload_config(), 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 222 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 531 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 564 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 548 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 534 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 533 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 555 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 543 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 544 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 556 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 539 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 532 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 541 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 542 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 540 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 560 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 550 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 549 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 551 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 557 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 11476 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 598 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1196 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 10110 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 9661 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 186 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 185 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 592 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 11468 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 11472 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 225 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 1202 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 11408 of file chan_sip.c.
int ourport [static] |
Definition at line 1199 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 537 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 11450 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 553 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(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 575 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 573 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 571 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 597 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 11432 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 11428 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 11403 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 11436 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 11423 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 11489 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 11445 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 11440 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 11455 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 11493 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 11485 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 11418 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 11413 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 11481 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 594 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 595 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 1600 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 1542 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 1568 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 1609 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 11730 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 11650 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1190 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 599 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 572 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is off, RFC behavior is on
Definition at line 536 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 570 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17290 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17295 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.