#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | 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_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. | |
struct ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
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 1827 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 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 |
#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 |
#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 |
#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 1011 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_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(), 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 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 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(), build_user(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 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(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 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) |
Definition at line 763 of file chan_sip.c.
Referenced by expire_register(), realtime_peer(), and reload_config().
#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(), realtime_peer(), realtime_user(), reload_config(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 765 of file chan_sip.c.
Referenced by realtime_update_peer(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 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(), realtime_peer(), realtime_user(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 739 of file chan_sip.c.
Referenced by 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().
#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(), reload_config(), 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 1588 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.
INV_NONE | No state at all, maybe not an INVITE dialog |
INV_CALLING | Invite sent, no answer |
INV_PROCEEDING | We got/sent 1xx message |
INV_EARLY_MEDIA | We got 18x message with to-tag back |
INV_COMPLETED | Got final response with error. Wait for ACK, then CONFIRMED |
INV_CONFIRMED | Confirmed response - we've got an ack (Incoming calls only) |
INV_TERMINATED | Transaction done - either successful (AST_STATE_UP) or failed, but done The only way out of this is a BYE from one side |
INV_CANCELLED | Transaction cancelled by client or server in non-terminated state |
Definition at line 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.
REFER_IDLE | No REFER is in progress |
REFER_SENT | Sent REFER to transferee |
REFER_RECEIVED | Received REFER from transferer |
REFER_CONFIRMED | Refer confirmed with a 100 TRYING |
REFER_ACCEPTED | Accepted by transferee |
REFER_RINGING | Target Ringing |
REFER_200OK | Answered by transfer target |
REFER_FAILED | REFER declined - go on |
REFER_NOAUTH | We had no auth for REFER |
Definition at line 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 |
XMIT_CRITICAL | Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session |
XMIT_RELIABLE | Transmit SIP message reliably, with re-transmits |
XMIT_UNRELIABLE | Transmit SIP message without bothering with re-transmits |
Definition at line 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 4121 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04122 { 04123 int pass; 04124 04125 /* 04126 * Technically you can place arbitrary whitespace both before and after the ':' in 04127 * a header, although RFC3261 clearly says you shouldn't before, and place just 04128 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04129 * a good idea to say you can do it, and if you can do it, why in the hell would. 04130 * you say you shouldn't. 04131 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04132 * and we always allow spaces after that for compatibility. 04133 */ 04134 for (pass = 0; name && pass < 2;pass++) { 04135 int x, len = strlen(name); 04136 for (x=*start; x<req->headers; x++) { 04137 if (!strncasecmp(req->header[x], name, len)) { 04138 char *r = req->header[x] + len; /* skip name */ 04139 if (pedanticsipchecking) 04140 r = ast_skip_blanks(r); 04141 04142 if (*r == ':') { 04143 *start = x+1; 04144 return ast_skip_blanks(r+1); 04145 } 04146 } 04147 } 04148 if (pass == 0) /* Try aliases */ 04149 name = find_alias(name, NULL); 04150 } 04151 04152 /* Don't return NULL, so get_header is always a valid pointer */ 04153 return ""; 04154 }
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 2104 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02105 { 02106 struct sip_pkt *cur, *prev = NULL; 02107 02108 /* Just in case... */ 02109 char *msg; 02110 int res = FALSE; 02111 02112 msg = sip_methods[sipmethod].text; 02113 02114 ast_mutex_lock(&p->lock); 02115 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02116 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02117 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02118 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02119 if (!resp && (seqno == p->pendinginvite)) { 02120 if (option_debug) 02121 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02122 p->pendinginvite = 0; 02123 } 02124 /* this is our baby */ 02125 res = TRUE; 02126 UNLINK(cur, p->packets, prev); 02127 if (cur->retransid > -1) { 02128 if (sipdebug && option_debug > 3) 02129 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02130 ast_sched_del(sched, cur->retransid); 02131 cur->retransid = -1; 02132 } 02133 free(cur); 02134 break; 02135 } 02136 } 02137 ast_mutex_unlock(&p->lock); 02138 if (option_debug) 02139 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02140 }
static int __sip_autodestruct | ( | void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2038 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, MWI_NOTIFICATION, NONE, option_debug, sip_pvt::owner, sip_pvt::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().
02039 { 02040 struct sip_pvt *p = data; 02041 02042 /* If this is a subscription, tell the phone that we got a timeout */ 02043 if (p->subscribed) { 02044 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02045 p->subscribed = NONE; 02046 append_history(p, "Subscribestatus", "timeout"); 02047 if (option_debug > 2) 02048 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02049 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02050 } 02051 02052 /* If we're destroying a subscription, dereference peer object too */ 02053 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02054 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02055 02056 /* Reset schedule ID */ 02057 p->autokillid = -1; 02058 02059 if (option_debug) 02060 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02061 append_history(p, "AutoDestroy", "%s", p->callid); 02062 if (p->owner) { 02063 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02064 ast_queue_hangup(p->owner); 02065 } else if (p->refer) { 02066 if (option_debug > 2) 02067 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02068 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02069 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02070 } else 02071 sip_destroy(p); 02072 return 0; 02073 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 2990 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_rtp_destroy(), ast_sched_del(), ast_string_field_free_pools, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::autokillid, sip_registry::call, sip_pvt::chanvars, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), sip_pvt::history, iflist, sip_pvt::initid, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pkt::next, sip_pvt::next, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::route, sip_pvt::rtp, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), sip_pvt::stateid, ast_channel::tech_pvt, cfsip_methods::text, sip_pvt::udptl, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
02991 { 02992 struct sip_pvt *cur, *prev = NULL; 02993 struct sip_pkt *cp; 02994 02995 if (sip_debug_test_pvt(p) || option_debug > 2) 02996 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 02997 02998 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 02999 update_call_counter(p, DEC_CALL_LIMIT); 03000 if (option_debug > 1) 03001 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03002 } 03003 03004 /* Remove link from peer to subscription of MWI */ 03005 if (p->relatedpeer && p->relatedpeer->mwipvt) 03006 p->relatedpeer->mwipvt = NULL; 03007 03008 if (dumphistory) 03009 sip_dump_history(p); 03010 03011 if (p->options) 03012 free(p->options); 03013 03014 if (p->stateid > -1) 03015 ast_extension_state_del(p->stateid, NULL); 03016 if (p->initid > -1) 03017 ast_sched_del(sched, p->initid); 03018 if (p->autokillid > -1) 03019 ast_sched_del(sched, p->autokillid); 03020 03021 if (p->rtp) 03022 ast_rtp_destroy(p->rtp); 03023 if (p->vrtp) 03024 ast_rtp_destroy(p->vrtp); 03025 if (p->udptl) 03026 ast_udptl_destroy(p->udptl); 03027 if (p->refer) 03028 free(p->refer); 03029 if (p->route) { 03030 free_old_route(p->route); 03031 p->route = NULL; 03032 } 03033 if (p->registry) { 03034 if (p->registry->call == p) 03035 p->registry->call = NULL; 03036 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03037 } 03038 03039 /* Unlink us from the owner if we have one */ 03040 if (p->owner) { 03041 if (lockowner) 03042 ast_channel_lock(p->owner); 03043 if (option_debug) 03044 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03045 p->owner->tech_pvt = NULL; 03046 if (lockowner) 03047 ast_channel_unlock(p->owner); 03048 } 03049 /* Clear history */ 03050 if (p->history) { 03051 struct sip_history *hist; 03052 while( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) 03053 free(hist); 03054 free(p->history); 03055 p->history = NULL; 03056 } 03057 03058 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03059 if (cur == p) { 03060 UNLINK(cur, iflist, prev); 03061 break; 03062 } 03063 } 03064 if (!cur) { 03065 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03066 return; 03067 } 03068 03069 /* remove all current packets in this dialog */ 03070 while((cp = p->packets)) { 03071 p->packets = p->packets->next; 03072 if (cp->retransid > -1) 03073 ast_sched_del(sched, cp->retransid); 03074 free(cp); 03075 } 03076 if (p->chanvars) { 03077 ast_variables_destroy(p->chanvars); 03078 p->chanvars = NULL; 03079 } 03080 ast_mutex_destroy(&p->lock); 03081 03082 ast_string_field_free_pools(p); 03083 03084 free(p); 03085 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7280 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07281 { 07282 int res; 07283 07284 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07285 return res; 07286 }
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 2144 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().
02145 { 02146 struct sip_pkt *cur = NULL; 02147 02148 while (p->packets) { 02149 int method; 02150 if (cur == p->packets) { 02151 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02152 return; 02153 } 02154 cur = p->packets; 02155 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02156 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02157 } 02158 }
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 1992 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_sched_del(), ast_set_flag, AST_SUCCESS, ast_test_flag, sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sip_pkt::retransid, sip_pkt::seqno, SIP_INVITE, sipdebug, sip_pvt::timer_t1, sip_pkt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
01993 { 01994 struct sip_pkt *pkt; 01995 int siptimer_a = DEFAULT_RETRANS; 01996 int xmitres = 0; 01997 01998 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 01999 return AST_FAILURE; 02000 memcpy(pkt->data, data, len); 02001 pkt->method = sipmethod; 02002 pkt->packetlen = len; 02003 pkt->next = p->packets; 02004 pkt->owner = p; 02005 pkt->seqno = seqno; 02006 if (resp) 02007 ast_set_flag(pkt, FLAG_RESPONSE); 02008 pkt->data[len] = '\0'; 02009 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02010 if (fatal) 02011 ast_set_flag(pkt, FLAG_FATAL); 02012 if (pkt->timer_t1) 02013 siptimer_a = pkt->timer_t1 * 2; 02014 02015 /* Schedule retransmission */ 02016 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02017 if (option_debug > 3 && sipdebug) 02018 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 02019 pkt->next = p->packets; 02020 p->packets = pkt; 02021 if (sipmethod == SIP_INVITE) { 02022 /* Note this is a pending invite */ 02023 p->pendinginvite = seqno; 02024 } 02025 02026 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02027 02028 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02029 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02030 ast_sched_del(sched, pkt->retransid); /* No more retransmission */ 02031 pkt->retransid = -1; 02032 return AST_FAILURE; 02033 } else 02034 return AST_SUCCESS; 02035 }
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 2161 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02162 { 02163 struct sip_pkt *cur; 02164 int res = -1; 02165 02166 for (cur = p->packets; cur; cur = cur->next) { 02167 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02168 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02169 /* this is our baby */ 02170 if (cur->retransid > -1) { 02171 if (option_debug > 3 && sipdebug) 02172 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02173 ast_sched_del(sched, cur->retransid); 02174 cur->retransid = -1; 02175 } 02176 res = 0; 02177 break; 02178 } 02179 } 02180 if (option_debug) 02181 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"); 02182 return res; 02183 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10558 of file chan_sip.c.
References ast_cli(), ast_extension_state2str(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, sip_pvt::laststate, sip_peer::mailbox, MWI_NOTIFICATION, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_refer::status, sip_pvt::subscribed, and subscription_type2str().
Referenced by sip_show_channels(), and sip_show_subscriptions().
10559 { 10560 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10561 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 10562 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10563 struct sip_pvt *cur; 10564 int numchans = 0; 10565 char *referstatus = NULL; 10566 10567 if (argc != 3) 10568 return RESULT_SHOWUSAGE; 10569 ast_mutex_lock(&iflock); 10570 cur = iflist; 10571 if (!subscriptions) 10572 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10573 else 10574 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10575 for (; cur; cur = cur->next) { 10576 referstatus = ""; 10577 if (cur->refer) { /* SIP transfer in progress */ 10578 referstatus = referstatus2str(cur->refer->status); 10579 } 10580 if (cur->subscribed == NONE && !subscriptions) { 10581 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10582 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10583 cur->callid, 10584 cur->ocseq, cur->icseq, 10585 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 10586 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10587 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10588 cur->lastmsg , 10589 referstatus 10590 ); 10591 numchans++; 10592 } 10593 if (cur->subscribed != NONE && subscriptions) { 10594 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10595 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10596 cur->callid, 10597 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10598 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10599 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10600 subscription_type2str(cur->subscribed), 10601 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10602 ); 10603 numchans++; 10604 } 10605 } 10606 ast_mutex_unlock(&iflock); 10607 if (!subscriptions) 10608 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10609 else 10610 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10611 return RESULT_SUCCESS; 10612 #undef FORMAT 10613 #undef FORMAT2 10614 #undef FORMAT3 10615 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1755 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().
01756 { 01757 int res; 01758 const struct sockaddr_in *dst = sip_real_dst(p); 01759 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01760 01761 if (res == -1) { 01762 switch (errno) { 01763 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01764 case EHOSTUNREACH: /* Host can't be reached */ 01765 case ENETDOWN: /* Inteface down */ 01766 case ENETUNREACH: /* Network failure */ 01767 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01768 } 01769 } 01770 if (res != len) 01771 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)); 01772 return res; 01773 }
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 5843 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
05844 { 05845 struct sip_request resp; 05846 int seqno = 0; 05847 05848 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05849 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05850 return -1; 05851 } 05852 respprep(&resp, p, msg, req); 05853 add_header_contentLength(&resp, 0); 05854 /* If we are cancelling an incoming invite for some reason, add information 05855 about the reason why we are doing this in clear text */ 05856 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05857 char buf[10]; 05858 05859 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05860 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05861 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05862 } 05863 return send_response(p, &resp, reliable, seqno); 05864 }
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 10116 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, cfsip_options::id, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10117 { 10118 char status[30] = ""; 10119 char cbuf[256]; 10120 struct sip_peer *peer; 10121 char codec_buf[512]; 10122 struct ast_codec_pref *pref; 10123 struct ast_variable *v; 10124 struct sip_auth *auth; 10125 int x = 0, codec = 0, load_realtime; 10126 int realtimepeers; 10127 10128 realtimepeers = ast_check_realtime("sippeers"); 10129 10130 if (argc < 4) 10131 return RESULT_SHOWUSAGE; 10132 10133 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10134 peer = find_peer(argv[3], NULL, load_realtime); 10135 if (s) { /* Manager */ 10136 if (peer) { 10137 const char *id = astman_get_header(m,"ActionID"); 10138 10139 astman_append(s, "Response: Success\r\n"); 10140 if (!ast_strlen_zero(id)) 10141 astman_append(s, "ActionID: %s\r\n",id); 10142 } else { 10143 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10144 astman_send_error(s, m, cbuf); 10145 return 0; 10146 } 10147 } 10148 if (peer && type==0 ) { /* Normal listing */ 10149 ast_cli(fd,"\n\n"); 10150 ast_cli(fd, " * Name : %s\n", peer->name); 10151 if (realtimepeers) { /* Realtime is enabled */ 10152 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10153 } 10154 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10155 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10156 for (auth = peer->auth; auth; auth = auth->next) { 10157 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10158 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10159 } 10160 ast_cli(fd, " Context : %s\n", peer->context); 10161 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10162 ast_cli(fd, " Language : %s\n", peer->language); 10163 if (!ast_strlen_zero(peer->accountcode)) 10164 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10165 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10166 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10167 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10168 if (!ast_strlen_zero(peer->fromuser)) 10169 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10170 if (!ast_strlen_zero(peer->fromdomain)) 10171 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10172 ast_cli(fd, " Callgroup : "); 10173 print_group(fd, peer->callgroup, 0); 10174 ast_cli(fd, " Pickupgroup : "); 10175 print_group(fd, peer->pickupgroup, 0); 10176 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10177 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10178 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10179 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10180 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10181 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10182 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10183 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10184 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))); 10185 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10186 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10187 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10188 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10189 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10190 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10191 #endif 10192 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10193 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10194 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10195 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10196 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10197 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10198 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10199 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10200 10201 /* - is enumerated */ 10202 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10203 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10204 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10205 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)); 10206 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10207 if (!ast_strlen_zero(global_regcontext)) 10208 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10209 ast_cli(fd, " Def. Username: %s\n", peer->username); 10210 ast_cli(fd, " SIP Options : "); 10211 if (peer->sipoptions) { 10212 int lastoption = -1; 10213 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10214 if (sip_options[x].id != lastoption) { 10215 if (peer->sipoptions & sip_options[x].id) 10216 ast_cli(fd, "%s ", sip_options[x].text); 10217 lastoption = x; 10218 } 10219 } 10220 } else 10221 ast_cli(fd, "(none)"); 10222 10223 ast_cli(fd, "\n"); 10224 ast_cli(fd, " Codecs : "); 10225 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10226 ast_cli(fd, "%s\n", codec_buf); 10227 ast_cli(fd, " Codec Order : ("); 10228 print_codec_to_cli(fd, &peer->prefs); 10229 ast_cli(fd, ")\n"); 10230 10231 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10232 ast_cli(fd, " Status : "); 10233 peer_status(peer, status, sizeof(status)); 10234 ast_cli(fd, "%s\n",status); 10235 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10236 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10237 if (peer->chanvars) { 10238 ast_cli(fd, " Variables :\n"); 10239 for (v = peer->chanvars ; v ; v = v->next) 10240 ast_cli(fd, " %s = %s\n", v->name, v->value); 10241 } 10242 ast_cli(fd,"\n"); 10243 ASTOBJ_UNREF(peer,sip_destroy_peer); 10244 } else if (peer && type == 1) { /* manager listing */ 10245 char buf[256]; 10246 astman_append(s, "Channeltype: SIP\r\n"); 10247 astman_append(s, "ObjectName: %s\r\n", peer->name); 10248 astman_append(s, "ChanObjectType: peer\r\n"); 10249 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10250 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10251 astman_append(s, "Context: %s\r\n", peer->context); 10252 astman_append(s, "Language: %s\r\n", peer->language); 10253 if (!ast_strlen_zero(peer->accountcode)) 10254 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10255 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10256 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10257 if (!ast_strlen_zero(peer->fromuser)) 10258 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10259 if (!ast_strlen_zero(peer->fromdomain)) 10260 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10261 astman_append(s, "Callgroup: "); 10262 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10263 astman_append(s, "Pickupgroup: "); 10264 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10265 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10266 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10267 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10268 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10269 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10270 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10271 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10272 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10273 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))); 10274 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10275 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10276 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10277 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10278 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10279 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10280 10281 /* - is enumerated */ 10282 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10283 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10284 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10285 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)); 10286 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)); 10287 astman_append(s, "Default-Username: %s\r\n", peer->username); 10288 if (!ast_strlen_zero(global_regcontext)) 10289 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10290 astman_append(s, "Codecs: "); 10291 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10292 astman_append(s, "%s\r\n", codec_buf); 10293 astman_append(s, "CodecOrder: "); 10294 pref = &peer->prefs; 10295 for(x = 0; x < 32 ; x++) { 10296 codec = ast_codec_pref_index(pref,x); 10297 if (!codec) 10298 break; 10299 astman_append(s, "%s", ast_getformatname(codec)); 10300 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10301 astman_append(s, ","); 10302 } 10303 10304 astman_append(s, "\r\n"); 10305 astman_append(s, "Status: "); 10306 peer_status(peer, status, sizeof(status)); 10307 astman_append(s, "%s\r\n", status); 10308 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10309 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10310 if (peer->chanvars) { 10311 for (v = peer->chanvars ; v ; v = v->next) { 10312 astman_append(s, "ChanVariable:\n"); 10313 astman_append(s, " %s,%s\r\n", v->name, v->value); 10314 } 10315 } 10316 10317 ASTOBJ_UNREF(peer,sip_destroy_peer); 10318 10319 } else { 10320 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10321 ast_cli(fd,"\n"); 10322 } 10323 10324 return RESULT_SUCCESS; 10325 }
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 9666 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09667 { 09668 regex_t regexbuf; 09669 int havepattern = FALSE; 09670 09671 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09672 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09673 09674 char name[256]; 09675 int total_peers = 0; 09676 int peers_mon_online = 0; 09677 int peers_mon_offline = 0; 09678 int peers_unmon_offline = 0; 09679 int peers_unmon_online = 0; 09680 const char *id; 09681 char idtext[256] = ""; 09682 int realtimepeers; 09683 09684 realtimepeers = ast_check_realtime("sippeers"); 09685 09686 if (s) { /* Manager - get ActionID */ 09687 id = astman_get_header(m,"ActionID"); 09688 if (!ast_strlen_zero(id)) 09689 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09690 } 09691 09692 switch (argc) { 09693 case 5: 09694 if (!strcasecmp(argv[3], "like")) { 09695 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09696 return RESULT_SHOWUSAGE; 09697 havepattern = TRUE; 09698 } else 09699 return RESULT_SHOWUSAGE; 09700 case 3: 09701 break; 09702 default: 09703 return RESULT_SHOWUSAGE; 09704 } 09705 09706 if (!s) /* Normal list */ 09707 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09708 09709 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09710 char status[20] = ""; 09711 char srch[2000]; 09712 char pstatus; 09713 09714 ASTOBJ_RDLOCK(iterator); 09715 09716 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09717 ASTOBJ_UNLOCK(iterator); 09718 continue; 09719 } 09720 09721 if (!ast_strlen_zero(iterator->username) && !s) 09722 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09723 else 09724 ast_copy_string(name, iterator->name, sizeof(name)); 09725 09726 pstatus = peer_status(iterator, status, sizeof(status)); 09727 if (pstatus == 1) 09728 peers_mon_online++; 09729 else if (pstatus == 0) 09730 peers_mon_offline++; 09731 else { 09732 if (iterator->addr.sin_port == 0) 09733 peers_unmon_offline++; 09734 else 09735 peers_unmon_online++; 09736 } 09737 09738 snprintf(srch, sizeof(srch), FORMAT, name, 09739 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09740 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09741 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09742 iterator->ha ? " A " : " ", /* permit/deny */ 09743 ntohs(iterator->addr.sin_port), status, 09744 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09745 09746 if (!s) {/* Normal CLI list */ 09747 ast_cli(fd, FORMAT, name, 09748 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09749 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09750 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09751 iterator->ha ? " A " : " ", /* permit/deny */ 09752 09753 ntohs(iterator->addr.sin_port), status, 09754 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09755 } else { /* Manager format */ 09756 /* The names here need to be the same as other channels */ 09757 astman_append(s, 09758 "Event: PeerEntry\r\n%s" 09759 "Channeltype: SIP\r\n" 09760 "ObjectName: %s\r\n" 09761 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 09762 "IPaddress: %s\r\n" 09763 "IPport: %d\r\n" 09764 "Dynamic: %s\r\n" 09765 "Natsupport: %s\r\n" 09766 "VideoSupport: %s\r\n" 09767 "ACL: %s\r\n" 09768 "Status: %s\r\n" 09769 "RealtimeDevice: %s\r\n\r\n", 09770 idtext, 09771 iterator->name, 09772 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 09773 ntohs(iterator->addr.sin_port), 09774 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 09775 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 09776 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 09777 iterator->ha ? "yes" : "no", /* permit/deny */ 09778 status, 09779 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 09780 } 09781 09782 ASTOBJ_UNLOCK(iterator); 09783 09784 total_peers++; 09785 } while(0) ); 09786 09787 if (!s) 09788 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 09789 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 09790 09791 if (havepattern) 09792 regfree(®exbuf); 09793 09794 if (total) 09795 *total = total_peers; 09796 09797 09798 return RESULT_SUCCESS; 09799 #undef FORMAT 09800 #undef FORMAT2 09801 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14337 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, LOG_ERROR, LOG_WARNING, parse(), ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, sip_pvt::rtp, ast_rtp_quality::rtt, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14338 { 14339 struct ast_rtp_quality qos; 14340 struct sip_pvt *p = chan->tech_pvt; 14341 char *all = "", *parse = ast_strdupa(preparse); 14342 AST_DECLARE_APP_ARGS(args, 14343 AST_APP_ARG(param); 14344 AST_APP_ARG(type); 14345 AST_APP_ARG(field); 14346 ); 14347 AST_STANDARD_APP_ARGS(args, parse); 14348 14349 /* Sanity check */ 14350 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14351 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14352 return 0; 14353 } 14354 14355 if (strcasecmp(args.param, "rtpqos")) 14356 return 0; 14357 14358 /* Default arguments of audio,all */ 14359 if (ast_strlen_zero(args.type)) 14360 args.type = "audio"; 14361 if (ast_strlen_zero(args.field)) 14362 args.field = "all"; 14363 14364 memset(buf, 0, buflen); 14365 memset(&qos, 0, sizeof(qos)); 14366 14367 if (strcasecmp(args.type, "AUDIO") == 0) { 14368 all = ast_rtp_get_quality(p->rtp, &qos); 14369 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14370 all = ast_rtp_get_quality(p->vrtp, &qos); 14371 } 14372 14373 if (strcasecmp(args.field, "local_ssrc") == 0) 14374 snprintf(buf, buflen, "%u", qos.local_ssrc); 14375 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14376 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14377 else if (strcasecmp(args.field, "local_jitter") == 0) 14378 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14379 else if (strcasecmp(args.field, "local_count") == 0) 14380 snprintf(buf, buflen, "%u", qos.local_count); 14381 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14382 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14383 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14384 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14385 else if (strcasecmp(args.field, "remote_jitter") == 0) 14386 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14387 else if (strcasecmp(args.field, "remote_count") == 0) 14388 snprintf(buf, buflen, "%u", qos.remote_count); 14389 else if (strcasecmp(args.field, "rtt") == 0) 14390 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14391 else if (strcasecmp(args.field, "all") == 0) 14392 ast_copy_string(buf, all, buflen); 14393 else { 14394 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14395 return -1; 14396 } 14397 return 0; 14398 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2196 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02197 { 02198 if (!req->lines) { 02199 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02200 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02201 req->len += strlen(req->data + req->len); 02202 } 02203 }
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 6047 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06050 { 06051 int rtp_code; 06052 struct ast_format_list fmt; 06053 06054 06055 if (debug) 06056 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06057 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06058 return; 06059 06060 if (p->rtp) { 06061 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06062 fmt = ast_codec_pref_getsize(pref, codec); 06063 } 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 */ 06064 return; 06065 ast_build_string(m_buf, m_size, " %d", rtp_code); 06066 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06067 ast_rtp_lookup_mime_subtype(1, codec, 06068 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06069 sample_rate); 06070 if (codec == AST_FORMAT_G729A) { 06071 /* Indicate that we don't support VAD (G.729 annex B) */ 06072 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06073 } else if (codec == AST_FORMAT_G723_1) { 06074 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06075 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06076 } else if (codec == AST_FORMAT_ILBC) { 06077 /* Add information about us using only 20/30 ms packetization */ 06078 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06079 } 06080 06081 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06082 *min_packet_size = fmt.cur_ms; 06083 06084 /* Our first codec packetization processed cannot be less than zero */ 06085 if ((*min_packet_size) == 0 && fmt.cur_ms) 06086 *min_packet_size = fmt.cur_ms; 06087 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6015 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06016 { 06017 char tmp[256]; 06018 06019 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06020 add_header(req, "Content-Type", "application/dtmf-relay"); 06021 add_header_contentLength(req, strlen(tmp)); 06022 add_line(req, tmp); 06023 return 0; 06024 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5406 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
05407 { 05408 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05409 05410 if (req->headers == SIP_MAX_HEADERS) { 05411 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05412 return -1; 05413 } 05414 05415 if (req->lines) { 05416 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05417 return -1; 05418 } 05419 05420 if (maxlen <= 0) { 05421 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05422 return -1; 05423 } 05424 05425 req->header[req->headers] = req->data + req->len; 05426 05427 if (compactheaders) 05428 var = find_alias(var, var); 05429 05430 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05431 req->len += strlen(req->header[req->headers]); 05432 req->headers++; 05433 if (req->headers < SIP_MAX_HEADERS) 05434 req->headers++; 05435 else 05436 ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n"); 05437 05438 return 0; 05439 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5442 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().
05443 { 05444 char clen[10]; 05445 05446 snprintf(clen, sizeof(clen), "%d", len); 05447 return add_header(req, "Content-Length", clen); 05448 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5451 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.
05452 { 05453 if (req->lines == SIP_MAX_LINES) { 05454 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05455 return -1; 05456 } 05457 if (!req->lines) { 05458 /* Add extra empty return */ 05459 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05460 req->len += strlen(req->data + req->len); 05461 } 05462 if (req->len >= sizeof(req->data) - 4) { 05463 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05464 return -1; 05465 } 05466 req->line[req->lines] = req->data + req->len; 05467 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05468 req->len += strlen(req->line[req->lines]); 05469 req->lines++; 05470 return 0; 05471 }
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 6223 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().
06226 { 06227 int rtp_code; 06228 06229 if (debug) 06230 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06231 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06232 return; 06233 06234 ast_build_string(m_buf, m_size, " %d", rtp_code); 06235 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06236 ast_rtp_lookup_mime_subtype(0, format, 0), 06237 sample_rate); 06238 if (format == AST_RTP_DTMF) 06239 /* Indicate we support DTMF and FLASH... */ 06240 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06241 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static, read] |
Add realm authentication in list.
Definition at line 15900 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, sip_auth::secret, secret, strsep(), sip_auth::username, and username.
Referenced by build_peer(), and reload_config().
15901 { 15902 char authcopy[256]; 15903 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 15904 char *stringp; 15905 struct sip_auth *a, *b, *auth; 15906 15907 if (ast_strlen_zero(configuration)) 15908 return authlist; 15909 15910 if (option_debug) 15911 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 15912 15913 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 15914 stringp = authcopy; 15915 15916 username = stringp; 15917 realm = strrchr(stringp, '@'); 15918 if (realm) 15919 *realm++ = '\0'; 15920 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 15921 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 15922 return authlist; 15923 } 15924 stringp = username; 15925 username = strsep(&stringp, ":"); 15926 if (username) { 15927 secret = strsep(&stringp, ":"); 15928 if (!secret) { 15929 stringp = username; 15930 md5secret = strsep(&stringp,"#"); 15931 } 15932 } 15933 if (!(auth = ast_calloc(1, sizeof(*auth)))) 15934 return authlist; 15935 15936 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 15937 ast_copy_string(auth->username, username, sizeof(auth->username)); 15938 if (secret) 15939 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 15940 if (md5secret) 15941 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 15942 15943 /* find the end of the list */ 15944 for (b = NULL, a = authlist; a ; b = a, a = a->next) 15945 ; 15946 if (b) 15947 b->next = auth; /* Add structure add end of list */ 15948 else 15949 authlist = auth; 15950 15951 if (option_verbose > 2) 15952 ast_verbose("Added authentication for realm %s\n", realm); 15953 15954 return authlist; 15955 15956 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5572 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05573 { 05574 char r[BUFSIZ*2], *p; 05575 int n, rem = sizeof(r); 05576 05577 if (!route) 05578 return; 05579 05580 p = r; 05581 for (;route ; route = route->next) { 05582 n = strlen(route->hop); 05583 if (rem < n+3) /* we need room for ",<route>" */ 05584 break; 05585 if (p != r) { /* add a separator after fist route */ 05586 *p++ = ','; 05587 --rem; 05588 } 05589 *p++ = '<'; 05590 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05591 p += n; 05592 *p++ = '>'; 05593 rem -= (n+2); 05594 } 05595 *p = '\0'; 05596 add_header(req, "Route", r); 05597 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6246 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06247 { 06248 int len = 0; 06249 int alreadysent = 0; 06250 06251 struct sockaddr_in sin; 06252 struct sockaddr_in vsin; 06253 struct sockaddr_in dest; 06254 struct sockaddr_in vdest = { 0, }; 06255 06256 /* SDP fields */ 06257 char *version = "v=0\r\n"; /* Protocol version */ 06258 char *subject = "s=session\r\n"; /* Subject of the session */ 06259 char owner[256]; /* Session owner/creator */ 06260 char connection[256]; /* Connection data */ 06261 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06262 char bandwidth[256] = ""; /* Max bitrate */ 06263 char *hold; 06264 char m_audio[256]; /* Media declaration line for audio */ 06265 char m_video[256]; /* Media declaration line for video */ 06266 char a_audio[1024]; /* Attributes for audio */ 06267 char a_video[1024]; /* Attributes for video */ 06268 char *m_audio_next = m_audio; 06269 char *m_video_next = m_video; 06270 size_t m_audio_left = sizeof(m_audio); 06271 size_t m_video_left = sizeof(m_video); 06272 char *a_audio_next = a_audio; 06273 char *a_video_next = a_video; 06274 size_t a_audio_left = sizeof(a_audio); 06275 size_t a_video_left = sizeof(a_video); 06276 06277 int x; 06278 int capability; 06279 int needvideo = FALSE; 06280 int debug = sip_debug_test_pvt(p); 06281 int min_audio_packet_size = 0; 06282 int min_video_packet_size = 0; 06283 06284 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06285 06286 if (!p->rtp) { 06287 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06288 return AST_FAILURE; 06289 } 06290 06291 /* Set RTP Session ID and version */ 06292 if (!p->sessionid) { 06293 p->sessionid = getpid(); 06294 p->sessionversion = p->sessionid; 06295 } else 06296 p->sessionversion++; 06297 06298 /* Get our addresses */ 06299 ast_rtp_get_us(p->rtp, &sin); 06300 if (p->vrtp) 06301 ast_rtp_get_us(p->vrtp, &vsin); 06302 06303 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06304 if (p->redirip.sin_addr.s_addr) { 06305 dest.sin_port = p->redirip.sin_port; 06306 dest.sin_addr = p->redirip.sin_addr; 06307 } else { 06308 dest.sin_addr = p->ourip; 06309 dest.sin_port = sin.sin_port; 06310 } 06311 06312 capability = p->jointcapability; 06313 06314 06315 if (option_debug > 1) { 06316 char codecbuf[BUFSIZ]; 06317 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"); 06318 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06319 } 06320 06321 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06322 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06323 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06324 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06325 } 06326 #endif 06327 06328 /* Check if we need video in this call */ 06329 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06330 if (p->vrtp) { 06331 needvideo = TRUE; 06332 if (option_debug > 1) 06333 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06334 } else if (option_debug > 1) 06335 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06336 } 06337 06338 06339 /* Ok, we need video. Let's add what we need for video and set codecs. 06340 Video is handled differently than audio since we can not transcode. */ 06341 if (needvideo) { 06342 /* Determine video destination */ 06343 if (p->vredirip.sin_addr.s_addr) { 06344 vdest.sin_addr = p->vredirip.sin_addr; 06345 vdest.sin_port = p->vredirip.sin_port; 06346 } else { 06347 vdest.sin_addr = p->ourip; 06348 vdest.sin_port = vsin.sin_port; 06349 } 06350 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06351 06352 /* Build max bitrate string */ 06353 if (p->maxcallbitrate) 06354 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06355 if (debug) 06356 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06357 } 06358 06359 if (debug) 06360 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06361 06362 /* Start building generic SDP headers */ 06363 06364 /* We break with the "recommendation" and send our IP, in order that our 06365 peer doesn't have to ast_gethostbyname() us */ 06366 06367 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06368 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06369 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06370 06371 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06372 hold = "a=recvonly\r\n"; 06373 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06374 hold = "a=inactive\r\n"; 06375 else 06376 hold = "a=sendrecv\r\n"; 06377 06378 /* Now, start adding audio codecs. These are added in this order: 06379 - First what was requested by the calling channel 06380 - Then preferences in order from sip.conf device config for this peer/user 06381 - Then other codecs in capabilities, including video 06382 */ 06383 06384 /* Prefer the audio codec we were requested to use, first, no matter what 06385 Note that p->prefcodec can include video codecs, so mask them out 06386 */ 06387 if (capability & p->prefcodec) { 06388 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06389 06390 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06391 &m_audio_next, &m_audio_left, 06392 &a_audio_next, &a_audio_left, 06393 debug, &min_audio_packet_size); 06394 alreadysent |= codec; 06395 } 06396 06397 /* Start by sending our preferred audio codecs */ 06398 for (x = 0; x < 32; x++) { 06399 int codec; 06400 06401 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06402 break; 06403 06404 if (!(capability & codec)) 06405 continue; 06406 06407 if (alreadysent & codec) 06408 continue; 06409 06410 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06411 &m_audio_next, &m_audio_left, 06412 &a_audio_next, &a_audio_left, 06413 debug, &min_audio_packet_size); 06414 alreadysent |= codec; 06415 } 06416 06417 /* Now send any other common audio and video codecs, and non-codec formats: */ 06418 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06419 if (!(capability & x)) /* Codec not requested */ 06420 continue; 06421 06422 if (alreadysent & x) /* Already added to SDP */ 06423 continue; 06424 06425 if (x <= AST_FORMAT_MAX_AUDIO) 06426 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06427 &m_audio_next, &m_audio_left, 06428 &a_audio_next, &a_audio_left, 06429 debug, &min_audio_packet_size); 06430 else 06431 add_codec_to_sdp(p, x, 90000, 06432 &m_video_next, &m_video_left, 06433 &a_video_next, &a_video_left, 06434 debug, &min_video_packet_size); 06435 } 06436 06437 /* Now add DTMF RFC2833 telephony-event as a codec */ 06438 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06439 if (!(p->jointnoncodeccapability & x)) 06440 continue; 06441 06442 add_noncodec_to_sdp(p, x, 8000, 06443 &m_audio_next, &m_audio_left, 06444 &a_audio_next, &a_audio_left, 06445 debug); 06446 } 06447 06448 if (option_debug > 2) 06449 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06450 06451 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06452 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06453 06454 if (min_audio_packet_size) 06455 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06456 06457 if (min_video_packet_size) 06458 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06459 06460 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06461 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06462 06463 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06464 if (needvideo) 06465 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06466 06467 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06468 if (needvideo) /* only if video response is appropriate */ 06469 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06470 06471 add_header(resp, "Content-Type", "application/sdp"); 06472 add_header_contentLength(resp, len); 06473 add_line(resp, version); 06474 add_line(resp, owner); 06475 add_line(resp, subject); 06476 add_line(resp, connection); 06477 if (needvideo) /* only if video response is appropriate */ 06478 add_line(resp, bandwidth); 06479 add_line(resp, stime); 06480 add_line(resp, m_audio); 06481 add_line(resp, a_audio); 06482 add_line(resp, hold); 06483 if (needvideo) { /* only if video response is appropriate */ 06484 add_line(resp, m_video); 06485 add_line(resp, a_video); 06486 add_line(resp, hold); /* Repeat hold for the video stream */ 06487 } 06488 06489 /* Update lastrtprx when we send our SDP */ 06490 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06491 06492 if (option_debug > 2) { 06493 char buf[BUFSIZ]; 06494 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06495 } 06496 06497 return AST_SUCCESS; 06498 }
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 15836 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::context, domain::domain, LOG_DEBUG, LOG_WARNING, domain::mode, and sipdebug.
Referenced by reload_config().
15837 { 15838 struct domain *d; 15839 15840 if (ast_strlen_zero(domain)) { 15841 ast_log(LOG_WARNING, "Zero length domain.\n"); 15842 return 1; 15843 } 15844 15845 if (!(d = ast_calloc(1, sizeof(*d)))) 15846 return 0; 15847 15848 ast_copy_string(d->domain, domain, sizeof(d->domain)); 15849 15850 if (!ast_strlen_zero(context)) 15851 ast_copy_string(d->context, context, sizeof(d->context)); 15852 15853 d->mode = mode; 15854 15855 AST_LIST_LOCK(&domain_list); 15856 AST_LIST_INSERT_TAIL(&domain_list, d, list); 15857 AST_LIST_UNLOCK(&domain_list); 15858 15859 if (sipdebug) 15860 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 15861 15862 return 1; 15863 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6126 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06127 { 06128 int len = 0; 06129 int x = 0; 06130 struct sockaddr_in udptlsin; 06131 char v[256] = ""; 06132 char s[256] = ""; 06133 char o[256] = ""; 06134 char c[256] = ""; 06135 char t[256] = ""; 06136 char m_modem[256]; 06137 char a_modem[1024]; 06138 char *m_modem_next = m_modem; 06139 size_t m_modem_left = sizeof(m_modem); 06140 char *a_modem_next = a_modem; 06141 size_t a_modem_left = sizeof(a_modem); 06142 struct sockaddr_in udptldest = { 0, }; 06143 int debug; 06144 06145 debug = sip_debug_test_pvt(p); 06146 len = 0; 06147 if (!p->udptl) { 06148 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06149 return -1; 06150 } 06151 06152 if (!p->sessionid) { 06153 p->sessionid = getpid(); 06154 p->sessionversion = p->sessionid; 06155 } else 06156 p->sessionversion++; 06157 06158 /* Our T.38 end is */ 06159 ast_udptl_get_us(p->udptl, &udptlsin); 06160 06161 /* Determine T.38 UDPTL destination */ 06162 if (p->udptlredirip.sin_addr.s_addr) { 06163 udptldest.sin_port = p->udptlredirip.sin_port; 06164 udptldest.sin_addr = p->udptlredirip.sin_addr; 06165 } else { 06166 udptldest.sin_addr = p->ourip; 06167 udptldest.sin_port = udptlsin.sin_port; 06168 } 06169 06170 if (debug) 06171 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06172 06173 /* We break with the "recommendation" and send our IP, in order that our 06174 peer doesn't have to ast_gethostbyname() us */ 06175 06176 if (debug) { 06177 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06178 p->t38.capability, 06179 p->t38.peercapability, 06180 p->t38.jointcapability); 06181 } 06182 snprintf(v, sizeof(v), "v=0\r\n"); 06183 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06184 snprintf(s, sizeof(s), "s=session\r\n"); 06185 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06186 snprintf(t, sizeof(t), "t=0 0\r\n"); 06187 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06188 06189 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06190 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06191 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06192 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06193 if ((x = t38_get_rate(p->t38.jointcapability))) 06194 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06195 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06196 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06197 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06198 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06199 x = ast_udptl_get_local_max_datagram(p->udptl); 06200 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06201 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06202 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06203 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06204 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06205 add_header(resp, "Content-Type", "application/sdp"); 06206 add_header_contentLength(resp, len); 06207 add_line(resp, v); 06208 add_line(resp, o); 06209 add_line(resp, s); 06210 add_line(resp, c); 06211 add_line(resp, t); 06212 add_line(resp, m_modem); 06213 add_line(resp, a_modem); 06214 06215 /* Update lastrtprx when we send our SDP */ 06216 p->lastrtprx = p->lastrtptx = time(NULL); 06217 06218 return 0; 06219 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6004 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06005 { 06006 /* XXX Convert \n's to \r\n's XXX */ 06007 add_header(req, "Content-Type", "text/plain"); 06008 add_header_contentLength(req, strlen(text)); 06009 add_line(req, text); 06010 return 0; 06011 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6028 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06029 { 06030 const char *xml_is_a_huge_waste_of_space = 06031 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06032 " <media_control>\r\n" 06033 " <vc_primitive>\r\n" 06034 " <to_encoder>\r\n" 06035 " <picture_fast_update>\r\n" 06036 " </picture_fast_update>\r\n" 06037 " </to_encoder>\r\n" 06038 " </vc_primitive>\r\n" 06039 " </media_control>\r\n"; 06040 add_header(req, "Content-Type", "application/media_control+xml"); 06041 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06042 add_line(req, xml_is_a_huge_waste_of_space); 06043 return 0; 06044 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 5951 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().
05952 { 05953 char tmpdat[256]; 05954 struct tm tm; 05955 time_t t = time(NULL); 05956 05957 gmtime_r(&t, &tm); 05958 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 05959 add_header(req, "Date", tmpdat); 05960 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1853 of file chan_sip.c.
References append_history_va().
01854 { 01855 va_list ap; 01856 01857 if (!p) 01858 return; 01859 va_start(ap, fmt); 01860 append_history_va(p, fmt, ap); 01861 va_end(ap); 01862 01863 return; 01864 }
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 1833 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, free, and strsep().
Referenced by append_history_full().
01834 { 01835 char buf[80], *c = buf; /* max history length */ 01836 struct sip_history *hist; 01837 int l; 01838 01839 vsnprintf(buf, sizeof(buf), fmt, ap); 01840 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01841 l = strlen(buf) + 1; 01842 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01843 return; 01844 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01845 free(hist); 01846 return; 01847 } 01848 memcpy(hist->event, buf, l); 01849 AST_LIST_INSERT_TAIL(p->history, hist, list); 01850 }
AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
sip_history | ||||
) |
history list, entry in sip_pvt
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Session Initiation Protocol (SIP)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 12907 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().
12908 { 12909 if (chan && chan->_state == AST_STATE_UP) { 12910 if (chan->generatordata) 12911 ast_deactivate_generator(chan); 12912 } 12913 }
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 1793 of file chan_sip.c.
References ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, bindaddr, externexpire, externhost, externip, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01794 { 01795 struct sockaddr_in theirs, ours; 01796 01797 /* Get our local information */ 01798 ast_ouraddrfor(them, us); 01799 theirs.sin_addr = *them; 01800 ours.sin_addr = *us; 01801 01802 if (localaddr && externip.sin_addr.s_addr && 01803 (ast_apply_ha(localaddr, &theirs)) && 01804 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01805 if (externexpire && time(NULL) >= externexpire) { 01806 struct ast_hostent ahp; 01807 struct hostent *hp; 01808 01809 externexpire = time(NULL) + externrefresh; 01810 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01811 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01812 } else 01813 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01814 } 01815 *us = externip.sin_addr; 01816 if (option_debug) { 01817 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01818 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01819 } 01820 } else if (bindaddr.sin_addr.s_addr) 01821 *us = bindaddr.sin_addr; 01822 return AST_SUCCESS; 01823 }
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 12917 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), ast_channel::cdr, sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
12918 { 12919 int res = 0; 12920 struct ast_channel *peera = NULL, 12921 *peerb = NULL, 12922 *peerc = NULL, 12923 *peerd = NULL; 12924 12925 12926 /* We will try to connect the transferee with the target and hangup 12927 all channels to the transferer */ 12928 if (option_debug > 3) { 12929 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 12930 if (transferer->chan1) 12931 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 12932 else 12933 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 12934 if (target->chan1) 12935 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 12936 else 12937 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 12938 if (transferer->chan2) 12939 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 12940 else 12941 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 12942 if (target->chan2) 12943 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)"); 12944 else 12945 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 12946 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 12947 } 12948 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 12949 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 12950 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 12951 peerc = transferer->chan2; /* Asterisk to Transferee */ 12952 peerd = target->chan2; /* Asterisk to Target */ 12953 if (option_debug > 2) 12954 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 12955 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 12956 peera = target->chan1; /* Transferer to PBX -> target channel */ 12957 peerb = transferer->chan1; /* Transferer to IVR*/ 12958 peerc = target->chan2; /* Asterisk to Target */ 12959 peerd = transferer->chan2; /* Nothing */ 12960 if (option_debug > 2) 12961 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 12962 } 12963 12964 if (peera && peerb && peerc && (peerb != peerc)) { 12965 ast_quiet_chan(peera); /* Stop generators */ 12966 ast_quiet_chan(peerb); 12967 ast_quiet_chan(peerc); 12968 if (peerd) 12969 ast_quiet_chan(peerd); 12970 12971 /* Fix CDRs so they're attached to the remaining channel */ 12972 if (peera->cdr && peerb->cdr) 12973 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 12974 else if (peera->cdr) 12975 peerb->cdr = peera->cdr; 12976 peera->cdr = NULL; 12977 12978 if (peerb->cdr && peerc->cdr) 12979 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 12980 else if (peerc->cdr) 12981 peerb->cdr = peerc->cdr; 12982 peerc->cdr = NULL; 12983 12984 if (option_debug > 3) 12985 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 12986 if (ast_channel_masquerade(peerb, peerc)) { 12987 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 12988 res = -1; 12989 } else 12990 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 12991 return res; 12992 } else { 12993 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 12994 if (transferer->chan1) 12995 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 12996 if (target->chan1) 12997 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 12998 return -2; 12999 } 13000 return 0; 13001 }
static int auto_congest | ( | void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2852 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.
02853 { 02854 struct sip_pvt *p = nothing; 02855 02856 ast_mutex_lock(&p->lock); 02857 p->initid = -1; 02858 if (p->owner) { 02859 /* XXX fails on possible deadlock */ 02860 if (!ast_channel_trylock(p->owner)) { 02861 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02862 append_history(p, "Cong", "Auto-congesting (timer)"); 02863 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02864 ast_channel_unlock(p->owner); 02865 } 02866 } 02867 ast_mutex_unlock(&p->lock); 02868 return 0; 02869 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4282 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().
04283 { 04284 char buf[33]; 04285 04286 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04287 04288 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04289 04290 }
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 4293 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04294 { 04295 char buf[33]; 04296 04297 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04298 04299 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04300 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6669 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::ourip, ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06670 { 06671 /* Construct Contact: header */ 06672 if (ourport != STANDARD_SIP_PORT) 06673 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); 06674 else 06675 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06676 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 16166 of file chan_sip.c.
References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
16167 { 16168 struct sip_peer *peer = NULL; 16169 struct ast_ha *oldha = NULL; 16170 int obproxyfound=0; 16171 int found=0; 16172 int firstpass=1; 16173 int format=0; /* Ama flags */ 16174 time_t regseconds = 0; 16175 char *varname = NULL, *varval = NULL; 16176 struct ast_variable *tmpvar = NULL; 16177 struct ast_flags peerflags[2] = {{(0)}}; 16178 struct ast_flags mask[2] = {{(0)}}; 16179 16180 16181 if (!realtime) 16182 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 16183 /* We also use a case-sensitive comparison (unlike find_peer) so 16184 that case changes made to the peer name will be properly handled 16185 during reload 16186 */ 16187 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 16188 16189 if (peer) { 16190 /* Already in the list, remove it and it will be added back (or FREE'd) */ 16191 found = 1; 16192 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 16193 firstpass = 0; 16194 } else { 16195 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16196 return NULL; 16197 16198 if (realtime) 16199 rpeerobjs++; 16200 else 16201 speerobjs++; 16202 ASTOBJ_INIT(peer); 16203 } 16204 /* Note that our peer HAS had its reference count incrased */ 16205 if (firstpass) { 16206 peer->lastmsgssent = -1; 16207 oldha = peer->ha; 16208 peer->ha = NULL; 16209 set_peer_defaults(peer); /* Set peer defaults */ 16210 } 16211 if (!found && name) 16212 ast_copy_string(peer->name, name, sizeof(peer->name)); 16213 16214 /* If we have channel variables, remove them (reload) */ 16215 if (peer->chanvars) { 16216 ast_variables_destroy(peer->chanvars); 16217 peer->chanvars = NULL; 16218 /* XXX should unregister ? */ 16219 } 16220 16221 /* If we have realm authentication information, remove them (reload) */ 16222 clear_realm_authentication(peer->auth); 16223 peer->auth = NULL; 16224 16225 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16226 if (handle_common_options(&peerflags[0], &mask[0], v)) 16227 continue; 16228 if (realtime && !strcasecmp(v->name, "regseconds")) { 16229 ast_get_time_t(v->value, ®seconds, 0, NULL); 16230 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16231 inet_aton(v->value, &(peer->addr.sin_addr)); 16232 } else if (realtime && !strcasecmp(v->name, "name")) 16233 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16234 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16235 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16236 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16237 } else if (!strcasecmp(v->name, "secret")) 16238 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16239 else if (!strcasecmp(v->name, "md5secret")) 16240 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16241 else if (!strcasecmp(v->name, "auth")) 16242 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16243 else if (!strcasecmp(v->name, "callerid")) { 16244 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16245 } else if (!strcasecmp(v->name, "fullname")) { 16246 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16247 } else if (!strcasecmp(v->name, "cid_number")) { 16248 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16249 } else if (!strcasecmp(v->name, "context")) { 16250 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16251 } else if (!strcasecmp(v->name, "subscribecontext")) { 16252 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16253 } else if (!strcasecmp(v->name, "fromdomain")) { 16254 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16255 } else if (!strcasecmp(v->name, "usereqphone")) { 16256 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16257 } else if (!strcasecmp(v->name, "fromuser")) { 16258 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16259 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16260 if (!strcasecmp(v->value, "dynamic")) { 16261 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16262 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16263 } else { 16264 /* They'll register with us */ 16265 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16266 /* Initialize stuff if this is a new peer, or if it used to be 16267 * non-dynamic before the reload. */ 16268 memset(&peer->addr.sin_addr, 0, 4); 16269 if (peer->addr.sin_port) { 16270 /* If we've already got a port, make it the default rather than absolute */ 16271 peer->defaddr.sin_port = peer->addr.sin_port; 16272 peer->addr.sin_port = 0; 16273 } 16274 } 16275 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16276 } 16277 } else { 16278 /* Non-dynamic. Make sure we become that way if we're not */ 16279 if (peer->expire > -1) 16280 ast_sched_del(sched, peer->expire); 16281 peer->expire = -1; 16282 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16283 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16284 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16285 ASTOBJ_UNREF(peer, sip_destroy_peer); 16286 return NULL; 16287 } 16288 } 16289 if (!strcasecmp(v->name, "outboundproxy")) 16290 obproxyfound=1; 16291 else { 16292 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16293 if (!peer->addr.sin_port) 16294 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16295 } 16296 } 16297 } else if (!strcasecmp(v->name, "defaultip")) { 16298 if (ast_get_ip(&peer->defaddr, v->value)) { 16299 ASTOBJ_UNREF(peer, sip_destroy_peer); 16300 return NULL; 16301 } 16302 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16303 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16304 } else if (!strcasecmp(v->name, "port")) { 16305 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16306 peer->defaddr.sin_port = htons(atoi(v->value)); 16307 else 16308 peer->addr.sin_port = htons(atoi(v->value)); 16309 } else if (!strcasecmp(v->name, "callingpres")) { 16310 peer->callingpres = ast_parse_caller_presentation(v->value); 16311 if (peer->callingpres == -1) 16312 peer->callingpres = atoi(v->value); 16313 } else if (!strcasecmp(v->name, "username")) { 16314 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16315 } else if (!strcasecmp(v->name, "language")) { 16316 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16317 } else if (!strcasecmp(v->name, "regexten")) { 16318 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16319 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16320 peer->call_limit = atoi(v->value); 16321 if (peer->call_limit < 0) 16322 peer->call_limit = 0; 16323 } else if (!strcasecmp(v->name, "amaflags")) { 16324 format = ast_cdr_amaflags2int(v->value); 16325 if (format < 0) { 16326 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16327 } else { 16328 peer->amaflags = format; 16329 } 16330 } else if (!strcasecmp(v->name, "accountcode")) { 16331 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16332 } else if (!strcasecmp(v->name, "mohinterpret") 16333 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16334 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16335 } else if (!strcasecmp(v->name, "mohsuggest")) { 16336 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16337 } else if (!strcasecmp(v->name, "mailbox")) { 16338 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16339 } else if (!strcasecmp(v->name, "subscribemwi")) { 16340 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16341 } else if (!strcasecmp(v->name, "vmexten")) { 16342 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16343 } else if (!strcasecmp(v->name, "callgroup")) { 16344 peer->callgroup = ast_get_group(v->value); 16345 } else if (!strcasecmp(v->name, "allowtransfer")) { 16346 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16347 } else if (!strcasecmp(v->name, "pickupgroup")) { 16348 peer->pickupgroup = ast_get_group(v->value); 16349 } else if (!strcasecmp(v->name, "allow")) { 16350 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16351 } else if (!strcasecmp(v->name, "disallow")) { 16352 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16353 } else if (!strcasecmp(v->name, "autoframing")) { 16354 peer->autoframing = ast_true(v->value); 16355 } else if (!strcasecmp(v->name, "rtptimeout")) { 16356 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16357 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16358 peer->rtptimeout = global_rtptimeout; 16359 } 16360 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16361 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16362 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16363 peer->rtpholdtimeout = global_rtpholdtimeout; 16364 } 16365 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16366 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16367 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16368 peer->rtpkeepalive = global_rtpkeepalive; 16369 } 16370 } else if (!strcasecmp(v->name, "setvar")) { 16371 /* Set peer channel variable */ 16372 varname = ast_strdupa(v->value); 16373 if ((varval = strchr(varname, '='))) { 16374 *varval++ = '\0'; 16375 if ((tmpvar = ast_variable_new(varname, varval))) { 16376 tmpvar->next = peer->chanvars; 16377 peer->chanvars = tmpvar; 16378 } 16379 } 16380 } else if (!strcasecmp(v->name, "qualify")) { 16381 if (!strcasecmp(v->value, "no")) { 16382 peer->maxms = 0; 16383 } else if (!strcasecmp(v->value, "yes")) { 16384 peer->maxms = DEFAULT_MAXMS; 16385 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16386 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); 16387 peer->maxms = 0; 16388 } 16389 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16390 peer->maxcallbitrate = atoi(v->value); 16391 if (peer->maxcallbitrate < 0) 16392 peer->maxcallbitrate = default_maxcallbitrate; 16393 } 16394 } 16395 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16396 time_t nowtime = time(NULL); 16397 16398 if ((nowtime - regseconds) > 0) { 16399 destroy_association(peer); 16400 memset(&peer->addr, 0, sizeof(peer->addr)); 16401 if (option_debug) 16402 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16403 } 16404 } 16405 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16406 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16407 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16408 global_allowsubscribe = TRUE; /* No global ban any more */ 16409 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16410 reg_source_db(peer); 16411 ASTOBJ_UNMARK(peer); 16412 ast_free_ha(oldha); 16413 return peer; 16414 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11298 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11299 { 11300 char a1[256]; 11301 char a2[256]; 11302 char a1_hash[256]; 11303 char a2_hash[256]; 11304 char resp[256]; 11305 char resp_hash[256]; 11306 char uri[256]; 11307 char cnonce[80]; 11308 const char *username; 11309 const char *secret; 11310 const char *md5secret; 11311 struct sip_auth *auth = NULL; /* Realm authentication */ 11312 11313 if (!ast_strlen_zero(p->domain)) 11314 ast_copy_string(uri, p->domain, sizeof(uri)); 11315 else if (!ast_strlen_zero(p->uri)) 11316 ast_copy_string(uri, p->uri, sizeof(uri)); 11317 else 11318 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11319 11320 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11321 11322 /* Check if we have separate auth credentials */ 11323 if ((auth = find_realm_authentication(authl, p->realm))) { 11324 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11325 auth->username, p->peername, p->username); 11326 username = auth->username; 11327 secret = auth->secret; 11328 md5secret = auth->md5secret; 11329 if (sipdebug) 11330 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11331 } else { 11332 /* No authentication, use peer or register= config */ 11333 username = p->authname; 11334 secret = p->peersecret; 11335 md5secret = p->peermd5secret; 11336 } 11337 if (ast_strlen_zero(username)) /* We have no authentication */ 11338 return -1; 11339 11340 /* Calculate SIP digest response */ 11341 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11342 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11343 if (!ast_strlen_zero(md5secret)) 11344 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11345 else 11346 ast_md5_hash(a1_hash,a1); 11347 ast_md5_hash(a2_hash,a2); 11348 11349 p->noncecount++; 11350 if (!ast_strlen_zero(p->qop)) 11351 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11352 else 11353 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11354 ast_md5_hash(resp_hash, resp); 11355 /* XXX We hard code our qop to "auth" for now. XXX */ 11356 if (!ast_strlen_zero(p->qop)) 11357 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); 11358 else 11359 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); 11360 11361 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11362 11363 return 0; 11364 }
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 8048 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().
08049 { 08050 struct sip_route *thishop, *head, *tail; 08051 int start = 0; 08052 int len; 08053 const char *rr, *contact, *c; 08054 08055 /* Once a persistant route is set, don't fool with it */ 08056 if (p->route && p->route_persistant) { 08057 if (option_debug) 08058 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08059 return; 08060 } 08061 08062 if (p->route) { 08063 free_old_route(p->route); 08064 p->route = NULL; 08065 } 08066 08067 p->route_persistant = backwards; 08068 08069 /* Build a tailq, then assign it to p->route when done. 08070 * If backwards, we add entries from the head so they end up 08071 * in reverse order. However, we do need to maintain a correct 08072 * tail pointer because the contact is always at the end. 08073 */ 08074 head = NULL; 08075 tail = head; 08076 /* 1st we pass through all the hops in any Record-Route headers */ 08077 for (;;) { 08078 /* Each Record-Route header */ 08079 rr = __get_header(req, "Record-Route", &start); 08080 if (*rr == '\0') 08081 break; 08082 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08083 ++rr; 08084 len = strcspn(rr, ">") + 1; 08085 /* Make a struct route */ 08086 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08087 /* ast_calloc is not needed because all fields are initialized in this block */ 08088 ast_copy_string(thishop->hop, rr, len); 08089 if (option_debug > 1) 08090 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08091 /* Link in */ 08092 if (backwards) { 08093 /* Link in at head so they end up in reverse order */ 08094 thishop->next = head; 08095 head = thishop; 08096 /* If this was the first then it'll be the tail */ 08097 if (!tail) 08098 tail = thishop; 08099 } else { 08100 thishop->next = NULL; 08101 /* Link in at the end */ 08102 if (tail) 08103 tail->next = thishop; 08104 else 08105 head = thishop; 08106 tail = thishop; 08107 } 08108 } 08109 } 08110 } 08111 08112 /* Only append the contact if we are dealing with a strict router */ 08113 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08114 /* 2nd append the Contact: if there is one */ 08115 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08116 contact = get_header(req, "Contact"); 08117 if (!ast_strlen_zero(contact)) { 08118 if (option_debug > 1) 08119 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08120 /* Look for <: delimited address */ 08121 c = strchr(contact, '<'); 08122 if (c) { 08123 /* Take to > */ 08124 ++c; 08125 len = strcspn(c, ">") + 1; 08126 } else { 08127 /* No <> - just take the lot */ 08128 c = contact; 08129 len = strlen(contact) + 1; 08130 } 08131 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08132 /* ast_calloc is not needed because all fields are initialized in this block */ 08133 ast_copy_string(thishop->hop, c, len); 08134 thishop->next = NULL; 08135 /* Goes at the end */ 08136 if (tail) 08137 tail->next = thishop; 08138 else 08139 head = thishop; 08140 } 08141 } 08142 } 08143 08144 /* Store as new route */ 08145 p->route = head; 08146 08147 /* For debugging dump what we ended up with */ 08148 if (sip_debug_test_pvt(p)) 08149 list_route(p->route); 08150 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6679 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06680 { 06681 int send_pres_tags = TRUE; 06682 const char *privacy=NULL; 06683 const char *screen=NULL; 06684 char buf[256]; 06685 const char *clid = default_callerid; 06686 const char *clin = NULL; 06687 const char *fromdomain; 06688 06689 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06690 return; 06691 06692 if (p->owner && p->owner->cid.cid_num) 06693 clid = p->owner->cid.cid_num; 06694 if (p->owner && p->owner->cid.cid_name) 06695 clin = p->owner->cid.cid_name; 06696 if (ast_strlen_zero(clin)) 06697 clin = clid; 06698 06699 switch (p->callingpres) { 06700 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06701 privacy = "off"; 06702 screen = "no"; 06703 break; 06704 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06705 privacy = "off"; 06706 screen = "yes"; 06707 break; 06708 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06709 privacy = "off"; 06710 screen = "no"; 06711 break; 06712 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06713 privacy = "off"; 06714 screen = "yes"; 06715 break; 06716 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06717 privacy = "full"; 06718 screen = "no"; 06719 break; 06720 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06721 privacy = "full"; 06722 screen = "yes"; 06723 break; 06724 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06725 privacy = "full"; 06726 screen = "no"; 06727 break; 06728 case AST_PRES_PROHIB_NETWORK_NUMBER: 06729 privacy = "full"; 06730 screen = "yes"; 06731 break; 06732 case AST_PRES_NUMBER_NOT_AVAILABLE: 06733 send_pres_tags = FALSE; 06734 break; 06735 default: 06736 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06737 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06738 privacy = "full"; 06739 else 06740 privacy = "off"; 06741 screen = "no"; 06742 break; 06743 } 06744 06745 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06746 06747 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06748 if (send_pres_tags) 06749 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06750 ast_string_field_set(p, rpid, buf); 06751 06752 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06753 S_OR(p->fromuser, clid), 06754 fromdomain, p->tag); 06755 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static, read] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 15987 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::capability, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, default_prefs, ast_flags::flags, sip_user::flags, format, sip_user::ha, handle_common_options(), sip_user::language, ast_variable::lineno, LOG_WARNING, sip_user::maxcallbitrate, sip_user::md5secret, sip_user::mohinterpret, sip_user::mohsuggest, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, sip_user::subscribecontext, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
15988 { 15989 struct sip_user *user; 15990 int format; 15991 struct ast_ha *oldha = NULL; 15992 char *varname = NULL, *varval = NULL; 15993 struct ast_variable *tmpvar = NULL; 15994 struct ast_flags userflags[2] = {{(0)}}; 15995 struct ast_flags mask[2] = {{(0)}}; 15996 15997 15998 if (!(user = ast_calloc(1, sizeof(*user)))) 15999 return NULL; 16000 16001 suserobjs++; 16002 ASTOBJ_INIT(user); 16003 ast_copy_string(user->name, name, sizeof(user->name)); 16004 oldha = user->ha; 16005 user->ha = NULL; 16006 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16007 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16008 user->capability = global_capability; 16009 user->allowtransfer = global_allowtransfer; 16010 user->maxcallbitrate = default_maxcallbitrate; 16011 user->autoframing = global_autoframing; 16012 user->prefs = default_prefs; 16013 /* set default context */ 16014 strcpy(user->context, default_context); 16015 strcpy(user->language, default_language); 16016 strcpy(user->mohinterpret, default_mohinterpret); 16017 strcpy(user->mohsuggest, default_mohsuggest); 16018 for (; v; v = v->next) { 16019 if (handle_common_options(&userflags[0], &mask[0], v)) 16020 continue; 16021 16022 if (!strcasecmp(v->name, "context")) { 16023 ast_copy_string(user->context, v->value, sizeof(user->context)); 16024 } else if (!strcasecmp(v->name, "subscribecontext")) { 16025 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 16026 } else if (!strcasecmp(v->name, "setvar")) { 16027 varname = ast_strdupa(v->value); 16028 if ((varval = strchr(varname,'='))) { 16029 *varval++ = '\0'; 16030 if ((tmpvar = ast_variable_new(varname, varval))) { 16031 tmpvar->next = user->chanvars; 16032 user->chanvars = tmpvar; 16033 } 16034 } 16035 } else if (!strcasecmp(v->name, "permit") || 16036 !strcasecmp(v->name, "deny")) { 16037 user->ha = ast_append_ha(v->name, v->value, user->ha); 16038 } else if (!strcasecmp(v->name, "allowtransfer")) { 16039 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16040 } else if (!strcasecmp(v->name, "secret")) { 16041 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 16042 } else if (!strcasecmp(v->name, "md5secret")) { 16043 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 16044 } else if (!strcasecmp(v->name, "callerid")) { 16045 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 16046 } else if (!strcasecmp(v->name, "fullname")) { 16047 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 16048 } else if (!strcasecmp(v->name, "cid_number")) { 16049 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 16050 } else if (!strcasecmp(v->name, "callgroup")) { 16051 user->callgroup = ast_get_group(v->value); 16052 } else if (!strcasecmp(v->name, "pickupgroup")) { 16053 user->pickupgroup = ast_get_group(v->value); 16054 } else if (!strcasecmp(v->name, "language")) { 16055 ast_copy_string(user->language, v->value, sizeof(user->language)); 16056 } else if (!strcasecmp(v->name, "mohinterpret") 16057 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16058 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 16059 } else if (!strcasecmp(v->name, "mohsuggest")) { 16060 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 16061 } else if (!strcasecmp(v->name, "accountcode")) { 16062 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 16063 } else if (!strcasecmp(v->name, "call-limit")) { 16064 user->call_limit = atoi(v->value); 16065 if (user->call_limit < 0) 16066 user->call_limit = 0; 16067 } else if (!strcasecmp(v->name, "amaflags")) { 16068 format = ast_cdr_amaflags2int(v->value); 16069 if (format < 0) { 16070 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 16071 } else { 16072 user->amaflags = format; 16073 } 16074 } else if (!strcasecmp(v->name, "allow")) { 16075 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 16076 } else if (!strcasecmp(v->name, "disallow")) { 16077 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 16078 } else if (!strcasecmp(v->name, "autoframing")) { 16079 user->autoframing = ast_true(v->value); 16080 } else if (!strcasecmp(v->name, "callingpres")) { 16081 user->callingpres = ast_parse_caller_presentation(v->value); 16082 if (user->callingpres == -1) 16083 user->callingpres = atoi(v->value); 16084 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16085 user->maxcallbitrate = atoi(v->value); 16086 if (user->maxcallbitrate < 0) 16087 user->maxcallbitrate = default_maxcallbitrate; 16088 } 16089 /* We can't just report unknown options here because this may be a 16090 * type=friend entry. All user options are valid for a peer, but not 16091 * the other way around. */ 16092 } 16093 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 16094 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 16095 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16096 global_allowsubscribe = TRUE; /* No global ban any more */ 16097 ast_free_ha(oldha); 16098 return user; 16099 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1777 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().
01778 { 01779 /* Work around buggy UNIDEN UIP200 firmware */ 01780 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01781 01782 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01783 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01784 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01785 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8340 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().
08341 { 08342 struct sip_pvt *p = data; 08343 08344 ast_mutex_lock(&p->lock); 08345 08346 switch(state) { 08347 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08348 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08349 if (p->autokillid > -1) 08350 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08351 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08352 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); 08353 p->stateid = -1; 08354 p->subscribed = NONE; 08355 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08356 break; 08357 default: /* Tell user */ 08358 p->laststate = state; 08359 break; 08360 } 08361 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08362 transmit_state_notify(p, state, 1, FALSE); 08363 08364 if (option_verbose > 1) 08365 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08366 08367 ast_mutex_unlock(&p->lock); 08368 08369 return 0; 08370 }
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 4823 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), sip_pvt::owner, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
04824 { 04825 if (global_notifyhold) 04826 sip_peer_hold(dialog, holdstate); 04827 if (global_callevents) 04828 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 04829 "Channel: %s\r\n" 04830 "Uniqueid: %s\r\n", 04831 dialog->owner->name, 04832 dialog->owner->uniqueid); 04833 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 04834 if (!holdstate) { /* Put off remote hold */ 04835 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 04836 return; 04837 } 04838 /* No address for RTP, we're on hold */ 04839 04840 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 04841 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 04842 else if (sendonly == 2) /* Inactive stream */ 04843 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 04844 else 04845 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 04846 return; 04847 }
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 8158 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, LOG_WARNING, s, S_OR, sip_methods, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08161 { 08162 const char *response = "407 Proxy Authentication Required"; 08163 const char *reqheader = "Proxy-Authorization"; 08164 const char *respheader = "Proxy-Authenticate"; 08165 const char *authtoken; 08166 char a1_hash[256]; 08167 char resp_hash[256]=""; 08168 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08169 char *c; 08170 int wrongnonce = FALSE; 08171 int good_response; 08172 const char *usednonce = p->randdata; 08173 08174 /* table of recognised keywords, and their value in the digest */ 08175 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08176 struct x { 08177 const char *key; 08178 const char *s; 08179 } *i, keys[] = { 08180 [K_RESP] = { "response=", "" }, 08181 [K_URI] = { "uri=", "" }, 08182 [K_USER] = { "username=", "" }, 08183 [K_NONCE] = { "nonce=", "" }, 08184 [K_LAST] = { NULL, NULL} 08185 }; 08186 08187 /* Always OK if no secret */ 08188 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08189 return AUTH_SUCCESSFUL; 08190 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08191 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08192 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08193 different circumstances! What a surprise. */ 08194 response = "401 Unauthorized"; 08195 reqheader = "Authorization"; 08196 respheader = "WWW-Authenticate"; 08197 } 08198 authtoken = get_header(req, reqheader); 08199 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08200 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08201 information */ 08202 if (!reliable) { 08203 /* Resend message if this was NOT a reliable delivery. Otherwise the 08204 retransmission should get it */ 08205 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08206 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08207 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08208 } 08209 return AUTH_CHALLENGE_SENT; 08210 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08211 /* We have no auth, so issue challenge and request authentication */ 08212 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08213 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08214 /* Schedule auto destroy in 32 seconds */ 08215 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08216 return AUTH_CHALLENGE_SENT; 08217 } 08218 08219 /* --- We have auth, so check it */ 08220 08221 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08222 an example in the spec of just what it is you're doing a hash on. */ 08223 08224 08225 /* Make a copy of the response and parse it */ 08226 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08227 c = tmp; 08228 08229 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08230 for (i = keys; i->key != NULL; i++) { 08231 const char *separator = ","; /* default */ 08232 08233 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08234 continue; 08235 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08236 c += strlen(i->key); 08237 if (*c == '"') { /* in quotes. Skip first and look for last */ 08238 c++; 08239 separator = "\""; 08240 } 08241 i->s = c; 08242 strsep(&c, separator); 08243 break; 08244 } 08245 if (i->key == NULL) /* not found, jump after space or comma */ 08246 strsep(&c, " ,"); 08247 } 08248 08249 /* Verify that digest username matches the username we auth as */ 08250 if (strcmp(username, keys[K_USER].s)) { 08251 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08252 username, keys[K_USER].s); 08253 /* Oops, we're trying something here */ 08254 return AUTH_USERNAME_MISMATCH; 08255 } 08256 08257 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08258 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08259 wrongnonce = TRUE; 08260 usednonce = keys[K_NONCE].s; 08261 } 08262 08263 if (!ast_strlen_zero(md5secret)) 08264 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08265 else { 08266 char a1[256]; 08267 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08268 ast_md5_hash(a1_hash, a1); 08269 } 08270 08271 /* compute the expected response to compare with what we received */ 08272 { 08273 char a2[256]; 08274 char a2_hash[256]; 08275 char resp[256]; 08276 08277 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08278 S_OR(keys[K_URI].s, uri)); 08279 ast_md5_hash(a2_hash, a2); 08280 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08281 ast_md5_hash(resp_hash, resp); 08282 } 08283 08284 good_response = keys[K_RESP].s && 08285 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08286 if (wrongnonce) { 08287 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08288 if (good_response) { 08289 if (sipdebug) 08290 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08291 /* We got working auth token, based on stale nonce . */ 08292 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08293 } else { 08294 /* Everything was wrong, so give the device one more try with a new challenge */ 08295 if (sipdebug) 08296 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08297 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08298 } 08299 08300 /* Schedule auto destroy in 32 seconds */ 08301 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08302 return AUTH_CHALLENGE_SENT; 08303 } 08304 if (good_response) { 08305 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08306 return AUTH_SUCCESSFUL; 08307 } 08308 08309 /* Ok, we have a bad username/secret pair */ 08310 /* Challenge again, and again, and again */ 08311 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08312 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08313 08314 return AUTH_CHALLENGE_SENT; 08315 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 11759 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, sip_pvt::ocseq, 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().
11760 { 11761 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 11762 /* if we can't BYE, then this is really a pending CANCEL */ 11763 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 11764 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 11765 /* Actually don't destroy us yet, wait for the 487 on our original 11766 INVITE, but do set an autodestruct just in case we never get it. */ 11767 else 11768 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 11769 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 11770 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11771 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 11772 if (option_debug) 11773 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 11774 /* Didn't get to reinvite yet, so do it now */ 11775 transmit_reinvite_with_sdp(p); 11776 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 11777 } 11778 }
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 15866 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, and domain::domain.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
15867 { 15868 struct domain *d; 15869 int result = 0; 15870 15871 AST_LIST_LOCK(&domain_list); 15872 AST_LIST_TRAVERSE(&domain_list, d, list) { 15873 if (strcasecmp(d->domain, domain)) 15874 continue; 15875 15876 if (len && !ast_strlen_zero(d->context)) 15877 ast_copy_string(context, d->context, len); 15878 15879 result = 1; 15880 break; 15881 } 15882 AST_LIST_UNLOCK(&domain_list); 15883 15884 return result; 15885 }
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 9414 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09415 { 09416 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09417 }
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 9093 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_pvt::allowtransfer, sip_peer::amaflags, sip_user::amaflags, sip_pvt::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, sip_pvt::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_pvt::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_pvt::callingpres, sip_peer::capability, sip_user::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, domain::context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_pvt::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_pvt::noncodeccapability, t38properties::peercapability, sip_pvt::peercapability, sip_peer::pickupgroup, sip_user::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_pvt::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_pvt::t38, sip_pvt::timer_t1, sip_peer::username, username, and sip_pvt::vrtp.
Referenced by check_user(), and handle_request_subscribe().
09096 { 09097 struct sip_user *user = NULL; 09098 struct sip_peer *peer; 09099 char from[256], *c; 09100 char *of; 09101 char rpid_num[50]; 09102 const char *rpid; 09103 enum check_auth_result res = AUTH_SUCCESSFUL; 09104 char *t; 09105 char calleridname[50]; 09106 int debug=sip_debug_test_addr(sin); 09107 struct ast_variable *tmpvar = NULL, *v = NULL; 09108 char *uri2 = ast_strdupa(uri); 09109 09110 /* Terminate URI */ 09111 t = uri2; 09112 while (*t && *t > 32 && *t != ';') 09113 t++; 09114 *t = '\0'; 09115 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09116 if (pedanticsipchecking) 09117 ast_uri_decode(from); 09118 /* XXX here tries to map the username for invite things */ 09119 memset(calleridname, 0, sizeof(calleridname)); 09120 get_calleridname(from, calleridname, sizeof(calleridname)); 09121 if (calleridname[0]) 09122 ast_string_field_set(p, cid_name, calleridname); 09123 09124 rpid = get_header(req, "Remote-Party-ID"); 09125 memset(rpid_num, 0, sizeof(rpid_num)); 09126 if (!ast_strlen_zero(rpid)) 09127 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09128 09129 of = get_in_brackets(from); 09130 if (ast_strlen_zero(p->exten)) { 09131 t = uri2; 09132 if (!strncasecmp(t, "sip:", 4)) 09133 t+= 4; 09134 ast_string_field_set(p, exten, t); 09135 t = strchr(p->exten, '@'); 09136 if (t) 09137 *t = '\0'; 09138 if (ast_strlen_zero(p->our_contact)) 09139 build_contact(p); 09140 } 09141 /* save the URI part of the From header */ 09142 ast_string_field_set(p, from, of); 09143 if (strncasecmp(of, "sip:", 4)) { 09144 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09145 } else 09146 of += 4; 09147 /* Get just the username part */ 09148 if ((c = strchr(of, '@'))) { 09149 char *tmp; 09150 *c = '\0'; 09151 if ((c = strchr(of, ':'))) 09152 *c = '\0'; 09153 tmp = ast_strdupa(of); 09154 /* We need to be able to handle auth-headers looking like 09155 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09156 */ 09157 tmp = strsep(&tmp, ";"); 09158 if (ast_is_shrinkable_phonenumber(tmp)) 09159 ast_shrink_phone_number(tmp); 09160 ast_string_field_set(p, cid_num, tmp); 09161 } 09162 if (ast_strlen_zero(of)) 09163 return AUTH_SUCCESSFUL; 09164 09165 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09166 user = find_user(of, 1); 09167 09168 /* Find user based on user name in the from header */ 09169 if (user && ast_apply_ha(user->ha, sin)) { 09170 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09171 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09172 /* copy channel vars */ 09173 for (v = user->chanvars ; v ; v = v->next) { 09174 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09175 tmpvar->next = p->chanvars; 09176 p->chanvars = tmpvar; 09177 } 09178 } 09179 p->prefs = user->prefs; 09180 /* Set Frame packetization */ 09181 if (p->rtp) { 09182 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09183 p->autoframing = user->autoframing; 09184 } 09185 /* replace callerid if rpid found, and not restricted */ 09186 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09187 char *tmp; 09188 if (*calleridname) 09189 ast_string_field_set(p, cid_name, calleridname); 09190 tmp = ast_strdupa(rpid_num); 09191 if (ast_is_shrinkable_phonenumber(tmp)) 09192 ast_shrink_phone_number(tmp); 09193 ast_string_field_set(p, cid_num, tmp); 09194 } 09195 09196 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09197 09198 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09199 sip_cancel_destroy(p); 09200 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09201 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09202 /* Copy SIP extensions profile from INVITE */ 09203 if (p->sipoptions) 09204 user->sipoptions = p->sipoptions; 09205 09206 /* If we have a call limit, set flag */ 09207 if (user->call_limit) 09208 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09209 if (!ast_strlen_zero(user->context)) 09210 ast_string_field_set(p, context, user->context); 09211 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09212 char *tmp = ast_strdupa(user->cid_num); 09213 if (ast_is_shrinkable_phonenumber(tmp)) 09214 ast_shrink_phone_number(tmp); 09215 ast_string_field_set(p, cid_num, tmp); 09216 } 09217 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09218 ast_string_field_set(p, cid_name, user->cid_name); 09219 ast_string_field_set(p, username, user->name); 09220 ast_string_field_set(p, peername, user->name); 09221 ast_string_field_set(p, peersecret, user->secret); 09222 ast_string_field_set(p, peermd5secret, user->md5secret); 09223 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09224 ast_string_field_set(p, accountcode, user->accountcode); 09225 ast_string_field_set(p, language, user->language); 09226 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09227 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09228 p->allowtransfer = user->allowtransfer; 09229 p->amaflags = user->amaflags; 09230 p->callgroup = user->callgroup; 09231 p->pickupgroup = user->pickupgroup; 09232 if (user->callingpres) /* User callingpres setting will override RPID header */ 09233 p->callingpres = user->callingpres; 09234 09235 /* Set default codec settings for this call */ 09236 p->capability = user->capability; /* User codec choice */ 09237 p->jointcapability = user->capability; /* Our codecs */ 09238 if (p->peercapability) /* AND with peer's codecs */ 09239 p->jointcapability &= p->peercapability; 09240 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09241 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09242 p->noncodeccapability |= AST_RTP_DTMF; 09243 else 09244 p->noncodeccapability &= ~AST_RTP_DTMF; 09245 p->jointnoncodeccapability = p->noncodeccapability; 09246 if (p->t38.peercapability) 09247 p->t38.jointcapability &= p->t38.peercapability; 09248 p->maxcallbitrate = user->maxcallbitrate; 09249 /* If we do not support video, remove video from call structure */ 09250 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09251 ast_rtp_destroy(p->vrtp); 09252 p->vrtp = NULL; 09253 } 09254 } 09255 if (user && debug) 09256 ast_verbose("Found user '%s'\n", user->name); 09257 } else { 09258 if (user) { 09259 if (!authpeer && debug) 09260 ast_verbose("Found user '%s', but fails host access\n", user->name); 09261 ASTOBJ_UNREF(user,sip_destroy_user); 09262 } 09263 user = NULL; 09264 } 09265 09266 if (!user) { 09267 /* If we didn't find a user match, check for peers */ 09268 if (sipmethod == SIP_SUBSCRIBE) 09269 /* For subscribes, match on peer name only */ 09270 peer = find_peer(of, NULL, 1); 09271 else 09272 /* Look for peer based on the IP address we received data from */ 09273 /* If peer is registered from this IP address or have this as a default 09274 IP address, this call is from the peer 09275 */ 09276 peer = find_peer(NULL, &p->recv, 1); 09277 09278 if (peer) { 09279 /* Set Frame packetization */ 09280 if (p->rtp) { 09281 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09282 p->autoframing = peer->autoframing; 09283 } 09284 if (debug) 09285 ast_verbose("Found peer '%s'\n", peer->name); 09286 09287 /* Take the peer */ 09288 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09289 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09290 09291 /* Copy SIP extensions profile to peer */ 09292 if (p->sipoptions) 09293 peer->sipoptions = p->sipoptions; 09294 09295 /* replace callerid if rpid found, and not restricted */ 09296 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09297 char *tmp = ast_strdupa(rpid_num); 09298 if (*calleridname) 09299 ast_string_field_set(p, cid_name, calleridname); 09300 if (ast_is_shrinkable_phonenumber(tmp)) 09301 ast_shrink_phone_number(tmp); 09302 ast_string_field_set(p, cid_num, tmp); 09303 } 09304 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09305 09306 ast_string_field_set(p, peersecret, peer->secret); 09307 ast_string_field_set(p, peermd5secret, peer->md5secret); 09308 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09309 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09310 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09311 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09312 p->callingpres = peer->callingpres; 09313 if (peer->maxms && peer->lastms) 09314 p->timer_t1 = peer->lastms; 09315 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09316 /* Pretend there is no required authentication */ 09317 ast_string_field_free(p, peersecret); 09318 ast_string_field_free(p, peermd5secret); 09319 } 09320 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09321 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09322 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09323 /* If we have a call limit, set flag */ 09324 if (peer->call_limit) 09325 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09326 ast_string_field_set(p, peername, peer->name); 09327 ast_string_field_set(p, authname, peer->name); 09328 09329 /* copy channel vars */ 09330 for (v = peer->chanvars ; v ; v = v->next) { 09331 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09332 tmpvar->next = p->chanvars; 09333 p->chanvars = tmpvar; 09334 } 09335 } 09336 if (authpeer) { 09337 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09338 } 09339 09340 if (!ast_strlen_zero(peer->username)) { 09341 ast_string_field_set(p, username, peer->username); 09342 /* Use the default username for authentication on outbound calls */ 09343 /* XXX this takes the name from the caller... can we override ? */ 09344 ast_string_field_set(p, authname, peer->username); 09345 } 09346 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09347 char *tmp = ast_strdupa(peer->cid_num); 09348 if (ast_is_shrinkable_phonenumber(tmp)) 09349 ast_shrink_phone_number(tmp); 09350 ast_string_field_set(p, cid_num, tmp); 09351 } 09352 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09353 ast_string_field_set(p, cid_name, peer->cid_name); 09354 ast_string_field_set(p, fullcontact, peer->fullcontact); 09355 if (!ast_strlen_zero(peer->context)) 09356 ast_string_field_set(p, context, peer->context); 09357 ast_string_field_set(p, peersecret, peer->secret); 09358 ast_string_field_set(p, peermd5secret, peer->md5secret); 09359 ast_string_field_set(p, language, peer->language); 09360 ast_string_field_set(p, accountcode, peer->accountcode); 09361 p->amaflags = peer->amaflags; 09362 p->callgroup = peer->callgroup; 09363 p->pickupgroup = peer->pickupgroup; 09364 p->capability = peer->capability; 09365 p->prefs = peer->prefs; 09366 p->jointcapability = peer->capability; 09367 if (p->peercapability) 09368 p->jointcapability &= p->peercapability; 09369 p->maxcallbitrate = peer->maxcallbitrate; 09370 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09371 ast_rtp_destroy(p->vrtp); 09372 p->vrtp = NULL; 09373 } 09374 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09375 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09376 p->noncodeccapability |= AST_RTP_DTMF; 09377 else 09378 p->noncodeccapability &= ~AST_RTP_DTMF; 09379 p->jointnoncodeccapability = p->noncodeccapability; 09380 if (p->t38.peercapability) 09381 p->t38.jointcapability &= p->t38.peercapability; 09382 } 09383 ASTOBJ_UNREF(peer, sip_destroy_peer); 09384 } else { 09385 if (debug) 09386 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09387 09388 /* do we allow guests? */ 09389 if (!global_allowguest) { 09390 if (global_alwaysauthreject) 09391 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09392 else 09393 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09394 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09395 char *tmp = ast_strdupa(rpid_num); 09396 if (*calleridname) 09397 ast_string_field_set(p, cid_name, calleridname); 09398 if (ast_is_shrinkable_phonenumber(tmp)) 09399 ast_shrink_phone_number(tmp); 09400 ast_string_field_set(p, cid_num, tmp); 09401 } 09402 } 09403 09404 } 09405 09406 if (user) 09407 ASTOBJ_UNREF(user, sip_destroy_user); 09408 return res; 09409 }
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 8961 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
08962 { 08963 char via[256]; 08964 char *c, *pt; 08965 struct hostent *hp; 08966 struct ast_hostent ahp; 08967 08968 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 08969 08970 /* Work on the leftmost value of the topmost Via header */ 08971 c = strchr(via, ','); 08972 if (c) 08973 *c = '\0'; 08974 08975 /* Check for rport */ 08976 c = strstr(via, ";rport"); 08977 if (c && (c[6] != '=')) /* rport query, not answer */ 08978 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 08979 08980 c = strchr(via, ';'); 08981 if (c) 08982 *c = '\0'; 08983 08984 c = strchr(via, ' '); 08985 if (c) { 08986 *c = '\0'; 08987 c = ast_skip_blanks(c+1); 08988 if (strcasecmp(via, "SIP/2.0/UDP")) { 08989 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 08990 return; 08991 } 08992 pt = strchr(c, ':'); 08993 if (pt) 08994 *pt++ = '\0'; /* remember port pointer */ 08995 hp = ast_gethostbyname(c, &ahp); 08996 if (!hp) { 08997 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 08998 return; 08999 } 09000 memset(&p->sa, 0, sizeof(p->sa)); 09001 p->sa.sin_family = AF_INET; 09002 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09003 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09004 09005 if (sip_debug_test_pvt(p)) { 09006 const struct sockaddr_in *dst = sip_real_dst(p); 09007 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09008 } 09009 } 09010 }
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 9856 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
Referenced by reload_config().
09857 { 09858 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 09859 09860 while ((oldcontext = strsep(&old, "&"))) { 09861 stalecontext = '\0'; 09862 ast_copy_string(newlist, new, sizeof(newlist)); 09863 stringp = newlist; 09864 while ((newcontext = strsep(&stringp, "&"))) { 09865 if (strcmp(newcontext, oldcontext) == 0) { 09866 /* This is not the context you're looking for */ 09867 stalecontext = '\0'; 09868 break; 09869 } else if (strcmp(newcontext, oldcontext)) { 09870 stalecontext = oldcontext; 09871 } 09872 09873 } 09874 if (stalecontext) 09875 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 09876 } 09877 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 15959 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), sip_destroy_peer(), sip_do_reload(), and unload_module().
15960 { 15961 struct sip_auth *a = authlist; 15962 struct sip_auth *b; 15963 15964 while (a) { 15965 b = a; 15966 a = a->next; 15967 free(b); 15968 } 15969 15970 return 1; 15971 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 15888 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().
15889 { 15890 struct domain *d; 15891 15892 AST_LIST_LOCK(&domain_list); 15893 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 15894 free(d); 15895 AST_LIST_UNLOCK(&domain_list); 15896 }
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 10663 of file chan_sip.c.
References complete_sip_peer().
10664 { 10665 if (pos == 3) 10666 return complete_sip_peer(word, state, 0); 10667 10668 return NULL; 10669 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10637 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10638 { 10639 char *result = NULL; 10640 int wordlen = strlen(word); 10641 int which = 0; 10642 10643 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10644 /* locking of the object is not required because only the name and flags are being compared */ 10645 if (!strncasecmp(word, iterator->name, wordlen) && 10646 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10647 ++which > state) 10648 result = ast_strdup(iterator->name); 10649 } while(0) ); 10650 return result; 10651 }
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 10731 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10732 { 10733 if (pos == 4) 10734 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10735 return NULL; 10736 }
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 10739 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10740 { 10741 if (pos == 4) 10742 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10743 10744 return NULL; 10745 }
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 10654 of file chan_sip.c.
References complete_sip_peer().
10655 { 10656 if (pos == 3) 10657 return complete_sip_peer(word, state, 0); 10658 10659 return NULL; 10660 }
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 10692 of file chan_sip.c.
References complete_sip_user().
10693 { 10694 if (pos == 3) 10695 return complete_sip_user(word, state, 0); 10696 10697 return NULL; 10698 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10672 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10673 { 10674 char *result = NULL; 10675 int wordlen = strlen(word); 10676 int which = 0; 10677 10678 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10679 /* locking of the object is not required because only the name and flags are being compared */ 10680 if (!strncasecmp(word, iterator->name, wordlen)) { 10681 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10682 continue; 10683 if (++which > state) { 10684 result = ast_strdup(iterator->name); 10685 } 10686 } 10687 } while(0) ); 10688 return result; 10689 }
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 10618 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, iflist, and sip_pvt::next.
10619 { 10620 int which=0; 10621 struct sip_pvt *cur; 10622 char *c = NULL; 10623 int wordlen = strlen(word); 10624 10625 ast_mutex_lock(&iflock); 10626 for (cur = iflist; cur; cur = cur->next) { 10627 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10628 c = ast_strdup(cur->callid); 10629 break; 10630 } 10631 } 10632 ast_mutex_unlock(&iflock); 10633 return c; 10634 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10701 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10702 { 10703 char *c = NULL; 10704 10705 if (pos == 2) { 10706 int which = 0; 10707 char *cat = NULL; 10708 int wordlen = strlen(word); 10709 10710 /* do completion for notify type */ 10711 10712 if (!notify_types) 10713 return NULL; 10714 10715 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10716 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10717 c = ast_strdup(cat); 10718 break; 10719 } 10720 } 10721 return c; 10722 } 10723 10724 if (pos > 2) 10725 return complete_sip_peer(word, state, 0); 10726 10727 return NULL; 10728 }
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 5485 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05486 { 05487 int start = 0; 05488 int copied = 0; 05489 for (;;) { 05490 const char *tmp = __get_header(orig, field, &start); 05491 05492 if (ast_strlen_zero(tmp)) 05493 break; 05494 /* Add what we're responding to */ 05495 add_header(req, field, tmp); 05496 copied++; 05497 } 05498 return copied ? 0 : -1; 05499 }
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 5474 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05475 { 05476 const char *tmp = get_header(orig, field); 05477 05478 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05479 return add_header(req, field, tmp); 05480 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05481 return -1; 05482 }
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 6522 of file chan_sip.c.
References sip_request::header, sip_request::line, offset, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06523 { 06524 long offset; 06525 int x; 06526 offset = ((void *)dst) - ((void *)src); 06527 /* First copy stuff */ 06528 memcpy(dst, src, sizeof(*dst)); 06529 /* Now fix pointer arithmetic */ 06530 for (x=0; x < src->headers; x++) 06531 dst->header[x] += offset; 06532 for (x=0; x < src->lines; x++) 06533 dst->line[x] += offset; 06534 dst->rlPart1 += offset; 06535 dst->rlPart2 += offset; 06536 }
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 5507 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().
05508 { 05509 int copied = 0; 05510 int start = 0; 05511 05512 for (;;) { 05513 char new[256]; 05514 const char *oh = __get_header(orig, field, &start); 05515 05516 if (ast_strlen_zero(oh)) 05517 break; 05518 05519 if (!copied) { /* Only check for empty rport in topmost via header */ 05520 char leftmost[256], *others, *rport; 05521 05522 /* Only work on leftmost value */ 05523 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05524 others = strchr(leftmost, ','); 05525 if (others) 05526 *others++ = '\0'; 05527 05528 /* Find ;rport; (empty request) */ 05529 rport = strstr(leftmost, ";rport"); 05530 if (rport && *(rport+6) == '=') 05531 rport = NULL; /* We already have a parameter to rport */ 05532 05533 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05534 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05535 /* We need to add received port - rport */ 05536 char *end; 05537 05538 rport = strstr(leftmost, ";rport"); 05539 05540 if (rport) { 05541 end = strchr(rport + 1, ';'); 05542 if (end) 05543 memmove(rport, end, strlen(end) + 1); 05544 else 05545 *rport = '\0'; 05546 } 05547 05548 /* Add rport to first VIA header if requested */ 05549 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05550 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05551 ntohs(p->recv.sin_port), 05552 others ? "," : "", others ? others : ""); 05553 } else { 05554 /* We should *always* add a received to the topmost via */ 05555 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05556 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05557 others ? "," : "", others ? others : ""); 05558 } 05559 oh = new; /* the header to copy */ 05560 } /* else add the following via headers untouched */ 05561 add_header(req, field, oh); 05562 copied++; 05563 } 05564 if (!copied) { 05565 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05566 return -1; 05567 } 05568 return 0; 05569 }
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 2802 of file chan_sip.c.
References ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02803 { 02804 struct hostent *hp; 02805 struct ast_hostent ahp; 02806 struct sip_peer *p; 02807 char *port; 02808 int portno; 02809 char host[MAXHOSTNAMELEN], *hostn; 02810 char peer[256]; 02811 02812 ast_copy_string(peer, opeer, sizeof(peer)); 02813 port = strchr(peer, ':'); 02814 if (port) 02815 *port++ = '\0'; 02816 dialog->sa.sin_family = AF_INET; 02817 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02818 p = find_peer(peer, NULL, 1); 02819 02820 if (p) { 02821 int res = create_addr_from_peer(dialog, p); 02822 ASTOBJ_UNREF(p, sip_destroy_peer); 02823 return res; 02824 } 02825 hostn = peer; 02826 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02827 if (srvlookup) { 02828 char service[MAXHOSTNAMELEN]; 02829 int tportno; 02830 int ret; 02831 02832 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02833 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02834 if (ret > 0) { 02835 hostn = host; 02836 portno = tportno; 02837 } 02838 } 02839 hp = ast_gethostbyname(hostn, &ahp); 02840 if (!hp) { 02841 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02842 return -1; 02843 } 02844 ast_string_field_set(dialog, tohost, peer); 02845 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02846 dialog->sa.sin_port = htons(portno); 02847 dialog->recv = dialog->sa; 02848 return 0; 02849 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2694 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, domain::context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02695 { 02696 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02697 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02698 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02699 dialog->recv = dialog->sa; 02700 } else 02701 return -1; 02702 02703 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02704 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02705 dialog->capability = peer->capability; 02706 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02707 ast_rtp_destroy(dialog->vrtp); 02708 dialog->vrtp = NULL; 02709 } 02710 dialog->prefs = peer->prefs; 02711 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02712 dialog->t38.capability = global_t38_capability; 02713 if (dialog->udptl) { 02714 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02715 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02716 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02717 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02718 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02719 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02720 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02721 if (option_debug > 1) 02722 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02723 } 02724 dialog->t38.jointcapability = dialog->t38.capability; 02725 } else if (dialog->udptl) { 02726 ast_udptl_destroy(dialog->udptl); 02727 dialog->udptl = NULL; 02728 } 02729 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02730 02731 if (dialog->rtp) { 02732 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02733 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02734 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02735 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02736 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02737 /* Set Frame packetization */ 02738 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02739 dialog->autoframing = peer->autoframing; 02740 } 02741 if (dialog->vrtp) { 02742 ast_rtp_setdtmf(dialog->vrtp, 0); 02743 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02744 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02745 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02746 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02747 } 02748 02749 ast_string_field_set(dialog, peername, peer->name); 02750 ast_string_field_set(dialog, authname, peer->username); 02751 ast_string_field_set(dialog, username, peer->username); 02752 ast_string_field_set(dialog, peersecret, peer->secret); 02753 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02754 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02755 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02756 ast_string_field_set(dialog, tohost, peer->tohost); 02757 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02758 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02759 char *tmpcall; 02760 char *c; 02761 tmpcall = ast_strdupa(dialog->callid); 02762 c = strchr(tmpcall, '@'); 02763 if (c) { 02764 *c = '\0'; 02765 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02766 } 02767 } 02768 if (ast_strlen_zero(dialog->tohost)) 02769 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02770 if (!ast_strlen_zero(peer->fromdomain)) 02771 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02772 if (!ast_strlen_zero(peer->fromuser)) 02773 ast_string_field_set(dialog, fromuser, peer->fromuser); 02774 if (!ast_strlen_zero(peer->language)) 02775 ast_string_field_set(dialog, language, peer->language); 02776 dialog->maxtime = peer->maxms; 02777 dialog->callgroup = peer->callgroup; 02778 dialog->pickupgroup = peer->pickupgroup; 02779 dialog->allowtransfer = peer->allowtransfer; 02780 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02781 /* Minimum is settable or default to 100 ms */ 02782 if (peer->maxms && peer->lastms) 02783 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02784 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02785 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02786 dialog->noncodeccapability |= AST_RTP_DTMF; 02787 else 02788 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02789 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02790 ast_string_field_set(dialog, context, peer->context); 02791 dialog->rtptimeout = peer->rtptimeout; 02792 if (peer->call_limit) 02793 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02794 dialog->maxcallbitrate = peer->maxcallbitrate; 02795 02796 return 0; 02797 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7683 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07684 { 07685 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07686 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07687 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07688 else 07689 ast_db_del("SIP/Registry", peer->name); 07690 } 07691 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6566 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06567 { 06568 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06569 06570 if (!*e) 06571 return -1; 06572 req->rlPart1 = e; /* method or protocol */ 06573 e = ast_skip_nonblanks(e); 06574 if (*e) 06575 *e++ = '\0'; 06576 /* Get URI or status code */ 06577 e = ast_skip_blanks(e); 06578 if ( !*e ) 06579 return -1; 06580 ast_trim_blanks(e); 06581 06582 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06583 if (strlen(e) < 3) /* status code is 3 digits */ 06584 return -1; 06585 req->rlPart2 = e; 06586 } else { /* We have a request */ 06587 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06588 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06589 e++; 06590 if (!*e) 06591 return -1; 06592 } 06593 req->rlPart2 = e; /* URI */ 06594 e = ast_skip_nonblanks(e); 06595 if (*e) 06596 *e++ = '\0'; 06597 e = ast_skip_blanks(e); 06598 if (strcasecmp(e, "SIP/2.0") ) { 06599 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06600 return -1; 06601 } 06602 } 06603 return 1; 06604 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15224 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_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_sched_runq(), ast_sched_wait(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, does_peer_need_mwi(), FALSE, iflist, LOG_DEBUG, LOG_NOTICE, sip_pvt::next, option_debug, option_verbose, peerl, sip_destroy_peer(), sip_do_reload(), SIP_NEEDDESTROY, sip_send_mwi_to_peer(), sipsock, sipsock_read(), t, T38_ENABLED, TRUE, and VERBOSE_PREFIX_1.
15225 { 15226 int res; 15227 struct sip_pvt *sip; 15228 struct sip_peer *peer = NULL; 15229 time_t t; 15230 int fastrestart = FALSE; 15231 int lastpeernum = -1; 15232 int curpeernum; 15233 int reloading; 15234 15235 /* Add an I/O event to our SIP UDP socket */ 15236 if (sipsock > -1) 15237 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15238 15239 /* From here on out, we die whenever asked */ 15240 for(;;) { 15241 /* Check for a reload request */ 15242 ast_mutex_lock(&sip_reload_lock); 15243 reloading = sip_reloading; 15244 sip_reloading = FALSE; 15245 ast_mutex_unlock(&sip_reload_lock); 15246 if (reloading) { 15247 if (option_verbose > 0) 15248 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15249 sip_do_reload(sip_reloadreason); 15250 15251 /* Change the I/O fd of our UDP socket */ 15252 if (sipsock > -1) { 15253 if (sipsock_read_id) 15254 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15255 else 15256 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15257 } 15258 } 15259 /* Check for interfaces needing to be killed */ 15260 ast_mutex_lock(&iflock); 15261 restartsearch: 15262 t = time(NULL); 15263 /* don't scan the interface list if it hasn't been a reasonable period 15264 of time since the last time we did it (when MWI is being sent, we can 15265 get back to this point every millisecond or less) 15266 */ 15267 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15268 ast_mutex_lock(&sip->lock); 15269 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15270 if (sip->rtp && sip->owner && 15271 (sip->owner->_state == AST_STATE_UP) && 15272 !sip->redirip.sin_addr.s_addr && 15273 sip->t38.state != T38_ENABLED) { 15274 if (sip->lastrtptx && 15275 ast_rtp_get_rtpkeepalive(sip->rtp) && 15276 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15277 /* Need to send an empty RTP packet */ 15278 sip->lastrtptx = time(NULL); 15279 ast_rtp_sendcng(sip->rtp, 0); 15280 } 15281 if (sip->lastrtprx && 15282 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15283 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15284 /* Might be a timeout now -- see if we're on hold */ 15285 struct sockaddr_in sin; 15286 ast_rtp_get_peer(sip->rtp, &sin); 15287 if (sin.sin_addr.s_addr || 15288 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15289 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15290 /* Needs a hangup */ 15291 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15292 while (sip->owner && ast_channel_trylock(sip->owner)) { 15293 ast_mutex_unlock(&sip->lock); 15294 usleep(1); 15295 ast_mutex_lock(&sip->lock); 15296 } 15297 if (sip->owner) { 15298 if (!(ast_rtp_get_bridged(sip->rtp))) { 15299 ast_log(LOG_NOTICE, 15300 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15301 sip->owner->name, 15302 (long) (t - sip->lastrtprx)); 15303 /* Issue a softhangup */ 15304 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15305 } else 15306 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)); 15307 ast_channel_unlock(sip->owner); 15308 /* forget the timeouts for this call, since a hangup 15309 has already been requested and we don't want to 15310 repeatedly request hangups 15311 */ 15312 ast_rtp_set_rtptimeout(sip->rtp, 0); 15313 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15314 if (sip->vrtp) { 15315 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15316 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15317 } 15318 } 15319 } 15320 } 15321 } 15322 } 15323 /* If we have sessions that needs to be destroyed, do it now */ 15324 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15325 !sip->owner) { 15326 ast_mutex_unlock(&sip->lock); 15327 __sip_destroy(sip, 1); 15328 goto restartsearch; 15329 } 15330 ast_mutex_unlock(&sip->lock); 15331 } 15332 ast_mutex_unlock(&iflock); 15333 15334 pthread_testcancel(); 15335 /* Wait for sched or io */ 15336 res = ast_sched_wait(sched); 15337 if ((res < 0) || (res > 1000)) 15338 res = 1000; 15339 /* If we might need to send more mailboxes, don't wait long at all.*/ 15340 if (fastrestart) 15341 res = 1; 15342 res = ast_io_wait(io, res); 15343 if (option_debug && res > 20) 15344 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15345 ast_mutex_lock(&monlock); 15346 if (res >= 0) { 15347 res = ast_sched_runq(sched); 15348 if (option_debug && res >= 20) 15349 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15350 } 15351 15352 /* Send MWI notifications to peers - static and cached realtime peers */ 15353 t = time(NULL); 15354 fastrestart = FALSE; 15355 curpeernum = 0; 15356 peer = NULL; 15357 /* Find next peer that needs mwi */ 15358 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15359 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15360 fastrestart = TRUE; 15361 lastpeernum = curpeernum; 15362 peer = ASTOBJ_REF(iterator); 15363 }; 15364 curpeernum++; 15365 } while (0) 15366 ); 15367 /* Send MWI to the peer */ 15368 if (peer) { 15369 ASTOBJ_WRLOCK(peer); 15370 sip_send_mwi_to_peer(peer); 15371 ASTOBJ_UNLOCK(peer); 15372 ASTOBJ_UNREF(peer,sip_destroy_peer); 15373 } else { 15374 /* Reset where we come from */ 15375 lastpeernum = -1; 15376 } 15377 ast_mutex_unlock(&monlock); 15378 } 15379 /* Never reached */ 15380 return NULL; 15381 15382 }
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 11199 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().
11200 { 11201 char digest[1024]; 11202 11203 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11204 return -2; 11205 11206 p->authtries++; 11207 if (option_debug > 1) 11208 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11209 memset(digest, 0, sizeof(digest)); 11210 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11211 /* No way to authenticate */ 11212 return -1; 11213 } 11214 /* Now we have a reply digest */ 11215 p->options->auth = digest; 11216 p->options->authheader = respheader; 11217 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11218 }
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 11178 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
11179 { 11180 char digest[1024]; 11181 p->authtries++; 11182 memset(digest,0,sizeof(digest)); 11183 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11184 /* There's nothing to use for authentication */ 11185 /* No digest challenge in request */ 11186 if (sip_debug_test_pvt(p) && p->registry) 11187 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11188 /* No old challenge */ 11189 return -1; 11190 } 11191 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11192 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11193 if (sip_debug_test_pvt(p) && p->registry) 11194 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11195 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11196 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2670 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, domain::mode, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02671 { 02672 const char *mode = natflags ? "On" : "Off"; 02673 02674 if (p->rtp) { 02675 if (option_debug) 02676 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02677 ast_rtp_setnat(p->rtp, natflags); 02678 } 02679 if (p->vrtp) { 02680 if (option_debug) 02681 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02682 ast_rtp_setnat(p->vrtp, natflags); 02683 } 02684 if (p->udptl) { 02685 if (option_debug) 02686 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02687 ast_udptl_setnat(p->udptl, natflags); 02688 } 02689 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15203 of file chan_sip.c.
References ast_strlen_zero(), ast_test_flag, FALSE, sip_peer::flags, sip_peer::lastmsgcheck, sip_peer::mailbox, sip_peer::mwipvt, SIP_PAGE2_SUBSCRIBEMWIONLY, t, and TRUE.
Referenced by do_monitor().
15204 { 15205 time_t t = time(NULL); 15206 15207 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15208 !peer->mwipvt) { /* We don't have a subscription */ 15209 peer->lastmsgcheck = t; /* Reset timer */ 15210 return FALSE; 15211 } 15212 15213 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15214 return TRUE; 15215 15216 return FALSE; 15217 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10045 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10046 { 10047 switch (mode) { 10048 case SIP_DOMAIN_AUTO: 10049 return "[Automatic]"; 10050 case SIP_DOMAIN_CONFIG: 10051 return "[Configured]"; 10052 } 10053 10054 return ""; 10055 }
static const char * dtmfmode2str | ( | int | mode | ) | [static] |
Convert DTMF mode to printable string.
Definition at line 9825 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().
09826 { 09827 switch (mode) { 09828 case SIP_DTMF_RFC2833: 09829 return "rfc2833"; 09830 case SIP_DTMF_INFO: 09831 return "info"; 09832 case SIP_DTMF_INBAND: 09833 return "inband"; 09834 case SIP_DTMF_AUTO: 09835 return "auto"; 09836 } 09837 return "<error>"; 09838 }
static int expire_register | ( | void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7694 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), realtime_peer(), and reg_source_db().
07695 { 07696 struct sip_peer *peer = data; 07697 07698 if (!peer) /* Hmmm. We have no peer. Weird. */ 07699 return 0; 07700 07701 memset(&peer->addr, 0, sizeof(peer->addr)); 07702 07703 destroy_association(peer); /* remove registration data from storage */ 07704 07705 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07706 register_peer_exten(peer, FALSE); /* Remove regexten */ 07707 peer->expire = -1; 07708 ast_device_state_changed("SIP/%s", peer->name); 07709 07710 /* Do we need to release this peer from memory? 07711 Only for realtime peers and autocreated peers 07712 */ 07713 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07714 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07715 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07716 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07717 } 07718 07719 return 0; 07720 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6656 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().
06657 { 06658 char stripped[BUFSIZ]; 06659 char *c; 06660 06661 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06662 c = get_in_brackets(stripped); 06663 c = strsep(&c, ";"); /* trim ; and beyond */ 06664 if (!ast_strlen_zero(c)) 06665 ast_string_field_set(p, uri, c); 06666 }
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 4084 of file chan_sip.c.
References aliases.
04085 { 04086 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04087 static const struct cfalias { 04088 char * const fullname; 04089 char * const shortname; 04090 } aliases[] = { 04091 { "Content-Type", "c" }, 04092 { "Content-Encoding", "e" }, 04093 { "From", "f" }, 04094 { "Call-ID", "i" }, 04095 { "Contact", "m" }, 04096 { "Content-Length", "l" }, 04097 { "Subject", "s" }, 04098 { "To", "t" }, 04099 { "Supported", "k" }, 04100 { "Refer-To", "r" }, 04101 { "Referred-By", "b" }, 04102 { "Allow-Events", "u" }, 04103 { "Event", "o" }, 04104 { "Via", "v" }, 04105 { "Accept-Contact", "a" }, 04106 { "Reject-Contact", "j" }, 04107 { "Request-Disposition", "d" }, 04108 { "Session-Expires", "x" }, 04109 { "Identity", "y" }, 04110 { "Identity-Info", "n" }, 04111 }; 04112 int x; 04113 04114 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04115 if (!strcasecmp(aliases[x].fullname, name)) 04116 return aliases[x].shortname; 04117 04118 return _default; 04119 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static, read] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4435 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD, FALSE, get_header(), gettag(), iflist, sip_pvt::lock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_ACK, sip_alloc(), sip_methods, SIP_NOTIFY, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, cfsip_methods::text, and transmit_response_using_temp().
Referenced by sipsock_read().
04436 { 04437 struct sip_pvt *p = NULL; 04438 char *tag = ""; /* note, tag is never NULL */ 04439 char totag[128]; 04440 char fromtag[128]; 04441 const char *callid = get_header(req, "Call-ID"); 04442 const char *from = get_header(req, "From"); 04443 const char *to = get_header(req, "To"); 04444 const char *cseq = get_header(req, "Cseq"); 04445 04446 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04447 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04448 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04449 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04450 return NULL; /* Invalid packet */ 04451 04452 if (pedanticsipchecking) { 04453 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04454 we need more to identify a branch - so we have to check branch, from 04455 and to tags to identify a call leg. 04456 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04457 in sip.conf 04458 */ 04459 if (gettag(req, "To", totag, sizeof(totag))) 04460 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04461 gettag(req, "From", fromtag, sizeof(fromtag)); 04462 04463 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04464 04465 if (option_debug > 4 ) 04466 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); 04467 } 04468 04469 ast_mutex_lock(&iflock); 04470 for (p = iflist; p; p = p->next) { 04471 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04472 int found = FALSE; 04473 if (ast_strlen_zero(p->callid)) 04474 continue; 04475 if (req->method == SIP_REGISTER) 04476 found = (!strcmp(p->callid, callid)); 04477 else 04478 found = (!strcmp(p->callid, callid) && 04479 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04480 04481 if (option_debug > 4) 04482 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); 04483 04484 /* If we get a new request within an existing to-tag - check the to tag as well */ 04485 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04486 if (p->tag[0] == '\0' && totag[0]) { 04487 /* We have no to tag, but they have. Wrong dialog */ 04488 found = FALSE; 04489 } else if (totag[0]) { /* Both have tags, compare them */ 04490 if (strcmp(totag, p->tag)) { 04491 found = FALSE; /* This is not our packet */ 04492 } 04493 } 04494 if (!found && option_debug > 4) 04495 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); 04496 } 04497 04498 04499 if (found) { 04500 /* Found the call */ 04501 ast_mutex_lock(&p->lock); 04502 ast_mutex_unlock(&iflock); 04503 return p; 04504 } 04505 } 04506 ast_mutex_unlock(&iflock); 04507 04508 /* See if the method is capable of creating a dialog */ 04509 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04510 if (intended_method == SIP_REFER) { 04511 /* We do support REFER, but not outside of a dialog yet */ 04512 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04513 } else if (intended_method == SIP_NOTIFY) { 04514 /* We do not support out-of-dialog NOTIFY either, 04515 like voicemail notification, so cancel that early */ 04516 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04517 } else { 04518 /* Ok, time to create a new SIP dialog object, a pvt */ 04519 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04520 /* Ok, we've created a dialog, let's go and process it */ 04521 ast_mutex_lock(&p->lock); 04522 } else { 04523 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04524 getting a dialog from sip_alloc. 04525 04526 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04527 send an error message. 04528 04529 Sorry, we apologize for the inconvienience 04530 */ 04531 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04532 if (option_debug > 3) 04533 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04534 } 04535 } 04536 return p; 04537 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04538 /* A method we do not support, let's take it on the volley */ 04539 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04540 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04541 /* This is a request outside of a dialog that we don't know about 04542 ...never reply to an ACK! 04543 */ 04544 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04545 } 04546 /* We do not respond to responses for dialogs that we don't know about, we just drop 04547 the session quickly */ 04548 04549 return p; 04550 }
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 2260 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02261 { 02262 char last_char = '\0'; 02263 const char *s; 02264 for (s = start; *s && s != lim; last_char = *s++) { 02265 if (*s == '"' && last_char != '\\') 02266 break; 02267 } 02268 return s; 02269 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static, read] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2582 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02583 { 02584 struct sip_peer *p = NULL; 02585 02586 if (peer) 02587 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02588 else 02589 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02590 02591 if (!p && realtime) 02592 p = realtime_peer(peer, sin); 02593 02594 return p; 02595 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static, read] |
Find authentication for a specific realm.
Definition at line 15974 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
15975 { 15976 struct sip_auth *a; 15977 15978 for (a = authlist; a; a = a->next) { 15979 if (!strcasecmp(a->realm, realm)) 15980 break; 15981 } 15982 15983 return a; 15984 }
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 4756 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().
04757 { 04758 const char *content_type; 04759 const char *search; 04760 char *boundary; 04761 unsigned int x; 04762 int boundaryisquoted = FALSE; 04763 04764 content_type = get_header(req, "Content-Type"); 04765 04766 /* if the body contains only SDP, this is easy */ 04767 if (!strcasecmp(content_type, "application/sdp")) { 04768 req->sdp_start = 0; 04769 req->sdp_end = req->lines; 04770 return req->lines ? 1 : 0; 04771 } 04772 04773 /* if it's not multipart/mixed, there cannot be an SDP */ 04774 if (strncasecmp(content_type, "multipart/mixed", 15)) 04775 return 0; 04776 04777 /* if there is no boundary marker, it's invalid */ 04778 if (!(search = strcasestr(content_type, ";boundary="))) 04779 return 0; 04780 04781 search += 10; 04782 if (ast_strlen_zero(search)) 04783 return 0; 04784 04785 /* If the boundary is quoted with ", remove quote */ 04786 if (*search == '\"') { 04787 search++; 04788 boundaryisquoted = TRUE; 04789 } 04790 04791 /* make a duplicate of the string, with two extra characters 04792 at the beginning */ 04793 boundary = ast_strdupa(search - 2); 04794 boundary[0] = boundary[1] = '-'; 04795 04796 /* Remove final quote */ 04797 if (boundaryisquoted) 04798 boundary[strlen(boundary) - 1] = '\0'; 04799 04800 /* search for the boundary marker, but stop when there are not enough 04801 lines left for it, the Content-Type header and at least one line of 04802 body */ 04803 for (x = 0; x < (req->lines - 2); x++) { 04804 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 04805 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 04806 x += 2; 04807 req->sdp_start = x; 04808 04809 /* search for the end of the body part */ 04810 for ( ; x < req->lines; x++) { 04811 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 04812 break; 04813 } 04814 req->sdp_end = x; 04815 return 1; 04816 } 04817 } 04818 04819 return 0; 04820 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1663 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01664 { 01665 int i, res = 0; 01666 01667 if (ast_strlen_zero(msg)) 01668 return 0; 01669 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01670 if (method_match(i, msg)) 01671 res = sip_methods[i].id; 01672 } 01673 return res; 01674 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static, read] |
Find subscription type in array.
Definition at line 10533 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10534 { 10535 int i; 10536 10537 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10538 if (subscription_types[i].type == subtype) { 10539 return &subscription_types[i]; 10540 } 10541 } 10542 return &subscription_types[0]; 10543 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2661 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02662 { 02663 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02664 if (!u && realtime) 02665 u = realtime_user(name); 02666 return u; 02667 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8025 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08026 { 08027 struct sip_route *next; 08028 08029 while (route) { 08030 next = route->next; 08031 free(route); 08032 route = next; 08033 } 08034 }
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 11525 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11526 { 11527 if (ast_strlen_zero(data)) { 11528 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11529 return -1; 11530 } 11531 if (check_sip_domain(data, NULL, 0)) 11532 ast_copy_string(buf, data, len); 11533 else 11534 buf[0] = '\0'; 11535 return 0; 11536 }
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 11461 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11462 { 11463 struct sip_pvt *p; 11464 const char *content = NULL; 11465 AST_DECLARE_APP_ARGS(args, 11466 AST_APP_ARG(header); 11467 AST_APP_ARG(number); 11468 ); 11469 int i, number, start = 0; 11470 11471 if (ast_strlen_zero(data)) { 11472 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11473 return -1; 11474 } 11475 11476 ast_channel_lock(chan); 11477 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11478 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11479 ast_channel_unlock(chan); 11480 return -1; 11481 } 11482 11483 AST_STANDARD_APP_ARGS(args, data); 11484 if (!args.number) { 11485 number = 1; 11486 } else { 11487 sscanf(args.number, "%d", &number); 11488 if (number < 1) 11489 number = 1; 11490 } 11491 11492 p = chan->tech_pvt; 11493 11494 /* If there is no private structure, this channel is no longer alive */ 11495 if (!p) { 11496 ast_channel_unlock(chan); 11497 return -1; 11498 } 11499 11500 for (i = 0; i < number; i++) 11501 content = __get_header(&p->initreq, args.header, &start); 11502 11503 if (ast_strlen_zero(content)) { 11504 ast_channel_unlock(chan); 11505 return -1; 11506 } 11507 11508 ast_copy_string(buf, content, len); 11509 ast_channel_unlock(chan); 11510 11511 return 0; 11512 }
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 11640 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.
11641 { 11642 struct sip_pvt *p; 11643 11644 *buf = 0; 11645 11646 if (!data) { 11647 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11648 return -1; 11649 } 11650 11651 ast_channel_lock(chan); 11652 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11653 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11654 ast_channel_unlock(chan); 11655 return -1; 11656 } 11657 11658 p = chan->tech_pvt; 11659 11660 /* If there is no private structure, this channel is no longer alive */ 11661 if (!p) { 11662 ast_channel_unlock(chan); 11663 return -1; 11664 } 11665 11666 if (!strcasecmp(data, "peerip")) { 11667 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11668 } else if (!strcasecmp(data, "recvip")) { 11669 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11670 } else if (!strcasecmp(data, "from")) { 11671 ast_copy_string(buf, p->from, len); 11672 } else if (!strcasecmp(data, "uri")) { 11673 ast_copy_string(buf, p->uri, len); 11674 } else if (!strcasecmp(data, "useragent")) { 11675 ast_copy_string(buf, p->useragent, len); 11676 } else if (!strcasecmp(data, "peername")) { 11677 ast_copy_string(buf, p->peername, len); 11678 } else if (!strcasecmp(data, "t38passthrough")) { 11679 if (p->t38.state == T38_DISABLED) 11680 ast_copy_string(buf, "0", sizeof("0")); 11681 else /* T38 is offered or enabled in this call */ 11682 ast_copy_string(buf, "1", sizeof("1")); 11683 } else { 11684 ast_channel_unlock(chan); 11685 return -1; 11686 } 11687 ast_channel_unlock(chan); 11688 11689 return 0; 11690 }
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 11550 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.
11551 { 11552 struct sip_peer *peer; 11553 char *colname; 11554 11555 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11556 *colname++ = '\0'; 11557 else if ((colname = strchr(data, '|'))) 11558 *colname++ = '\0'; 11559 else 11560 colname = "ip"; 11561 11562 if (!(peer = find_peer(data, NULL, 1))) 11563 return -1; 11564 11565 if (!strcasecmp(colname, "ip")) { 11566 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11567 } else if (!strcasecmp(colname, "status")) { 11568 peer_status(peer, buf, len); 11569 } else if (!strcasecmp(colname, "language")) { 11570 ast_copy_string(buf, peer->language, len); 11571 } else if (!strcasecmp(colname, "regexten")) { 11572 ast_copy_string(buf, peer->regexten, len); 11573 } else if (!strcasecmp(colname, "limit")) { 11574 snprintf(buf, len, "%d", peer->call_limit); 11575 } else if (!strcasecmp(colname, "curcalls")) { 11576 snprintf(buf, len, "%d", peer->inUse); 11577 } else if (!strcasecmp(colname, "accountcode")) { 11578 ast_copy_string(buf, peer->accountcode, len); 11579 } else if (!strcasecmp(colname, "useragent")) { 11580 ast_copy_string(buf, peer->useragent, len); 11581 } else if (!strcasecmp(colname, "mailbox")) { 11582 ast_copy_string(buf, peer->mailbox, len); 11583 } else if (!strcasecmp(colname, "context")) { 11584 ast_copy_string(buf, peer->context, len); 11585 } else if (!strcasecmp(colname, "expire")) { 11586 snprintf(buf, len, "%d", peer->expire); 11587 } else if (!strcasecmp(colname, "dynamic")) { 11588 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11589 } else if (!strcasecmp(colname, "callerid_name")) { 11590 ast_copy_string(buf, peer->cid_name, len); 11591 } else if (!strcasecmp(colname, "callerid_num")) { 11592 ast_copy_string(buf, peer->cid_num, len); 11593 } else if (!strcasecmp(colname, "codecs")) { 11594 ast_getformatname_multiple(buf, len -1, peer->capability); 11595 } else if (!strncasecmp(colname, "codec[", 6)) { 11596 char *codecnum; 11597 int index = 0, codec = 0; 11598 11599 codecnum = colname + 6; /* move past the '[' */ 11600 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11601 index = atoi(codecnum); 11602 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11603 ast_copy_string(buf, ast_getformatname(codec), len); 11604 } 11605 } 11606 11607 ASTOBJ_UNREF(peer, sip_destroy_peer); 11608 11609 return 0; 11610 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4269 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04270 { 04271 long val[4]; 04272 int x; 04273 04274 for (x=0; x<4; x++) 04275 val[x] = ast_random(); 04276 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04277 04278 return buf; 04279 }
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 8906 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), domain::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, and sip_debug_test_pvt().
Referenced by handle_request_bye().
08907 { 08908 char tmp[256] = "", *c, *a; 08909 struct sip_request *req = oreq ? oreq : &p->initreq; 08910 struct sip_refer *referdata = p->refer; 08911 const char *transfer_context = NULL; 08912 08913 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 08914 c = get_in_brackets(tmp); 08915 08916 if (pedanticsipchecking) 08917 ast_uri_decode(c); 08918 08919 if (strncasecmp(c, "sip:", 4)) { 08920 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 08921 return -1; 08922 } 08923 c += 4; 08924 if ((a = strchr(c, ';'))) /* Remove arguments */ 08925 *a = '\0'; 08926 08927 if ((a = strchr(c, '@'))) { /* Separate Domain */ 08928 *a++ = '\0'; 08929 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 08930 } 08931 08932 if (sip_debug_test_pvt(p)) 08933 ast_verbose("Looking for %s in %s\n", c, p->context); 08934 08935 if (p->owner) /* Mimic behaviour in res_features.c */ 08936 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 08937 08938 /* By default, use the context in the channel sending the REFER */ 08939 if (ast_strlen_zero(transfer_context)) { 08940 transfer_context = S_OR(p->owner->macrocontext, 08941 S_OR(p->context, default_context)); 08942 } 08943 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 08944 /* This is a blind transfer */ 08945 if (option_debug) 08946 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 08947 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 08948 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 08949 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 08950 referdata->refer_call = NULL; 08951 /* Set new context */ 08952 ast_string_field_set(p, context, transfer_context); 08953 return 0; 08954 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 08955 return 1; 08956 } 08957 08958 return -1; 08959 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4068 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04069 { 04070 int x; 04071 int len = strlen(name); 04072 char *r; 04073 04074 for (x = 0; x < req->lines; x++) { 04075 r = get_body_by_line(req->line[x], name, len); 04076 if (r[0] != '\0') 04077 return r; 04078 } 04079 04080 return ""; 04081 }
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 4034 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
04035 { 04036 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04037 return ast_skip_blanks(line + nameLen + 1); 04038 04039 return ""; 04040 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9013 of file chan_sip.c.
Referenced by check_user_full().
09014 { 09015 const char *end = strchr(input,'<'); /* first_bracket */ 09016 const char *tmp = strchr(input,'"'); /* first quote */ 09017 int bytes = 0; 09018 int maxbytes = outputsize - 1; 09019 09020 if (!end || end == input) /* we require a part in brackets */ 09021 return NULL; 09022 09023 end--; /* move just before "<" */ 09024 09025 if (tmp && tmp <= end) { 09026 /* The quote (tmp) precedes the bracket (end+1). 09027 * Find the matching quote and return the content. 09028 */ 09029 end = strchr(tmp+1, '"'); 09030 if (!end) 09031 return NULL; 09032 bytes = (int) (end - tmp); 09033 /* protect the output buffer */ 09034 if (bytes > maxbytes) 09035 bytes = maxbytes; 09036 ast_copy_string(output, tmp + 1, bytes); 09037 } else { 09038 /* No quoted string, or it is inside brackets. */ 09039 /* clear the empty characters in the begining*/ 09040 input = ast_skip_blanks(input); 09041 /* clear the empty characters in the end */ 09042 while(*end && *end < 33 && end > input) 09043 end--; 09044 if (end >= input) { 09045 bytes = (int) (end - input) + 2; 09046 /* protect the output buffer */ 09047 if (bytes > maxbytes) 09048 bytes = maxbytes; 09049 ast_copy_string(output, input, bytes); 09050 } else 09051 return NULL; 09052 } 09053 return output; 09054 }
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 8580 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(), domain::context, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, 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().
08581 { 08582 char tmp[256] = "", *uri, *a; 08583 char tmpf[256] = "", *from; 08584 struct sip_request *req; 08585 char *colon; 08586 08587 req = oreq; 08588 if (!req) 08589 req = &p->initreq; 08590 08591 /* Find the request URI */ 08592 if (req->rlPart2) 08593 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08594 08595 if (pedanticsipchecking) 08596 ast_uri_decode(tmp); 08597 08598 uri = get_in_brackets(tmp); 08599 08600 if (strncasecmp(uri, "sip:", 4)) { 08601 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08602 return -1; 08603 } 08604 uri += 4; 08605 08606 /* Now find the From: caller ID and name */ 08607 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08608 if (!ast_strlen_zero(tmpf)) { 08609 if (pedanticsipchecking) 08610 ast_uri_decode(tmpf); 08611 from = get_in_brackets(tmpf); 08612 } else { 08613 from = NULL; 08614 } 08615 08616 if (!ast_strlen_zero(from)) { 08617 if (strncasecmp(from, "sip:", 4)) { 08618 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08619 return -1; 08620 } 08621 from += 4; 08622 if ((a = strchr(from, '@'))) 08623 *a++ = '\0'; 08624 else 08625 a = from; /* just a domain */ 08626 from = strsep(&from, ";"); /* Remove userinfo options */ 08627 a = strsep(&a, ";"); /* Remove URI options */ 08628 ast_string_field_set(p, fromdomain, a); 08629 } 08630 08631 /* Skip any options and find the domain */ 08632 08633 /* Get the target domain */ 08634 if ((a = strchr(uri, '@'))) { 08635 *a++ = '\0'; 08636 } else { /* No username part */ 08637 a = uri; 08638 uri = "s"; /* Set extension to "s" */ 08639 } 08640 colon = strchr(a, ':'); /* Remove :port */ 08641 if (colon) 08642 *colon = '\0'; 08643 08644 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08645 a = strsep(&a, ";"); /* Remove URI options */ 08646 08647 ast_string_field_set(p, domain, a); 08648 08649 if (!AST_LIST_EMPTY(&domain_list)) { 08650 char domain_context[AST_MAX_EXTENSION]; 08651 08652 domain_context[0] = '\0'; 08653 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08654 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08655 if (option_debug) 08656 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08657 return -2; 08658 } 08659 } 08660 /* If we have a context defined, overwrite the original context */ 08661 if (!ast_strlen_zero(domain_context)) 08662 ast_string_field_set(p, context, domain_context); 08663 } 08664 08665 if (sip_debug_test_pvt(p)) 08666 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08667 08668 /* Check the dialplan for the username part of the request URI, 08669 the domain will be stored in the SIPDOMAIN variable 08670 Return 0 if we have a matching extension */ 08671 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 08672 !strcmp(uri, ast_pickup_ext())) { 08673 if (!oreq) 08674 ast_string_field_set(p, exten, uri); 08675 return 0; 08676 } 08677 08678 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08679 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08680 ast_canmatch_extension(NULL, p->context, uri, 1, from)) || 08681 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08682 return 1; 08683 } 08684 08685 return -1; 08686 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4157 of file chan_sip.c.
References __get_header().
04158 { 04159 int start = 0; 04160 return __get_header(req, name, &start); 04161 }
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 2282 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().
02283 { 02284 const char *parse = tmp; 02285 char *first_bracket; 02286 02287 /* 02288 * Skip any quoted text until we find the part in brackets. 02289 * On any error give up and return the full string. 02290 */ 02291 while ( (first_bracket = strchr(parse, '<')) ) { 02292 char *first_quote = strchr(parse, '"'); 02293 02294 if (!first_quote || first_quote > first_bracket) 02295 break; /* no need to look at quoted part */ 02296 /* the bracket is within quotes, so ignore it */ 02297 parse = find_closing_quote(first_quote + 1, NULL); 02298 if (!*parse) { /* not found, return full string ? */ 02299 /* XXX or be robust and return in-bracket part ? */ 02300 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02301 break; 02302 } 02303 parse++; 02304 } 02305 if (first_bracket) { 02306 char *second_bracket = strchr(first_bracket + 1, '>'); 02307 if (second_bracket) { 02308 *second_bracket = '\0'; 02309 tmp = first_bracket + 1; 02310 } else { 02311 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02312 } 02313 } 02314 return tmp; 02315 }
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 9420 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09421 { 09422 int x; 09423 int y; 09424 09425 buf[0] = '\0'; 09426 y = len - strlen(buf) - 5; 09427 if (y < 0) 09428 y = 0; 09429 for (x=0;x<req->lines;x++) { 09430 strncat(buf, req->line[x], y); /* safe */ 09431 y -= strlen(req->line[x]) + 1; 09432 if (y < 0) 09433 y = 0; 09434 if (y != 0) 09435 strcat(buf, "\n"); /* safe */ 09436 } 09437 return 0; 09438 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8551 of file chan_sip.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08552 { 08553 char tmp[256], *c, *a; 08554 struct sip_request *req; 08555 08556 req = oreq; 08557 if (!req) 08558 req = &p->initreq; 08559 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08560 if (ast_strlen_zero(tmp)) 08561 return 0; 08562 c = get_in_brackets(tmp); 08563 if (strncasecmp(c, "sip:", 4)) { 08564 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08565 return -1; 08566 } 08567 c += 4; 08568 a = c; 08569 strsep(&a, "@;"); /* trim anything after @ or ; */ 08570 if (sip_debug_test_pvt(p)) 08571 ast_verbose("RDNIS is %s\n", c); 08572 ast_string_field_set(p, rdnis, c); 08573 08574 return 0; 08575 }
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 8745 of file chan_sip.c.
References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
08746 { 08747 08748 const char *p_referred_by = NULL; 08749 char *h_refer_to = NULL; 08750 char *h_referred_by = NULL; 08751 char *refer_to; 08752 const char *p_refer_to; 08753 char *referred_by_uri = NULL; 08754 char *ptr; 08755 struct sip_request *req = NULL; 08756 const char *transfer_context = NULL; 08757 struct sip_refer *referdata; 08758 08759 08760 req = outgoing_req; 08761 referdata = transferer->refer; 08762 08763 if (!req) 08764 req = &transferer->initreq; 08765 08766 p_refer_to = get_header(req, "Refer-To"); 08767 if (ast_strlen_zero(p_refer_to)) { 08768 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 08769 return -2; /* Syntax error */ 08770 } 08771 h_refer_to = ast_strdupa(p_refer_to); 08772 refer_to = get_in_brackets(h_refer_to); 08773 if (pedanticsipchecking) 08774 ast_uri_decode(refer_to); 08775 08776 if (strncasecmp(refer_to, "sip:", 4)) { 08777 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 08778 return -3; 08779 } 08780 refer_to += 4; /* Skip sip: */ 08781 08782 /* Get referred by header if it exists */ 08783 p_referred_by = get_header(req, "Referred-By"); 08784 if (!ast_strlen_zero(p_referred_by)) { 08785 char *lessthan; 08786 h_referred_by = ast_strdupa(p_referred_by); 08787 if (pedanticsipchecking) 08788 ast_uri_decode(h_referred_by); 08789 08790 /* Store referrer's caller ID name */ 08791 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 08792 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 08793 *(lessthan - 1) = '\0'; /* Space */ 08794 } 08795 08796 referred_by_uri = get_in_brackets(h_referred_by); 08797 if(strncasecmp(referred_by_uri, "sip:", 4)) { 08798 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 08799 referred_by_uri = (char *) NULL; 08800 } else { 08801 referred_by_uri += 4; /* Skip sip: */ 08802 } 08803 } 08804 08805 /* Check for arguments in the refer_to header */ 08806 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 08807 *ptr++ = '\0'; 08808 if (!strncasecmp(ptr, "REPLACES=", 9)) { 08809 char *to = NULL, *from = NULL; 08810 08811 /* This is an attended transfer */ 08812 referdata->attendedtransfer = 1; 08813 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 08814 ast_uri_decode(referdata->replaces_callid); 08815 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 08816 *ptr++ = '\0'; 08817 } 08818 08819 if (ptr) { 08820 /* Find the different tags before we destroy the string */ 08821 to = strcasestr(ptr, "to-tag="); 08822 from = strcasestr(ptr, "from-tag="); 08823 } 08824 08825 /* Grab the to header */ 08826 if (to) { 08827 ptr = to + 7; 08828 if ((to = strchr(ptr, '&'))) 08829 *to = '\0'; 08830 if ((to = strchr(ptr, ';'))) 08831 *to = '\0'; 08832 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 08833 } 08834 08835 if (from) { 08836 ptr = from + 9; 08837 if ((to = strchr(ptr, '&'))) 08838 *to = '\0'; 08839 if ((to = strchr(ptr, ';'))) 08840 *to = '\0'; 08841 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 08842 } 08843 08844 if (option_debug > 1) { 08845 if (!pedanticsipchecking) 08846 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 08847 else 08848 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>" ); 08849 } 08850 } 08851 } 08852 08853 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 08854 char *urioption; 08855 08856 *ptr++ = '\0'; 08857 if ((urioption = strchr(ptr, ';'))) 08858 *urioption++ = '\0'; 08859 /* Save the domain for the dial plan */ 08860 ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain)); 08861 if (urioption) 08862 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 08863 } 08864 08865 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 08866 *ptr = '\0'; 08867 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 08868 08869 if (referred_by_uri) { 08870 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 08871 *ptr = '\0'; 08872 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 08873 } else { 08874 referdata->referred_by[0] = '\0'; 08875 } 08876 08877 /* Determine transfer context */ 08878 if (transferer->owner) /* Mimic behaviour in res_features.c */ 08879 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 08880 08881 /* By default, use the context in the channel sending the REFER */ 08882 if (ast_strlen_zero(transfer_context)) { 08883 transfer_context = S_OR(transferer->owner->macrocontext, 08884 S_OR(transferer->context, default_context)); 08885 } 08886 08887 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 08888 08889 /* Either an existing extension or the parking extension */ 08890 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 08891 if (sip_debug_test_pvt(transferer)) { 08892 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 08893 } 08894 /* We are ready to transfer to the extension */ 08895 return 0; 08896 } 08897 if (sip_debug_test_pvt(transferer)) 08898 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 08899 08900 /* Failure, we can't find this extension */ 08901 return -1; 08902 }
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 9060 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09061 { 09062 char *start; 09063 char *end; 09064 09065 start = strchr(input,':'); 09066 if (!start) { 09067 output[0] = '\0'; 09068 return 0; 09069 } 09070 start++; 09071 09072 /* we found "number" */ 09073 ast_copy_string(output,start,maxlen); 09074 output[maxlen-1] = '\0'; 09075 09076 end = strchr(output,'@'); 09077 if (end) 09078 *end = '\0'; 09079 else 09080 output[0] = '\0'; 09081 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09082 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09083 09084 return 0; 09085 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4060 of file chan_sip.c.
References get_sdp_iterate().
04061 { 04062 int dummy = 0; 04063 04064 return get_sdp_iterate(&dummy, req, name); 04065 }
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 4046 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
04047 { 04048 int len = strlen(name); 04049 04050 while (*start < req->sdp_end) { 04051 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04052 if (r[0] != '\0') 04053 return r; 04054 } 04055 04056 return ""; 04057 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static, read] |
Lock interface lock and find matching pvt lock
Definition at line 8693 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().
08694 { 08695 struct sip_pvt *sip_pvt_ptr; 08696 08697 ast_mutex_lock(&iflock); 08698 08699 if (option_debug > 3 && totag) 08700 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08701 08702 /* Search interfaces and find the match */ 08703 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08704 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08705 int match = 1; 08706 char *ourtag = sip_pvt_ptr->tag; 08707 08708 /* Go ahead and lock it (and its owner) before returning */ 08709 ast_mutex_lock(&sip_pvt_ptr->lock); 08710 08711 /* Check if tags match. If not, this is not the call we want 08712 (With a forking SIP proxy, several call legs share the 08713 call id, but have different tags) 08714 */ 08715 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, ourtag)))) 08716 match = 0; 08717 08718 if (!match) { 08719 ast_mutex_unlock(&sip_pvt_ptr->lock); 08720 continue; 08721 } 08722 08723 if (option_debug > 3 && totag) 08724 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08725 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08726 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08727 08728 /* deadlock avoidance... */ 08729 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08730 ast_mutex_unlock(&sip_pvt_ptr->lock); 08731 usleep(1); 08732 ast_mutex_lock(&sip_pvt_ptr->lock); 08733 } 08734 break; 08735 } 08736 } 08737 ast_mutex_unlock(&iflock); 08738 if (option_debug > 3 && !sip_pvt_ptr) 08739 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08740 return sip_pvt_ptr; 08741 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13008 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
13009 { 13010 const char *thetag; 13011 13012 if (!tagbuf) 13013 return NULL; 13014 tagbuf[0] = '\0'; /* reset the buffer */ 13015 thetag = get_header(req, header); 13016 thetag = strcasestr(thetag, ";tag="); 13017 if (thetag) { 13018 thetag += 5; 13019 ast_copy_string(tagbuf, thetag, tagbufsize); 13020 return strsep(&tagbuf, ";"); 13021 } 13022 return NULL; 13023 }
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 15713 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, set_insecure_flags(), SIP_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_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
15714 { 15715 int res = 1; 15716 static int dep_insecure_very = 0; 15717 static int dep_insecure_yes = 0; 15718 15719 if (!strcasecmp(v->name, "trustrpid")) { 15720 ast_set_flag(&mask[0], SIP_TRUSTRPID); 15721 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 15722 } else if (!strcasecmp(v->name, "sendrpid")) { 15723 ast_set_flag(&mask[0], SIP_SENDRPID); 15724 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 15725 } else if (!strcasecmp(v->name, "g726nonstandard")) { 15726 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 15727 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 15728 } else if (!strcasecmp(v->name, "useclientcode")) { 15729 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 15730 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 15731 } else if (!strcasecmp(v->name, "dtmfmode")) { 15732 ast_set_flag(&mask[0], SIP_DTMF); 15733 ast_clear_flag(&flags[0], SIP_DTMF); 15734 if (!strcasecmp(v->value, "inband")) 15735 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 15736 else if (!strcasecmp(v->value, "rfc2833")) 15737 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15738 else if (!strcasecmp(v->value, "info")) 15739 ast_set_flag(&flags[0], SIP_DTMF_INFO); 15740 else if (!strcasecmp(v->value, "auto")) 15741 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 15742 else { 15743 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 15744 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15745 } 15746 } else if (!strcasecmp(v->name, "nat")) { 15747 ast_set_flag(&mask[0], SIP_NAT); 15748 ast_clear_flag(&flags[0], SIP_NAT); 15749 if (!strcasecmp(v->value, "never")) 15750 ast_set_flag(&flags[0], SIP_NAT_NEVER); 15751 else if (!strcasecmp(v->value, "route")) 15752 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 15753 else if (ast_true(v->value)) 15754 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 15755 else 15756 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 15757 } else if (!strcasecmp(v->name, "canreinvite")) { 15758 ast_set_flag(&mask[0], SIP_REINVITE); 15759 ast_clear_flag(&flags[0], SIP_REINVITE); 15760 set_insecure_flags(flags, v->value, v->lineno); 15761 } else if (!strcasecmp(v->name, "insecure")) { 15762 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15763 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15764 if (!strcasecmp(v->value, "very")) { 15765 ast_set_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15766 if (!dep_insecure_very) { 15767 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", v->lineno); 15768 dep_insecure_very = 1; 15769 } 15770 } 15771 else if (ast_true(v->value)) { 15772 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15773 if (!dep_insecure_yes) { 15774 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", v->value, v->lineno); 15775 dep_insecure_yes = 1; 15776 } 15777 } 15778 else if (!ast_false(v->value)) { 15779 char buf[64]; 15780 char *word, *next; 15781 15782 ast_copy_string(buf, v->value, sizeof(buf)); 15783 next = buf; 15784 while ((word = strsep(&next, ","))) { 15785 if (!strcasecmp(word, "port")) 15786 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15787 else if (!strcasecmp(word, "invite")) 15788 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 15789 else 15790 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 15791 } 15792 } 15793 } else if (!strcasecmp(v->name, "progressinband")) { 15794 ast_set_flag(&mask[0], SIP_PROG_INBAND); 15795 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 15796 if (ast_true(v->value)) 15797 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 15798 else if (strcasecmp(v->value, "never")) 15799 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 15800 } else if (!strcasecmp(v->name, "promiscredir")) { 15801 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 15802 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 15803 } else if (!strcasecmp(v->name, "videosupport")) { 15804 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 15805 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 15806 } else if (!strcasecmp(v->name, "allowoverlap")) { 15807 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 15808 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 15809 } else if (!strcasecmp(v->name, "allowsubscribe")) { 15810 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 15811 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 15812 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 15813 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 15814 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 15815 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 15816 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 15817 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 15818 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 15819 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 15820 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 15821 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 15822 #endif 15823 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 15824 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 15825 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 15826 } else if (!strcasecmp(v->name, "buggymwi")) { 15827 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 15828 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 15829 } else 15830 res = 0; 15831 15832 return res; 15833 }
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 13181 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree(), ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13182 { 13183 struct ast_frame *f; 13184 int earlyreplace = 0; 13185 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13186 struct ast_channel *c = p->owner; /* Our incoming call */ 13187 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13188 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13189 13190 /* Check if we're in ring state */ 13191 if (replacecall->_state == AST_STATE_RING) 13192 earlyreplace = 1; 13193 13194 /* Check if we have a bridge */ 13195 if (!(targetcall = ast_bridged_channel(replacecall))) { 13196 /* We have no bridge */ 13197 if (!earlyreplace) { 13198 if (option_debug > 1) 13199 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13200 oneleggedreplace = 1; 13201 } 13202 } 13203 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13204 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13205 13206 if (option_debug > 3) { 13207 if (targetcall) 13208 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); 13209 else 13210 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13211 } 13212 13213 if (ignore) { 13214 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13215 /* We should answer something here. If we are here, the 13216 call we are replacing exists, so an accepted 13217 can't harm */ 13218 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13219 /* Do something more clever here */ 13220 ast_channel_unlock(c); 13221 ast_mutex_unlock(&p->refer->refer_call->lock); 13222 return 1; 13223 } 13224 if (!c) { 13225 /* What to do if no channel ??? */ 13226 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13227 transmit_response_reliable(p, "503 Service Unavailable", req); 13228 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13229 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13230 ast_mutex_unlock(&p->refer->refer_call->lock); 13231 return 1; 13232 } 13233 append_history(p, "Xfer", "INVITE/Replace received"); 13234 /* We have three channels to play with 13235 channel c: New incoming call 13236 targetcall: Call from PBX to target 13237 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13238 replacecall: The owner of the previous 13239 We need to masq C into refer_call to connect to 13240 targetcall; 13241 If we are talking to internal audio stream, target call is null. 13242 */ 13243 13244 /* Fake call progress */ 13245 transmit_response(p, "100 Trying", req); 13246 ast_setstate(c, AST_STATE_RING); 13247 13248 /* Masquerade the new call into the referred call to connect to target call 13249 Targetcall is not touched by the masq */ 13250 13251 /* Answer the incoming call and set channel to UP state */ 13252 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13253 13254 ast_setstate(c, AST_STATE_UP); 13255 13256 /* Stop music on hold and other generators */ 13257 ast_quiet_chan(replacecall); 13258 ast_quiet_chan(targetcall); 13259 if (option_debug > 3) 13260 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13261 /* Unlock clone, but not original (replacecall) */ 13262 ast_channel_unlock(c); 13263 13264 /* Unlock PVT */ 13265 ast_mutex_unlock(&p->refer->refer_call->lock); 13266 13267 /* Make sure that the masq does not free our PVT for the old call */ 13268 if (! earlyreplace && ! oneleggedreplace ) 13269 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13270 13271 /* Prepare the masquerade - if this does not happen, we will be gone */ 13272 if(ast_channel_masquerade(replacecall, c)) 13273 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13274 else if (option_debug > 3) 13275 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13276 13277 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13278 13279 /* C should now be in place of replacecall */ 13280 /* ast_read needs to lock channel */ 13281 ast_channel_unlock(c); 13282 13283 if (earlyreplace || oneleggedreplace ) { 13284 /* Force the masq to happen */ 13285 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13286 ast_frfree(f); 13287 f = NULL; 13288 if (option_debug > 3) 13289 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13290 } else { 13291 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13292 } 13293 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13294 ast_channel_unlock(replacecall); 13295 } else { /* Bridged call, UP channel */ 13296 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13297 /* Masq ok */ 13298 ast_frfree(f); 13299 f = NULL; 13300 if (option_debug > 2) 13301 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13302 } else { 13303 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13304 } 13305 ast_channel_unlock(replacecall); 13306 } 13307 ast_mutex_unlock(&p->refer->refer_call->lock); 13308 13309 ast_setstate(c, AST_STATE_DOWN); 13310 if (option_debug > 3) { 13311 struct ast_channel *test; 13312 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13313 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13314 if (replacecall) 13315 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13316 if (p->owner) { 13317 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13318 test = ast_bridged_channel(p->owner); 13319 if (test) 13320 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13321 else 13322 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13323 } else 13324 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13325 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13326 } 13327 13328 ast_channel_unlock(p->owner); /* Unlock new owner */ 13329 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13330 13331 /* The call should be down with no ast_channel, so hang it up */ 13332 c->tech_pvt = NULL; 13333 ast_hangup(c); 13334 return 0; 13335 }
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 14834 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, sip_pvt::icseq, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lastinvite, sip_pvt::lastmsg, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_pvt::method, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::pendinginvite, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, sip_pvt::sa, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
14835 { 14836 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 14837 relatively static */ 14838 const char *cmd; 14839 const char *cseq; 14840 const char *useragent; 14841 int seqno; 14842 int len; 14843 int ignore = FALSE; 14844 int respid; 14845 int res = 0; 14846 int debug = sip_debug_test_pvt(p); 14847 char *e; 14848 int error = 0; 14849 14850 /* Get Method and Cseq */ 14851 cseq = get_header(req, "Cseq"); 14852 cmd = req->header[0]; 14853 14854 /* Must have Cseq */ 14855 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 14856 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 14857 error = 1; 14858 } 14859 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 14860 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 14861 error = 1; 14862 } 14863 if (error) { 14864 if (!p->initreq.headers) /* New call */ 14865 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 14866 return -1; 14867 } 14868 /* Get the command XXX */ 14869 14870 cmd = req->rlPart1; 14871 e = req->rlPart2; 14872 14873 /* Save useragent of the client */ 14874 useragent = get_header(req, "User-Agent"); 14875 if (!ast_strlen_zero(useragent)) 14876 ast_string_field_set(p, useragent, useragent); 14877 14878 /* Find out SIP method for incoming request */ 14879 if (req->method == SIP_RESPONSE) { /* Response to our request */ 14880 /* Response to our request -- Do some sanity checks */ 14881 if (!p->initreq.headers) { 14882 if (option_debug) 14883 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 14884 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14885 return 0; 14886 } else if (p->ocseq && (p->ocseq < seqno)) { 14887 if (option_debug) 14888 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 14889 return -1; 14890 } else if (p->ocseq && (p->ocseq != seqno)) { 14891 /* ignore means "don't do anything with it" but still have to 14892 respond appropriately */ 14893 ignore = TRUE; 14894 ast_set_flag(req, SIP_PKT_IGNORE); 14895 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 14896 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14897 } else if (e) { 14898 e = ast_skip_blanks(e); 14899 if (sscanf(e, "%d %n", &respid, &len) != 1) { 14900 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 14901 } else { 14902 if (respid <= 0) { 14903 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 14904 return 0; 14905 } 14906 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 14907 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 14908 extract_uri(p, req); 14909 handle_response(p, respid, e + len, req, ignore, seqno); 14910 } 14911 } 14912 return 0; 14913 } 14914 14915 /* New SIP request coming in 14916 (could be new request in existing SIP dialog as well...) 14917 */ 14918 14919 p->method = req->method; /* Find out which SIP method they are using */ 14920 if (option_debug > 3) 14921 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 14922 14923 if (p->icseq && (p->icseq > seqno)) { 14924 if (option_debug) 14925 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 14926 if (req->method != SIP_ACK) 14927 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 14928 return -1; 14929 } else if (p->icseq && 14930 p->icseq == seqno && 14931 req->method != SIP_ACK && 14932 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 14933 /* ignore means "don't do anything with it" but still have to 14934 respond appropriately. We do this if we receive a repeat of 14935 the last sequence number */ 14936 ignore = 2; 14937 ast_set_flag(req, SIP_PKT_IGNORE); 14938 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 14939 if (option_debug > 2) 14940 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 14941 } 14942 14943 if (seqno >= p->icseq) 14944 /* Next should follow monotonically (but not necessarily 14945 incrementally -- thanks again to the genius authors of SIP -- 14946 increasing */ 14947 p->icseq = seqno; 14948 14949 /* Find their tag if we haven't got it */ 14950 if (ast_strlen_zero(p->theirtag)) { 14951 char tag[128]; 14952 14953 gettag(req, "From", tag, sizeof(tag)); 14954 ast_string_field_set(p, theirtag, tag); 14955 } 14956 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 14957 14958 if (pedanticsipchecking) { 14959 /* If this is a request packet without a from tag, it's not 14960 correct according to RFC 3261 */ 14961 /* Check if this a new request in a new dialog with a totag already attached to it, 14962 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 14963 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 14964 /* If this is a first request and it got a to-tag, it is not for us */ 14965 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 14966 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 14967 /* Will cease to exist after ACK */ 14968 } else if (req->method != SIP_ACK) { 14969 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 14970 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14971 } 14972 return res; 14973 } 14974 } 14975 14976 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 14977 transmit_response(p, "400 Bad request", req); 14978 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14979 return -1; 14980 } 14981 14982 /* Handle various incoming SIP methods in requests */ 14983 switch (p->method) { 14984 case SIP_OPTIONS: 14985 res = handle_request_options(p, req); 14986 break; 14987 case SIP_INVITE: 14988 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 14989 break; 14990 case SIP_REFER: 14991 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 14992 break; 14993 case SIP_CANCEL: 14994 res = handle_request_cancel(p, req); 14995 break; 14996 case SIP_BYE: 14997 res = handle_request_bye(p, req); 14998 break; 14999 case SIP_MESSAGE: 15000 res = handle_request_message(p, req); 15001 break; 15002 case SIP_SUBSCRIBE: 15003 res = handle_request_subscribe(p, req, sin, seqno, e); 15004 break; 15005 case SIP_REGISTER: 15006 res = handle_request_register(p, req, sin, e); 15007 break; 15008 case SIP_INFO: 15009 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15010 ast_verbose("Receiving INFO!\n"); 15011 if (!ignore) 15012 handle_request_info(p, req); 15013 else /* if ignoring, transmit response */ 15014 transmit_response(p, "200 OK", req); 15015 break; 15016 case SIP_NOTIFY: 15017 res = handle_request_notify(p, req, sin, seqno, e); 15018 break; 15019 case SIP_ACK: 15020 /* Make sure we don't ignore this */ 15021 if (seqno == p->pendinginvite) { 15022 p->invitestate = INV_TERMINATED; 15023 p->pendinginvite = 0; 15024 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15025 if (find_sdp(req)) { 15026 if (process_sdp(p, req)) 15027 return -1; 15028 } 15029 check_pendings(p); 15030 } 15031 /* Got an ACK that we did not match. Ignore silently */ 15032 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15033 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15034 break; 15035 default: 15036 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15037 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15038 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15039 /* If this is some new method, and we don't have a call, destroy it now */ 15040 if (!p->initreq.headers) 15041 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15042 break; 15043 } 15044 return res; 15045 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14401 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
14402 { 14403 struct ast_channel *c=NULL; 14404 int res; 14405 struct ast_channel *bridged_to; 14406 14407 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14408 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14409 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14410 14411 p->invitestate = INV_TERMINATED; 14412 14413 copy_request(&p->initreq, req); 14414 check_via(p, req); 14415 sip_alreadygone(p); 14416 14417 /* Get RTCP quality before end of call */ 14418 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14419 char *audioqos, *videoqos; 14420 if (p->rtp) { 14421 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14422 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14423 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14424 if (p->owner) 14425 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14426 } 14427 if (p->vrtp) { 14428 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14429 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14430 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14431 if (p->owner) 14432 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14433 } 14434 } 14435 14436 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14437 14438 if (!ast_strlen_zero(get_header(req, "Also"))) { 14439 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14440 ast_inet_ntoa(p->recv.sin_addr)); 14441 if (ast_strlen_zero(p->context)) 14442 ast_string_field_set(p, context, default_context); 14443 res = get_also_info(p, req); 14444 if (!res) { 14445 c = p->owner; 14446 if (c) { 14447 bridged_to = ast_bridged_channel(c); 14448 if (bridged_to) { 14449 /* Don't actually hangup here... */ 14450 ast_queue_control(c, AST_CONTROL_UNHOLD); 14451 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14452 } else 14453 ast_queue_hangup(p->owner); 14454 } 14455 } else { 14456 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14457 if (p->owner) 14458 ast_queue_hangup(p->owner); 14459 } 14460 } else if (p->owner) { 14461 ast_queue_hangup(p->owner); 14462 if (option_debug > 2) 14463 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14464 } else { 14465 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14466 if (option_debug > 2) 14467 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14468 } 14469 transmit_response(p, "200 OK", req); 14470 14471 return 1; 14472 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14303 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, sip_pvt::initreq, INV_CANCELLED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
14304 { 14305 14306 check_via(p, req); 14307 sip_alreadygone(p); 14308 p->invitestate = INV_CANCELLED; 14309 14310 if (p->owner && p->owner->_state == AST_STATE_UP) { 14311 /* This call is up, cancel is ignored, we need a bye */ 14312 transmit_response(p, "200 OK", req); 14313 if (option_debug) 14314 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14315 return 0; 14316 } 14317 14318 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14319 update_call_counter(p, DEC_CALL_LIMIT); 14320 14321 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14322 14323 if (p->owner) 14324 ast_queue_hangup(p->owner); 14325 else 14326 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14327 if (p->initreq.len > 0) { 14328 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14329 transmit_response(p, "200 OK", req); 14330 return 1; 14331 } else { 14332 transmit_response(p, "481 Call Leg Does Not Exist", req); 14333 return 0; 14334 } 14335 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 10886 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, sip_pvt::flags, get_body(), get_header(), ast_frame::len, LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, ast_frame::subclass, and transmit_response().
Referenced by handle_request().
10887 { 10888 char buf[1024]; 10889 unsigned int event; 10890 const char *c = get_header(req, "Content-Type"); 10891 10892 /* Need to check the media/type */ 10893 if (!strcasecmp(c, "application/dtmf-relay") || 10894 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 10895 unsigned int duration = 0; 10896 10897 /* Try getting the "signal=" part */ 10898 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 10899 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 10900 transmit_response(p, "200 OK", req); /* Should return error */ 10901 return; 10902 } else { 10903 ast_copy_string(buf, c, sizeof(buf)); 10904 } 10905 10906 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 10907 duration = atoi(c); 10908 if (!duration) 10909 duration = 100; /* 100 ms */ 10910 10911 if (!p->owner) { /* not a PBX call */ 10912 transmit_response(p, "481 Call leg/transaction does not exist", req); 10913 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10914 return; 10915 } 10916 10917 if (ast_strlen_zero(buf)) { 10918 transmit_response(p, "200 OK", req); 10919 return; 10920 } 10921 10922 if (buf[0] == '*') 10923 event = 10; 10924 else if (buf[0] == '#') 10925 event = 11; 10926 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 10927 event = 12 + buf[0] - 'A'; 10928 else 10929 event = atoi(buf); 10930 if (event == 16) { 10931 /* send a FLASH event */ 10932 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 10933 ast_queue_frame(p->owner, &f); 10934 if (sipdebug) 10935 ast_verbose("* DTMF-relay event received: FLASH\n"); 10936 } else { 10937 /* send a DTMF event */ 10938 struct ast_frame f = { AST_FRAME_DTMF, }; 10939 if (event < 10) { 10940 f.subclass = '0' + event; 10941 } else if (event < 11) { 10942 f.subclass = '*'; 10943 } else if (event < 12) { 10944 f.subclass = '#'; 10945 } else if (event < 16) { 10946 f.subclass = 'A' + (event - 12); 10947 } 10948 f.len = duration; 10949 ast_queue_frame(p->owner, &f); 10950 if (sipdebug) 10951 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 10952 } 10953 transmit_response(p, "200 OK", req); 10954 return; 10955 } else if (!strcasecmp(c, "application/media_control+xml")) { 10956 /* Eh, we'll just assume it's a fast picture update for now */ 10957 if (p->owner) 10958 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 10959 transmit_response(p, "200 OK", req); 10960 return; 10961 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 10962 /* Client code (from SNOM phone) */ 10963 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 10964 if (p->owner && p->owner->cdr) 10965 ast_cdr_setuserfield(p->owner, c); 10966 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 10967 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 10968 transmit_response(p, "200 OK", req); 10969 } else { 10970 transmit_response(p, "403 Unauthorized", req); 10971 } 10972 return; 10973 } 10974 /* Other type of INFO message, not really understood by Asterisk */ 10975 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 10976 10977 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 10978 transmit_response(p, "415 Unsupported media type", req); 10979 return; 10980 }
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 13344 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, ast_channel::lock, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
13345 { 13346 int res = 1; 13347 int gotdest; 13348 const char *p_replaces; 13349 char *replace_id = NULL; 13350 const char *required; 13351 unsigned int required_profile = 0; 13352 struct ast_channel *c = NULL; /* New channel */ 13353 int reinvite = 0; 13354 13355 /* Find out what they support */ 13356 if (!p->sipoptions) { 13357 const char *supported = get_header(req, "Supported"); 13358 if (!ast_strlen_zero(supported)) 13359 parse_sip_options(p, supported); 13360 } 13361 13362 /* Find out what they require */ 13363 required = get_header(req, "Require"); 13364 if (!ast_strlen_zero(required)) { 13365 required_profile = parse_sip_options(NULL, required); 13366 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13367 /* At this point we only support REPLACES */ 13368 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13369 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13370 p->invitestate = INV_COMPLETED; 13371 if (!p->lastinvite) 13372 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13373 return -1; 13374 } 13375 } 13376 13377 /* Check if this is a loop */ 13378 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13379 /* This is a call to ourself. Send ourselves an error code and stop 13380 processing immediately, as SIP really has no good mechanism for 13381 being able to call yourself */ 13382 /* If pedantic is on, we need to check the tags. If they're different, this is 13383 in fact a forked call through a SIP proxy somewhere. */ 13384 transmit_response(p, "482 Loop Detected", req); 13385 p->invitestate = INV_COMPLETED; 13386 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13387 return 0; 13388 } 13389 13390 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13391 /* We already have a pending invite. Sorry. You are on hold. */ 13392 transmit_response(p, "491 Request Pending", req); 13393 if (option_debug) 13394 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13395 /* Don't destroy dialog here */ 13396 return 0; 13397 } 13398 13399 p_replaces = get_header(req, "Replaces"); 13400 if (!ast_strlen_zero(p_replaces)) { 13401 /* We have a replaces header */ 13402 char *ptr; 13403 char *fromtag = NULL; 13404 char *totag = NULL; 13405 char *start, *to; 13406 int error = 0; 13407 13408 if (p->owner) { 13409 if (option_debug > 2) 13410 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13411 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13412 /* Do not destroy existing call */ 13413 return -1; 13414 } 13415 13416 if (sipdebug && option_debug > 2) 13417 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13418 /* Create a buffer we can manipulate */ 13419 replace_id = ast_strdupa(p_replaces); 13420 ast_uri_decode(replace_id); 13421 13422 if (!p->refer && !sip_refer_allocate(p)) { 13423 transmit_response(p, "500 Server Internal Error", req); 13424 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13425 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13426 p->invitestate = INV_COMPLETED; 13427 return -1; 13428 } 13429 13430 /* Todo: (When we find phones that support this) 13431 if the replaces header contains ";early-only" 13432 we can only replace the call in early 13433 stage, not after it's up. 13434 13435 If it's not in early mode, 486 Busy. 13436 */ 13437 13438 /* Skip leading whitespace */ 13439 replace_id = ast_skip_blanks(replace_id); 13440 13441 start = replace_id; 13442 while ( (ptr = strsep(&start, ";")) ) { 13443 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13444 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13445 totag = to + 7; /* skip the keyword */ 13446 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13447 fromtag = to + 9; /* skip the keyword */ 13448 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13449 } 13450 } 13451 13452 if (sipdebug && option_debug > 3) 13453 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>"); 13454 13455 13456 /* Try to find call that we are replacing 13457 If we have a Replaces header, we need to cancel that call if we succeed with this call 13458 */ 13459 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13460 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13461 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13462 error = 1; 13463 } 13464 13465 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13466 13467 /* The matched call is the call from the transferer to Asterisk . 13468 We want to bridge the bridged part of the call to the 13469 incoming invite, thus taking over the refered call */ 13470 13471 if (p->refer->refer_call == p) { 13472 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13473 p->refer->refer_call = NULL; 13474 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13475 error = 1; 13476 } 13477 13478 if (!error && !p->refer->refer_call->owner) { 13479 /* Oops, someting wrong anyway, no owner, no call */ 13480 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13481 /* Check for better return code */ 13482 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13483 error = 1; 13484 } 13485 13486 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 ) { 13487 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13488 transmit_response(p, "603 Declined (Replaces)", req); 13489 error = 1; 13490 } 13491 13492 if (error) { /* Give up this dialog */ 13493 append_history(p, "Xfer", "INVITE/Replace Failed."); 13494 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13495 ast_mutex_unlock(&p->lock); 13496 if (p->refer->refer_call) { 13497 ast_mutex_unlock(&p->refer->refer_call->lock); 13498 ast_channel_unlock(p->refer->refer_call->owner); 13499 } 13500 p->invitestate = INV_COMPLETED; 13501 return -1; 13502 } 13503 } 13504 13505 13506 /* Check if this is an INVITE that sets up a new dialog or 13507 a re-invite in an existing dialog */ 13508 13509 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13510 int newcall = (p->initreq.headers ? TRUE : FALSE); 13511 13512 sip_cancel_destroy(p); 13513 /* This also counts as a pending invite */ 13514 p->pendinginvite = seqno; 13515 check_via(p, req); 13516 13517 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13518 if (!p->owner) { /* Not a re-invite */ 13519 if (debug) 13520 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13521 if (newcall) 13522 append_history(p, "Invite", "New call: %s", p->callid); 13523 parse_ok_contact(p, req); 13524 } else { /* Re-invite on existing call */ 13525 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13526 /* Handle SDP here if we already have an owner */ 13527 if (find_sdp(req)) { 13528 if (process_sdp(p, req)) { 13529 transmit_response(p, "488 Not acceptable here", req); 13530 if (!p->lastinvite) 13531 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13532 return -1; 13533 } 13534 } else { 13535 p->jointcapability = p->capability; 13536 if (option_debug > 2) 13537 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13538 /* Some devices signal they want to be put off hold by sending a re-invite 13539 *without* an SDP, which is supposed to mean "Go back to your state" 13540 and since they put os on remote hold, we go back to off hold */ 13541 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 13542 change_hold_state(p, req, FALSE, 0); 13543 } 13544 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13545 append_history(p, "ReInv", "Re-invite received"); 13546 } 13547 } else if (debug) 13548 ast_verbose("Ignoring this INVITE request\n"); 13549 13550 13551 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13552 /* This is a new invite */ 13553 /* Handle authentication if this is our first invite */ 13554 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13555 if (res == AUTH_CHALLENGE_SENT) { 13556 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13557 return 0; 13558 } 13559 if (res < 0) { /* Something failed in authentication */ 13560 if (res == AUTH_FAKE_AUTH) { 13561 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13562 transmit_fake_auth_response(p, req, 1); 13563 } else { 13564 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13565 transmit_response_reliable(p, "403 Forbidden", req); 13566 } 13567 p->invitestate = INV_COMPLETED; 13568 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13569 ast_string_field_free(p, theirtag); 13570 return 0; 13571 } 13572 13573 /* We have a succesful authentication, process the SDP portion if there is one */ 13574 if (find_sdp(req)) { 13575 if (process_sdp(p, req)) { 13576 /* Unacceptable codecs */ 13577 transmit_response_reliable(p, "488 Not acceptable here", req); 13578 p->invitestate = INV_COMPLETED; 13579 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13580 if (option_debug) 13581 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13582 return -1; 13583 } 13584 } else { /* No SDP in invite, call control session */ 13585 p->jointcapability = p->capability; 13586 if (option_debug > 1) 13587 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13588 } 13589 13590 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13591 /* This seems redundant ... see !p-owner above */ 13592 if (p->owner) 13593 ast_queue_frame(p->owner, &ast_null_frame); 13594 13595 13596 /* Initialize the context if it hasn't been already */ 13597 if (ast_strlen_zero(p->context)) 13598 ast_string_field_set(p, context, default_context); 13599 13600 13601 /* Check number of concurrent calls -vs- incoming limit HERE */ 13602 if (option_debug) 13603 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13604 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13605 if (res < 0) { 13606 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13607 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13608 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13609 p->invitestate = INV_COMPLETED; 13610 } 13611 return 0; 13612 } 13613 gotdest = get_destination(p, NULL); /* Get destination right away */ 13614 get_rdnis(p, NULL); /* Get redirect information */ 13615 extract_uri(p, req); /* Get the Contact URI */ 13616 build_contact(p); /* Build our contact header */ 13617 13618 if (p->rtp) { 13619 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13620 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13621 } 13622 13623 if (!replace_id && gotdest) { /* No matching extension found */ 13624 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13625 transmit_response_reliable(p, "484 Address Incomplete", req); 13626 else 13627 transmit_response_reliable(p, "404 Not Found", req); 13628 p->invitestate = INV_COMPLETED; 13629 update_call_counter(p, DEC_CALL_LIMIT); 13630 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13631 return 0; 13632 } else { 13633 /* If no extension was specified, use the s one */ 13634 /* Basically for calling to IP/Host name only */ 13635 if (ast_strlen_zero(p->exten)) 13636 ast_string_field_set(p, exten, "s"); 13637 /* Initialize our tag */ 13638 13639 make_our_tag(p->tag, sizeof(p->tag)); 13640 /* First invitation - create the channel */ 13641 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13642 *recount = 1; 13643 13644 /* Save Record-Route for any later requests we make on this dialogue */ 13645 build_route(p, req, 0); 13646 13647 if (c) { 13648 /* Pre-lock the call */ 13649 ast_channel_lock(c); 13650 } 13651 } 13652 } else { 13653 if (option_debug > 1 && sipdebug) { 13654 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13655 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13656 else 13657 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13658 } 13659 reinvite = 1; 13660 c = p->owner; 13661 } 13662 13663 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 13664 p->lastinvite = seqno; 13665 13666 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 13667 /* Go and take over the target call */ 13668 if (sipdebug && option_debug > 3) 13669 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 13670 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 13671 } 13672 13673 13674 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 13675 switch(c->_state) { 13676 case AST_STATE_DOWN: 13677 if (option_debug > 1) 13678 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 13679 transmit_response(p, "100 Trying", req); 13680 p->invitestate = INV_PROCEEDING; 13681 ast_setstate(c, AST_STATE_RING); 13682 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 13683 enum ast_pbx_result res; 13684 13685 res = ast_pbx_start(c); 13686 13687 switch(res) { 13688 case AST_PBX_FAILED: 13689 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 13690 p->invitestate = INV_COMPLETED; 13691 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13692 transmit_response(p, "503 Unavailable", req); 13693 else 13694 transmit_response_reliable(p, "503 Unavailable", req); 13695 break; 13696 case AST_PBX_CALL_LIMIT: 13697 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 13698 p->invitestate = INV_COMPLETED; 13699 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13700 transmit_response(p, "480 Temporarily Unavailable", req); 13701 else 13702 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 13703 break; 13704 case AST_PBX_SUCCESS: 13705 /* nothing to do */ 13706 break; 13707 } 13708 13709 if (res) { 13710 13711 /* Unlock locks so ast_hangup can do its magic */ 13712 ast_mutex_unlock(&c->lock); 13713 ast_mutex_unlock(&p->lock); 13714 ast_hangup(c); 13715 ast_mutex_lock(&p->lock); 13716 c = NULL; 13717 } 13718 } else { /* Pickup call in call group */ 13719 ast_channel_unlock(c); 13720 *nounlock = 1; 13721 if (ast_pickup_call(c)) { 13722 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 13723 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13724 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 13725 else 13726 transmit_response_reliable(p, "503 Unavailable", req); 13727 sip_alreadygone(p); 13728 /* Unlock locks so ast_hangup can do its magic */ 13729 ast_mutex_unlock(&p->lock); 13730 c->hangupcause = AST_CAUSE_CALL_REJECTED; 13731 } else { 13732 ast_mutex_unlock(&p->lock); 13733 ast_setstate(c, AST_STATE_DOWN); 13734 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13735 } 13736 p->invitestate = INV_COMPLETED; 13737 ast_hangup(c); 13738 ast_mutex_lock(&p->lock); 13739 c = NULL; 13740 } 13741 break; 13742 case AST_STATE_RING: 13743 transmit_response(p, "100 Trying", req); 13744 p->invitestate = INV_PROCEEDING; 13745 break; 13746 case AST_STATE_RINGING: 13747 transmit_response(p, "180 Ringing", req); 13748 p->invitestate = INV_PROCEEDING; 13749 break; 13750 case AST_STATE_UP: 13751 if (option_debug > 1) 13752 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 13753 13754 transmit_response(p, "100 Trying", req); 13755 13756 if (p->t38.state == T38_PEER_REINVITE) { 13757 struct ast_channel *bridgepeer = NULL; 13758 struct sip_pvt *bridgepvt = NULL; 13759 13760 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13761 /* 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*/ 13762 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 13763 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13764 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13765 if (bridgepvt->t38.state == T38_DISABLED) { 13766 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 13767 /* Send re-invite to the bridged channel */ 13768 sip_handle_t38_reinvite(bridgepeer, p, 1); 13769 } else { /* Something is wrong with peers udptl struct */ 13770 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 13771 ast_mutex_lock(&bridgepvt->lock); 13772 bridgepvt->t38.state = T38_DISABLED; 13773 ast_mutex_unlock(&bridgepvt->lock); 13774 if (option_debug > 1) 13775 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 13776 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13777 transmit_response(p, "488 Not acceptable here", req); 13778 else 13779 transmit_response_reliable(p, "488 Not acceptable here", req); 13780 13781 } 13782 } else { 13783 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 13784 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13785 p->t38.state = T38_ENABLED; 13786 if (option_debug) 13787 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13788 } 13789 } else { 13790 /* Other side is not a SIP channel */ 13791 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13792 transmit_response(p, "488 Not acceptable here", req); 13793 else 13794 transmit_response_reliable(p, "488 Not acceptable here", req); 13795 p->t38.state = T38_DISABLED; 13796 if (option_debug > 1) 13797 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13798 13799 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 13800 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13801 } 13802 } else { 13803 /* we are not bridged in a call */ 13804 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13805 p->t38.state = T38_ENABLED; 13806 if (option_debug) 13807 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13808 } 13809 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 13810 int sendok = TRUE; 13811 13812 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 13813 /* so handle it here (re-invite other party to RTP) */ 13814 struct ast_channel *bridgepeer = NULL; 13815 struct sip_pvt *bridgepvt = NULL; 13816 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13817 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13818 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13819 /* Does the bridged peer have T38 ? */ 13820 if (bridgepvt->t38.state == T38_ENABLED) { 13821 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 13822 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 13823 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13824 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 13825 else 13826 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 13827 sendok = FALSE; 13828 } 13829 /* No bridged peer with T38 enabled*/ 13830 } 13831 } 13832 /* Respond to normal re-invite */ 13833 if (sendok) 13834 /* If this is not a re-invite or something to ignore - it's critical */ 13835 transmit_response_with_sdp(p, "200 OK", req, (reinvite || ast_test_flag(req, SIP_PKT_IGNORE)) ? XMIT_UNRELIABLE : XMIT_CRITICAL); 13836 } 13837 p->invitestate = INV_TERMINATED; 13838 break; 13839 default: 13840 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 13841 transmit_response(p, "100 Trying", req); 13842 break; 13843 } 13844 } else { 13845 if (p && (p->autokillid == -1)) { 13846 const char *msg; 13847 13848 if (!p->jointcapability) 13849 msg = "488 Not Acceptable Here (codec error)"; 13850 else { 13851 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 13852 msg = "503 Unavailable"; 13853 } 13854 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13855 transmit_response(p, msg, req); 13856 else 13857 transmit_response_reliable(p, msg, req); 13858 p->invitestate = INV_COMPLETED; 13859 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13860 } 13861 } 13862 return res; 13863 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14475 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().
14476 { 14477 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14478 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14479 ast_verbose("Receiving message!\n"); 14480 receive_message(p, req); 14481 } else 14482 transmit_response(p, "202 Accepted", req); 14483 return 1; 14484 }
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 13026 of file chan_sip.c.
References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13027 { 13028 /* This is mostly a skeleton for future improvements */ 13029 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13030 int res = 0; 13031 const char *event = get_header(req, "Event"); 13032 char *eventid = NULL; 13033 char *sep; 13034 13035 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13036 *sep++ = '\0'; 13037 eventid = sep; 13038 } 13039 13040 if (option_debug > 1 && sipdebug) 13041 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13042 13043 if (strcmp(event, "refer")) { 13044 /* We don't understand this event. */ 13045 /* Here's room to implement incoming voicemail notifications :-) */ 13046 transmit_response(p, "489 Bad event", req); 13047 res = -1; 13048 } else { 13049 /* Save nesting depth for now, since there might be other events we will 13050 support in the future */ 13051 13052 /* Handle REFER notifications */ 13053 13054 char buf[1024]; 13055 char *cmd, *code; 13056 int respcode; 13057 int success = TRUE; 13058 13059 /* EventID for each transfer... EventID is basically the REFER cseq 13060 13061 We are getting notifications on a call that we transfered 13062 We should hangup when we are getting a 200 OK in a sipfrag 13063 Check if we have an owner of this event */ 13064 13065 /* Check the content type */ 13066 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13067 /* We need a sipfrag */ 13068 transmit_response(p, "400 Bad request", req); 13069 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13070 return -1; 13071 } 13072 13073 /* Get the text of the attachment */ 13074 if (get_msg_text(buf, sizeof(buf), req)) { 13075 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13076 transmit_response(p, "400 Bad request", req); 13077 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13078 return -1; 13079 } 13080 13081 /* 13082 From the RFC... 13083 A minimal, but complete, implementation can respond with a single 13084 NOTIFY containing either the body: 13085 SIP/2.0 100 Trying 13086 13087 if the subscription is pending, the body: 13088 SIP/2.0 200 OK 13089 if the reference was successful, the body: 13090 SIP/2.0 503 Service Unavailable 13091 if the reference failed, or the body: 13092 SIP/2.0 603 Declined 13093 13094 if the REFER request was accepted before approval to follow the 13095 reference could be obtained and that approval was subsequently denied 13096 (see Section 2.4.7). 13097 13098 If there are several REFERs in the same dialog, we need to 13099 match the ID of the event header... 13100 */ 13101 if (option_debug > 2) 13102 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13103 cmd = ast_skip_blanks(buf); 13104 code = cmd; 13105 /* We are at SIP/2.0 */ 13106 while(*code && (*code > 32)) { /* Search white space */ 13107 code++; 13108 } 13109 *code++ = '\0'; 13110 code = ast_skip_blanks(code); 13111 sep = code; 13112 sep++; 13113 while(*sep && (*sep > 32)) { /* Search white space */ 13114 sep++; 13115 } 13116 *sep++ = '\0'; /* Response string */ 13117 respcode = atoi(code); 13118 switch (respcode) { 13119 case 100: /* Trying: */ 13120 case 101: /* dialog establishment */ 13121 /* Don't do anything yet */ 13122 break; 13123 case 183: /* Ringing: */ 13124 /* Don't do anything yet */ 13125 break; 13126 case 200: /* OK: The new call is up, hangup this call */ 13127 /* Hangup the call that we are replacing */ 13128 break; 13129 case 301: /* Moved permenantly */ 13130 case 302: /* Moved temporarily */ 13131 /* Do we get the header in the packet in this case? */ 13132 success = FALSE; 13133 break; 13134 case 503: /* Service Unavailable: The new call failed */ 13135 /* Cancel transfer, continue the call */ 13136 success = FALSE; 13137 break; 13138 case 603: /* Declined: Not accepted */ 13139 /* Cancel transfer, continue the current call */ 13140 success = FALSE; 13141 break; 13142 } 13143 if (!success) { 13144 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13145 } 13146 13147 /* Confirm that we received this packet */ 13148 transmit_response(p, "200 OK", req); 13149 }; 13150 13151 if (!p->lastinvite) 13152 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13153 13154 return res; 13155 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13158 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().
13159 { 13160 int res; 13161 13162 res = get_destination(p, req); 13163 build_contact(p); 13164 /* XXX Should we authenticate OPTIONS? XXX */ 13165 if (ast_strlen_zero(p->context)) 13166 ast_string_field_set(p, context, default_context); 13167 if (res < 0) 13168 transmit_response_with_allow(p, "404 Not Found", req, 0); 13169 else 13170 transmit_response_with_allow(p, "200 OK", req, 0); 13171 /* Destroy if this OPTIONS was the opening request, but not if 13172 it's in the middle of a normal call flow. */ 13173 if (!p->lastinvite) 13174 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13175 13176 return res; 13177 }
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 14031 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().
14032 { 14033 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14034 /* Chan2: Call between asterisk and transferee */ 14035 14036 int res = 0; 14037 14038 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14039 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"); 14040 14041 if (!p->owner) { 14042 /* This is a REFER outside of an existing SIP dialog */ 14043 /* We can't handle that, so decline it */ 14044 if (option_debug > 2) 14045 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14046 transmit_response(p, "603 Declined (No dialog)", req); 14047 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14048 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14049 sip_alreadygone(p); 14050 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14051 } 14052 return 0; 14053 } 14054 14055 14056 /* Check if transfer is allowed from this device */ 14057 if (p->allowtransfer == TRANSFER_CLOSED ) { 14058 /* Transfer not allowed, decline */ 14059 transmit_response(p, "603 Declined (policy)", req); 14060 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14061 /* Do not destroy SIP session */ 14062 return 0; 14063 } 14064 14065 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14066 /* Already have a pending REFER */ 14067 transmit_response(p, "491 Request pending", req); 14068 append_history(p, "Xfer", "Refer failed. Request pending."); 14069 return 0; 14070 } 14071 14072 /* Allocate memory for call transfer data */ 14073 if (!p->refer && !sip_refer_allocate(p)) { 14074 transmit_response(p, "500 Internal Server Error", req); 14075 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14076 return -3; 14077 } 14078 14079 res = get_refer_info(p, req); /* Extract headers */ 14080 14081 p->refer->status = REFER_SENT; 14082 14083 if (res != 0) { 14084 switch (res) { 14085 case -2: /* Syntax error */ 14086 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 14087 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 14088 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14089 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 14090 break; 14091 case -3: 14092 transmit_response(p, "603 Declined (Non sip: uri)", req); 14093 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 14094 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14095 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 14096 break; 14097 default: 14098 /* Refer-to extension not found, fake a failed transfer */ 14099 transmit_response(p, "202 Accepted", req); 14100 append_history(p, "Xfer", "Refer failed. Bad extension."); 14101 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 14102 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14103 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 14104 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 14105 break; 14106 } 14107 return 0; 14108 } 14109 if (ast_strlen_zero(p->context)) 14110 ast_string_field_set(p, context, default_context); 14111 14112 /* If we do not support SIP domains, all transfers are local */ 14113 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 14114 p->refer->localtransfer = 1; 14115 if (sipdebug && option_debug > 2) 14116 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 14117 } else if (AST_LIST_EMPTY(&domain_list)) { 14118 /* This PBX don't bother with SIP domains, so all transfers are local */ 14119 p->refer->localtransfer = 1; 14120 } else 14121 if (sipdebug && option_debug > 2) 14122 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 14123 14124 /* Is this a repeat of a current request? Ignore it */ 14125 /* Don't know what else to do right now. */ 14126 if (ignore) 14127 return res; 14128 14129 /* If this is a blind transfer, we have the following 14130 channels to work with: 14131 - chan1, chan2: The current call between transferer and transferee (2 channels) 14132 - target_channel: A new call from the transferee to the target (1 channel) 14133 We need to stay tuned to what happens in order to be able 14134 to bring back the call to the transferer */ 14135 14136 /* If this is a attended transfer, we should have all call legs within reach: 14137 - chan1, chan2: The call between the transferer and transferee (2 channels) 14138 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 14139 We want to bridge chan2 with targetcall_pvt! 14140 14141 The replaces call id in the refer message points 14142 to the call leg between Asterisk and the transferer. 14143 So we need to connect the target and the transferee channel 14144 and hangup the two other channels silently 14145 14146 If the target is non-local, the call ID could be on a remote 14147 machine and we need to send an INVITE with replaces to the 14148 target. We basically handle this as a blind transfer 14149 and let the sip_call function catch that we need replaces 14150 header in the INVITE. 14151 */ 14152 14153 14154 /* Get the transferer's channel */ 14155 current.chan1 = p->owner; 14156 14157 /* Find the other part of the bridge (2) - transferee */ 14158 current.chan2 = ast_bridged_channel(current.chan1); 14159 14160 if (sipdebug && option_debug > 2) 14161 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>"); 14162 14163 if (!current.chan2 && !p->refer->attendedtransfer) { 14164 /* No bridged channel, propably IVR or echo or similar... */ 14165 /* Guess we should masquerade or something here */ 14166 /* Until we figure it out, refuse transfer of such calls */ 14167 if (sipdebug && option_debug > 2) 14168 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 14169 p->refer->status = REFER_FAILED; 14170 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 14171 transmit_response(p, "603 Declined", req); 14172 return -1; 14173 } 14174 14175 if (current.chan2) { 14176 if (sipdebug && option_debug > 3) 14177 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14178 14179 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14180 } 14181 14182 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14183 14184 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14185 if (p->refer->attendedtransfer) { 14186 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14187 return res; /* We're done with the transfer */ 14188 /* Fall through for remote transfers that we did not find locally */ 14189 if (sipdebug && option_debug > 3) 14190 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14191 /* Fallthrough if we can't find the call leg internally */ 14192 } 14193 14194 14195 /* Parking a call */ 14196 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14197 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14198 *nounlock = 1; 14199 ast_channel_unlock(current.chan1); 14200 copy_request(¤t.req, req); 14201 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14202 p->refer->status = REFER_200OK; 14203 append_history(p, "Xfer", "REFER to call parking."); 14204 if (sipdebug && option_debug > 3) 14205 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14206 sip_park(current.chan2, current.chan1, req, seqno); 14207 return res; 14208 } 14209 14210 /* Blind transfers and remote attended xfers */ 14211 transmit_response(p, "202 Accepted", req); 14212 14213 if (current.chan1 && current.chan2) { 14214 if (option_debug > 2) 14215 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14216 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14217 } 14218 if (current.chan2) { 14219 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14220 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14221 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14222 /* One for the new channel */ 14223 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14224 /* Attended transfer to remote host, prepare headers for the INVITE */ 14225 if (p->refer->referred_by) 14226 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14227 } 14228 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14229 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14230 char tempheader[BUFSIZ]; 14231 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14232 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14233 p->refer->replaces_callid_totag, 14234 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14235 p->refer->replaces_callid_fromtag); 14236 if (current.chan2) 14237 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14238 } 14239 /* Must release lock now, because it will not longer 14240 be accessible after the transfer! */ 14241 *nounlock = 1; 14242 ast_channel_unlock(current.chan1); 14243 14244 /* Connect the call */ 14245 14246 /* FAKE ringing if not attended transfer */ 14247 if (!p->refer->attendedtransfer) 14248 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14249 14250 /* For blind transfer, this will lead to a new call */ 14251 /* For attended transfer to remote host, this will lead to 14252 a new SIP call with a replaces header, if the dial plan allows it 14253 */ 14254 if (!current.chan2) { 14255 /* We have no bridge, so we're talking with Asterisk somehow */ 14256 /* We need to masquerade this call */ 14257 /* What to do to fix this situation: 14258 * Set up the new call in a new channel 14259 * Let the new channel masq into this channel 14260 Please add that code here :-) 14261 */ 14262 p->refer->status = REFER_FAILED; 14263 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14264 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14265 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14266 return -1; 14267 } 14268 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14269 14270 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14271 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14272 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14273 14274 if (!res) { 14275 /* Success - we have a new channel */ 14276 if (option_debug > 2) 14277 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14278 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14279 if (p->refer->localtransfer) 14280 p->refer->status = REFER_200OK; 14281 if (p->owner) 14282 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14283 append_history(p, "Xfer", "Refer succeeded."); 14284 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14285 /* Do not hangup call, the other side do that when we say 200 OK */ 14286 /* We could possibly implement a timer here, auto congestion */ 14287 res = 0; 14288 } else { 14289 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14290 if (option_debug > 2) 14291 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14292 append_history(p, "Xfer", "Refer failed."); 14293 /* Failure of some kind */ 14294 p->refer->status = REFER_FAILED; 14295 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14296 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14297 res = -1; 14298 } 14299 return res; 14300 }
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 14781 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().
14782 { 14783 enum check_auth_result res; 14784 14785 /* Use this as the basis */ 14786 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14787 ast_verbose("Using latest REGISTER request as basis request\n"); 14788 copy_request(&p->initreq, req); 14789 check_via(p, req); 14790 if ((res = register_verify(p, sin, req, e)) < 0) { 14791 const char *reason; 14792 14793 switch (res) { 14794 case AUTH_SECRET_FAILED: 14795 reason = "Wrong password"; 14796 break; 14797 case AUTH_USERNAME_MISMATCH: 14798 reason = "Username/auth name mismatch"; 14799 break; 14800 case AUTH_NOT_FOUND: 14801 reason = "No matching peer found"; 14802 break; 14803 case AUTH_UNKNOWN_DOMAIN: 14804 reason = "Not a local domain"; 14805 break; 14806 case AUTH_PEER_NOT_DYNAMIC: 14807 reason = "Peer is not supposed to register"; 14808 break; 14809 case AUTH_ACL_FAILED: 14810 reason = "Device does not match ACL"; 14811 break; 14812 default: 14813 reason = "Unknown failure"; 14814 break; 14815 } 14816 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 14817 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 14818 reason); 14819 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 14820 } else 14821 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 14822 14823 if (res < 1) { 14824 /* Destroy the session, but keep us around for just a bit in case they don't 14825 get our 200 OK */ 14826 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14827 } 14828 return res; 14829 }
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 14487 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, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, MWI_NOTIFICATION, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.
Referenced by handle_request().
14488 { 14489 int gotdest; 14490 int res = 0; 14491 int firststate = AST_EXTENSION_REMOVED; 14492 struct sip_peer *authpeer = NULL; 14493 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14494 const char *accept = get_header(req, "Accept"); 14495 int resubscribe = (p->subscribed != NONE); 14496 char *temp, *event; 14497 14498 if (p->initreq.headers) { 14499 /* We already have a dialog */ 14500 if (p->initreq.method != SIP_SUBSCRIBE) { 14501 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14502 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14503 transmit_response(p, "403 Forbidden (within dialog)", req); 14504 /* Do not destroy session, since we will break the call if we do */ 14505 if (option_debug) 14506 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); 14507 return 0; 14508 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14509 if (option_debug) { 14510 if (resubscribe) 14511 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14512 else 14513 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14514 } 14515 } 14516 } 14517 14518 /* Check if we have a global disallow setting on subscriptions. 14519 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14520 */ 14521 if (!global_allowsubscribe) { 14522 transmit_response(p, "403 Forbidden (policy)", req); 14523 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14524 return 0; 14525 } 14526 14527 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14528 /* Use this as the basis */ 14529 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14530 ast_verbose("Creating new subscription\n"); 14531 14532 copy_request(&p->initreq, req); 14533 check_via(p, req); 14534 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14535 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14536 14537 /* Find parameters to Event: header value and remove them for now */ 14538 if (ast_strlen_zero(eventheader)) { 14539 transmit_response(p, "489 Bad Event", req); 14540 if (option_debug > 1) 14541 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14542 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14543 return 0; 14544 } 14545 14546 if ( (strchr(eventheader, ';'))) { 14547 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14548 temp = strchr(event, ';'); 14549 *temp = '\0'; /* Remove any options for now */ 14550 /* We might need to use them later :-) */ 14551 } else 14552 event = (char *) eventheader; /* XXX is this legal ? */ 14553 14554 /* Handle authentication */ 14555 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14556 /* if an authentication response was sent, we are done here */ 14557 if (res == AUTH_CHALLENGE_SENT) { 14558 if (authpeer) 14559 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14560 return 0; 14561 } 14562 if (res < 0) { 14563 if (res == AUTH_FAKE_AUTH) { 14564 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14565 transmit_fake_auth_response(p, req, 1); 14566 } else { 14567 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14568 transmit_response_reliable(p, "403 Forbidden", req); 14569 } 14570 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14571 if (authpeer) 14572 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14573 return 0; 14574 } 14575 14576 /* Check if this user/peer is allowed to subscribe at all */ 14577 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14578 transmit_response(p, "403 Forbidden (policy)", req); 14579 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14580 if (authpeer) 14581 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14582 return 0; 14583 } 14584 14585 /* Get destination right away */ 14586 gotdest = get_destination(p, NULL); 14587 14588 /* Initialize the context if it hasn't been already; 14589 note this is done _after_ handling any domain lookups, 14590 because the context specified there is for calls, not 14591 subscriptions 14592 */ 14593 if (!ast_strlen_zero(p->subscribecontext)) 14594 ast_string_field_set(p, context, p->subscribecontext); 14595 else if (ast_strlen_zero(p->context)) 14596 ast_string_field_set(p, context, default_context); 14597 14598 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14599 parse_ok_contact(p, req); 14600 14601 build_contact(p); 14602 if (gotdest) { 14603 transmit_response(p, "404 Not Found", req); 14604 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14605 if (authpeer) 14606 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14607 return 0; 14608 } 14609 14610 /* Initialize tag for new subscriptions */ 14611 if (ast_strlen_zero(p->tag)) 14612 make_our_tag(p->tag, sizeof(p->tag)); 14613 14614 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14615 if (authpeer) /* No need for authpeer here */ 14616 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14617 14618 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14619 /* Polycom phones only handle xpidf+xml, even if they say they can 14620 handle pidf+xml as well 14621 */ 14622 if (strstr(p->useragent, "Polycom")) { 14623 p->subscribed = XPIDF_XML; 14624 } else if (strstr(accept, "application/pidf+xml")) { 14625 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14626 } else if (strstr(accept, "application/dialog-info+xml")) { 14627 p->subscribed = DIALOG_INFO_XML; 14628 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14629 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14630 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14631 } else if (strstr(accept, "application/xpidf+xml")) { 14632 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14633 } else if (ast_strlen_zero(accept)) { 14634 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14635 transmit_response(p, "489 Bad Event", req); 14636 14637 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14638 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14639 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14640 return 0; 14641 } 14642 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14643 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14644 } else { 14645 /* Can't find a format for events that we know about */ 14646 char mybuf[200]; 14647 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14648 transmit_response(p, mybuf, req); 14649 14650 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14651 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14652 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14653 return 0; 14654 } 14655 } else if (!strcmp(event, "message-summary")) { 14656 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14657 /* Format requested that we do not support */ 14658 transmit_response(p, "406 Not Acceptable", req); 14659 if (option_debug > 1) 14660 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 14661 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14662 if (authpeer) /* No need for authpeer here */ 14663 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14664 return 0; 14665 } 14666 /* Looks like they actually want a mailbox status 14667 This version of Asterisk supports mailbox subscriptions 14668 The subscribed URI needs to exist in the dial plan 14669 In most devices, this is configurable to the voicemailmain extension you use 14670 */ 14671 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 14672 transmit_response(p, "404 Not found (no mailbox)", req); 14673 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14674 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 14675 if (authpeer) /* No need for authpeer here */ 14676 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14677 return 0; 14678 } 14679 14680 p->subscribed = MWI_NOTIFICATION; 14681 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 14682 /* We only allow one subscription per peer */ 14683 sip_destroy(authpeer->mwipvt); 14684 authpeer->mwipvt = p; /* Link from peer to pvt */ 14685 p->relatedpeer = authpeer; /* Link from pvt to peer */ 14686 } else { /* At this point, Asterisk does not understand the specified event */ 14687 transmit_response(p, "489 Bad Event", req); 14688 if (option_debug > 1) 14689 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 14690 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14691 if (authpeer) /* No need for authpeer here */ 14692 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14693 return 0; 14694 } 14695 14696 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 14697 if (p->stateid > -1) 14698 ast_extension_state_del(p->stateid, cb_extensionstate); 14699 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 14700 } 14701 14702 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14703 p->lastinvite = seqno; 14704 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 14705 p->expiry = atoi(get_header(req, "Expires")); 14706 14707 /* check if the requested expiry-time is within the approved limits from sip.conf */ 14708 if (p->expiry > max_expiry) 14709 p->expiry = max_expiry; 14710 if (p->expiry < min_expiry && p->expiry > 0) 14711 p->expiry = min_expiry; 14712 14713 if (sipdebug || option_debug > 1) { 14714 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 14715 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 14716 else 14717 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 14718 } 14719 if (p->autokillid > -1) 14720 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 14721 if (p->expiry > 0) 14722 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 14723 14724 if (p->subscribed == MWI_NOTIFICATION) { 14725 transmit_response(p, "200 OK", req); 14726 if (p->relatedpeer) { /* Send first notification */ 14727 ASTOBJ_WRLOCK(p->relatedpeer); 14728 sip_send_mwi_to_peer(p->relatedpeer); 14729 ASTOBJ_UNLOCK(p->relatedpeer); 14730 } 14731 } else { 14732 struct sip_pvt *p_old; 14733 14734 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 14735 14736 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)); 14737 transmit_response(p, "404 Not found", req); 14738 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14739 return 0; 14740 } 14741 14742 transmit_response(p, "200 OK", req); 14743 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 14744 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 14745 /* hide the 'complete' exten/context in the refer_to field for later display */ 14746 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 14747 14748 /* remove any old subscription from this peer for the same exten/context, 14749 as the peer has obviously forgotten about it and it's wasteful to wait 14750 for it to expire and send NOTIFY messages to the peer only to have them 14751 ignored (or generate errors) 14752 */ 14753 ast_mutex_lock(&iflock); 14754 for (p_old = iflist; p_old; p_old = p_old->next) { 14755 if (p_old == p) 14756 continue; 14757 if (p_old->initreq.method != SIP_SUBSCRIBE) 14758 continue; 14759 if (p_old->subscribed == NONE) 14760 continue; 14761 ast_mutex_lock(&p_old->lock); 14762 if (!strcmp(p_old->username, p->username)) { 14763 if (!strcmp(p_old->exten, p->exten) && 14764 !strcmp(p_old->context, p->context)) { 14765 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 14766 ast_mutex_unlock(&p_old->lock); 14767 break; 14768 } 14769 } 14770 ast_mutex_unlock(&p_old->lock); 14771 } 14772 ast_mutex_unlock(&iflock); 14773 } 14774 if (!p->expiry) 14775 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14776 } 14777 return 1; 14778 }
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 12340 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::authtries, do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::recv, sip_pvt::refer, sip_pvt::registry, sip_pvt::relatedpeer, sip_pvt::sa, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12341 { 12342 struct ast_channel *owner; 12343 int sipmethod; 12344 int res = 1; 12345 const char *c = get_header(req, "Cseq"); 12346 const char *msg = strchr(c, ' '); 12347 12348 if (!msg) 12349 msg = ""; 12350 else 12351 msg++; 12352 sipmethod = find_sip_method(msg); 12353 12354 owner = p->owner; 12355 if (owner) 12356 owner->hangupcause = hangup_sip2cause(resp); 12357 12358 /* Acknowledge whatever it is destined for */ 12359 if ((resp >= 100) && (resp <= 199)) 12360 __sip_semi_ack(p, seqno, 0, sipmethod); 12361 else 12362 __sip_ack(p, seqno, 0, sipmethod); 12363 12364 /* Get their tag if we haven't already */ 12365 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12366 char tag[128]; 12367 12368 gettag(req, "To", tag, sizeof(tag)); 12369 ast_string_field_set(p, theirtag, tag); 12370 } 12371 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12372 /* We don't really care what the response is, just that it replied back. 12373 Well, as long as it's not a 100 response... since we might 12374 need to hang around for something more "definitive" */ 12375 if (resp != 100) 12376 handle_response_peerpoke(p, resp, req); 12377 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12378 switch(resp) { 12379 case 100: /* 100 Trying */ 12380 case 101: /* 101 Dialog establishment */ 12381 if (sipmethod == SIP_INVITE) 12382 handle_response_invite(p, resp, rest, req, seqno); 12383 break; 12384 case 183: /* 183 Session Progress */ 12385 if (sipmethod == SIP_INVITE) 12386 handle_response_invite(p, resp, rest, req, seqno); 12387 break; 12388 case 180: /* 180 Ringing */ 12389 if (sipmethod == SIP_INVITE) 12390 handle_response_invite(p, resp, rest, req, seqno); 12391 break; 12392 case 200: /* 200 OK */ 12393 p->authtries = 0; /* Reset authentication counter */ 12394 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12395 /* We successfully transmitted a message 12396 or a video update request in INFO */ 12397 /* Nothing happens here - the message is inside a dialog */ 12398 } else if (sipmethod == SIP_INVITE) { 12399 handle_response_invite(p, resp, rest, req, seqno); 12400 } else if (sipmethod == SIP_NOTIFY) { 12401 /* They got the notify, this is the end */ 12402 if (p->owner) { 12403 if (!p->refer) { 12404 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12405 ast_queue_hangup(p->owner); 12406 } else if (option_debug > 3) 12407 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12408 } else { 12409 if (p->subscribed == NONE) 12410 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12411 } 12412 } else if (sipmethod == SIP_REGISTER) 12413 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12414 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12415 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12416 break; 12417 case 202: /* Transfer accepted */ 12418 if (sipmethod == SIP_REFER) 12419 handle_response_refer(p, resp, rest, req, seqno); 12420 break; 12421 case 401: /* Not www-authorized on SIP method */ 12422 if (sipmethod == SIP_INVITE) 12423 handle_response_invite(p, resp, rest, req, seqno); 12424 else if (sipmethod == SIP_REFER) 12425 handle_response_refer(p, resp, rest, req, seqno); 12426 else if (p->registry && sipmethod == SIP_REGISTER) 12427 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12428 else if (sipmethod == SIP_BYE) { 12429 if (ast_strlen_zero(p->authname)) { 12430 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12431 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12432 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12433 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 12434 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12435 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12436 /* We fail to auth bye on our own call, but still needs to tear down the call. 12437 Life, they call it. */ 12438 } 12439 } else { 12440 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12441 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12442 } 12443 break; 12444 case 403: /* Forbidden - we failed authentication */ 12445 if (sipmethod == SIP_INVITE) 12446 handle_response_invite(p, resp, rest, req, seqno); 12447 else if (p->registry && sipmethod == SIP_REGISTER) 12448 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12449 else { 12450 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12451 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12452 } 12453 break; 12454 case 404: /* Not found */ 12455 if (p->registry && sipmethod == SIP_REGISTER) 12456 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12457 else if (sipmethod == SIP_INVITE) 12458 handle_response_invite(p, resp, rest, req, seqno); 12459 else if (owner) 12460 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12461 break; 12462 case 407: /* Proxy auth required */ 12463 if (sipmethod == SIP_INVITE) 12464 handle_response_invite(p, resp, rest, req, seqno); 12465 else if (sipmethod == SIP_REFER) 12466 handle_response_refer(p, resp, rest, req, seqno); 12467 else if (p->registry && sipmethod == SIP_REGISTER) 12468 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12469 else if (sipmethod == SIP_BYE) { 12470 if (ast_strlen_zero(p->authname)) { 12471 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12472 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12473 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12474 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12475 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12476 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12477 } 12478 } else /* We can't handle this, giving up in a bad way */ 12479 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12480 12481 break; 12482 case 408: /* Request timeout - terminate dialog */ 12483 if (sipmethod == SIP_INVITE) 12484 handle_response_invite(p, resp, rest, req, seqno); 12485 else if (sipmethod == SIP_REGISTER) 12486 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12487 else if (sipmethod == SIP_BYE) { 12488 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12489 if (option_debug) 12490 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 12491 } else { 12492 if (owner) 12493 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12494 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12495 } 12496 break; 12497 case 481: /* Call leg does not exist */ 12498 if (sipmethod == SIP_INVITE) { 12499 handle_response_invite(p, resp, rest, req, seqno); 12500 } else if (sipmethod == SIP_REFER) { 12501 handle_response_refer(p, resp, rest, req, seqno); 12502 } else if (sipmethod == SIP_BYE) { 12503 /* The other side has no transaction to bye, 12504 just assume it's all right then */ 12505 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12506 } else if (sipmethod == SIP_CANCEL) { 12507 /* The other side has no transaction to cancel, 12508 just assume it's all right then */ 12509 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12510 } else { 12511 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12512 /* Guessing that this is not an important request */ 12513 } 12514 break; 12515 case 487: 12516 if (sipmethod == SIP_INVITE) 12517 handle_response_invite(p, resp, rest, req, seqno); 12518 break; 12519 case 488: /* Not acceptable here - codec error */ 12520 if (sipmethod == SIP_INVITE) 12521 handle_response_invite(p, resp, rest, req, seqno); 12522 break; 12523 case 491: /* Pending */ 12524 if (sipmethod == SIP_INVITE) 12525 handle_response_invite(p, resp, rest, req, seqno); 12526 else { 12527 if (option_debug) 12528 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12529 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12530 } 12531 break; 12532 case 501: /* Not Implemented */ 12533 if (sipmethod == SIP_INVITE) 12534 handle_response_invite(p, resp, rest, req, seqno); 12535 else if (sipmethod == SIP_REFER) 12536 handle_response_refer(p, resp, rest, req, seqno); 12537 else 12538 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12539 break; 12540 case 603: /* Declined transfer */ 12541 if (sipmethod == SIP_REFER) { 12542 handle_response_refer(p, resp, rest, req, seqno); 12543 break; 12544 } 12545 /* Fallthrough */ 12546 default: 12547 if ((resp >= 300) && (resp < 700)) { 12548 /* Fatal response */ 12549 if ((option_verbose > 2) && (resp != 487)) 12550 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12551 12552 if (sipmethod == SIP_INVITE) 12553 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12554 12555 /* XXX Locking issues?? XXX */ 12556 switch(resp) { 12557 case 300: /* Multiple Choices */ 12558 case 301: /* Moved permenantly */ 12559 case 302: /* Moved temporarily */ 12560 case 305: /* Use Proxy */ 12561 parse_moved_contact(p, req); 12562 /* Fall through */ 12563 case 486: /* Busy here */ 12564 case 600: /* Busy everywhere */ 12565 case 603: /* Decline */ 12566 if (p->owner) 12567 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12568 break; 12569 case 482: /* 12570 \note SIP is incapable of performing a hairpin call, which 12571 is yet another failure of not having a layer 2 (again, YAY 12572 IETF for thinking ahead). So we treat this as a call 12573 forward and hope we end up at the right place... */ 12574 if (option_debug) 12575 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12576 if (p->owner) 12577 ast_string_field_build(p->owner, call_forward, 12578 "Local/%s@%s", p->username, p->context); 12579 /* Fall through */ 12580 case 480: /* Temporarily Unavailable */ 12581 case 404: /* Not Found */ 12582 case 410: /* Gone */ 12583 case 400: /* Bad Request */ 12584 case 500: /* Server error */ 12585 if (sipmethod == SIP_REFER) { 12586 handle_response_refer(p, resp, rest, req, seqno); 12587 break; 12588 } 12589 /* Fall through */ 12590 case 503: /* Service Unavailable */ 12591 case 504: /* Server Timeout */ 12592 if (owner) 12593 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12594 break; 12595 default: 12596 /* Send hangup */ 12597 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 12598 ast_queue_hangup(p->owner); 12599 break; 12600 } 12601 /* ACK on invite */ 12602 if (sipmethod == SIP_INVITE) 12603 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12604 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12605 sip_alreadygone(p); 12606 if (!p->owner) 12607 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12608 } else if ((resp >= 100) && (resp < 200)) { 12609 if (sipmethod == SIP_INVITE) { 12610 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12611 sip_cancel_destroy(p); 12612 if (find_sdp(req)) 12613 process_sdp(p, req); 12614 if (p->owner) { 12615 /* Queue a progress frame */ 12616 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12617 } 12618 } 12619 } else 12620 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)); 12621 } 12622 } else { 12623 /* Responses to OUTGOING SIP requests on INCOMING calls 12624 get handled here. As well as out-of-call message responses */ 12625 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12626 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12627 12628 if (sipmethod == SIP_INVITE && resp == 200) { 12629 /* Tags in early session is replaced by the tag in 200 OK, which is 12630 the final reply to our INVITE */ 12631 char tag[128]; 12632 12633 gettag(req, "To", tag, sizeof(tag)); 12634 ast_string_field_set(p, theirtag, tag); 12635 } 12636 12637 switch(resp) { 12638 case 200: 12639 if (sipmethod == SIP_INVITE) { 12640 handle_response_invite(p, resp, rest, req, seqno); 12641 } else if (sipmethod == SIP_CANCEL) { 12642 if (option_debug) 12643 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12644 12645 /* Wait for 487, then destroy */ 12646 } else if (sipmethod == SIP_NOTIFY) { 12647 /* They got the notify, this is the end */ 12648 if (p->owner) { 12649 if (p->refer) { 12650 if (option_debug) 12651 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12652 } else 12653 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12654 /* ast_queue_hangup(p->owner); Disabled */ 12655 } else { 12656 if (!p->subscribed && !p->refer) 12657 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12658 } 12659 } else if (sipmethod == SIP_BYE) 12660 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12661 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12662 /* We successfully transmitted a message or 12663 a video update request in INFO */ 12664 ; 12665 else if (sipmethod == SIP_BYE) 12666 /* Ok, we're ready to go */ 12667 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12668 break; 12669 case 202: /* Transfer accepted */ 12670 if (sipmethod == SIP_REFER) 12671 handle_response_refer(p, resp, rest, req, seqno); 12672 break; 12673 case 401: /* www-auth */ 12674 case 407: 12675 if (sipmethod == SIP_REFER) 12676 handle_response_refer(p, resp, rest, req, seqno); 12677 else if (sipmethod == SIP_INVITE) 12678 handle_response_invite(p, resp, rest, req, seqno); 12679 else if (sipmethod == SIP_BYE) { 12680 char *auth, *auth2; 12681 12682 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 12683 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 12684 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 12685 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12686 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12687 } 12688 } 12689 break; 12690 case 481: /* Call leg does not exist */ 12691 if (sipmethod == SIP_INVITE) { 12692 /* Re-invite failed */ 12693 handle_response_invite(p, resp, rest, req, seqno); 12694 } else if (sipmethod == SIP_BYE) { 12695 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12696 } else if (sipdebug) { 12697 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 12698 } 12699 break; 12700 case 501: /* Not Implemented */ 12701 if (sipmethod == SIP_INVITE) 12702 handle_response_invite(p, resp, rest, req, seqno); 12703 else if (sipmethod == SIP_REFER) 12704 handle_response_refer(p, resp, rest, req, seqno); 12705 break; 12706 case 603: /* Declined transfer */ 12707 if (sipmethod == SIP_REFER) { 12708 handle_response_refer(p, resp, rest, req, seqno); 12709 break; 12710 } 12711 /* Fallthrough */ 12712 default: /* Errors without handlers */ 12713 if ((resp >= 100) && (resp < 200)) { 12714 if (sipmethod == SIP_INVITE) { /* re-invite */ 12715 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12716 sip_cancel_destroy(p); 12717 } 12718 } 12719 if ((resp >= 300) && (resp < 700)) { 12720 if ((option_verbose > 2) && (resp != 487)) 12721 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)); 12722 switch(resp) { 12723 case 488: /* Not acceptable here - codec error */ 12724 case 603: /* Decline */ 12725 case 500: /* Server error */ 12726 case 503: /* Service Unavailable */ 12727 case 504: /* Server timeout */ 12728 12729 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 12730 sip_cancel_destroy(p); 12731 } 12732 break; 12733 } 12734 } 12735 break; 12736 } 12737 } 12738 }
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 11781 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, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
11782 { 11783 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 11784 int res = 0; 11785 int xmitres = 0; 11786 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 11787 struct ast_channel *bridgepeer = NULL; 11788 11789 if (option_debug > 3) { 11790 if (reinvite) 11791 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 11792 else 11793 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 11794 } 11795 11796 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 11797 if (option_debug) 11798 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 11799 return; 11800 } 11801 11802 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 11803 if (p->initid > -1) { 11804 /* Don't auto congest anymore since we've gotten something useful back */ 11805 ast_sched_del(sched, p->initid); 11806 p->initid = -1; 11807 } 11808 11809 /* RFC3261 says we must treat every 1xx response (but not 100) 11810 that we don't recognize as if it was 183. 11811 */ 11812 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183) 11813 resp = 183; 11814 11815 /* Any response between 100 and 199 is PROCEEDING */ 11816 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 11817 p->invitestate = INV_PROCEEDING; 11818 11819 /* Final response, not 200 ? */ 11820 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 11821 p->invitestate = INV_COMPLETED; 11822 11823 11824 switch (resp) { 11825 case 100: /* Trying */ 11826 case 101: /* Dialog establishment */ 11827 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11828 sip_cancel_destroy(p); 11829 check_pendings(p); 11830 break; 11831 11832 case 180: /* 180 Ringing */ 11833 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11834 sip_cancel_destroy(p); 11835 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11836 ast_queue_control(p->owner, AST_CONTROL_RINGING); 11837 if (p->owner->_state != AST_STATE_UP) { 11838 ast_setstate(p->owner, AST_STATE_RINGING); 11839 } 11840 } 11841 if (find_sdp(req)) { 11842 p->invitestate = INV_EARLY_MEDIA; 11843 res = process_sdp(p, req); 11844 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11845 /* Queue a progress frame only if we have SDP in 180 */ 11846 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11847 } 11848 } 11849 check_pendings(p); 11850 break; 11851 11852 case 183: /* Session progress */ 11853 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11854 sip_cancel_destroy(p); 11855 /* Ignore 183 Session progress without SDP */ 11856 if (find_sdp(req)) { 11857 p->invitestate = INV_EARLY_MEDIA; 11858 res = process_sdp(p, req); 11859 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11860 /* Queue a progress frame */ 11861 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11862 } 11863 } 11864 check_pendings(p); 11865 break; 11866 11867 case 200: /* 200 OK on invite - someone's answering our call */ 11868 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11869 sip_cancel_destroy(p); 11870 p->authtries = 0; 11871 if (find_sdp(req)) { 11872 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 11873 if (!reinvite) 11874 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 11875 /* For re-invites, we try to recover */ 11876 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11877 } 11878 11879 /* Parse contact header for continued conversation */ 11880 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 11881 /* This is important when we have a SIP proxy between us and the phone */ 11882 if (outgoing) { 11883 update_call_counter(p, DEC_CALL_RINGING); 11884 parse_ok_contact(p, req); 11885 if(set_address_from_contact(p)) { 11886 /* Bad contact - we don't know how to reach this device */ 11887 /* We need to ACK, but then send a bye */ 11888 /* OEJ: Possible issue that may need a check: 11889 If we have a proxy route between us and the device, 11890 should we care about resolving the contact 11891 or should we just send it? 11892 */ 11893 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11894 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11895 } 11896 11897 /* Save Record-Route for any later requests we make on this dialogue */ 11898 build_route(p, req, 1); 11899 } 11900 11901 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 11902 struct sip_pvt *bridgepvt = NULL; 11903 11904 if (!bridgepeer->tech) { 11905 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 11906 break; 11907 } 11908 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 11909 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 11910 if (bridgepvt->udptl) { 11911 if (p->t38.state == T38_PEER_REINVITE) { 11912 sip_handle_t38_reinvite(bridgepeer, p, 0); 11913 ast_rtp_set_rtptimers_onhold(p->rtp); 11914 if (p->vrtp) 11915 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 11916 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 11917 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 11918 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 11919 /* XXXX Should we really destroy this session here, without any response at all??? */ 11920 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11921 } 11922 } else { 11923 if (option_debug > 1) 11924 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 11925 ast_mutex_lock(&bridgepvt->lock); 11926 bridgepvt->t38.state = T38_DISABLED; 11927 ast_mutex_unlock(&bridgepvt->lock); 11928 if (option_debug) 11929 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 11930 p->t38.state = T38_DISABLED; 11931 if (option_debug > 1) 11932 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11933 } 11934 } else { 11935 /* Other side is not a SIP channel */ 11936 if (option_debug > 1) 11937 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 11938 p->t38.state = T38_DISABLED; 11939 if (option_debug > 1) 11940 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11941 } 11942 } 11943 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 11944 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 11945 p->t38.state = T38_ENABLED; 11946 if (option_debug) 11947 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11948 } 11949 11950 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11951 if (!reinvite) { 11952 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 11953 } else { /* RE-invite */ 11954 ast_queue_frame(p->owner, &ast_null_frame); 11955 } 11956 } else { 11957 /* It's possible we're getting an 200 OK after we've tried to disconnect 11958 by sending CANCEL */ 11959 /* First send ACK, then send bye */ 11960 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11961 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11962 } 11963 /* If I understand this right, the branch is different for a non-200 ACK only */ 11964 p->invitestate = INV_TERMINATED; 11965 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 11966 check_pendings(p); 11967 break; 11968 case 407: /* Proxy authentication */ 11969 case 401: /* Www auth */ 11970 /* First we ACK */ 11971 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11972 if (p->options) 11973 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 11974 11975 /* Then we AUTH */ 11976 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 11977 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 11978 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 11979 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 11980 if (p->authtries < MAX_AUTHTRIES) 11981 p->invitestate = INV_CALLING; 11982 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 11983 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 11984 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11985 sip_alreadygone(p); 11986 if (p->owner) 11987 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11988 } 11989 } 11990 break; 11991 11992 case 403: /* Forbidden */ 11993 /* First we ACK */ 11994 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11995 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 11996 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 11997 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11998 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11999 sip_alreadygone(p); 12000 break; 12001 12002 case 404: /* Not found */ 12003 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12004 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12005 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12006 sip_alreadygone(p); 12007 break; 12008 12009 case 408: /* Request timeout */ 12010 case 481: /* Call leg does not exist */ 12011 /* Could be REFER caused INVITE with replaces */ 12012 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12013 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12014 if (p->owner) 12015 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12016 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12017 break; 12018 case 487: /* Cancelled transaction */ 12019 /* We have sent CANCEL on an outbound INVITE 12020 This transaction is already scheduled to be killed by sip_hangup(). 12021 */ 12022 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12023 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12024 ast_queue_hangup(p->owner); 12025 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12026 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12027 update_call_counter(p, DEC_CALL_LIMIT); 12028 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12029 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12030 sip_alreadygone(p); 12031 } 12032 break; 12033 case 488: /* Not acceptable here */ 12034 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12035 if (reinvite && p->udptl) { 12036 /* If this is a T.38 call, we should go back to 12037 audio. If this is an audio call - something went 12038 terribly wrong since we don't renegotiate codecs, 12039 only IP/port . 12040 */ 12041 p->t38.state = T38_DISABLED; 12042 /* Try to reset RTP timers */ 12043 ast_rtp_set_rtptimers_onhold(p->rtp); 12044 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12045 12046 /*! \bug Is there any way we can go back to the audio call on both 12047 sides here? 12048 */ 12049 /* While figuring that out, hangup the call */ 12050 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12051 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12052 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12053 } else { 12054 /* We can't set up this call, so give up */ 12055 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12056 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12057 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12058 } 12059 break; 12060 case 491: /* Pending */ 12061 /* we really should have to wait a while, then retransmit */ 12062 /* We should support the retry-after at some point */ 12063 /* At this point, we treat this as a congestion */ 12064 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12065 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12066 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12067 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12068 break; 12069 12070 case 501: /* Not implemented */ 12071 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12072 if (p->owner) 12073 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12074 break; 12075 } 12076 if (xmitres == XMIT_ERROR) 12077 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12078 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12280 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12281 { 12282 struct sip_peer *peer = p->relatedpeer; 12283 int statechanged, is_reachable, was_reachable; 12284 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12285 12286 /* 12287 * Compute the response time to a ping (goes in peer->lastms.) 12288 * -1 means did not respond, 0 means unknown, 12289 * 1..maxms is a valid response, >maxms means late response. 12290 */ 12291 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12292 pingtime = 1; 12293 12294 /* Now determine new state and whether it has changed. 12295 * Use some helper variables to simplify the writing 12296 * of the expressions. 12297 */ 12298 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12299 is_reachable = pingtime <= peer->maxms; 12300 statechanged = peer->lastms == 0 /* yes, unknown before */ 12301 || was_reachable != is_reachable; 12302 12303 peer->lastms = pingtime; 12304 peer->call = NULL; 12305 if (statechanged) { 12306 const char *s = is_reachable ? "Reachable" : "Lagged"; 12307 12308 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12309 peer->name, s, pingtime, peer->maxms); 12310 ast_device_state_changed("SIP/%s", peer->name); 12311 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12312 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12313 peer->name, s, pingtime); 12314 } 12315 12316 if (peer->pokeexpire > -1) 12317 ast_sched_del(sched, peer->pokeexpire); 12318 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12319 12320 /* Try again eventually */ 12321 peer->pokeexpire = ast_sched_add(sched, 12322 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12323 sip_poke_peer_s, peer); 12324 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12083 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
12084 { 12085 char *auth = "Proxy-Authenticate"; 12086 char *auth2 = "Proxy-Authorization"; 12087 12088 /* If no refer structure exists, then do nothing */ 12089 if (!p->refer) 12090 return; 12091 12092 switch (resp) { 12093 case 202: /* Transfer accepted */ 12094 /* We need to do something here */ 12095 /* The transferee is now sending INVITE to target */ 12096 p->refer->status = REFER_ACCEPTED; 12097 /* Now wait for next message */ 12098 if (option_debug > 2) 12099 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12100 /* We should hang along, waiting for NOTIFY's here */ 12101 break; 12102 12103 case 401: /* Not www-authorized on SIP method */ 12104 case 407: /* Proxy auth */ 12105 if (ast_strlen_zero(p->authname)) { 12106 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12107 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12108 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12109 } 12110 if (resp == 401) { 12111 auth = "WWW-Authenticate"; 12112 auth2 = "Authorization"; 12113 } 12114 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12115 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12116 p->refer->status = REFER_NOAUTH; 12117 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12118 } 12119 break; 12120 case 481: /* Call leg does not exist */ 12121 12122 /* A transfer with Replaces did not work */ 12123 /* OEJ: We should Set flag, cancel the REFER, go back 12124 to original call - but right now we can't */ 12125 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12126 if (p->owner) 12127 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12128 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12129 break; 12130 12131 case 500: /* Server error */ 12132 case 501: /* Method not implemented */ 12133 /* Return to the current call onhold */ 12134 /* Status flag needed to be reset */ 12135 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12136 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12137 p->refer->status = REFER_FAILED; 12138 break; 12139 case 603: /* Transfer declined */ 12140 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12141 p->refer->status = REFER_FAILED; 12142 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12143 break; 12144 } 12145 }
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 12148 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12149 { 12150 int expires, expires_ms; 12151 struct sip_registry *r; 12152 r=p->registry; 12153 12154 switch (resp) { 12155 case 401: /* Unauthorized */ 12156 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12157 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12158 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12159 } 12160 break; 12161 case 403: /* Forbidden */ 12162 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12163 if (global_regattempts_max) 12164 p->registry->regattempts = global_regattempts_max+1; 12165 ast_sched_del(sched, r->timeout); 12166 r->timeout = -1; 12167 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12168 break; 12169 case 404: /* Not found */ 12170 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12171 if (global_regattempts_max) 12172 p->registry->regattempts = global_regattempts_max+1; 12173 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12174 r->call = NULL; 12175 ast_sched_del(sched, r->timeout); 12176 r->timeout = -1; 12177 break; 12178 case 407: /* Proxy auth */ 12179 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12180 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12181 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12182 } 12183 break; 12184 case 408: /* Request timeout */ 12185 if (global_regattempts_max) 12186 p->registry->regattempts = global_regattempts_max+1; 12187 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12188 r->call = NULL; 12189 ast_sched_del(sched, r->timeout); 12190 r->timeout = -1; 12191 break; 12192 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12193 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12194 if (global_regattempts_max) 12195 p->registry->regattempts = global_regattempts_max+1; 12196 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12197 r->call = NULL; 12198 ast_sched_del(sched, r->timeout); 12199 r->timeout = -1; 12200 break; 12201 case 200: /* 200 OK */ 12202 if (!r) { 12203 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12204 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12205 return 0; 12206 } 12207 12208 r->regstate = REG_STATE_REGISTERED; 12209 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12210 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12211 r->regattempts = 0; 12212 if (option_debug) 12213 ast_log(LOG_DEBUG, "Registration successful\n"); 12214 if (r->timeout > -1) { 12215 if (option_debug) 12216 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12217 ast_sched_del(sched, r->timeout); 12218 } 12219 r->timeout=-1; 12220 r->call = NULL; 12221 p->registry = NULL; 12222 /* Let this one hang around until we have all the responses */ 12223 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12224 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12225 12226 /* set us up for re-registering */ 12227 /* figure out how long we got registered for */ 12228 if (r->expire > -1) 12229 ast_sched_del(sched, r->expire); 12230 /* according to section 6.13 of RFC, contact headers override 12231 expires headers, so check those first */ 12232 expires = 0; 12233 12234 /* XXX todo: try to save the extra call */ 12235 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12236 const char *contact = NULL; 12237 const char *tmptmp = NULL; 12238 int start = 0; 12239 for(;;) { 12240 contact = __get_header(req, "Contact", &start); 12241 /* this loop ensures we get a contact header about our register request */ 12242 if(!ast_strlen_zero(contact)) { 12243 if( (tmptmp=strstr(contact, p->our_contact))) { 12244 contact=tmptmp; 12245 break; 12246 } 12247 } else 12248 break; 12249 } 12250 tmptmp = strcasestr(contact, "expires="); 12251 if (tmptmp) { 12252 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12253 expires = 0; 12254 } 12255 12256 } 12257 if (!expires) 12258 expires=atoi(get_header(req, "expires")); 12259 if (!expires) 12260 expires=default_expiry; 12261 12262 expires_ms = expires * 1000; 12263 if (expires <= EXPIRY_GUARD_LIMIT) 12264 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12265 else 12266 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12267 if (sipdebug) 12268 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12269 12270 r->refresh= (int) expires_ms / 1000; 12271 12272 /* Schedule re-registration before we expire */ 12273 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 12274 ASTOBJ_UNREF(r, sip_registry_destroy); 12275 } 12276 return 1; 12277 }
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 3337 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().
03338 { 03339 switch (cause) { 03340 case AST_CAUSE_UNALLOCATED: /* 1 */ 03341 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03342 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03343 return "404 Not Found"; 03344 case AST_CAUSE_CONGESTION: /* 34 */ 03345 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03346 return "503 Service Unavailable"; 03347 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03348 return "408 Request Timeout"; 03349 case AST_CAUSE_NO_ANSWER: /* 19 */ 03350 return "480 Temporarily unavailable"; 03351 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03352 return "403 Forbidden"; 03353 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03354 return "410 Gone"; 03355 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03356 return "480 Temporarily unavailable"; 03357 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03358 return "484 Address incomplete"; 03359 case AST_CAUSE_USER_BUSY: 03360 return "486 Busy here"; 03361 case AST_CAUSE_FAILURE: 03362 return "500 Server internal failure"; 03363 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03364 return "501 Not Implemented"; 03365 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03366 return "503 Service Unavailable"; 03367 /* Used in chan_iax2 */ 03368 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03369 return "502 Bad Gateway"; 03370 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03371 return "488 Not Acceptable Here"; 03372 03373 case AST_CAUSE_NOTDEFINED: 03374 default: 03375 if (option_debug) 03376 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03377 return NULL; 03378 } 03379 03380 /* Never reached */ 03381 return 0; 03382 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3225 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().
03226 { 03227 /* Possible values taken from causes.h */ 03228 03229 switch(cause) { 03230 case 401: /* Unauthorized */ 03231 return AST_CAUSE_CALL_REJECTED; 03232 case 403: /* Not found */ 03233 return AST_CAUSE_CALL_REJECTED; 03234 case 404: /* Not found */ 03235 return AST_CAUSE_UNALLOCATED; 03236 case 405: /* Method not allowed */ 03237 return AST_CAUSE_INTERWORKING; 03238 case 407: /* Proxy authentication required */ 03239 return AST_CAUSE_CALL_REJECTED; 03240 case 408: /* No reaction */ 03241 return AST_CAUSE_NO_USER_RESPONSE; 03242 case 409: /* Conflict */ 03243 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03244 case 410: /* Gone */ 03245 return AST_CAUSE_UNALLOCATED; 03246 case 411: /* Length required */ 03247 return AST_CAUSE_INTERWORKING; 03248 case 413: /* Request entity too large */ 03249 return AST_CAUSE_INTERWORKING; 03250 case 414: /* Request URI too large */ 03251 return AST_CAUSE_INTERWORKING; 03252 case 415: /* Unsupported media type */ 03253 return AST_CAUSE_INTERWORKING; 03254 case 420: /* Bad extension */ 03255 return AST_CAUSE_NO_ROUTE_DESTINATION; 03256 case 480: /* No answer */ 03257 return AST_CAUSE_NO_ANSWER; 03258 case 481: /* No answer */ 03259 return AST_CAUSE_INTERWORKING; 03260 case 482: /* Loop detected */ 03261 return AST_CAUSE_INTERWORKING; 03262 case 483: /* Too many hops */ 03263 return AST_CAUSE_NO_ANSWER; 03264 case 484: /* Address incomplete */ 03265 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03266 case 485: /* Ambigous */ 03267 return AST_CAUSE_UNALLOCATED; 03268 case 486: /* Busy everywhere */ 03269 return AST_CAUSE_BUSY; 03270 case 487: /* Request terminated */ 03271 return AST_CAUSE_INTERWORKING; 03272 case 488: /* No codecs approved */ 03273 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03274 case 491: /* Request pending */ 03275 return AST_CAUSE_INTERWORKING; 03276 case 493: /* Undecipherable */ 03277 return AST_CAUSE_INTERWORKING; 03278 case 500: /* Server internal failure */ 03279 return AST_CAUSE_FAILURE; 03280 case 501: /* Call rejected */ 03281 return AST_CAUSE_FACILITY_REJECTED; 03282 case 502: 03283 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03284 case 503: /* Service unavailable */ 03285 return AST_CAUSE_CONGESTION; 03286 case 504: /* Gateway timeout */ 03287 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03288 case 505: /* SIP version not supported */ 03289 return AST_CAUSE_INTERWORKING; 03290 case 600: /* Busy everywhere */ 03291 return AST_CAUSE_USER_BUSY; 03292 case 603: /* Decline */ 03293 return AST_CAUSE_CALL_REJECTED; 03294 case 604: /* Does not exist anywhere */ 03295 return AST_CAUSE_UNALLOCATED; 03296 case 606: /* Not acceptable */ 03297 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03298 default: 03299 return AST_CAUSE_NORMAL; 03300 } 03301 /* Never reached */ 03302 return 0; 03303 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5677 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, sip_methods, and cfsip_methods::text.
05678 { 05679 /* Initialize a request */ 05680 memset(req, 0, sizeof(*req)); 05681 req->method = sipmethod; 05682 req->header[0] = req->data; 05683 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05684 req->len = strlen(req->header[0]); 05685 req->headers++; 05686 return 0; 05687 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5664 of file chan_sip.c.
References sip_request::data, sip_request::header, sip_request::headers, sip_request::len, sip_request::method, and SIP_RESPONSE.
05665 { 05666 /* Initialize a response */ 05667 memset(resp, 0, sizeof(*resp)); 05668 resp->method = SIP_RESPONSE; 05669 resp->header[0] = resp->data; 05670 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05671 resp->len = strlen(resp->header[0]); 05672 resp->headers++; 05673 return 0; 05674 }
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 1627 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().
01628 { 01629 if (p->initreq.headers && option_debug) { 01630 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01631 } 01632 /* Use this as the basis */ 01633 copy_request(&p->initreq, req); 01634 parse_request(&p->initreq); 01635 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01636 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01637 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6758 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().
06759 { 06760 char invite_buf[256] = ""; 06761 char *invite = invite_buf; 06762 size_t invite_max = sizeof(invite_buf); 06763 char from[256]; 06764 char to[256]; 06765 char tmp[BUFSIZ/2]; 06766 char tmp2[BUFSIZ/2]; 06767 const char *l = NULL, *n = NULL; 06768 const char *urioptions = ""; 06769 06770 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06771 const char *s = p->username; /* being a string field, cannot be NULL */ 06772 06773 /* Test p->username against allowed characters in AST_DIGIT_ANY 06774 If it matches the allowed characters list, then sipuser = ";user=phone" 06775 If not, then sipuser = "" 06776 */ 06777 /* + is allowed in first position in a tel: uri */ 06778 if (*s == '+') 06779 s++; 06780 for (; *s; s++) { 06781 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06782 break; 06783 } 06784 /* If we have only digits, add ;user=phone to the uri */ 06785 if (*s) 06786 urioptions = ";user=phone"; 06787 } 06788 06789 06790 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06791 06792 if (p->owner) { 06793 l = p->owner->cid.cid_num; 06794 n = p->owner->cid.cid_name; 06795 } 06796 /* if we are not sending RPID and user wants his callerid restricted */ 06797 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06798 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06799 l = CALLERID_UNKNOWN; 06800 n = l; 06801 } 06802 if (ast_strlen_zero(l)) 06803 l = default_callerid; 06804 if (ast_strlen_zero(n)) 06805 n = l; 06806 /* Allow user to be overridden */ 06807 if (!ast_strlen_zero(p->fromuser)) 06808 l = p->fromuser; 06809 else /* Save for any further attempts */ 06810 ast_string_field_set(p, fromuser, l); 06811 06812 /* Allow user to be overridden */ 06813 if (!ast_strlen_zero(p->fromname)) 06814 n = p->fromname; 06815 else /* Save for any further attempts */ 06816 ast_string_field_set(p, fromname, n); 06817 06818 if (pedanticsipchecking) { 06819 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06820 n = tmp; 06821 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06822 l = tmp2; 06823 } 06824 06825 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06826 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); 06827 else 06828 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06829 06830 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06831 if (!ast_strlen_zero(p->fullcontact)) { 06832 /* If we have full contact, trust it */ 06833 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06834 } else { 06835 /* Otherwise, use the username while waiting for registration */ 06836 ast_build_string(&invite, &invite_max, "sip:"); 06837 if (!ast_strlen_zero(p->username)) { 06838 n = p->username; 06839 if (pedanticsipchecking) { 06840 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06841 n = tmp; 06842 } 06843 ast_build_string(&invite, &invite_max, "%s@", n); 06844 } 06845 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06846 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06847 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06848 ast_build_string(&invite, &invite_max, "%s", urioptions); 06849 } 06850 06851 /* If custom URI options have been provided, append them */ 06852 if (p->options && p->options->uri_options) 06853 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06854 06855 ast_string_field_set(p, uri, invite_buf); 06856 06857 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06858 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06859 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 06860 } else if (p->options && p->options->vxml_url) { 06861 /* If there is a VXML URL append it to the SIP URL */ 06862 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06863 } else 06864 snprintf(to, sizeof(to), "<%s>", p->uri); 06865 06866 init_req(req, sipmethod, p->uri); 06867 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06868 06869 add_header(req, "Via", p->via); 06870 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06871 * OTOH, then we won't have anything in p->route anyway */ 06872 /* Build Remote Party-ID and From */ 06873 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06874 build_rpid(p); 06875 add_header(req, "From", p->rpid_from); 06876 } else 06877 add_header(req, "From", from); 06878 add_header(req, "To", to); 06879 ast_string_field_set(p, exten, l); 06880 build_contact(p); 06881 add_header(req, "Contact", p->our_contact); 06882 add_header(req, "Call-ID", p->callid); 06883 add_header(req, "CSeq", tmp); 06884 if (!ast_strlen_zero(global_useragent)) 06885 add_header(req, "User-Agent", global_useragent); 06886 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06887 if (!ast_strlen_zero(p->rpid)) 06888 add_header(req, "Remote-Party-ID", p->rpid); 06889 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | [static] |
Convert Insecure setting to printable string.
Definition at line 9841 of file chan_sip.c.
Referenced by _sip_show_peer().
09842 { 09843 if (port && invite) 09844 return "port,invite"; 09845 else if (port) 09846 return "port"; 09847 else if (invite) 09848 return "invite"; 09849 else 09850 return "no"; 09851 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8037 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08038 { 08039 if (!route) 08040 ast_verbose("list_route: no route\n"); 08041 else { 08042 for (;route; route = route->next) 08043 ast_verbose("list_route: hop: <%s>\n", route->hop); 08044 } 08045 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17634 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, EVENT_FLAG_SYSTEM, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), mandescr_show_peer, mandescr_show_peers, peerl, regl, reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, and userl.
17635 { 17636 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 17637 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 17638 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 17639 17640 if (!(sched = sched_context_create())) { 17641 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 17642 return AST_MODULE_LOAD_FAILURE; 17643 } 17644 17645 if (!(io = io_context_create())) { 17646 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 17647 sched_context_destroy(sched); 17648 return AST_MODULE_LOAD_FAILURE; 17649 } 17650 17651 sip_reloadreason = CHANNEL_MODULE_LOAD; 17652 17653 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 17654 return AST_MODULE_LOAD_DECLINE; 17655 17656 /* Make sure we can register our sip channel type */ 17657 if (ast_channel_register(&sip_tech)) { 17658 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 17659 io_context_destroy(io); 17660 sched_context_destroy(sched); 17661 return AST_MODULE_LOAD_FAILURE; 17662 } 17663 17664 /* Register all CLI functions for SIP */ 17665 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 17666 17667 /* Tell the RTP subdriver that we're here */ 17668 ast_rtp_proto_register(&sip_rtp); 17669 17670 /* Tell the UDPTL subdriver that we're here */ 17671 ast_udptl_proto_register(&sip_udptl); 17672 17673 /* Register dialplan applications */ 17674 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 17675 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 17676 17677 /* Register dialplan functions */ 17678 ast_custom_function_register(&sip_header_function); 17679 ast_custom_function_register(&sippeer_function); 17680 ast_custom_function_register(&sipchaninfo_function); 17681 ast_custom_function_register(&checksipdomain_function); 17682 17683 /* Register manager commands */ 17684 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 17685 "List SIP peers (text format)", mandescr_show_peers); 17686 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 17687 "Show SIP peer (text format)", mandescr_show_peer); 17688 17689 sip_poke_all_peers(); 17690 sip_send_all_registers(); 17691 17692 /* And start the monitor for the first time */ 17693 restart_monitor(); 17694 17695 return AST_MODULE_LOAD_SUCCESS; 17696 }
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 13867 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().
13868 { 13869 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 13870 /* Chan 2: Call from Asterisk to target */ 13871 int res = 0; 13872 struct sip_pvt *targetcall_pvt; 13873 13874 /* Check if the call ID of the replaces header does exist locally */ 13875 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 13876 transferer->refer->replaces_callid_fromtag))) { 13877 if (transferer->refer->localtransfer) { 13878 /* We did not find the refered call. Sorry, can't accept then */ 13879 transmit_response(transferer, "202 Accepted", req); 13880 /* Let's fake a response from someone else in order 13881 to follow the standard */ 13882 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 13883 append_history(transferer, "Xfer", "Refer failed"); 13884 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13885 transferer->refer->status = REFER_FAILED; 13886 return -1; 13887 } 13888 /* Fall through for remote transfers that we did not find locally */ 13889 if (option_debug > 2) 13890 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 13891 return 0; 13892 } 13893 13894 /* Ok, we can accept this transfer */ 13895 transmit_response(transferer, "202 Accepted", req); 13896 append_history(transferer, "Xfer", "Refer accepted"); 13897 if (!targetcall_pvt->owner) { /* No active channel */ 13898 if (option_debug > 3) 13899 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 13900 /* Cancel transfer */ 13901 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 13902 append_history(transferer, "Xfer", "Refer failed"); 13903 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13904 transferer->refer->status = REFER_FAILED; 13905 ast_mutex_unlock(&targetcall_pvt->lock); 13906 ast_channel_unlock(current->chan1); 13907 return -1; 13908 } 13909 13910 /* We have a channel, find the bridge */ 13911 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 13912 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 13913 13914 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 13915 /* Wrong state of new channel */ 13916 if (option_debug > 3) { 13917 if (target.chan2) 13918 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 13919 else if (target.chan1->_state != AST_STATE_RING) 13920 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 13921 else 13922 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 13923 } 13924 } 13925 13926 /* Transfer */ 13927 if (option_debug > 3 && sipdebug) { 13928 if (current->chan2) /* We have two bridges */ 13929 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 13930 else /* One bridge, propably transfer of IVR/voicemail etc */ 13931 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 13932 } 13933 13934 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13935 13936 /* Perform the transfer */ 13937 res = attempt_transfer(current, &target); 13938 ast_mutex_unlock(&targetcall_pvt->lock); 13939 if (res) { 13940 /* Failed transfer */ 13941 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 13942 append_history(transferer, "Xfer", "Refer failed"); 13943 transferer->refer->status = REFER_FAILED; 13944 if (targetcall_pvt->owner) 13945 ast_channel_unlock(targetcall_pvt->owner); 13946 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 13947 if (res != -2) 13948 ast_hangup(transferer->owner); 13949 else 13950 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 13951 } else { 13952 /* Transfer succeeded! */ 13953 13954 /* Tell transferer that we're done. */ 13955 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 13956 append_history(transferer, "Xfer", "Refer succeeded"); 13957 transferer->refer->status = REFER_200OK; 13958 if (targetcall_pvt->owner) { 13959 if (option_debug) 13960 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 13961 ast_channel_unlock(targetcall_pvt->owner); 13962 } 13963 } 13964 return 1; 13965 }
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 4631 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04632 { 04633 int h = 0, t = 0; 04634 int lws = 0; 04635 04636 for (; h < len;) { 04637 /* Eliminate all CRs */ 04638 if (msgbuf[h] == '\r') { 04639 h++; 04640 continue; 04641 } 04642 /* Check for end-of-line */ 04643 if (msgbuf[h] == '\n') { 04644 /* Check for end-of-message */ 04645 if (h + 1 == len) 04646 break; 04647 /* Check for a continuation line */ 04648 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04649 /* Merge continuation line */ 04650 h++; 04651 continue; 04652 } 04653 /* Propagate LF and start new line */ 04654 msgbuf[t++] = msgbuf[h++]; 04655 lws = 0; 04656 continue; 04657 } 04658 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04659 if (lws) { 04660 h++; 04661 continue; 04662 } 04663 msgbuf[t++] = msgbuf[h++]; 04664 lws = 1; 04665 continue; 04666 } 04667 msgbuf[t++] = msgbuf[h++]; 04668 if (lws) 04669 lws = 0; 04670 } 04671 msgbuf[t] = '\0'; 04672 return t; 04673 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4303 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().
04304 { 04305 snprintf(tagbuf, len, "as%08lx", ast_random()); 04306 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10086 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().
Referenced by load_module().
10087 { 10088 const char *a[4]; 10089 const char *peer; 10090 int ret; 10091 10092 peer = astman_get_header(m,"Peer"); 10093 if (ast_strlen_zero(peer)) { 10094 astman_send_error(s, m, "Peer: <name> missing.\n"); 10095 return 0; 10096 } 10097 a[0] = "sip"; 10098 a[1] = "show"; 10099 a[2] = "peer"; 10100 a[3] = peer; 10101 10102 ret = _sip_show_peer(1, -1, s, m, 4, a); 10103 astman_append(s, "\r\n\r\n" ); 10104 return ret; 10105 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9637 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), and total.
Referenced by load_module().
09638 { 09639 const char *id = astman_get_header(m,"ActionID"); 09640 const char *a[] = {"sip", "show", "peers"}; 09641 char idtext[256] = ""; 09642 int total = 0; 09643 09644 if (!ast_strlen_zero(id)) 09645 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09646 09647 astman_send_ack(s, m, "Peer status list will follow"); 09648 /* List the peers in separate manager events */ 09649 _sip_show_peers(-1, &total, s, m, 3, a); 09650 /* Send final confirmation */ 09651 astman_append(s, 09652 "Event: PeerlistComplete\r\n" 09653 "ListItems: %d\r\n" 09654 "%s" 09655 "\r\n", total, idtext); 09656 return 0; 09657 }
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 1653 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01654 { 01655 int len = strlen(sip_methods[id].text); 01656 int l_name = name ? strlen(name) : 0; 01657 /* true if the string is long enough, and ends with whitespace, and matches */ 01658 return (l_name >= len && name[len] < 33 && 01659 !strncasecmp(sip_methods[id].text, name, len)); 01660 }
static char * nat2str | ( | int | nat | ) | [static] |
Convert NAT setting to text string.
Definition at line 9540 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().
09541 { 09542 switch(nat) { 09543 case SIP_NAT_NEVER: 09544 return "No"; 09545 case SIP_NAT_ROUTE: 09546 return "Route"; 09547 case SIP_NAT_ALWAYS: 09548 return "Always"; 09549 case SIP_NAT_RFC3581: 09550 return "RFC3581"; 09551 default: 09552 return "Unknown"; 09553 } 09554 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2187 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02188 { 02189 memset(dst, 0, sizeof(*dst)); 02190 memcpy(dst->data, src->data, sizeof(dst->data)); 02191 dst->len = src->len; 02192 parse_request(dst); 02193 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11709 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().
11710 { 11711 char tmp[BUFSIZ]; 11712 char *s, *e, *uri, *t; 11713 char *domain; 11714 11715 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11716 if ((t = strchr(tmp, ','))) 11717 *t = '\0'; 11718 s = get_in_brackets(tmp); 11719 uri = ast_strdupa(s); 11720 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11721 if (!strncasecmp(s, "sip:", 4)) 11722 s += 4; 11723 e = strchr(s, ';'); 11724 if (e) 11725 *e = '\0'; 11726 if (option_debug) 11727 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11728 if (p->owner) 11729 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11730 } else { 11731 e = strchr(tmp, '@'); 11732 if (e) { 11733 *e++ = '\0'; 11734 domain = e; 11735 } else { 11736 /* No username part */ 11737 domain = tmp; 11738 } 11739 e = strchr(s, ';'); /* Strip of parameters in the username part */ 11740 if (e) 11741 *e = '\0'; 11742 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 11743 if (e) 11744 *e = '\0'; 11745 11746 if (!strncasecmp(s, "sip:", 4)) 11747 s += 4; 11748 if (option_debug > 1) 11749 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 11750 if (p->owner) { 11751 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 11752 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 11753 ast_string_field_set(p->owner, call_forward, s); 11754 } 11755 } 11756 }
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 7793 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().
07794 { 07795 char contact[BUFSIZ]; 07796 char *c; 07797 07798 /* Look for brackets */ 07799 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07800 c = get_in_brackets(contact); 07801 07802 /* Save full contact to call pvt for later bye or re-invite */ 07803 ast_string_field_set(pvt, fullcontact, c); 07804 07805 /* Save URI for later ACKs, BYE or RE-invites */ 07806 ast_string_field_set(pvt, okcontacturi, c); 07807 07808 /* We should return false for URI:s we can't handle, 07809 like sips:, tel:, mailto:,ldap: etc */ 07810 return TRUE; 07811 }
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 7877 of file chan_sip.c.
References sip_peer::addr, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
07878 { 07879 char contact[BUFSIZ]; 07880 char data[BUFSIZ]; 07881 const char *expires = get_header(req, "Expires"); 07882 int expiry = atoi(expires); 07883 char *curi, *n, *pt; 07884 int port; 07885 const char *useragent; 07886 struct hostent *hp; 07887 struct ast_hostent ahp; 07888 struct sockaddr_in oldsin; 07889 07890 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07891 07892 if (ast_strlen_zero(expires)) { /* No expires header */ 07893 expires = strcasestr(contact, ";expires="); 07894 if (expires) { 07895 /* XXX bug here, we overwrite the string */ 07896 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 07897 if (sscanf(expires + 9, "%d", &expiry) != 1) 07898 expiry = default_expiry; 07899 } else { 07900 /* Nothing has been specified */ 07901 expiry = default_expiry; 07902 } 07903 } 07904 07905 /* Look for brackets */ 07906 curi = contact; 07907 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 07908 strsep(&curi, ";"); /* This is Header options, not URI options */ 07909 curi = get_in_brackets(contact); 07910 07911 /* if they did not specify Contact: or Expires:, they are querying 07912 what we currently have stored as their contact address, so return 07913 it 07914 */ 07915 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 07916 /* If we have an active registration, tell them when the registration is going to expire */ 07917 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 07918 pvt->expiry = ast_sched_when(sched, peer->expire); 07919 return PARSE_REGISTER_QUERY; 07920 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 07921 /* This means remove all registrations and return OK */ 07922 memset(&peer->addr, 0, sizeof(peer->addr)); 07923 if (peer->expire > -1) 07924 ast_sched_del(sched, peer->expire); 07925 peer->expire = -1; 07926 07927 destroy_association(peer); 07928 07929 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 07930 peer->fullcontact[0] = '\0'; 07931 peer->useragent[0] = '\0'; 07932 peer->sipoptions = 0; 07933 peer->lastms = 0; 07934 07935 if (option_verbose > 2) 07936 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 07937 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 07938 return PARSE_REGISTER_UPDATE; 07939 } 07940 07941 /* Store whatever we got as a contact from the client */ 07942 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 07943 07944 /* For the 200 OK, we should use the received contact */ 07945 ast_string_field_build(pvt, our_contact, "<%s>", curi); 07946 07947 /* Make sure it's a SIP URL */ 07948 if (strncasecmp(curi, "sip:", 4)) { 07949 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 07950 } else 07951 curi += 4; 07952 /* Ditch q */ 07953 curi = strsep(&curi, ";"); 07954 /* Grab host */ 07955 n = strchr(curi, '@'); 07956 if (!n) { 07957 n = curi; 07958 curi = NULL; 07959 } else 07960 *n++ = '\0'; 07961 pt = strchr(n, ':'); 07962 if (pt) { 07963 *pt++ = '\0'; 07964 port = atoi(pt); 07965 } else 07966 port = STANDARD_SIP_PORT; 07967 oldsin = peer->addr; 07968 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 07969 /* XXX This could block for a long time XXX */ 07970 hp = ast_gethostbyname(n, &ahp); 07971 if (!hp) { 07972 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 07973 return PARSE_REGISTER_FAILED; 07974 } 07975 peer->addr.sin_family = AF_INET; 07976 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 07977 peer->addr.sin_port = htons(port); 07978 } else { 07979 /* Don't trust the contact field. Just use what they came to us 07980 with */ 07981 peer->addr = pvt->recv; 07982 } 07983 07984 /* Save SIP options profile */ 07985 peer->sipoptions = pvt->sipoptions; 07986 07987 if (curi && ast_strlen_zero(peer->username)) 07988 ast_copy_string(peer->username, curi, sizeof(peer->username)); 07989 07990 if (peer->expire > -1) { 07991 ast_sched_del(sched, peer->expire); 07992 peer->expire = -1; 07993 } 07994 if (expiry > max_expiry) 07995 expiry = max_expiry; 07996 if (expiry < min_expiry) 07997 expiry = min_expiry; 07998 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 07999 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 08000 pvt->expiry = expiry; 08001 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); 08002 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08003 ast_db_put("SIP/Registry", peer->name, data); 08004 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08005 08006 /* Is this a new IP address for us? */ 08007 if (inaddrcmp(&peer->addr, &oldsin)) { 08008 sip_poke_peer(peer); 08009 if (option_verbose > 2) 08010 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); 08011 register_peer_exten(peer, 1); 08012 } 08013 08014 /* Save User agent */ 08015 useragent = get_header(req, "User-Agent"); 08016 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08017 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08018 if (option_verbose > 3) 08019 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08020 } 08021 return PARSE_REGISTER_UPDATE; 08022 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4678 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04679 { 04680 /* Divide fields by NULL's */ 04681 char *c; 04682 int f = 0; 04683 04684 c = req->data; 04685 04686 /* First header starts immediately */ 04687 req->header[f] = c; 04688 while(*c) { 04689 if (*c == '\n') { 04690 /* We've got a new header */ 04691 *c = 0; 04692 04693 if (sipdebug && option_debug > 3) 04694 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04695 if (ast_strlen_zero(req->header[f])) { 04696 /* Line by itself means we're now in content */ 04697 c++; 04698 break; 04699 } 04700 if (f >= SIP_MAX_HEADERS - 1) { 04701 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04702 } else 04703 f++; 04704 req->header[f] = c + 1; 04705 } else if (*c == '\r') { 04706 /* Ignore but eliminate \r's */ 04707 *c = 0; 04708 } 04709 c++; 04710 } 04711 /* Check for last header */ 04712 if (!ast_strlen_zero(req->header[f])) { 04713 if (sipdebug && option_debug > 3) 04714 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04715 f++; 04716 } 04717 req->headers = f; 04718 /* Now we process any mime content */ 04719 f = 0; 04720 req->line[f] = c; 04721 while(*c) { 04722 if (*c == '\n') { 04723 /* We've got a new line */ 04724 *c = 0; 04725 if (sipdebug && option_debug > 3) 04726 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04727 if (f >= SIP_MAX_LINES - 1) { 04728 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04729 } else 04730 f++; 04731 req->line[f] = c + 1; 04732 } else if (*c == '\r') { 04733 /* Ignore and eliminate \r's */ 04734 *c = 0; 04735 } 04736 c++; 04737 } 04738 /* Check for last line */ 04739 if (!ast_strlen_zero(req->line[f])) 04740 f++; 04741 req->lines = f; 04742 if (*c) 04743 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04744 /* Split up the first line parts */ 04745 determine_firstline_parts(req); 04746 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1677 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01678 { 01679 char *next, *sep; 01680 char *temp; 01681 unsigned int profile = 0; 01682 int i, found; 01683 01684 if (ast_strlen_zero(supported) ) 01685 return 0; 01686 temp = ast_strdupa(supported); 01687 01688 if (option_debug > 2 && sipdebug) 01689 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01690 01691 for (next = temp; next; next = sep) { 01692 found = FALSE; 01693 if ( (sep = strchr(next, ',')) != NULL) 01694 *sep++ = '\0'; 01695 next = ast_skip_blanks(next); 01696 if (option_debug > 2 && sipdebug) 01697 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01698 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01699 if (!strcasecmp(next, sip_options[i].text)) { 01700 profile |= sip_options[i].id; 01701 found = TRUE; 01702 if (option_debug > 2 && sipdebug) 01703 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01704 break; 01705 } 01706 } 01707 if (!found && option_debug > 2 && sipdebug) { 01708 if (!strncasecmp(next, "x-", 2)) 01709 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01710 else 01711 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01712 } 01713 } 01714 01715 if (pvt) 01716 pvt->sipoptions = profile; 01717 return profile; 01718 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9559 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09560 { 09561 int res = 0; 09562 if (peer->maxms) { 09563 if (peer->lastms < 0) { 09564 ast_copy_string(status, "UNREACHABLE", statuslen); 09565 } else if (peer->lastms > peer->maxms) { 09566 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09567 res = 1; 09568 } else if (peer->lastms) { 09569 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09570 res = 1; 09571 } else { 09572 ast_copy_string(status, "UNKNOWN", statuslen); 09573 } 09574 } else { 09575 ast_copy_string(status, "Unmonitored", statuslen); 09576 /* Checking if port is 0 */ 09577 res = -1; 09578 } 09579 return res; 09580 }
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 10027 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().
10028 { 10029 int x, codec; 10030 10031 for(x = 0; x < 32 ; x++) { 10032 codec = ast_codec_pref_index(pref, x); 10033 if (!codec) 10034 break; 10035 ast_cli(fd, "%s", ast_getformatname(codec)); 10036 ast_cli(fd, ":%d", pref->framing[x]); 10037 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10038 ast_cli(fd, ","); 10039 } 10040 if (!x) 10041 ast_cli(fd, "none"); 10042 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 9818 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
09819 { 09820 char buf[256]; 09821 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 09822 }
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 4854 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, LOG_WARNING, LONG_MAX, LONG_MIN, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, 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.
04855 { 04856 const char *m; /* SDP media offer */ 04857 const char *c; 04858 const char *a; 04859 char host[258]; 04860 int len = -1; 04861 int portno = -1; /*!< RTP Audio port number */ 04862 int vportno = -1; /*!< RTP Video port number */ 04863 int udptlportno = -1; 04864 int peert38capability = 0; 04865 char s[256]; 04866 int old = 0; 04867 04868 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04869 int peercapability = 0, peernoncodeccapability = 0; 04870 int vpeercapability = 0, vpeernoncodeccapability = 0; 04871 struct sockaddr_in sin; /*!< media socket address */ 04872 struct sockaddr_in vsin; /*!< Video socket address */ 04873 04874 const char *codecs; 04875 struct hostent *hp; /*!< RTP Audio host IP */ 04876 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04877 struct ast_hostent audiohp; 04878 struct ast_hostent videohp; 04879 int codec; 04880 int destiterator = 0; 04881 int iterator; 04882 int sendonly = -1; 04883 int numberofports; 04884 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04885 int newjointcapability; /* Negotiated capability */ 04886 int newpeercapability; 04887 int newnoncodeccapability; 04888 int numberofmediastreams = 0; 04889 int debug = sip_debug_test_pvt(p); 04890 04891 int found_rtpmap_codecs[32]; 04892 int last_rtpmap_codec=0; 04893 04894 if (!p->rtp) { 04895 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04896 return -1; 04897 } 04898 04899 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04900 newaudiortp = alloca(ast_rtp_alloc_size()); 04901 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04902 ast_rtp_new_init(newaudiortp); 04903 ast_rtp_pt_clear(newaudiortp); 04904 04905 newvideortp = alloca(ast_rtp_alloc_size()); 04906 memset(newvideortp, 0, ast_rtp_alloc_size()); 04907 ast_rtp_new_init(newvideortp); 04908 ast_rtp_pt_clear(newvideortp); 04909 04910 /* Update our last rtprx when we receive an SDP, too */ 04911 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 04912 04913 04914 /* Try to find first media stream */ 04915 m = get_sdp(req, "m"); 04916 destiterator = req->sdp_start; 04917 c = get_sdp_iterate(&destiterator, req, "c"); 04918 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 04919 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 04920 return -1; 04921 } 04922 04923 /* Check for IPv4 address (not IPv6 yet) */ 04924 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04925 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 04926 return -1; 04927 } 04928 04929 /* XXX This could block for a long time, and block the main thread! XXX */ 04930 hp = ast_gethostbyname(host, &audiohp); 04931 if (!hp) { 04932 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 04933 return -1; 04934 } 04935 vhp = hp; /* Copy to video address as default too */ 04936 04937 iterator = req->sdp_start; 04938 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 04939 04940 04941 /* Find media streams in this SDP offer */ 04942 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 04943 int x; 04944 int audio = FALSE; 04945 04946 numberofports = 1; 04947 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04948 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 04949 audio = TRUE; 04950 numberofmediastreams++; 04951 /* Found audio stream in this media definition */ 04952 portno = x; 04953 /* Scan through the RTP payload types specified in a "m=" line: */ 04954 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04955 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04956 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04957 return -1; 04958 } 04959 if (debug) 04960 ast_verbose("Found RTP audio format %d\n", codec); 04961 ast_rtp_set_m_type(newaudiortp, codec); 04962 } 04963 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04964 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 04965 /* If it is not audio - is it video ? */ 04966 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 04967 numberofmediastreams++; 04968 vportno = x; 04969 /* Scan through the RTP payload types specified in a "m=" line: */ 04970 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04971 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04972 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04973 return -1; 04974 } 04975 if (debug) 04976 ast_verbose("Found RTP video format %d\n", codec); 04977 ast_rtp_set_m_type(newvideortp, codec); 04978 } 04979 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 04980 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 04981 if (debug) 04982 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 04983 udptlportno = x; 04984 numberofmediastreams++; 04985 04986 if (p->owner && p->lastinvite) { 04987 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 04988 if (option_debug > 1) 04989 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 04990 } else { 04991 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 04992 if (option_debug > 1) 04993 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 04994 } 04995 } else 04996 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 04997 if (numberofports > 1) 04998 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 04999 05000 05001 /* Check for Media-description-level-address for audio */ 05002 c = get_sdp_iterate(&destiterator, req, "c"); 05003 if (!ast_strlen_zero(c)) { 05004 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05005 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05006 } else { 05007 /* XXX This could block for a long time, and block the main thread! XXX */ 05008 if (audio) { 05009 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05010 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05011 return -2; 05012 } 05013 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05014 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05015 return -2; 05016 } 05017 } 05018 05019 } 05020 } 05021 if (portno == -1 && vportno == -1 && udptlportno == -1) 05022 /* No acceptable offer found in SDP - we have no ports */ 05023 /* Do not change RTP or VRTP if this is a re-invite */ 05024 return -2; 05025 05026 if (numberofmediastreams > 2) 05027 /* We have too many fax, audio and/or video media streams, fail this offer */ 05028 return -3; 05029 05030 /* RTP addresses and ports for audio and video */ 05031 sin.sin_family = AF_INET; 05032 vsin.sin_family = AF_INET; 05033 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05034 if (vhp) 05035 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05036 05037 /* Setup UDPTL port number */ 05038 if (p->udptl) { 05039 if (udptlportno > 0) { 05040 sin.sin_port = htons(udptlportno); 05041 ast_udptl_set_peer(p->udptl, &sin); 05042 if (debug) 05043 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05044 } else { 05045 ast_udptl_stop(p->udptl); 05046 if (debug) 05047 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05048 } 05049 } 05050 05051 05052 if (p->rtp) { 05053 if (portno > 0) { 05054 sin.sin_port = htons(portno); 05055 ast_rtp_set_peer(p->rtp, &sin); 05056 if (debug) 05057 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05058 } else { 05059 if (udptlportno > 0) { 05060 if (debug) 05061 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05062 } else { 05063 ast_rtp_stop(p->rtp); 05064 if (debug) 05065 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05066 } 05067 } 05068 } 05069 /* Setup video port number */ 05070 if (vportno != -1) 05071 vsin.sin_port = htons(vportno); 05072 05073 /* Next, scan through each "a=rtpmap:" line, noting each 05074 * specified RTP payload type (with corresponding MIME subtype): 05075 */ 05076 /* XXX This needs to be done per media stream, since it's media stream specific */ 05077 iterator = req->sdp_start; 05078 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05079 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05080 if (option_debug > 1) { 05081 int breakout = FALSE; 05082 05083 /* If we're debugging, check for unsupported sdp options */ 05084 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05085 if (debug) 05086 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05087 breakout = TRUE; 05088 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05089 /* Format parameters: Not supported */ 05090 /* Note: This is used for codec parameters, like bitrate for 05091 G722 and video formats for H263 and H264 05092 See RFC2327 for an example */ 05093 if (debug) 05094 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05095 breakout = TRUE; 05096 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05097 /* Video stuff: Not supported */ 05098 if (debug) 05099 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05100 breakout = TRUE; 05101 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05102 /* Video stuff: Not supported */ 05103 if (debug) 05104 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05105 breakout = TRUE; 05106 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05107 /* SRTP stuff, not yet supported */ 05108 if (debug) 05109 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05110 breakout = TRUE; 05111 } 05112 if (breakout) /* We have a match, skip to next header */ 05113 continue; 05114 } 05115 if (!strcasecmp(a, "sendonly")) { 05116 if (sendonly == -1) 05117 sendonly = 1; 05118 continue; 05119 } else if (!strcasecmp(a, "inactive")) { 05120 if (sendonly == -1) 05121 sendonly = 2; 05122 continue; 05123 } else if (!strcasecmp(a, "sendrecv")) { 05124 if (sendonly == -1) 05125 sendonly = 0; 05126 continue; 05127 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05128 char *tmp = strrchr(a, ':'); 05129 long int framing = 0; 05130 if (tmp) { 05131 tmp++; 05132 framing = strtol(tmp, NULL, 10); 05133 if (framing == LONG_MIN || framing == LONG_MAX) { 05134 framing = 0; 05135 if (option_debug) 05136 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05137 } 05138 } 05139 if (framing && last_rtpmap_codec) { 05140 if (p->autoframing) { 05141 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05142 int codec_n; 05143 int format = 0; 05144 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05145 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05146 if (!format) /* non-codec or not found */ 05147 continue; 05148 if (option_debug) 05149 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05150 ast_codec_pref_setsize(pref, format, framing); 05151 } 05152 ast_rtp_codec_setpref(p->rtp, pref); 05153 } 05154 } 05155 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05156 last_rtpmap_codec = 0; 05157 continue; 05158 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05159 /* We have a rtpmap to handle */ 05160 if (debug) 05161 ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec); 05162 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05163 last_rtpmap_codec++; 05164 05165 /* Note: should really look at the 'freq' and '#chans' params too */ 05166 ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05167 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0); 05168 if (p->vrtp) 05169 ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0); 05170 } 05171 } 05172 05173 if (udptlportno != -1) { 05174 int found = 0, x; 05175 05176 old = 0; 05177 05178 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05179 iterator = req->sdp_start; 05180 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05181 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05182 found = 1; 05183 if (option_debug > 2) 05184 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05185 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05186 found = 1; 05187 if (option_debug > 2) 05188 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05189 switch (x) { 05190 case 14400: 05191 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05192 break; 05193 case 12000: 05194 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05195 break; 05196 case 9600: 05197 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05198 break; 05199 case 7200: 05200 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05201 break; 05202 case 4800: 05203 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05204 break; 05205 case 2400: 05206 peert38capability |= T38FAX_RATE_2400; 05207 break; 05208 } 05209 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05210 found = 1; 05211 if (option_debug > 2) 05212 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05213 if (x == 0) 05214 peert38capability |= T38FAX_VERSION_0; 05215 else if (x == 1) 05216 peert38capability |= T38FAX_VERSION_1; 05217 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05218 found = 1; 05219 if (option_debug > 2) 05220 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05221 ast_udptl_set_far_max_datagram(p->udptl, x); 05222 ast_udptl_set_local_max_datagram(p->udptl, x); 05223 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05224 found = 1; 05225 if (option_debug > 2) 05226 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05227 if (x == 1) 05228 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05229 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05230 found = 1; 05231 if (option_debug > 2) 05232 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05233 if (x == 1) 05234 peert38capability |= T38FAX_TRANSCODING_MMR; 05235 } 05236 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05237 found = 1; 05238 if (option_debug > 2) 05239 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05240 if (x == 1) 05241 peert38capability |= T38FAX_TRANSCODING_JBIG; 05242 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05243 found = 1; 05244 if (option_debug > 2) 05245 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05246 if (!strcasecmp(s, "localTCF")) 05247 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05248 else if (!strcasecmp(s, "transferredTCF")) 05249 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05250 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05251 found = 1; 05252 if (option_debug > 2) 05253 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05254 if (!strcasecmp(s, "t38UDPRedundancy")) { 05255 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05256 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05257 } else if (!strcasecmp(s, "t38UDPFEC")) { 05258 peert38capability |= T38FAX_UDP_EC_FEC; 05259 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05260 } else { 05261 peert38capability |= T38FAX_UDP_EC_NONE; 05262 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05263 } 05264 } 05265 } 05266 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05267 p->t38.peercapability = peert38capability; 05268 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05269 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05270 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05271 } 05272 if (debug) 05273 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05274 p->t38.capability, 05275 p->t38.peercapability, 05276 p->t38.jointcapability); 05277 } else { 05278 p->t38.state = T38_DISABLED; 05279 if (option_debug > 2) 05280 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05281 } 05282 05283 /* Now gather all of the codecs that we are asked for: */ 05284 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05285 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05286 05287 newjointcapability = p->capability & (peercapability | vpeercapability); 05288 newpeercapability = (peercapability | vpeercapability); 05289 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05290 05291 05292 if (debug) { 05293 /* shame on whoever coded this.... */ 05294 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05295 05296 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05297 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05298 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05299 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05300 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05301 05302 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05303 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05304 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05305 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05306 } 05307 if (!newjointcapability) { 05308 /* If T.38 was not negotiated either, totally bail out... */ 05309 if (!p->t38.jointcapability) { 05310 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05311 /* Do NOT Change current setting */ 05312 return -1; 05313 } else { 05314 if (option_debug > 2) 05315 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05316 return 0; 05317 } 05318 } 05319 05320 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05321 they are acceptable */ 05322 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05323 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05324 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05325 05326 ast_rtp_pt_copy(p->rtp, newaudiortp); 05327 if (p->vrtp) 05328 ast_rtp_pt_copy(p->vrtp, newvideortp); 05329 05330 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05331 ast_clear_flag(&p->flags[0], SIP_DTMF); 05332 if (newnoncodeccapability & AST_RTP_DTMF) { 05333 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05334 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05335 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05336 ast_rtp_setdtmf(p->rtp, 1); 05337 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05338 } else { 05339 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05340 } 05341 } 05342 05343 /* Setup audio port number */ 05344 if (p->rtp && sin.sin_port) { 05345 ast_rtp_set_peer(p->rtp, &sin); 05346 if (debug) 05347 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05348 } 05349 05350 /* Setup video port number */ 05351 if (p->vrtp && vsin.sin_port) { 05352 ast_rtp_set_peer(p->vrtp, &vsin); 05353 if (debug) 05354 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05355 } 05356 05357 /* Ok, we're going with this offer */ 05358 if (option_debug > 1) { 05359 char buf[BUFSIZ]; 05360 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05361 } 05362 05363 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05364 return 0; 05365 05366 if (option_debug > 3) 05367 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05368 05369 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05370 if (debug) { 05371 char s1[BUFSIZ], s2[BUFSIZ]; 05372 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05373 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05374 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05375 } 05376 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05377 ast_set_read_format(p->owner, p->owner->readformat); 05378 ast_set_write_format(p->owner, p->owner->writeformat); 05379 } 05380 05381 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05382 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05383 /* Activate a re-invite */ 05384 ast_queue_frame(p->owner, &ast_null_frame); 05385 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05386 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05387 S_OR(p->mohsuggest, NULL), 05388 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05389 if (sendonly) 05390 ast_rtp_stop(p->rtp); 05391 /* RTCP needs to go ahead, even if we're on hold!!! */ 05392 /* Activate a re-invite */ 05393 ast_queue_frame(p->owner, &ast_null_frame); 05394 } 05395 05396 /* Manager Hold and Unhold events must be generated, if necessary */ 05397 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05398 change_hold_state(p, req, FALSE, sendonly); 05399 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05400 change_hold_state(p, req, TRUE, sendonly); 05401 return 0; 05402 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2456 of file chan_sip.c.
References ast_category_browse(), ast_category_root(), ast_config_destroy(), ast_copy_flags, ast_inet_ntoa(), ast_load_realtime(), ast_load_realtime_multientry(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variable_retrieve(), ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_peer(), sip_peer::expire, expire_register(), sip_peer::flags, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, set_insecure_flags(), SIP_INSECURE_PORT, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, ast_variable::value, and var.
02457 { 02458 struct sip_peer *peer=NULL; 02459 struct ast_variable *var; 02460 struct ast_config *peerlist = NULL; 02461 struct ast_variable *tmp; 02462 struct ast_flags flags = {0}; 02463 const char *iabuf = NULL; 02464 char portstring[6]; /*up to five digits plus null terminator*/ 02465 const char *insecure; 02466 char *cat = NULL; 02467 unsigned short portnum; 02468 02469 /* First check on peer name */ 02470 if (newpeername) 02471 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02472 else if (sin) { /* Then check on IP address */ 02473 iabuf = ast_inet_ntoa(sin->sin_addr); 02474 portnum = ntohs(sin->sin_port); 02475 sprintf(portstring, "%d", portnum); 02476 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02477 if (!var) 02478 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02479 if (!var) { 02480 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02481 if(peerlist){ 02482 while((cat = ast_category_browse(peerlist, cat))) 02483 { 02484 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02485 set_insecure_flags(&flags, insecure, -1); 02486 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02487 var = ast_category_root(peerlist, cat); 02488 break; 02489 } 02490 } 02491 } 02492 if(!var) { 02493 ast_config_destroy(peerlist); 02494 peerlist = NULL; /*for safety's sake*/ 02495 cat = NULL; 02496 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02497 if(peerlist) { 02498 while((cat = ast_category_browse(peerlist, cat))) 02499 { 02500 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02501 set_insecure_flags(&flags, insecure, -1); 02502 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02503 var = ast_category_root(peerlist, cat); 02504 break; 02505 } 02506 } 02507 } 02508 } 02509 } 02510 } else 02511 return NULL; 02512 02513 if (!var) { 02514 if(peerlist) 02515 ast_config_destroy(peerlist); 02516 return NULL; 02517 } 02518 02519 for (tmp = var; tmp; tmp = tmp->next) { 02520 /* If this is type=user, then skip this object. */ 02521 if (!strcasecmp(tmp->name, "type") && 02522 !strcasecmp(tmp->value, "user")) { 02523 ast_variables_destroy(var); 02524 return NULL; 02525 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02526 newpeername = tmp->value; 02527 } 02528 } 02529 02530 if (!newpeername) { /* Did not find peer in realtime */ 02531 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02532 if(peerlist) 02533 ast_config_destroy(peerlist); 02534 else 02535 ast_variables_destroy(var); 02536 return NULL; 02537 } 02538 02539 /* Peer found in realtime, now build it in memory */ 02540 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02541 if (!peer) { 02542 if(peerlist) 02543 ast_config_destroy(peerlist); 02544 else 02545 ast_variables_destroy(var); 02546 return NULL; 02547 } 02548 02549 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02550 /* Cache peer */ 02551 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02552 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02553 if (peer->expire > -1) { 02554 ast_sched_del(sched, peer->expire); 02555 } 02556 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02557 } 02558 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02559 } else { 02560 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02561 } 02562 if(peerlist) 02563 ast_config_destroy(peerlist); 02564 else 02565 ast_variables_destroy(var); 02566 return peer; 02567 }
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 2341 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02342 { 02343 char port[10]; 02344 char ipaddr[INET_ADDRSTRLEN]; 02345 char regseconds[20]; 02346 02347 char *sysname = ast_config_AST_SYSTEM_NAME; 02348 char *syslabel = NULL; 02349 02350 time_t nowtime = time(NULL) + expirey; 02351 const char *fc = fullcontact ? "fullcontact" : NULL; 02352 02353 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02354 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02355 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02356 02357 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02358 sysname = NULL; 02359 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02360 syslabel = "regserver"; 02361 02362 if (fc) 02363 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02364 "port", port, "regseconds", regseconds, 02365 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02366 else 02367 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02368 "port", port, "regseconds", regseconds, 02369 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02370 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static, read] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2617 of file chan_sip.c.
References ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ASTOBJ_CONTAINER_LINK, build_user(), sip_user::flags, ast_variable::name, ast_variable::next, SIP_PAGE2_RTCACHEFRIENDS, SIP_REALTIME, userl, ast_variable::value, and var.
02618 { 02619 struct ast_variable *var; 02620 struct ast_variable *tmp; 02621 struct sip_user *user = NULL; 02622 02623 var = ast_load_realtime("sipusers", "name", username, NULL); 02624 02625 if (!var) 02626 return NULL; 02627 02628 for (tmp = var; tmp; tmp = tmp->next) { 02629 if (!strcasecmp(tmp->name, "type") && 02630 !strcasecmp(tmp->value, "peer")) { 02631 ast_variables_destroy(var); 02632 return NULL; 02633 } 02634 } 02635 02636 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02637 02638 if (!user) { /* No user found */ 02639 ast_variables_destroy(var); 02640 return NULL; 02641 } 02642 02643 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02644 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02645 suserobjs++; 02646 ASTOBJ_CONTAINER_LINK(&userl,user); 02647 } else { 02648 /* Move counter from s to r... */ 02649 suserobjs--; 02650 ruserobjs++; 02651 ast_set_flag(&user->flags[0], SIP_REALTIME); 02652 } 02653 ast_variables_destroy(var); 02654 return user; 02655 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9444 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), ast_frame::data, ast_frame::datalen, DEFAULT_TRANS_TIMEOUT, ast_frame::frametype, get_header(), get_msg_text(), LOG_WARNING, ast_frame::offset, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), ast_frame::subclass, and transmit_response().
Referenced by handle_request_message().
09445 { 09446 char buf[1024]; 09447 struct ast_frame f; 09448 const char *content_type = get_header(req, "Content-Type"); 09449 09450 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09451 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09452 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09453 return; 09454 } 09455 09456 if (get_msg_text(buf, sizeof(buf), req)) { 09457 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09458 transmit_response(p, "202 Accepted", req); 09459 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09460 return; 09461 } 09462 09463 if (p->owner) { 09464 if (sip_debug_test_pvt(p)) 09465 ast_verbose("Message received: '%s'\n", buf); 09466 memset(&f, 0, sizeof(f)); 09467 f.frametype = AST_FRAME_TEXT; 09468 f.subclass = 0; 09469 f.offset = 0; 09470 f.data = buf; 09471 f.datalen = strlen(buf); 09472 ast_queue_frame(p->owner, &f); 09473 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09474 } else { /* Message outside of a call, we do not support that */ 09475 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); 09476 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09477 } 09478 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09479 return; 09480 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1612 of file chan_sip.c.
References referstatusstrings, and c_referstatusstring::text.
Referenced by __sip_show_channels().
01613 { 01614 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01615 int x; 01616 01617 for (x = 0; x < i; x++) { 01618 if (referstatusstrings[x].status == rstatus) 01619 return (char *) referstatusstrings[x].text; 01620 } 01621 return ""; 01622 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7733 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_test_flag, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07734 { 07735 char data[256]; 07736 struct in_addr in; 07737 int expiry; 07738 int port; 07739 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07740 07741 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07742 return; 07743 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07744 return; 07745 07746 scan = data; 07747 addr = strsep(&scan, ":"); 07748 port_str = strsep(&scan, ":"); 07749 expiry_str = strsep(&scan, ":"); 07750 username = strsep(&scan, ":"); 07751 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07752 07753 if (!inet_aton(addr, &in)) 07754 return; 07755 07756 if (port_str) 07757 port = atoi(port_str); 07758 else 07759 return; 07760 07761 if (expiry_str) 07762 expiry = atoi(expiry_str); 07763 else 07764 return; 07765 07766 if (username) 07767 ast_copy_string(peer->username, username, sizeof(peer->username)); 07768 if (contact) 07769 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07770 07771 if (option_debug > 1) 07772 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07773 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07774 07775 memset(&peer->addr, 0, sizeof(peer->addr)); 07776 peer->addr.sin_family = AF_INET; 07777 peer->addr.sin_addr = in; 07778 peer->addr.sin_port = htons(port); 07779 if (sipsock < 0) { 07780 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07781 if (peer->pokeexpire > -1) 07782 ast_sched_del(sched, peer->pokeexpire); 07783 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07784 } else 07785 sip_poke_peer(peer); 07786 if (peer->expire > -1) 07787 ast_sched_del(sched, peer->expire); 07788 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07789 register_peer_exten(peer, TRUE); 07790 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2373 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().
02374 { 02375 char multi[256]; 02376 char *stringp, *ext, *context; 02377 02378 /* XXX note that global_regcontext is both a global 'enable' flag and 02379 * the name of the global regexten context, if not specified 02380 * individually. 02381 */ 02382 if (ast_strlen_zero(global_regcontext)) 02383 return; 02384 02385 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02386 stringp = multi; 02387 while ((ext = strsep(&stringp, "&"))) { 02388 if ((context = strchr(ext, '@'))) { 02389 *context++ = '\0'; /* split ext@context */ 02390 if (!ast_context_find(context)) { 02391 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02392 continue; 02393 } 02394 } else { 02395 context = global_regcontext; 02396 } 02397 if (onoff) 02398 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02399 ast_strdup(peer->name), ast_free, "SIP"); 02400 else 02401 ast_context_remove_extension(context, ext, 1, NULL); 02402 } 02403 }
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 8386 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, sip_pvt::expiry, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08388 { 08389 enum check_auth_result res = AUTH_NOT_FOUND; 08390 struct sip_peer *peer; 08391 char tmp[256]; 08392 char *name, *c; 08393 char *t; 08394 char *domain; 08395 08396 /* Terminate URI */ 08397 t = uri; 08398 while(*t && (*t > 32) && (*t != ';')) 08399 t++; 08400 *t = '\0'; 08401 08402 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08403 if (pedanticsipchecking) 08404 ast_uri_decode(tmp); 08405 08406 c = get_in_brackets(tmp); 08407 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08408 08409 if (!strncasecmp(c, "sip:", 4)) { 08410 name = c + 4; 08411 } else { 08412 name = c; 08413 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08414 } 08415 08416 /* Strip off the domain name */ 08417 if ((c = strchr(name, '@'))) { 08418 *c++ = '\0'; 08419 domain = c; 08420 if ((c = strchr(domain, ':'))) /* Remove :port */ 08421 *c = '\0'; 08422 if (!AST_LIST_EMPTY(&domain_list)) { 08423 if (!check_sip_domain(domain, NULL, 0)) { 08424 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08425 return AUTH_UNKNOWN_DOMAIN; 08426 } 08427 } 08428 } 08429 08430 ast_string_field_set(p, exten, name); 08431 build_contact(p); 08432 peer = find_peer(name, NULL, 1); 08433 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08434 /* Peer fails ACL check */ 08435 if (peer) { 08436 ASTOBJ_UNREF(peer, sip_destroy_peer); 08437 peer = NULL; 08438 res = AUTH_ACL_FAILED; 08439 } else 08440 res = AUTH_NOT_FOUND; 08441 } 08442 if (peer) { 08443 /* Set Frame packetization */ 08444 if (p->rtp) { 08445 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08446 p->autoframing = peer->autoframing; 08447 } 08448 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08449 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08450 res = AUTH_PEER_NOT_DYNAMIC; 08451 } else { 08452 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08453 transmit_response(p, "100 Trying", req); 08454 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08455 sip_cancel_destroy(p); 08456 08457 /* We have a succesful registration attemp with proper authentication, 08458 now, update the peer */ 08459 switch (parse_register_contact(p, peer, req)) { 08460 case PARSE_REGISTER_FAILED: 08461 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08462 transmit_response_with_date(p, "400 Bad Request", req); 08463 peer->lastmsgssent = -1; 08464 res = 0; 08465 break; 08466 case PARSE_REGISTER_QUERY: 08467 transmit_response_with_date(p, "200 OK", req); 08468 peer->lastmsgssent = -1; 08469 res = 0; 08470 break; 08471 case PARSE_REGISTER_UPDATE: 08472 update_peer(peer, p->expiry); 08473 /* Say OK and ask subsystem to retransmit msg counter */ 08474 transmit_response_with_date(p, "200 OK", req); 08475 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08476 peer->lastmsgssent = -1; 08477 res = 0; 08478 break; 08479 } 08480 } 08481 } 08482 } 08483 if (!peer && autocreatepeer) { 08484 /* Create peer if we have autocreate mode enabled */ 08485 peer = temp_peer(name); 08486 if (peer) { 08487 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08488 sip_cancel_destroy(p); 08489 switch (parse_register_contact(p, peer, req)) { 08490 case PARSE_REGISTER_FAILED: 08491 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08492 transmit_response_with_date(p, "400 Bad Request", req); 08493 peer->lastmsgssent = -1; 08494 res = 0; 08495 break; 08496 case PARSE_REGISTER_QUERY: 08497 transmit_response_with_date(p, "200 OK", req); 08498 peer->lastmsgssent = -1; 08499 res = 0; 08500 break; 08501 case PARSE_REGISTER_UPDATE: 08502 /* Say OK and ask subsystem to retransmit msg counter */ 08503 transmit_response_with_date(p, "200 OK", req); 08504 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08505 peer->lastmsgssent = -1; 08506 res = 0; 08507 break; 08508 } 08509 } 08510 } 08511 if (!res) { 08512 ast_device_state_changed("SIP/%s", peer->name); 08513 } 08514 if (res < 0) { 08515 switch (res) { 08516 case AUTH_SECRET_FAILED: 08517 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08518 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08519 break; 08520 case AUTH_USERNAME_MISMATCH: 08521 /* Username and digest username does not match. 08522 Asterisk uses the From: username for authentication. We need the 08523 users to use the same authentication user name until we support 08524 proper authentication by digest auth name */ 08525 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08526 break; 08527 case AUTH_NOT_FOUND: 08528 case AUTH_PEER_NOT_DYNAMIC: 08529 case AUTH_ACL_FAILED: 08530 if (global_alwaysauthreject) { 08531 transmit_fake_auth_response(p, &p->initreq, 1); 08532 } else { 08533 /* URI not found */ 08534 if (res == AUTH_UNKNOWN_DOMAIN || res == AUTH_PEER_NOT_DYNAMIC) 08535 transmit_response(p, "403 Forbidden", &p->initreq); 08536 else 08537 transmit_response(p, "404 Not found", &p->initreq); 08538 } 08539 break; 08540 default: 08541 break; 08542 } 08543 } 08544 if (peer) 08545 ASTOBJ_UNREF(peer, sip_destroy_peer); 08546 08547 return res; 08548 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | [static] |
Convert registration state status to string.
Definition at line 7232 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.
07233 { 07234 switch(regstate) { 07235 case REG_STATE_FAILED: 07236 return "Failed"; 07237 case REG_STATE_UNREGISTERED: 07238 return "Unregistered"; 07239 case REG_STATE_REGSENT: 07240 return "Request Sent"; 07241 case REG_STATE_AUTHSENT: 07242 return "Auth. Sent"; 07243 case REG_STATE_REGISTERED: 07244 return "Registered"; 07245 case REG_STATE_REJECTED: 07246 return "Rejected"; 07247 case REG_STATE_TIMEOUT: 07248 return "Timeout"; 07249 case REG_STATE_NOAUTH: 07250 return "No Authentication"; 07251 default: 07252 return "Unknown"; 07253 } 07254 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17520 of file chan_sip.c.
References sip_reload().
17521 { 17522 return sip_reload(0, 0, NULL); 17523 }
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 16422 of file chan_sip.c.
References __ourip, add_realm_authentication(), add_sip_domain(), ast_append_ha(), ast_category_browse(), ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_flags, ast_device_state_changed(), ast_enable_packet_fragmentation(), ast_find_ourip(), AST_FLAGS_ALL, ast_free_ha(), ast_get_ip_or_srv(), ast_gethostbyname(), ast_inet_ntoa(), ast_jb_read_conf(), AST_LIST_EMPTY, ast_log(), AST_MAX_CONTEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_strdupa, ast_strlen_zero(), ast_tos2str(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, authl, bindaddr, build_peer(), build_user(), channelreloadreason2txt(), cleanup_stale_contexts(), context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_DEFAULT_EXPIRY, DEFAULT_EXPIRY, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MAX_EXPIRY, DEFAULT_MAXMS, DEFAULT_MIN_EXPIRY, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, EVENT_FLAG_SYSTEM, externexpire, externhost, externip, externrefresh, FALSE, gen, global_jbconf, handle_common_options(), hp, ast_variable::lineno, localaddr, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_variable::name, ast_variable::next, notify_types, option_debug, option_verbose, ourport, outboundproxyip, peerl, secret, SIP_CAN_REINVITE, sip_destroy_peer(), sip_destroy_user(), SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, sip_register(), SIP_USEREQPHONE, sipsock, STANDARD_SIP_PORT, strsep(), TRANSFER_CLOSED, TRANSFER_OPENFORALL, userl, username, ast_variable::value, and VERBOSE_PREFIX_2.
16423 { 16424 struct ast_config *cfg, *ucfg; 16425 struct ast_variable *v; 16426 struct sip_peer *peer; 16427 struct sip_user *user; 16428 struct ast_hostent ahp; 16429 char *cat, *stringp, *context, *oldregcontext; 16430 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16431 struct hostent *hp; 16432 int format; 16433 struct ast_flags dummy[2]; 16434 int auto_sip_domains = FALSE; 16435 struct sockaddr_in old_bindaddr = bindaddr; 16436 int registry_count = 0, peer_count = 0, user_count = 0; 16437 unsigned int temp_tos = 0; 16438 struct ast_flags debugflag = {0}; 16439 16440 cfg = ast_config_load(config); 16441 16442 /* We *must* have a config file otherwise stop immediately */ 16443 if (!cfg) { 16444 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16445 return -1; 16446 } 16447 16448 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16449 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16450 oldregcontext = oldcontexts; 16451 16452 /* Clear all flags before setting default values */ 16453 /* Preserve debugging settings for console */ 16454 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16455 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16456 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16457 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16458 16459 /* Reset IP addresses */ 16460 memset(&bindaddr, 0, sizeof(bindaddr)); 16461 ast_free_ha(localaddr); 16462 memset(&localaddr, 0, sizeof(localaddr)); 16463 memset(&externip, 0, sizeof(externip)); 16464 memset(&default_prefs, 0 , sizeof(default_prefs)); 16465 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16466 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16467 ourport = STANDARD_SIP_PORT; 16468 srvlookup = DEFAULT_SRVLOOKUP; 16469 global_tos_sip = DEFAULT_TOS_SIP; 16470 global_tos_audio = DEFAULT_TOS_AUDIO; 16471 global_tos_video = DEFAULT_TOS_VIDEO; 16472 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16473 externexpire = 0; /* Expiration for DNS re-issuing */ 16474 externrefresh = 10; 16475 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16476 16477 /* Reset channel settings to default before re-configuring */ 16478 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16479 global_regcontext[0] = '\0'; 16480 expiry = DEFAULT_EXPIRY; 16481 global_notifyringing = DEFAULT_NOTIFYRINGING; 16482 global_limitonpeers = FALSE; 16483 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16484 global_notifyhold = FALSE; 16485 global_alwaysauthreject = 0; 16486 global_allowsubscribe = FALSE; 16487 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16488 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16489 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16490 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16491 else 16492 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16493 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16494 compactheaders = DEFAULT_COMPACTHEADERS; 16495 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16496 global_regattempts_max = 0; 16497 pedanticsipchecking = DEFAULT_PEDANTIC; 16498 global_mwitime = DEFAULT_MWITIME; 16499 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16500 global_autoframing = 0; 16501 global_allowguest = DEFAULT_ALLOWGUEST; 16502 global_rtptimeout = 0; 16503 global_rtpholdtimeout = 0; 16504 global_rtpkeepalive = 0; 16505 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16506 global_rtautoclear = 120; 16507 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16508 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16509 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16510 16511 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16512 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16513 default_subscribecontext[0] = '\0'; 16514 default_language[0] = '\0'; 16515 default_fromdomain[0] = '\0'; 16516 default_qualify = DEFAULT_QUALIFY; 16517 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16518 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16519 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16520 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16521 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16522 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16523 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16524 16525 /* Debugging settings, always default to off */ 16526 dumphistory = FALSE; 16527 recordhistory = FALSE; 16528 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16529 16530 /* Misc settings for the channel */ 16531 global_relaxdtmf = FALSE; 16532 global_callevents = FALSE; 16533 global_t1min = DEFAULT_T1MIN; 16534 16535 global_matchexterniplocally = FALSE; 16536 16537 /* Copy the default jb config over global_jbconf */ 16538 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16539 16540 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16541 16542 /* Read the [general] config section of sip.conf (or from realtime config) */ 16543 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16544 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16545 continue; 16546 /* handle jb conf */ 16547 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16548 continue; 16549 16550 /* Create the interface list */ 16551 if (!strcasecmp(v->name, "context")) { 16552 ast_copy_string(default_context, v->value, sizeof(default_context)); 16553 } else if (!strcasecmp(v->name, "allowguest")) { 16554 global_allowguest = ast_true(v->value) ? 1 : 0; 16555 } else if (!strcasecmp(v->name, "realm")) { 16556 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16557 } else if (!strcasecmp(v->name, "useragent")) { 16558 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16559 if (option_debug) 16560 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16561 } else if (!strcasecmp(v->name, "allowtransfer")) { 16562 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16563 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16564 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16565 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16566 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16567 } else if (!strcasecmp(v->name, "rtupdate")) { 16568 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16569 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16570 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16571 } else if (!strcasecmp(v->name, "t1min")) { 16572 global_t1min = atoi(v->value); 16573 } else if (!strcasecmp(v->name, "rtautoclear")) { 16574 int i = atoi(v->value); 16575 if (i > 0) 16576 global_rtautoclear = i; 16577 else 16578 i = 0; 16579 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16580 } else if (!strcasecmp(v->name, "usereqphone")) { 16581 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16582 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16583 global_relaxdtmf = ast_true(v->value); 16584 } else if (!strcasecmp(v->name, "checkmwi")) { 16585 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16586 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16587 global_mwitime = DEFAULT_MWITIME; 16588 } 16589 } else if (!strcasecmp(v->name, "vmexten")) { 16590 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16591 } else if (!strcasecmp(v->name, "rtptimeout")) { 16592 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16593 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16594 global_rtptimeout = 0; 16595 } 16596 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16597 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16598 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16599 global_rtpholdtimeout = 0; 16600 } 16601 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16602 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16603 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16604 global_rtpkeepalive = 0; 16605 } 16606 } else if (!strcasecmp(v->name, "compactheaders")) { 16607 compactheaders = ast_true(v->value); 16608 } else if (!strcasecmp(v->name, "notifymimetype")) { 16609 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 16610 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 16611 global_limitonpeers = ast_true(v->value); 16612 } else if (!strcasecmp(v->name, "directrtpsetup")) { 16613 global_directrtpsetup = ast_true(v->value); 16614 } else if (!strcasecmp(v->name, "notifyringing")) { 16615 global_notifyringing = ast_true(v->value); 16616 } else if (!strcasecmp(v->name, "notifyhold")) { 16617 global_notifyhold = ast_true(v->value); 16618 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 16619 global_alwaysauthreject = ast_true(v->value); 16620 } else if (!strcasecmp(v->name, "mohinterpret") 16621 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16622 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 16623 } else if (!strcasecmp(v->name, "mohsuggest")) { 16624 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 16625 } else if (!strcasecmp(v->name, "language")) { 16626 ast_copy_string(default_language, v->value, sizeof(default_language)); 16627 } else if (!strcasecmp(v->name, "regcontext")) { 16628 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 16629 stringp = newcontexts; 16630 /* Let's remove any contexts that are no longer defined in regcontext */ 16631 cleanup_stale_contexts(stringp, oldregcontext); 16632 /* Create contexts if they don't exist already */ 16633 while ((context = strsep(&stringp, "&"))) { 16634 if (!ast_context_find(context)) 16635 ast_context_create(NULL, context,"SIP"); 16636 } 16637 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 16638 } else if (!strcasecmp(v->name, "callerid")) { 16639 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 16640 } else if (!strcasecmp(v->name, "fromdomain")) { 16641 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 16642 } else if (!strcasecmp(v->name, "outboundproxy")) { 16643 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 16644 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 16645 } else if (!strcasecmp(v->name, "outboundproxyport")) { 16646 /* Port needs to be after IP */ 16647 sscanf(v->value, "%d", &format); 16648 outboundproxyip.sin_port = htons(format); 16649 } else if (!strcasecmp(v->name, "autocreatepeer")) { 16650 autocreatepeer = ast_true(v->value); 16651 } else if (!strcasecmp(v->name, "srvlookup")) { 16652 srvlookup = ast_true(v->value); 16653 } else if (!strcasecmp(v->name, "pedantic")) { 16654 pedanticsipchecking = ast_true(v->value); 16655 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 16656 max_expiry = atoi(v->value); 16657 if (max_expiry < 1) 16658 max_expiry = DEFAULT_MAX_EXPIRY; 16659 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 16660 min_expiry = atoi(v->value); 16661 if (min_expiry < 1) 16662 min_expiry = DEFAULT_MIN_EXPIRY; 16663 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 16664 default_expiry = atoi(v->value); 16665 if (default_expiry < 1) 16666 default_expiry = DEFAULT_DEFAULT_EXPIRY; 16667 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 16668 if (ast_true(v->value)) 16669 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16670 } else if (!strcasecmp(v->name, "dumphistory")) { 16671 dumphistory = ast_true(v->value); 16672 } else if (!strcasecmp(v->name, "recordhistory")) { 16673 recordhistory = ast_true(v->value); 16674 } else if (!strcasecmp(v->name, "registertimeout")) { 16675 global_reg_timeout = atoi(v->value); 16676 if (global_reg_timeout < 1) 16677 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16678 } else if (!strcasecmp(v->name, "registerattempts")) { 16679 global_regattempts_max = atoi(v->value); 16680 } else if (!strcasecmp(v->name, "bindaddr")) { 16681 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 16682 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 16683 } else { 16684 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 16685 } 16686 } else if (!strcasecmp(v->name, "localnet")) { 16687 struct ast_ha *na; 16688 if (!(na = ast_append_ha("d", v->value, localaddr))) 16689 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 16690 else 16691 localaddr = na; 16692 } else if (!strcasecmp(v->name, "localmask")) { 16693 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 16694 } else if (!strcasecmp(v->name, "externip")) { 16695 if (!(hp = ast_gethostbyname(v->value, &ahp))) 16696 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 16697 else 16698 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16699 externexpire = 0; 16700 } else if (!strcasecmp(v->name, "externhost")) { 16701 ast_copy_string(externhost, v->value, sizeof(externhost)); 16702 if (!(hp = ast_gethostbyname(externhost, &ahp))) 16703 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 16704 else 16705 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16706 externexpire = time(NULL); 16707 } else if (!strcasecmp(v->name, "externrefresh")) { 16708 if (sscanf(v->value, "%d", &externrefresh) != 1) { 16709 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 16710 externrefresh = 10; 16711 } 16712 } else if (!strcasecmp(v->name, "allow")) { 16713 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 16714 } else if (!strcasecmp(v->name, "disallow")) { 16715 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 16716 } else if (!strcasecmp(v->name, "autoframing")) { 16717 global_autoframing = ast_true(v->value); 16718 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 16719 allow_external_domains = ast_true(v->value); 16720 } else if (!strcasecmp(v->name, "autodomain")) { 16721 auto_sip_domains = ast_true(v->value); 16722 } else if (!strcasecmp(v->name, "domain")) { 16723 char *domain = ast_strdupa(v->value); 16724 char *context = strchr(domain, ','); 16725 16726 if (context) 16727 *context++ = '\0'; 16728 16729 if (option_debug && ast_strlen_zero(context)) 16730 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 16731 if (ast_strlen_zero(domain)) 16732 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 16733 else 16734 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 16735 } else if (!strcasecmp(v->name, "register")) { 16736 if (sip_register(v->value, v->lineno) == 0) 16737 registry_count++; 16738 } else if (!strcasecmp(v->name, "tos")) { 16739 if (!ast_str2tos(v->value, &temp_tos)) { 16740 global_tos_sip = temp_tos; 16741 global_tos_audio = temp_tos; 16742 global_tos_video = temp_tos; 16743 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 16744 } else 16745 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 16746 } else if (!strcasecmp(v->name, "tos_sip")) { 16747 if (ast_str2tos(v->value, &global_tos_sip)) 16748 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 16749 } else if (!strcasecmp(v->name, "tos_audio")) { 16750 if (ast_str2tos(v->value, &global_tos_audio)) 16751 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 16752 } else if (!strcasecmp(v->name, "tos_video")) { 16753 if (ast_str2tos(v->value, &global_tos_video)) 16754 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 16755 } else if (!strcasecmp(v->name, "bindport")) { 16756 if (sscanf(v->value, "%d", &ourport) == 1) { 16757 bindaddr.sin_port = htons(ourport); 16758 } else { 16759 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 16760 } 16761 } else if (!strcasecmp(v->name, "qualify")) { 16762 if (!strcasecmp(v->value, "no")) { 16763 default_qualify = 0; 16764 } else if (!strcasecmp(v->value, "yes")) { 16765 default_qualify = DEFAULT_MAXMS; 16766 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 16767 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 16768 default_qualify = 0; 16769 } 16770 } else if (!strcasecmp(v->name, "callevents")) { 16771 global_callevents = ast_true(v->value); 16772 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16773 default_maxcallbitrate = atoi(v->value); 16774 if (default_maxcallbitrate < 0) 16775 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16776 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 16777 global_matchexterniplocally = ast_true(v->value); 16778 } 16779 } 16780 16781 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 16782 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 16783 allow_external_domains = 1; 16784 } 16785 16786 /* Build list of authentication to various SIP realms, i.e. service providers */ 16787 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 16788 /* Format for authentication is auth = username:password@realm */ 16789 if (!strcasecmp(v->name, "auth")) 16790 authl = add_realm_authentication(authl, v->value, v->lineno); 16791 } 16792 16793 ucfg = ast_config_load("users.conf"); 16794 if (ucfg) { 16795 struct ast_variable *gen; 16796 int genhassip, genregistersip; 16797 const char *hassip, *registersip; 16798 16799 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 16800 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 16801 gen = ast_variable_browse(ucfg, "general"); 16802 cat = ast_category_browse(ucfg, NULL); 16803 while (cat) { 16804 if (strcasecmp(cat, "general")) { 16805 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 16806 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 16807 if (ast_true(hassip) || (!hassip && genhassip)) { 16808 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 16809 if (peer) { 16810 ast_device_state_changed("SIP/%s", peer->name); 16811 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16812 ASTOBJ_UNREF(peer, sip_destroy_peer); 16813 peer_count++; 16814 } 16815 } 16816 if (ast_true(registersip) || (!registersip && genregistersip)) { 16817 char tmp[256]; 16818 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 16819 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 16820 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 16821 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 16822 if (!host) 16823 host = ast_variable_retrieve(ucfg, "general", "host"); 16824 if (!username) 16825 username = ast_variable_retrieve(ucfg, "general", "username"); 16826 if (!secret) 16827 secret = ast_variable_retrieve(ucfg, "general", "secret"); 16828 if (!contact) 16829 contact = "s"; 16830 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 16831 if (!ast_strlen_zero(secret)) 16832 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 16833 else 16834 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 16835 if (sip_register(tmp, 0) == 0) 16836 registry_count++; 16837 } 16838 } 16839 } 16840 cat = ast_category_browse(ucfg, cat); 16841 } 16842 ast_config_destroy(ucfg); 16843 } 16844 16845 16846 /* Load peers, users and friends */ 16847 cat = NULL; 16848 while ( (cat = ast_category_browse(cfg, cat)) ) { 16849 const char *utype; 16850 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 16851 continue; 16852 utype = ast_variable_retrieve(cfg, cat, "type"); 16853 if (!utype) { 16854 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 16855 continue; 16856 } else { 16857 int is_user = 0, is_peer = 0; 16858 if (!strcasecmp(utype, "user")) 16859 is_user = 1; 16860 else if (!strcasecmp(utype, "friend")) 16861 is_user = is_peer = 1; 16862 else if (!strcasecmp(utype, "peer")) 16863 is_peer = 1; 16864 else { 16865 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 16866 continue; 16867 } 16868 if (is_user) { 16869 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 16870 if (user) { 16871 ASTOBJ_CONTAINER_LINK(&userl,user); 16872 ASTOBJ_UNREF(user, sip_destroy_user); 16873 user_count++; 16874 } 16875 } 16876 if (is_peer) { 16877 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 16878 if (peer) { 16879 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16880 ASTOBJ_UNREF(peer, sip_destroy_peer); 16881 peer_count++; 16882 } 16883 } 16884 } 16885 } 16886 if (ast_find_ourip(&__ourip, bindaddr)) { 16887 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 16888 return 0; 16889 } 16890 if (!ntohs(bindaddr.sin_port)) 16891 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 16892 bindaddr.sin_family = AF_INET; 16893 ast_mutex_lock(&netlock); 16894 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 16895 close(sipsock); 16896 sipsock = -1; 16897 } 16898 if (sipsock < 0) { 16899 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 16900 if (sipsock < 0) { 16901 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 16902 return -1; 16903 } else { 16904 /* Allow SIP clients on the same host to access us: */ 16905 const int reuseFlag = 1; 16906 16907 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 16908 (const char*)&reuseFlag, 16909 sizeof reuseFlag); 16910 16911 ast_enable_packet_fragmentation(sipsock); 16912 16913 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 16914 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 16915 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 16916 strerror(errno)); 16917 close(sipsock); 16918 sipsock = -1; 16919 } else { 16920 if (option_verbose > 1) { 16921 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 16922 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 16923 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 16924 } 16925 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 16926 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 16927 } 16928 } 16929 } 16930 ast_mutex_unlock(&netlock); 16931 16932 /* Add default domains - host name, IP address and IP:port */ 16933 /* Only do this if user added any sip domain with "localdomains" */ 16934 /* In order to *not* break backwards compatibility */ 16935 /* Some phones address us at IP only, some with additional port number */ 16936 if (auto_sip_domains) { 16937 char temp[MAXHOSTNAMELEN]; 16938 16939 /* First our default IP address */ 16940 if (bindaddr.sin_addr.s_addr) 16941 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 16942 else 16943 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 16944 16945 /* Our extern IP address, if configured */ 16946 if (externip.sin_addr.s_addr) 16947 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 16948 16949 /* Extern host name (NAT traversal support) */ 16950 if (!ast_strlen_zero(externhost)) 16951 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 16952 16953 /* Our host name */ 16954 if (!gethostname(temp, sizeof(temp))) 16955 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 16956 } 16957 16958 /* Release configuration from memory */ 16959 ast_config_destroy(cfg); 16960 16961 /* Load the list of manual NOTIFY types to support */ 16962 if (notify_types) 16963 ast_config_destroy(notify_types); 16964 notify_types = ast_config_load(notify_config); 16965 16966 /* Done, tell the manager */ 16967 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); 16968 16969 return 0; 16970 }
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 11224 of file chan_sip.c.
References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), key(), keys, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11225 { 11226 char tmp[512]; 11227 char *c; 11228 char oldnonce[256]; 11229 11230 /* table of recognised keywords, and places where they should be copied */ 11231 const struct x { 11232 const char *key; 11233 int field_index; 11234 } *i, keys[] = { 11235 { "realm=", ast_string_field_index(p, realm) }, 11236 { "nonce=", ast_string_field_index(p, nonce) }, 11237 { "opaque=", ast_string_field_index(p, opaque) }, 11238 { "qop=", ast_string_field_index(p, qop) }, 11239 { "domain=", ast_string_field_index(p, domain) }, 11240 { NULL, 0 }, 11241 }; 11242 11243 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11244 if (ast_strlen_zero(tmp)) 11245 return -1; 11246 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11247 ast_log(LOG_WARNING, "missing Digest.\n"); 11248 return -1; 11249 } 11250 c = tmp + strlen("Digest "); 11251 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11252 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11253 for (i = keys; i->key != NULL; i++) { 11254 char *src, *separator; 11255 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11256 continue; 11257 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11258 c += strlen(i->key); 11259 if (*c == '"') { 11260 src = ++c; 11261 separator = "\""; 11262 } else { 11263 src = c; 11264 separator = ","; 11265 } 11266 strsep(&c, separator); /* clear separator and move ptr */ 11267 ast_string_field_index_set(p, i->field_index, src); 11268 break; 11269 } 11270 if (i->key == NULL) /* not found, try ',' */ 11271 strsep(&c, ","); 11272 } 11273 /* Reset nonce count */ 11274 if (strcmp(p->nonce, oldnonce)) 11275 p->noncecount = 0; 11276 11277 /* Save auth data for following registrations */ 11278 if (p->registry) { 11279 struct sip_registry *r = p->registry; 11280 11281 if (strcmp(r->nonce, p->nonce)) { 11282 ast_string_field_set(r, realm, p->realm); 11283 ast_string_field_set(r, nonce, p->nonce); 11284 ast_string_field_set(r, domain, p->domain); 11285 ast_string_field_set(r, opaque, p->opaque); 11286 ast_string_field_set(r, qop, p->qop); 11287 r->noncecount = 0; 11288 } 11289 } 11290 return build_reply_digest(p, sipmethod, digest, digest_len); 11291 }
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 5739 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.
05740 { 05741 struct sip_request *orig = &p->initreq; 05742 char stripped[80]; 05743 char tmp[80]; 05744 char newto[256]; 05745 const char *c; 05746 const char *ot, *of; 05747 int is_strict = FALSE; /*!< Strict routing flag */ 05748 05749 memset(req, 0, sizeof(struct sip_request)); 05750 05751 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05752 05753 if (!seqno) { 05754 p->ocseq++; 05755 seqno = p->ocseq; 05756 } 05757 05758 if (newbranch) { 05759 p->branch ^= ast_random(); 05760 build_via(p); 05761 } 05762 05763 /* Check for strict or loose router */ 05764 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05765 is_strict = TRUE; 05766 if (sipdebug) 05767 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05768 } 05769 05770 if (sipmethod == SIP_CANCEL) 05771 c = p->initreq.rlPart2; /* Use original URI */ 05772 else if (sipmethod == SIP_ACK) { 05773 /* Use URI from Contact: in 200 OK (if INVITE) 05774 (we only have the contacturi on INVITEs) */ 05775 if (!ast_strlen_zero(p->okcontacturi)) 05776 c = is_strict ? p->route->hop : p->okcontacturi; 05777 else 05778 c = p->initreq.rlPart2; 05779 } else if (!ast_strlen_zero(p->okcontacturi)) 05780 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05781 else if (!ast_strlen_zero(p->uri)) 05782 c = p->uri; 05783 else { 05784 char *n; 05785 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05786 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05787 sizeof(stripped)); 05788 n = get_in_brackets(stripped); 05789 c = strsep(&n, ";"); /* trim ; and beyond */ 05790 } 05791 init_req(req, sipmethod, c); 05792 05793 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05794 05795 add_header(req, "Via", p->via); 05796 if (p->route) { 05797 set_destination(p, p->route->hop); 05798 add_route(req, is_strict ? p->route->next : p->route); 05799 } 05800 05801 ot = get_header(orig, "To"); 05802 of = get_header(orig, "From"); 05803 05804 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05805 as our original request, including tag (or presumably lack thereof) */ 05806 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05807 /* Add the proper tag if we don't have it already. If they have specified 05808 their tag, use it. Otherwise, use our own tag */ 05809 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05810 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05811 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05812 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05813 else 05814 snprintf(newto, sizeof(newto), "%s", ot); 05815 ot = newto; 05816 } 05817 05818 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05819 add_header(req, "From", of); 05820 add_header(req, "To", ot); 05821 } else { 05822 add_header(req, "From", ot); 05823 add_header(req, "To", of); 05824 } 05825 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05826 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05827 add_header(req, "Contact", p->our_contact); 05828 05829 copy_header(req, orig, "Call-ID"); 05830 add_header(req, "CSeq", tmp); 05831 05832 if (!ast_strlen_zero(global_useragent)) 05833 add_header(req, "User-Agent", global_useragent); 05834 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05835 05836 if (!ast_strlen_zero(p->rpid)) 05837 add_header(req, "Remote-Party-ID", p->rpid); 05838 05839 return 0; 05840 }
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 5691 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.
05692 { 05693 char newto[256]; 05694 const char *ot; 05695 05696 init_resp(resp, msg); 05697 copy_via_headers(p, resp, req, "Via"); 05698 if (msg[0] == '2') 05699 copy_all_header(resp, req, "Record-Route"); 05700 copy_header(resp, req, "From"); 05701 ot = get_header(req, "To"); 05702 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05703 /* Add the proper tag if we don't have it already. If they have specified 05704 their tag, use it. Otherwise, use our own tag */ 05705 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05706 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05707 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05708 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05709 else 05710 ast_copy_string(newto, ot, sizeof(newto)); 05711 ot = newto; 05712 } 05713 add_header(resp, "To", ot); 05714 copy_header(resp, req, "Call-ID"); 05715 copy_header(resp, req, "CSeq"); 05716 if (!ast_strlen_zero(global_useragent)) 05717 add_header(resp, "User-Agent", global_useragent); 05718 add_header(resp, "Allow", ALLOWED_METHODS); 05719 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05720 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05721 /* For registration responses, we also need expiry and 05722 contact info */ 05723 char tmp[256]; 05724 05725 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05726 add_header(resp, "Expires", tmp); 05727 if (p->expiry) { /* Only add contact if we have an expiry time */ 05728 char contact[BUFSIZ]; 05729 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05730 add_header(resp, "Contact", contact); /* Not when we unregister */ 05731 } 05732 } else if (msg[0] != '4' && p->our_contact[0]) { 05733 add_header(resp, "Contact", p->our_contact); 05734 } 05735 return 0; 05736 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15385 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
15386 { 15387 /* If we're supposed to be stopped -- stay stopped */ 15388 if (monitor_thread == AST_PTHREADT_STOP) 15389 return 0; 15390 ast_mutex_lock(&monlock); 15391 if (monitor_thread == pthread_self()) { 15392 ast_mutex_unlock(&monlock); 15393 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15394 return -1; 15395 } 15396 if (monitor_thread != AST_PTHREADT_NULL) { 15397 /* Wake up the thread */ 15398 pthread_kill(monitor_thread, SIGURG); 15399 } else { 15400 /* Start a new monitor */ 15401 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15402 ast_mutex_unlock(&monlock); 15403 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15404 return -1; 15405 } 15406 } 15407 ast_mutex_unlock(&monlock); 15408 return 0; 15409 }
static int retrans_pkt | ( | void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1867 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.
01868 { 01869 struct sip_pkt *pkt = data, *prev, *cur = NULL; 01870 int reschedule = DEFAULT_RETRANS; 01871 int xmitres = 0; 01872 01873 /* Lock channel PVT */ 01874 ast_mutex_lock(&pkt->owner->lock); 01875 01876 if (pkt->retrans < MAX_RETRANS) { 01877 pkt->retrans++; 01878 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01879 if (sipdebug && option_debug > 3) 01880 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); 01881 } else { 01882 int siptimer_a; 01883 01884 if (sipdebug && option_debug > 3) 01885 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01886 if (!pkt->timer_a) 01887 pkt->timer_a = 2 ; 01888 else 01889 pkt->timer_a = 2 * pkt->timer_a; 01890 01891 /* For non-invites, a maximum of 4 secs */ 01892 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01893 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01894 siptimer_a = 4000; 01895 01896 /* Reschedule re-transmit */ 01897 reschedule = siptimer_a; 01898 if (option_debug > 3) 01899 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); 01900 } 01901 01902 if (sip_debug_test_pvt(pkt->owner)) { 01903 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01904 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01905 pkt->retrans, sip_nat_mode(pkt->owner), 01906 ast_inet_ntoa(dst->sin_addr), 01907 ntohs(dst->sin_port), pkt->data); 01908 } 01909 01910 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01911 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01912 ast_mutex_unlock(&pkt->owner->lock); 01913 if (xmitres == XMIT_ERROR) 01914 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01915 else 01916 return reschedule; 01917 } 01918 /* Too many retries */ 01919 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01920 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01921 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"); 01922 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01923 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01924 } 01925 if (xmitres == XMIT_ERROR) { 01926 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01927 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01928 } else 01929 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01930 01931 pkt->retransid = -1; 01932 01933 if (ast_test_flag(pkt, FLAG_FATAL)) { 01934 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01935 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01936 usleep(1); 01937 ast_mutex_lock(&pkt->owner->lock); 01938 } 01939 01940 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01941 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01942 01943 if (pkt->owner->owner) { 01944 sip_alreadygone(pkt->owner); 01945 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01946 ast_queue_hangup(pkt->owner->owner); 01947 ast_channel_unlock(pkt->owner->owner); 01948 } else { 01949 /* If no channel owner, destroy now */ 01950 01951 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01952 if (pkt->method != SIP_OPTIONS) { 01953 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01954 sip_alreadygone(pkt->owner); 01955 if (option_debug) 01956 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 01957 } 01958 } 01959 } 01960 01961 if (pkt->method == SIP_BYE) { 01962 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 01963 if (pkt->owner->owner) 01964 ast_channel_unlock(pkt->owner->owner); 01965 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 01966 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01967 } 01968 01969 /* In any case, go ahead and remove the packet */ 01970 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01971 if (cur == pkt) 01972 break; 01973 } 01974 if (cur) { 01975 if (prev) 01976 prev->next = cur->next; 01977 else 01978 pkt->owner->packets = cur->next; 01979 ast_mutex_unlock(&pkt->owner->lock); 01980 free(cur); 01981 pkt = NULL; 01982 } else 01983 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01984 if (pkt) 01985 ast_mutex_unlock(&pkt->owner->lock); 01986 return 0; 01987 }
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 2234 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.
02235 { 02236 int res; 02237 02238 add_blank(req); 02239 if (sip_debug_test_pvt(p)) { 02240 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02241 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); 02242 else 02243 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); 02244 } 02245 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02246 struct sip_request tmp; 02247 parse_copy(&tmp, req); 02248 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02249 } 02250 res = (reliable) ? 02251 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02252 __sip_xmit(p, req->data, req->len); 02253 return res; 02254 }
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 2206 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_request::rlPart2, sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02207 { 02208 int res; 02209 02210 add_blank(req); 02211 if (sip_debug_test_pvt(p)) { 02212 const struct sockaddr_in *dst = sip_real_dst(p); 02213 02214 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02215 reliable ? "Reliably " : "", sip_nat_mode(p), 02216 ast_inet_ntoa(dst->sin_addr), 02217 ntohs(dst->sin_port), req->data); 02218 } 02219 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02220 struct sip_request tmp; 02221 parse_copy(&tmp, req); 02222 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02223 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02224 } 02225 res = (reliable) ? 02226 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02227 __sip_xmit(p, req->data, req->len); 02228 if (res > 0) 02229 return 0; 02230 return res; 02231 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7814 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strdupa, ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
07815 { 07816 struct hostent *hp; 07817 struct ast_hostent ahp; 07818 int port; 07819 char *c, *host, *pt; 07820 char *contact; 07821 07822 07823 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07824 /* NAT: Don't trust the contact field. Just use what they came to us 07825 with. */ 07826 pvt->sa = pvt->recv; 07827 return 0; 07828 } 07829 07830 07831 /* Work on a copy */ 07832 contact = ast_strdupa(pvt->fullcontact); 07833 07834 /* Make sure it's a SIP URL */ 07835 if (strncasecmp(contact, "sip:", 4)) { 07836 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07837 } else 07838 contact += 4; 07839 07840 /* Ditch arguments */ 07841 /* XXX this code is replicated also shortly below */ 07842 07843 /* Grab host */ 07844 host = strchr(contact, '@'); 07845 if (!host) { /* No username part */ 07846 host = contact; 07847 c = NULL; 07848 } else { 07849 *host++ = '\0'; 07850 } 07851 pt = strchr(host, ':'); 07852 if (pt) { 07853 *pt++ = '\0'; 07854 port = atoi(pt); 07855 } else 07856 port = STANDARD_SIP_PORT; 07857 07858 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 07859 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 07860 07861 /* XXX This could block for a long time XXX */ 07862 /* We should only do this if it's a name, not an IP */ 07863 hp = ast_gethostbyname(host, &ahp); 07864 if (!hp) { 07865 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07866 return -1; 07867 } 07868 pvt->sa.sin_family = AF_INET; 07869 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 07870 pvt->sa.sin_port = htons(port); 07871 07872 return 0; 07873 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5600 of file chan_sip.c.
References ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05601 { 05602 char *h, *maddr, hostname[256]; 05603 int port, hn; 05604 struct hostent *hp; 05605 struct ast_hostent ahp; 05606 int debug=sip_debug_test_pvt(p); 05607 05608 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05609 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05610 05611 if (debug) 05612 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05613 05614 /* Find and parse hostname */ 05615 h = strchr(uri, '@'); 05616 if (h) 05617 ++h; 05618 else { 05619 h = uri; 05620 if (strncasecmp(h, "sip:", 4) == 0) 05621 h += 4; 05622 else if (strncasecmp(h, "sips:", 5) == 0) 05623 h += 5; 05624 } 05625 hn = strcspn(h, ":;>") + 1; 05626 if (hn > sizeof(hostname)) 05627 hn = sizeof(hostname); 05628 ast_copy_string(hostname, h, hn); 05629 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05630 h += hn - 1; 05631 05632 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05633 if (*h == ':') { 05634 /* Parse port */ 05635 ++h; 05636 port = strtol(h, &h, 10); 05637 } 05638 else 05639 port = STANDARD_SIP_PORT; 05640 05641 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05642 maddr = strstr(h, "maddr="); 05643 if (maddr) { 05644 maddr += 6; 05645 hn = strspn(maddr, "0123456789.") + 1; 05646 if (hn > sizeof(hostname)) 05647 hn = sizeof(hostname); 05648 ast_copy_string(hostname, maddr, hn); 05649 } 05650 05651 hp = ast_gethostbyname(hostname, &ahp); 05652 if (hp == NULL) { 05653 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05654 return; 05655 } 05656 p->sa.sin_family = AF_INET; 05657 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05658 p->sa.sin_port = htons(port); 05659 if (debug) 05660 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05661 }
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 15684 of file chan_sip.c.
References ast_false(), ast_log(), ast_set_flag, ast_true(), LOG_WARNING, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().
Referenced by handle_common_options(), and realtime_peer().
15685 { 15686 if (!strcasecmp(value, "very")) 15687 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15688 else if (ast_true(value)) 15689 ast_set_flag(flags, SIP_INSECURE_PORT); 15690 else if (!ast_false(value)) { 15691 char buf[64]; 15692 char *word, *next; 15693 ast_copy_string(buf, value, sizeof(buf)); 15694 next = buf; 15695 while ((word = strsep(&next, ","))) { 15696 if (!strcasecmp(word, "port")) 15697 ast_set_flag(flags, SIP_INSECURE_PORT); 15698 else if (!strcasecmp(word, "invite")) 15699 ast_set_flag(flags, SIP_INSECURE_INVITE); 15700 else 15701 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 15702 } 15703 } 15704 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 16102 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
16103 { 16104 if (peer->expire == 0) { 16105 /* Don't reset expire or port time during reload 16106 if we have an active registration 16107 */ 16108 peer->expire = -1; 16109 peer->pokeexpire = -1; 16110 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16111 } 16112 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 16113 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16114 strcpy(peer->context, default_context); 16115 strcpy(peer->subscribecontext, default_subscribecontext); 16116 strcpy(peer->language, default_language); 16117 strcpy(peer->mohinterpret, default_mohinterpret); 16118 strcpy(peer->mohsuggest, default_mohsuggest); 16119 peer->addr.sin_family = AF_INET; 16120 peer->defaddr.sin_family = AF_INET; 16121 peer->capability = global_capability; 16122 peer->maxcallbitrate = default_maxcallbitrate; 16123 peer->rtptimeout = global_rtptimeout; 16124 peer->rtpholdtimeout = global_rtpholdtimeout; 16125 peer->rtpkeepalive = global_rtpkeepalive; 16126 peer->allowtransfer = global_allowtransfer; 16127 peer->autoframing = global_autoframing; 16128 strcpy(peer->vmexten, default_vmexten); 16129 peer->secret[0] = '\0'; 16130 peer->md5secret[0] = '\0'; 16131 peer->cid_num[0] = '\0'; 16132 peer->cid_name[0] = '\0'; 16133 peer->fromdomain[0] = '\0'; 16134 peer->fromuser[0] = '\0'; 16135 peer->regexten[0] = '\0'; 16136 peer->mailbox[0] = '\0'; 16137 peer->callgroup = 0; 16138 peer->pickupgroup = 0; 16139 peer->maxms = default_qualify; 16140 peer->prefs = default_prefs; 16141 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17309 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
17310 { 17311 int no = 0; 17312 int ok = FALSE; 17313 char varbuf[30]; 17314 char *inbuf = (char *) data; 17315 17316 if (ast_strlen_zero(inbuf)) { 17317 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17318 return 0; 17319 } 17320 ast_channel_lock(chan); 17321 17322 /* Check for headers */ 17323 while (!ok && no <= 50) { 17324 no++; 17325 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17326 17327 /* Compare without the leading underscore */ 17328 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17329 ok = TRUE; 17330 } 17331 if (ok) { 17332 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17333 if (sipdebug) 17334 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17335 } else { 17336 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17337 } 17338 ast_channel_unlock(chan); 17339 return 0; 17340 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2570 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02571 { 02572 /* We know name is the first field, so we can cast */ 02573 struct sip_peer *p = (struct sip_peer *) name; 02574 return !(!inaddrcmp(&p->addr, sin) || 02575 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02576 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02577 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static, read] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4309 of file chan_sip.c.
References __ourip, sip_pvt::allowtransfer, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), sip_pvt::autokillid, bindaddr, sip_pvt::branch, build_callid_pvt(), build_via(), t38properties::capability, sip_pvt::capability, sip_pvt::chanvars, domain::context, default_prefs, do_setnat(), sip_pvt::flags, free, global_t38_capability, iflist, INITIAL_CSEQ, sip_pvt::initid, t38properties::jointcapability, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, make_our_tag(), sip_pvt::maxcallbitrate, sip_pvt::method, mohinterpret, mohsuggest, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ocseq, option_debug, sip_pvt::ourip, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_pvt::sa, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::tag, text, sip_pvt::timer_t1, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and sip_pvt::vrtp.
Referenced by find_call(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04311 { 04312 struct sip_pvt *p; 04313 04314 if (!(p = ast_calloc(1, sizeof(*p)))) 04315 return NULL; 04316 04317 if (ast_string_field_init(p, 512)) { 04318 free(p); 04319 return NULL; 04320 } 04321 04322 ast_mutex_init(&p->lock); 04323 04324 p->method = intended_method; 04325 p->initid = -1; 04326 p->autokillid = -1; 04327 p->subscribed = NONE; 04328 p->stateid = -1; 04329 p->prefs = default_prefs; /* Set default codecs for this call */ 04330 04331 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04332 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04333 04334 if (sin) { 04335 p->sa = *sin; 04336 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04337 p->ourip = __ourip; 04338 } else 04339 p->ourip = __ourip; 04340 04341 /* Copy global flags to this PVT at setup. */ 04342 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04343 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04344 04345 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04346 04347 p->branch = ast_random(); 04348 make_our_tag(p->tag, sizeof(p->tag)); 04349 p->ocseq = INITIAL_CSEQ; 04350 04351 if (sip_methods[intended_method].need_rtp) { 04352 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04353 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04354 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04355 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04356 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04357 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04358 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04359 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04360 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04361 ast_mutex_destroy(&p->lock); 04362 if (p->chanvars) { 04363 ast_variables_destroy(p->chanvars); 04364 p->chanvars = NULL; 04365 } 04366 free(p); 04367 return NULL; 04368 } 04369 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04370 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04371 ast_rtp_settos(p->rtp, global_tos_audio); 04372 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04373 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04374 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04375 if (p->vrtp) { 04376 ast_rtp_settos(p->vrtp, global_tos_video); 04377 ast_rtp_setdtmf(p->vrtp, 0); 04378 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04379 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04380 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04381 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04382 } 04383 if (p->udptl) 04384 ast_udptl_settos(p->udptl, global_tos_audio); 04385 p->maxcallbitrate = default_maxcallbitrate; 04386 } 04387 04388 if (useglobal_nat && sin) { 04389 /* Setup NAT structure according to global settings if we have an address */ 04390 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04391 p->recv = *sin; 04392 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04393 } 04394 04395 if (p->method != SIP_REGISTER) 04396 ast_string_field_set(p, fromdomain, default_fromdomain); 04397 build_via(p); 04398 if (!callid) 04399 build_callid_pvt(p); 04400 else 04401 ast_string_field_set(p, callid, callid); 04402 /* Assign default music on hold class */ 04403 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04404 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04405 p->capability = global_capability; 04406 p->allowtransfer = global_allowtransfer; 04407 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04408 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04409 p->noncodeccapability |= AST_RTP_DTMF; 04410 if (p->udptl) { 04411 p->t38.capability = global_t38_capability; 04412 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04413 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04414 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04415 p->t38.capability |= T38FAX_UDP_EC_FEC; 04416 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04417 p->t38.capability |= T38FAX_UDP_EC_NONE; 04418 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04419 p->t38.jointcapability = p->t38.capability; 04420 } 04421 ast_string_field_set(p, context, default_context); 04422 04423 /* Add to active dialog list */ 04424 ast_mutex_lock(&iflock); 04425 p->next = iflist; 04426 iflist = p; 04427 ast_mutex_unlock(&iflock); 04428 if (option_debug) 04429 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"); 04430 return p; 04431 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1639 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().
01640 { 01641 if (option_debug > 2) 01642 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01643 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01644 }
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 3568 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::initreq, sip_pvt::lock, LOG_DEBUG, option_debug, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03569 { 03570 int res = 0; 03571 struct sip_pvt *p = ast->tech_pvt; 03572 03573 ast_mutex_lock(&p->lock); 03574 if (ast->_state != AST_STATE_UP) { 03575 try_suggested_sip_codec(p); 03576 03577 ast_setstate(ast, AST_STATE_UP); 03578 if (option_debug) 03579 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03580 if (p->t38.state == T38_PEER_DIRECT) { 03581 p->t38.state = T38_ENABLED; 03582 if (option_debug > 1) 03583 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03584 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03585 } else 03586 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03587 } 03588 ast_mutex_unlock(&p->lock); 03589 return res; 03590 }
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 2874 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_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
02875 { 02876 int res, xmitres = 0; 02877 struct sip_pvt *p; 02878 struct varshead *headp; 02879 struct ast_var_t *current; 02880 const char *referer = NULL; /* SIP refererer */ 02881 02882 p = ast->tech_pvt; 02883 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02884 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02885 return -1; 02886 } 02887 02888 /* Check whether there is vxml_url, distinctive ring variables */ 02889 headp=&ast->varshead; 02890 AST_LIST_TRAVERSE(headp,current,entries) { 02891 /* Check whether there is a VXML_URL variable */ 02892 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02893 p->options->vxml_url = ast_var_value(current); 02894 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02895 p->options->uri_options = ast_var_value(current); 02896 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02897 /* Check whether there is a ALERT_INFO variable */ 02898 p->options->distinctive_ring = ast_var_value(current); 02899 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02900 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02901 p->options->addsipheaders = 1; 02902 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02903 /* This is a transfered call */ 02904 p->options->transfer = 1; 02905 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02906 /* This is the referer */ 02907 referer = ast_var_value(current); 02908 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02909 /* We're replacing a call. */ 02910 p->options->replaces = ast_var_value(current); 02911 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02912 p->t38.state = T38_LOCAL_DIRECT; 02913 if (option_debug) 02914 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02915 } 02916 02917 } 02918 02919 res = 0; 02920 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02921 02922 if (p->options->transfer) { 02923 char buf[BUFSIZ/2]; 02924 02925 if (referer) { 02926 if (sipdebug && option_debug > 2) 02927 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02928 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02929 } else 02930 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02931 ast_string_field_set(p, cid_name, buf); 02932 } 02933 if (option_debug) 02934 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02935 02936 res = update_call_counter(p, INC_CALL_RINGING); 02937 if ( res != -1 ) { 02938 p->callingpres = ast->cid.cid_pres; 02939 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 02940 p->jointnoncodeccapability = p->noncodeccapability; 02941 02942 /* If there are no audio formats left to offer, punt */ 02943 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 02944 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 02945 res = -1; 02946 } else { 02947 p->t38.jointcapability = p->t38.capability; 02948 if (option_debug > 1) 02949 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 02950 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 02951 if (xmitres == XMIT_ERROR) 02952 return -1; /* Transmission error */ 02953 02954 p->invitestate = INV_CALLING; 02955 02956 /* Initialize auto-congest time */ 02957 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 02958 } 02959 } 02960 return res; 02961 }
static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2094 of file chan_sip.c.
References append_history, ast_sched_del(), and sip_pvt::autokillid.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02095 { 02096 if (p->autokillid > -1) { 02097 ast_sched_del(sched, p->autokillid); 02098 append_history(p, "CancelDestroy", ""); 02099 p->autokillid = -1; 02100 } 02101 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1721 of file chan_sip.c.
References debugaddr, and sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01722 { 01723 if (!sipdebug) 01724 return 0; 01725 if (debugaddr.sin_addr.s_addr) { 01726 if (((ntohs(debugaddr.sin_port) != 0) 01727 && (debugaddr.sin_port != addr->sin_port)) 01728 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01729 return 0; 01730 } 01731 return 1; 01732 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1747 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().
01748 { 01749 if (!sipdebug) 01750 return 0; 01751 return sip_debug_test_addr(sip_real_dst(p)); 01752 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3215 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().
03216 { 03217 ast_mutex_lock(&iflock); 03218 if (option_debug > 2) 03219 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03220 __sip_destroy(p, 1); 03221 ast_mutex_unlock(&iflock); 03222 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2406 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), do_monitor(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), reload_config(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_prune_realtime(), unload_module(), and update_call_counter().
02407 { 02408 if (option_debug > 2) 02409 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02410 02411 /* Delete it, it needs to disappear */ 02412 if (peer->call) 02413 sip_destroy(peer->call); 02414 02415 if (peer->mwipvt) /* We have an active subscription, delete it */ 02416 sip_destroy(peer->mwipvt); 02417 02418 if (peer->chanvars) { 02419 ast_variables_destroy(peer->chanvars); 02420 peer->chanvars = NULL; 02421 } 02422 if (peer->expire > -1) 02423 ast_sched_del(sched, peer->expire); 02424 02425 if (peer->pokeexpire > -1) 02426 ast_sched_del(sched, peer->pokeexpire); 02427 register_peer_exten(peer, FALSE); 02428 ast_free_ha(peer->ha); 02429 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02430 apeerobjs--; 02431 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02432 rpeerobjs--; 02433 else 02434 speerobjs--; 02435 clear_realm_authentication(peer->auth); 02436 peer->auth = NULL; 02437 free(peer); 02438 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2598 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), reload_config(), sip_do_reload(), sip_prune_realtime(), sip_show_user(), unload_module(), and update_call_counter().
02599 { 02600 if (option_debug > 2) 02601 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02602 ast_free_ha(user->ha); 02603 if (user->chanvars) { 02604 ast_variables_destroy(user->chanvars); 02605 user->chanvars = NULL; 02606 } 02607 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02608 ruserobjs--; 02609 else 02610 suserobjs--; 02611 free(user); 02612 }
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 15529 of file chan_sip.c.
References sip_peer::addr, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
15530 { 15531 char *host; 15532 char *tmp; 15533 15534 struct hostent *hp; 15535 struct ast_hostent ahp; 15536 struct sip_peer *p; 15537 15538 int res = AST_DEVICE_INVALID; 15539 15540 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15541 host = ast_strdupa(data ? data : ""); 15542 if ((tmp = strchr(host, '@'))) 15543 host = tmp + 1; 15544 15545 if (option_debug > 2) 15546 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15547 15548 if ((p = find_peer(host, NULL, 1))) { 15549 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15550 /* we have an address for the peer */ 15551 15552 /* Check status in this order 15553 - Hold 15554 - Ringing 15555 - Busy (enforced only by call limit) 15556 - Inuse (we have a call) 15557 - Unreachable (qualify) 15558 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15559 for registered devices */ 15560 15561 if (p->onHold) 15562 /* First check for hold or ring states */ 15563 res = AST_DEVICE_ONHOLD; 15564 else if (p->inRinging) { 15565 if (p->inRinging == p->inUse) 15566 res = AST_DEVICE_RINGING; 15567 else 15568 res = AST_DEVICE_RINGINUSE; 15569 } else if (p->call_limit && (p->inUse == p->call_limit)) 15570 /* check call limit */ 15571 res = AST_DEVICE_BUSY; 15572 else if (p->call_limit && p->inUse) 15573 /* Not busy, but we do have a call */ 15574 res = AST_DEVICE_INUSE; 15575 else if (p->maxms && (p->lastms > p->maxms)) 15576 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15577 res = AST_DEVICE_UNAVAILABLE; 15578 else /* Default reply if we're registered and have no other data */ 15579 res = AST_DEVICE_NOT_INUSE; 15580 } else { 15581 /* there is no address, it's unavailable */ 15582 res = AST_DEVICE_UNAVAILABLE; 15583 } 15584 ASTOBJ_UNREF(p,sip_destroy_peer); 15585 } else { 15586 hp = ast_gethostbyname(host, &ahp); 15587 if (hp) 15588 res = AST_DEVICE_UNKNOWN; 15589 } 15590 15591 return res; 15592 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11037 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11038 { 11039 int oldsipdebug = sipdebug_console; 11040 if (argc != 3) { 11041 if (argc != 5) 11042 return RESULT_SHOWUSAGE; 11043 else if (strcmp(argv[3], "ip") == 0) 11044 return sip_do_debug_ip(fd, argc, argv); 11045 else if (strcmp(argv[3], "peer") == 0) 11046 return sip_do_debug_peer(fd, argc, argv); 11047 else 11048 return RESULT_SHOWUSAGE; 11049 } 11050 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11051 memset(&debugaddr, 0, sizeof(debugaddr)); 11052 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11053 return RESULT_SUCCESS; 11054 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11056 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
11057 { 11058 int oldsipdebug = sipdebug_console; 11059 char *newargv[6] = { "sip", "set", "debug", NULL }; 11060 if (argc != 2) { 11061 if (argc != 4) 11062 return RESULT_SHOWUSAGE; 11063 else if (strcmp(argv[2], "ip") == 0) { 11064 newargv[3] = argv[2]; 11065 newargv[4] = argv[3]; 11066 return sip_do_debug_ip(fd, argc + 1, newargv); 11067 } else if (strcmp(argv[2], "peer") == 0) { 11068 newargv[3] = argv[2]; 11069 newargv[4] = argv[3]; 11070 return sip_do_debug_peer(fd, argc + 1, newargv); 11071 } else 11072 return RESULT_SHOWUSAGE; 11073 } 11074 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11075 memset(&debugaddr, 0, sizeof(debugaddr)); 11076 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11077 return RESULT_SUCCESS; 11078 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 10983 of file chan_sip.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
10984 { 10985 struct hostent *hp; 10986 struct ast_hostent ahp; 10987 int port = 0; 10988 char *p, *arg; 10989 10990 /* sip set debug ip <ip> */ 10991 if (argc != 5) 10992 return RESULT_SHOWUSAGE; 10993 p = arg = argv[4]; 10994 strsep(&p, ":"); 10995 if (p) 10996 port = atoi(p); 10997 hp = ast_gethostbyname(arg, &ahp); 10998 if (hp == NULL) 10999 return RESULT_SHOWUSAGE; 11000 11001 debugaddr.sin_family = AF_INET; 11002 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11003 debugaddr.sin_port = htons(port); 11004 if (port == 0) 11005 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11006 else 11007 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11008 11009 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11010 11011 return RESULT_SUCCESS; 11012 }
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 11015 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11016 { 11017 struct sip_peer *peer; 11018 if (argc != 5) 11019 return RESULT_SHOWUSAGE; 11020 peer = find_peer(argv[4], NULL, 1); 11021 if (peer) { 11022 if (peer->addr.sin_addr.s_addr) { 11023 debugaddr.sin_family = AF_INET; 11024 debugaddr.sin_addr = peer->addr.sin_addr; 11025 debugaddr.sin_port = peer->addr.sin_port; 11026 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11027 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11028 } else 11029 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11030 ASTOBJ_UNREF(peer,sip_destroy_peer); 11031 } else 11032 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11033 return RESULT_SUCCESS; 11034 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11156 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11157 { 11158 if (argc != 2) { 11159 return RESULT_SHOWUSAGE; 11160 } 11161 recordhistory = TRUE; 11162 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11163 return RESULT_SUCCESS; 11164 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17450 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, option_debug, peerl, regl, reload_config(), sip_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_poke_all_peers(), sip_registry_destroy(), sip_send_all_registers(), and userl.
Referenced by do_monitor().
17451 { 17452 if (option_debug > 3) 17453 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17454 17455 clear_realm_authentication(authl); 17456 clear_sip_domains(); 17457 authl = NULL; 17458 17459 /* First, destroy all outstanding registry calls */ 17460 /* This is needed, since otherwise active registry entries will not be destroyed */ 17461 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17462 ASTOBJ_RDLOCK(iterator); 17463 if (iterator->call) { 17464 if (option_debug > 2) 17465 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17466 /* This will also remove references to the registry */ 17467 sip_destroy(iterator->call); 17468 } 17469 ASTOBJ_UNLOCK(iterator); 17470 17471 } while(0)); 17472 17473 /* Then, actually destroy users and registry */ 17474 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17475 if (option_debug > 3) 17476 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17477 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17478 if (option_debug > 3) 17479 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17480 ASTOBJ_CONTAINER_MARKALL(&peerl); 17481 reload_config(reason); 17482 17483 /* Prune peers who still are supposed to be deleted */ 17484 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17485 if (option_debug > 3) 17486 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17487 17488 /* Send qualify (OPTIONS) to all peers */ 17489 sip_poke_all_peers(); 17490 17491 /* Register with all services */ 17492 sip_send_all_registers(); 17493 17494 if (option_debug > 3) 17495 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17496 17497 return 0; 17498 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17254 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
17255 { 17256 struct sip_pvt *p; 17257 char *mode; 17258 if (data) 17259 mode = (char *)data; 17260 else { 17261 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17262 return 0; 17263 } 17264 ast_channel_lock(chan); 17265 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17266 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17267 ast_channel_unlock(chan); 17268 return 0; 17269 } 17270 p = chan->tech_pvt; 17271 if (!p) { 17272 ast_channel_unlock(chan); 17273 return 0; 17274 } 17275 ast_mutex_lock(&p->lock); 17276 if (!strcasecmp(mode,"info")) { 17277 ast_clear_flag(&p->flags[0], SIP_DTMF); 17278 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17279 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17280 } else if (!strcasecmp(mode,"rfc2833")) { 17281 ast_clear_flag(&p->flags[0], SIP_DTMF); 17282 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17283 p->jointnoncodeccapability |= AST_RTP_DTMF; 17284 } else if (!strcasecmp(mode,"inband")) { 17285 ast_clear_flag(&p->flags[0], SIP_DTMF); 17286 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17287 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17288 } else 17289 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17290 if (p->rtp) 17291 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17292 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17293 if (!p->vad) { 17294 p->vad = ast_dsp_new(); 17295 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17296 } 17297 } else { 17298 if (p->vad) { 17299 ast_dsp_free(p->vad); 17300 p->vad = NULL; 17301 } 17302 } 17303 ast_mutex_unlock(&p->lock); 17304 ast_channel_unlock(chan); 17305 return 0; 17306 }
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 10853 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().
10854 { 10855 int x = 0; 10856 struct sip_history *hist; 10857 static int errmsg = 0; 10858 10859 if (!dialog) 10860 return; 10861 10862 if (!option_debug && !sipdebug) { 10863 if (!errmsg) { 10864 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 10865 errmsg = 1; 10866 } 10867 return; 10868 } 10869 10870 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 10871 if (dialog->subscribed) 10872 ast_log(LOG_DEBUG, " * Subscription\n"); 10873 else 10874 ast_log(LOG_DEBUG, " * SIP Call\n"); 10875 if (dialog->history) 10876 AST_LIST_TRAVERSE(dialog->history, hist, list) 10877 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 10878 if (!x) 10879 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 10880 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 10881 }
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 3670 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, and ast_channel::tech_pvt.
03671 { 03672 int ret = -1; 03673 struct sip_pvt *p; 03674 03675 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03676 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03677 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03678 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03679 03680 if (!newchan || !newchan->tech_pvt) { 03681 if (!newchan) 03682 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03683 else 03684 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03685 return -1; 03686 } 03687 p = newchan->tech_pvt; 03688 03689 if (!p) { 03690 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03691 return -1; 03692 } 03693 03694 ast_mutex_lock(&p->lock); 03695 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03696 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03697 if (p->owner != oldchan) 03698 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03699 else { 03700 p->owner = newchan; 03701 ret = 0; 03702 } 03703 if (option_debug > 2) 03704 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03705 03706 ast_mutex_unlock(&p->lock); 03707 return ret; 03708 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17399 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17400 { 17401 struct sip_pvt *p = chan->tech_pvt; 17402 return p->peercapability ? p->peercapability : p->capability; 17403 }
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 17107 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.
17108 { 17109 struct sip_pvt *p = NULL; 17110 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17111 17112 if (!(p = chan->tech_pvt)) 17113 return AST_RTP_GET_FAILED; 17114 17115 ast_mutex_lock(&p->lock); 17116 if (!(p->rtp)) { 17117 ast_mutex_unlock(&p->lock); 17118 return AST_RTP_GET_FAILED; 17119 } 17120 17121 *rtp = p->rtp; 17122 17123 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 17124 res = AST_RTP_TRY_PARTIAL; 17125 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17126 res = AST_RTP_TRY_NATIVE; 17127 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 17128 res = AST_RTP_GET_FAILED; 17129 17130 ast_mutex_unlock(&p->lock); 17131 17132 return res; 17133 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 16972 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.
16973 { 16974 struct sip_pvt *p; 16975 struct ast_udptl *udptl = NULL; 16976 16977 p = chan->tech_pvt; 16978 if (!p) 16979 return NULL; 16980 16981 ast_mutex_lock(&p->lock); 16982 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16983 udptl = p->udptl; 16984 ast_mutex_unlock(&p->lock); 16985 return udptl; 16986 }
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 17136 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
17137 { 17138 struct sip_pvt *p = NULL; 17139 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 17140 17141 if (!(p = chan->tech_pvt)) 17142 return AST_RTP_GET_FAILED; 17143 17144 ast_mutex_lock(&p->lock); 17145 if (!(p->vrtp)) { 17146 ast_mutex_unlock(&p->lock); 17147 return AST_RTP_GET_FAILED; 17148 } 17149 17150 *rtp = p->vrtp; 17151 17152 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 17153 res = AST_RTP_TRY_NATIVE; 17154 17155 ast_mutex_unlock(&p->lock); 17156 17157 return res; 17158 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
T38 negotiation helper function
Definition at line 17024 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
17025 { 17026 struct sip_pvt *p; 17027 int flag = 0; 17028 17029 p = chan->tech_pvt; 17030 if (!p || !pvt->udptl) 17031 return -1; 17032 17033 /* Setup everything on the other side like offered/responded from first side */ 17034 ast_mutex_lock(&p->lock); 17035 17036 /*! \todo check if this is not set earlier when setting up the PVT. If not 17037 maybe it should move there. */ 17038 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 17039 17040 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17041 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 17042 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 17043 17044 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 17045 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 17046 not really T38 re-invites which are different. In this 17047 case it's used properly, to see if we can reinvite over 17048 NAT 17049 */ 17050 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17051 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17052 flag =1; 17053 } else { 17054 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17055 } 17056 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17057 if (!p->pendinginvite) { 17058 if (option_debug > 2) { 17059 if (flag) 17060 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)); 17061 else 17062 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)); 17063 } 17064 transmit_reinvite_with_t38_sdp(p); 17065 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17066 if (option_debug > 2) { 17067 if (flag) 17068 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)); 17069 else 17070 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)); 17071 } 17072 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17073 } 17074 } 17075 /* Reset lastrtprx timer */ 17076 p->lastrtprx = p->lastrtptx = time(NULL); 17077 ast_mutex_unlock(&p->lock); 17078 return 0; 17079 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 17080 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 17081 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 17082 flag = 1; 17083 } else { 17084 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17085 } 17086 if (option_debug > 2) { 17087 if (flag) 17088 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)); 17089 else 17090 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)); 17091 } 17092 pvt->t38.state = T38_ENABLED; 17093 p->t38.state = T38_ENABLED; 17094 if (option_debug > 1) { 17095 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 17096 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 17097 } 17098 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 17099 p->lastrtprx = p->lastrtptx = time(NULL); 17100 ast_mutex_unlock(&p->lock); 17101 return 0; 17102 } 17103 }
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 3387 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, sip_request::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, sip_pvt::ocseq, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::refer, sip_pvt::rtp, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, sip_pvt::vrtp, and XMIT_RELIABLE.
03388 { 03389 struct sip_pvt *p = ast->tech_pvt; 03390 int needcancel = FALSE; 03391 int needdestroy = 0; 03392 struct ast_channel *oldowner = ast; 03393 03394 if (!p) { 03395 if (option_debug) 03396 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03397 return 0; 03398 } 03399 03400 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03401 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03402 if (option_debug && sipdebug) 03403 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03404 update_call_counter(p, DEC_CALL_LIMIT); 03405 } 03406 if (option_debug >3) 03407 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03408 if (p->autokillid > -1) 03409 sip_cancel_destroy(p); 03410 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03411 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03412 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03413 p->owner->tech_pvt = NULL; 03414 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03415 return 0; 03416 } 03417 if (option_debug) { 03418 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03419 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03420 else { 03421 if (option_debug) 03422 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03423 } 03424 } 03425 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03426 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03427 03428 ast_mutex_lock(&p->lock); 03429 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03430 if (option_debug && sipdebug) 03431 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03432 update_call_counter(p, DEC_CALL_LIMIT); 03433 } 03434 03435 /* Determine how to disconnect */ 03436 if (p->owner != ast) { 03437 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03438 ast_mutex_unlock(&p->lock); 03439 return 0; 03440 } 03441 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03442 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03443 needcancel = TRUE; 03444 if (option_debug > 3) 03445 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03446 } 03447 03448 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03449 03450 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03451 03452 /* Disconnect */ 03453 if (p->vad) 03454 ast_dsp_free(p->vad); 03455 03456 p->owner = NULL; 03457 ast->tech_pvt = NULL; 03458 03459 ast_module_unref(ast_module_info->self); 03460 03461 /* Do not destroy this pvt until we have timeout or 03462 get an answer to the BYE or INVITE/CANCEL 03463 If we get no answer during retransmit period, drop the call anyway. 03464 (Sorry, mother-in-law, you can't deny a hangup by sending 03465 603 declined to BYE...) 03466 */ 03467 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03468 needdestroy = 1; /* Set destroy flag at end of this function */ 03469 else if (p->invitestate != INV_CALLING) 03470 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03471 03472 /* Start the process if it's not already started */ 03473 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03474 if (needcancel) { /* Outgoing call, not up */ 03475 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03476 /* stop retransmitting an INVITE that has not received a response */ 03477 __sip_pretend_ack(p); 03478 03479 /* if we can't send right now, mark it pending */ 03480 if (p->invitestate == INV_CALLING) { 03481 /* We can't send anything in CALLING state */ 03482 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03483 /* 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. */ 03484 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03485 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03486 } else { 03487 /* Send a new request: CANCEL */ 03488 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03489 /* Actually don't destroy us yet, wait for the 487 on our original 03490 INVITE, but do set an autodestruct just in case we never get it. */ 03491 needdestroy = 0; 03492 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03493 } 03494 if ( p->initid != -1 ) { 03495 /* channel still up - reverse dec of inUse counter 03496 only if the channel is not auto-congested */ 03497 update_call_counter(p, INC_CALL_LIMIT); 03498 } 03499 } else { /* Incoming call, not up */ 03500 const char *res; 03501 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03502 transmit_response_reliable(p, res, &p->initreq); 03503 else 03504 transmit_response_reliable(p, "603 Declined", &p->initreq); 03505 } 03506 } else { /* Call is in UP state, send BYE */ 03507 if (!p->pendinginvite) { 03508 char *audioqos = ""; 03509 char *videoqos = ""; 03510 if (p->rtp) 03511 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03512 if (p->vrtp) 03513 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03514 /* Send a hangup */ 03515 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03516 03517 /* Get RTCP quality before end of call */ 03518 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03519 if (p->rtp) 03520 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03521 if (p->vrtp) 03522 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03523 } 03524 if (p->rtp && oldowner) 03525 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03526 if (p->vrtp && oldowner) 03527 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03528 } else { 03529 /* Note we will need a BYE when this all settles out 03530 but we can't send one while we have "INVITE" outstanding. */ 03531 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03532 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03533 sip_cancel_destroy(p); 03534 } 03535 } 03536 } 03537 if (needdestroy) 03538 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03539 ast_mutex_unlock(&p->lock); 03540 return 0; 03541 }
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 3779 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03780 { 03781 struct sip_pvt *p = ast->tech_pvt; 03782 int res = 0; 03783 03784 ast_mutex_lock(&p->lock); 03785 switch(condition) { 03786 case AST_CONTROL_RINGING: 03787 if (ast->_state == AST_STATE_RING) { 03788 p->invitestate = INV_EARLY_MEDIA; 03789 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03790 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03791 /* Send 180 ringing if out-of-band seems reasonable */ 03792 transmit_response(p, "180 Ringing", &p->initreq); 03793 ast_set_flag(&p->flags[0], SIP_RINGING); 03794 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03795 break; 03796 } else { 03797 /* Well, if it's not reasonable, just send in-band */ 03798 } 03799 } 03800 res = -1; 03801 break; 03802 case AST_CONTROL_BUSY: 03803 if (ast->_state != AST_STATE_UP) { 03804 transmit_response(p, "486 Busy Here", &p->initreq); 03805 p->invitestate = INV_COMPLETED; 03806 sip_alreadygone(p); 03807 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03808 break; 03809 } 03810 res = -1; 03811 break; 03812 case AST_CONTROL_CONGESTION: 03813 if (ast->_state != AST_STATE_UP) { 03814 transmit_response(p, "503 Service Unavailable", &p->initreq); 03815 p->invitestate = INV_COMPLETED; 03816 sip_alreadygone(p); 03817 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03818 break; 03819 } 03820 res = -1; 03821 break; 03822 case AST_CONTROL_PROCEEDING: 03823 if ((ast->_state != AST_STATE_UP) && 03824 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03825 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03826 transmit_response(p, "100 Trying", &p->initreq); 03827 p->invitestate = INV_PROCEEDING; 03828 break; 03829 } 03830 res = -1; 03831 break; 03832 case AST_CONTROL_PROGRESS: 03833 if ((ast->_state != AST_STATE_UP) && 03834 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03835 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03836 p->invitestate = INV_EARLY_MEDIA; 03837 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03838 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03839 break; 03840 } 03841 res = -1; 03842 break; 03843 case AST_CONTROL_HOLD: 03844 ast_moh_start(ast, data, p->mohinterpret); 03845 break; 03846 case AST_CONTROL_UNHOLD: 03847 ast_moh_stop(ast); 03848 break; 03849 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03850 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03851 transmit_info_with_vidupdate(p); 03852 /* ast_rtcp_send_h261fur(p->vrtp); */ 03853 } else 03854 res = -1; 03855 break; 03856 case -1: 03857 res = -1; 03858 break; 03859 default: 03860 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03861 res = -1; 03862 break; 03863 } 03864 ast_mutex_unlock(&p->lock); 03865 return res; 03866 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1741 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().
01742 { 01743 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01744 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static, read] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 3875 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_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, 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().
03876 { 03877 struct ast_channel *tmp; 03878 struct ast_variable *v = NULL; 03879 int fmt; 03880 int what; 03881 int needvideo = 0; 03882 { 03883 const char *my_name; /* pick a good name */ 03884 03885 if (title) 03886 my_name = title; 03887 else if ( (my_name = strchr(i->fromdomain,':')) ) 03888 my_name++; /* skip ':' */ 03889 else 03890 my_name = i->fromdomain; 03891 03892 ast_mutex_unlock(&i->lock); 03893 /* Don't hold a sip pvt lock while we allocate a channel */ 03894 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); 03895 03896 } 03897 if (!tmp) { 03898 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03899 return NULL; 03900 } 03901 ast_mutex_lock(&i->lock); 03902 03903 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03904 tmp->tech = &sip_tech_info; 03905 else 03906 tmp->tech = &sip_tech; 03907 03908 /* Select our native format based on codec preference until we receive 03909 something from another device to the contrary. */ 03910 if (i->jointcapability) /* The joint capabilities of us and peer */ 03911 what = i->jointcapability; 03912 else if (i->capability) /* Our configured capability for this peer */ 03913 what = i->capability; 03914 else 03915 what = global_capability; /* Global codec support */ 03916 03917 /* Set the native formats for audio and merge in video */ 03918 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK); 03919 if (option_debug > 2) { 03920 char buf[BUFSIZ]; 03921 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03922 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03923 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03924 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 03925 if (i->prefcodec) 03926 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 03927 } 03928 03929 /* XXX Why are we choosing a codec from the native formats?? */ 03930 fmt = ast_best_codec(tmp->nativeformats); 03931 03932 /* If we have a prefcodec setting, we have an inbound channel that set a 03933 preferred format for this call. Otherwise, we check the jointcapability 03934 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 03935 */ 03936 if (i->vrtp) { 03937 if (i->prefcodec) 03938 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 03939 else 03940 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 03941 } 03942 03943 if (option_debug > 2) { 03944 if (needvideo) 03945 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 03946 else 03947 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 03948 } 03949 03950 03951 03952 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 03953 i->vad = ast_dsp_new(); 03954 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 03955 if (global_relaxdtmf) 03956 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 03957 } 03958 if (i->rtp) { 03959 tmp->fds[0] = ast_rtp_fd(i->rtp); 03960 tmp->fds[1] = ast_rtcp_fd(i->rtp); 03961 } 03962 if (needvideo && i->vrtp) { 03963 tmp->fds[2] = ast_rtp_fd(i->vrtp); 03964 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 03965 } 03966 if (i->udptl) { 03967 tmp->fds[5] = ast_udptl_fd(i->udptl); 03968 } 03969 if (state == AST_STATE_RING) 03970 tmp->rings = 1; 03971 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03972 tmp->writeformat = fmt; 03973 tmp->rawwriteformat = fmt; 03974 tmp->readformat = fmt; 03975 tmp->rawreadformat = fmt; 03976 tmp->tech_pvt = i; 03977 03978 tmp->callgroup = i->callgroup; 03979 tmp->pickupgroup = i->pickupgroup; 03980 tmp->cid.cid_pres = i->callingpres; 03981 if (!ast_strlen_zero(i->accountcode)) 03982 ast_string_field_set(tmp, accountcode, i->accountcode); 03983 if (i->amaflags) 03984 tmp->amaflags = i->amaflags; 03985 if (!ast_strlen_zero(i->language)) 03986 ast_string_field_set(tmp, language, i->language); 03987 i->owner = tmp; 03988 ast_module_ref(ast_module_info->self); 03989 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03990 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03991 03992 03993 /* Don't use ast_set_callerid() here because it will 03994 * generate an unnecessary NewCallerID event */ 03995 tmp->cid.cid_num = ast_strdup(i->cid_num); 03996 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03997 tmp->cid.cid_name = ast_strdup(i->cid_name); 03998 if (!ast_strlen_zero(i->rdnis)) 03999 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04000 04001 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04002 tmp->cid.cid_dnid = ast_strdup(i->exten); 04003 04004 tmp->priority = 1; 04005 if (!ast_strlen_zero(i->uri)) 04006 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04007 if (!ast_strlen_zero(i->domain)) 04008 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04009 if (!ast_strlen_zero(i->useragent)) 04010 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04011 if (!ast_strlen_zero(i->callid)) 04012 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04013 if (i->rtp) 04014 ast_jb_configure(tmp, &global_jbconf); 04015 04016 /* Set channel variables for this call from configuration */ 04017 for (v = i->chanvars ; v ; v = v->next) 04018 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04019 04020 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04021 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04022 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04023 ast_hangup(tmp); 04024 tmp = NULL; 04025 } 04026 04027 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04028 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04029 04030 return tmp; 04031 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11137 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11138 { 11139 if (argc != 4) 11140 return RESULT_SHOWUSAGE; 11141 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11142 ast_cli(fd, "SIP Debugging Disabled\n"); 11143 return RESULT_SUCCESS; 11144 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11146 of file chan_sip.c.
References ast_clear_flag, ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11147 { 11148 if (argc != 3) 11149 return RESULT_SHOWUSAGE; 11150 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11151 ast_cli(fd, "SIP Debugging Disabled\n"); 11152 return RESULT_SUCCESS; 11153 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11167 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11168 { 11169 if (argc != 3) { 11170 return RESULT_SHOWUSAGE; 11171 } 11172 recordhistory = FALSE; 11173 ast_cli(fd, "SIP History Recording Disabled\n"); 11174 return RESULT_SUCCESS; 11175 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11081 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, ast_variable::name, ast_variable::next, notify_types, sip_pvt::ourip, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), ast_variable::value, and var.
11082 { 11083 struct ast_variable *varlist; 11084 int i; 11085 11086 if (argc < 4) 11087 return RESULT_SHOWUSAGE; 11088 11089 if (!notify_types) { 11090 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11091 return RESULT_FAILURE; 11092 } 11093 11094 varlist = ast_variable_browse(notify_types, argv[2]); 11095 11096 if (!varlist) { 11097 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11098 return RESULT_FAILURE; 11099 } 11100 11101 for (i = 3; i < argc; i++) { 11102 struct sip_pvt *p; 11103 struct sip_request req; 11104 struct ast_variable *var; 11105 11106 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11107 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11108 return RESULT_FAILURE; 11109 } 11110 11111 if (create_addr(p, argv[i])) { 11112 /* Maybe they're not registered, etc. */ 11113 sip_destroy(p); 11114 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11115 continue; 11116 } 11117 11118 initreqprep(&req, p, SIP_NOTIFY); 11119 11120 for (var = varlist; var; var = var->next) 11121 add_header(&req, var->name, var->value); 11122 11123 /* Recalculate our side, and recalculate Call ID */ 11124 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11125 p->ourip = __ourip; 11126 build_via(p); 11127 build_callid_pvt(p); 11128 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11129 transmit_sip_request(p, &req); 11130 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11131 } 11132 11133 return RESULT_SUCCESS; 11134 }
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 12813 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, sip_dual::chan1, sip_dual::chan2, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_dual::req, sip_dual::seqno, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
12814 { 12815 struct sip_dual *d; 12816 struct ast_channel *transferee, *transferer; 12817 /* Chan2m: The transferer, chan1m: The transferee */ 12818 pthread_t th; 12819 12820 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 12821 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 12822 if ((!transferer) || (!transferee)) { 12823 if (transferee) { 12824 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12825 ast_hangup(transferee); 12826 } 12827 if (transferer) { 12828 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12829 ast_hangup(transferer); 12830 } 12831 return -1; 12832 } 12833 12834 /* Make formats okay */ 12835 transferee->readformat = chan1->readformat; 12836 transferee->writeformat = chan1->writeformat; 12837 12838 /* Prepare for taking over the channel */ 12839 ast_channel_masquerade(transferee, chan1); 12840 12841 /* Setup the extensions and such */ 12842 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 12843 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 12844 transferee->priority = chan1->priority; 12845 12846 /* We make a clone of the peer channel too, so we can play 12847 back the announcement */ 12848 12849 /* Make formats okay */ 12850 transferer->readformat = chan2->readformat; 12851 transferer->writeformat = chan2->writeformat; 12852 12853 /* Prepare for taking over the channel */ 12854 ast_channel_masquerade(transferer, chan2); 12855 12856 /* Setup the extensions and such */ 12857 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 12858 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 12859 transferer->priority = chan2->priority; 12860 12861 ast_channel_lock(transferer); 12862 if (ast_do_masquerade(transferer)) { 12863 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 12864 ast_channel_unlock(transferer); 12865 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12866 ast_hangup(transferer); 12867 return -1; 12868 } 12869 ast_channel_unlock(transferer); 12870 if (!transferer || !transferee) { 12871 if (!transferer) { 12872 if (option_debug) 12873 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 12874 } 12875 if (!transferee) { 12876 if (option_debug) 12877 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 12878 } 12879 return -1; 12880 } 12881 if ((d = ast_calloc(1, sizeof(*d)))) { 12882 pthread_attr_t attr; 12883 12884 pthread_attr_init(&attr); 12885 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 12886 12887 /* Save original request for followup */ 12888 copy_request(&d->req, req); 12889 d->chan1 = transferee; /* Transferee */ 12890 d->chan2 = transferer; /* Transferer */ 12891 d->seqno = seqno; 12892 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 12893 /* Could not start thread */ 12894 free(d); /* We don't need it anymore. If thread is created, d will be free'd 12895 by sip_park_thread() */ 12896 pthread_attr_destroy(&attr); 12897 return 0; 12898 } 12899 pthread_attr_destroy(&attr); 12900 } 12901 return -1; 12902 }
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 12746 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
12747 { 12748 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 12749 struct sip_dual *d; 12750 struct sip_request req; 12751 int ext; 12752 int res; 12753 12754 d = stuff; 12755 transferee = d->chan1; 12756 transferer = d->chan2; 12757 copy_request(&req, &d->req); 12758 free(d); 12759 12760 if (!transferee || !transferer) { 12761 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 12762 return NULL; 12763 } 12764 if (option_debug > 3) 12765 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 12766 12767 ast_channel_lock(transferee); 12768 if (ast_do_masquerade(transferee)) { 12769 ast_log(LOG_WARNING, "Masquerade failed.\n"); 12770 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 12771 ast_channel_unlock(transferee); 12772 return NULL; 12773 } 12774 ast_channel_unlock(transferee); 12775 12776 res = ast_park_call(transferee, transferer, 0, &ext); 12777 12778 12779 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 12780 if (!res) { 12781 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 12782 } else { 12783 /* Then tell the transferer what happened */ 12784 sprintf(buf, "Call parked on extension '%d'", ext); 12785 transmit_message_with_text(transferer->tech_pvt, buf); 12786 } 12787 #endif 12788 12789 /* Any way back to the current call??? */ 12790 /* Transmit response to the REFER request */ 12791 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 12792 if (!res) { 12793 /* Transfer succeeded */ 12794 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 12795 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 12796 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 12797 ast_hangup(transferer); /* This will cause a BYE */ 12798 if (option_debug) 12799 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 12800 } else { 12801 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 12802 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 12803 if (option_debug) 12804 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 12805 /* Do not hangup call */ 12806 } 12807 return NULL; 12808 }
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 8318 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().
08319 { 08320 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08321 08322 if (!peer) 08323 return; 08324 08325 /* If they put someone on hold, increment the value... otherwise decrement it */ 08326 if (hold) 08327 peer->onHold++; 08328 else 08329 peer->onHold--; 08330 08331 /* Request device state update */ 08332 ast_device_state_changed("SIP/%s", peer->name); 08333 08334 return; 08335 }
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 17409 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
17410 { 17411 int ms = 0; 17412 17413 if (!speerobjs) /* No peers, just give up */ 17414 return; 17415 17416 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17417 ASTOBJ_WRLOCK(iterator); 17418 if (iterator->pokeexpire > -1) 17419 ast_sched_del(sched, iterator->pokeexpire); 17420 ms += 100; 17421 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17422 ASTOBJ_UNLOCK(iterator); 17423 } while (0) 17424 ); 17425 }
static int sip_poke_noanswer | ( | void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15412 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15413 { 15414 struct sip_peer *peer = data; 15415 15416 peer->pokeexpire = -1; 15417 if (peer->lastms > -1) { 15418 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15419 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15420 } 15421 if (peer->call) 15422 sip_destroy(peer->call); 15423 peer->call = NULL; 15424 peer->lastms = -1; 15425 ast_device_state_changed("SIP/%s", peer->name); 15426 /* Try again quickly */ 15427 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15428 return 0; 15429 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15434 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, 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().
15435 { 15436 struct sip_pvt *p; 15437 int xmitres = 0; 15438 15439 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15440 /* IF we have no IP, or this isn't to be monitored, return 15441 imeediately after clearing things out */ 15442 if (peer->pokeexpire > -1) 15443 ast_sched_del(sched, peer->pokeexpire); 15444 peer->lastms = 0; 15445 peer->pokeexpire = -1; 15446 peer->call = NULL; 15447 return 0; 15448 } 15449 if (peer->call) { 15450 if (sipdebug) 15451 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15452 sip_destroy(peer->call); 15453 } 15454 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15455 return -1; 15456 15457 p->sa = peer->addr; 15458 p->recv = peer->addr; 15459 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15460 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15461 15462 /* Send OPTIONs to peer's fullcontact */ 15463 if (!ast_strlen_zero(peer->fullcontact)) 15464 ast_string_field_set(p, fullcontact, peer->fullcontact); 15465 15466 if (!ast_strlen_zero(peer->tohost)) 15467 ast_string_field_set(p, tohost, peer->tohost); 15468 else 15469 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15470 15471 /* Recalculate our side, and recalculate Call ID */ 15472 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15473 p->ourip = __ourip; 15474 build_via(p); 15475 build_callid_pvt(p); 15476 15477 if (peer->pokeexpire > -1) 15478 ast_sched_del(sched, peer->pokeexpire); 15479 p->relatedpeer = peer; 15480 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15481 #ifdef VOCAL_DATA_HACK 15482 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15483 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 15484 #else 15485 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 15486 #endif 15487 gettimeofday(&peer->ps, NULL); 15488 if (xmitres == XMIT_ERROR) 15489 sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ 15490 else 15491 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 15492 15493 return 0; 15494 }
static int sip_poke_peer_s | ( | void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 7723 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().
07724 { 07725 struct sip_peer *peer = data; 07726 07727 peer->pokeexpire = -1; 07728 sip_poke_peer(peer); 07729 return 0; 07730 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 9880 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND_UNLINK, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, FALSE, sip_user::flags, sip_peer::flags, name, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), sip_destroy_user(), SIP_PAGE2_RTCACHEFRIENDS, TRUE, and userl.
09881 { 09882 struct sip_peer *peer; 09883 struct sip_user *user; 09884 int pruneuser = FALSE; 09885 int prunepeer = FALSE; 09886 int multi = FALSE; 09887 char *name = NULL; 09888 regex_t regexbuf; 09889 09890 switch (argc) { 09891 case 4: 09892 if (!strcasecmp(argv[3], "user")) 09893 return RESULT_SHOWUSAGE; 09894 if (!strcasecmp(argv[3], "peer")) 09895 return RESULT_SHOWUSAGE; 09896 if (!strcasecmp(argv[3], "like")) 09897 return RESULT_SHOWUSAGE; 09898 if (!strcasecmp(argv[3], "all")) { 09899 multi = TRUE; 09900 pruneuser = prunepeer = TRUE; 09901 } else { 09902 pruneuser = prunepeer = TRUE; 09903 name = argv[3]; 09904 } 09905 break; 09906 case 5: 09907 if (!strcasecmp(argv[4], "like")) 09908 return RESULT_SHOWUSAGE; 09909 if (!strcasecmp(argv[3], "all")) 09910 return RESULT_SHOWUSAGE; 09911 if (!strcasecmp(argv[3], "like")) { 09912 multi = TRUE; 09913 name = argv[4]; 09914 pruneuser = prunepeer = TRUE; 09915 } else if (!strcasecmp(argv[3], "user")) { 09916 pruneuser = TRUE; 09917 if (!strcasecmp(argv[4], "all")) 09918 multi = TRUE; 09919 else 09920 name = argv[4]; 09921 } else if (!strcasecmp(argv[3], "peer")) { 09922 prunepeer = TRUE; 09923 if (!strcasecmp(argv[4], "all")) 09924 multi = TRUE; 09925 else 09926 name = argv[4]; 09927 } else 09928 return RESULT_SHOWUSAGE; 09929 break; 09930 case 6: 09931 if (strcasecmp(argv[4], "like")) 09932 return RESULT_SHOWUSAGE; 09933 if (!strcasecmp(argv[3], "user")) { 09934 pruneuser = TRUE; 09935 name = argv[5]; 09936 } else if (!strcasecmp(argv[3], "peer")) { 09937 prunepeer = TRUE; 09938 name = argv[5]; 09939 } else 09940 return RESULT_SHOWUSAGE; 09941 break; 09942 default: 09943 return RESULT_SHOWUSAGE; 09944 } 09945 09946 if (multi && name) { 09947 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 09948 return RESULT_SHOWUSAGE; 09949 } 09950 09951 if (multi) { 09952 if (prunepeer) { 09953 int pruned = 0; 09954 09955 ASTOBJ_CONTAINER_WRLOCK(&peerl); 09956 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09957 ASTOBJ_RDLOCK(iterator); 09958 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09959 ASTOBJ_UNLOCK(iterator); 09960 continue; 09961 }; 09962 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09963 ASTOBJ_MARK(iterator); 09964 pruned++; 09965 } 09966 ASTOBJ_UNLOCK(iterator); 09967 } while (0) ); 09968 if (pruned) { 09969 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 09970 ast_cli(fd, "%d peers pruned.\n", pruned); 09971 } else 09972 ast_cli(fd, "No peers found to prune.\n"); 09973 ASTOBJ_CONTAINER_UNLOCK(&peerl); 09974 } 09975 if (pruneuser) { 09976 int pruned = 0; 09977 09978 ASTOBJ_CONTAINER_WRLOCK(&userl); 09979 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09980 ASTOBJ_RDLOCK(iterator); 09981 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09982 ASTOBJ_UNLOCK(iterator); 09983 continue; 09984 }; 09985 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09986 ASTOBJ_MARK(iterator); 09987 pruned++; 09988 } 09989 ASTOBJ_UNLOCK(iterator); 09990 } while (0) ); 09991 if (pruned) { 09992 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 09993 ast_cli(fd, "%d users pruned.\n", pruned); 09994 } else 09995 ast_cli(fd, "No users found to prune.\n"); 09996 ASTOBJ_CONTAINER_UNLOCK(&userl); 09997 } 09998 } else { 09999 if (prunepeer) { 10000 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10001 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10002 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10003 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10004 } else 10005 ast_cli(fd, "Peer '%s' pruned.\n", name); 10006 ASTOBJ_UNREF(peer, sip_destroy_peer); 10007 } else 10008 ast_cli(fd, "Peer '%s' not found.\n", name); 10009 } 10010 if (pruneuser) { 10011 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10012 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10013 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10014 ASTOBJ_CONTAINER_LINK(&userl, user); 10015 } else 10016 ast_cli(fd, "User '%s' pruned.\n", name); 10017 ASTOBJ_UNREF(user, sip_destroy_user); 10018 } else 10019 ast_cli(fd, "User '%s' not found.\n", name); 10020 } 10021 } 10022 10023 return RESULT_SUCCESS; 10024 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static, read] |
Read SIP RTP from channel.
Definition at line 4234 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().
04235 { 04236 struct ast_frame *fr; 04237 struct sip_pvt *p = ast->tech_pvt; 04238 int faxdetected = FALSE; 04239 04240 ast_mutex_lock(&p->lock); 04241 fr = sip_rtp_read(ast, p, &faxdetected); 04242 p->lastrtprx = time(NULL); 04243 04244 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04245 /* 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 */ 04246 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04247 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04248 if (!p->pendinginvite) { 04249 if (option_debug > 2) 04250 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04251 p->t38.state = T38_LOCAL_REINVITE; 04252 transmit_reinvite_with_t38_sdp(p); 04253 if (option_debug > 1) 04254 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04255 } 04256 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04257 if (option_debug > 2) 04258 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04259 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04260 } 04261 } 04262 04263 ast_mutex_unlock(&p->lock); 04264 return fr; 04265 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static, read] |
The real destination address for a write.
Definition at line 1735 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().
01736 { 01737 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01738 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7532 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by handle_request_invite(), handle_request_refer(), and transmit_refer().
07533 { 07534 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07535 return p->refer ? 1 : 0; 07536 }
static int sip_reg_timeout | ( | void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7289 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().
07290 { 07291 07292 /* if we are here, our registration timed out, so we'll just do it over */ 07293 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07294 struct sip_pvt *p; 07295 int res; 07296 07297 /* if we couldn't get a reference to the registry object, punt */ 07298 if (!r) 07299 return 0; 07300 07301 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07302 if (r->call) { 07303 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07304 in the single SIP manager thread. */ 07305 p = r->call; 07306 if (p->registry) 07307 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07308 r->call = NULL; 07309 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07310 /* Pretend to ACK anything just in case */ 07311 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07312 } 07313 /* If we have a limit, stop registration and give up */ 07314 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07315 /* Ok, enough is enough. Don't try any more */ 07316 /* We could add an external notification here... 07317 steal it from app_voicemail :-) */ 07318 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07319 r->regstate = REG_STATE_FAILED; 07320 } else { 07321 r->regstate = REG_STATE_UNREGISTERED; 07322 r->timeout = -1; 07323 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07324 } 07325 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)); 07326 ASTOBJ_UNREF(r, sip_registry_destroy); 07327 return 0; 07328 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4553 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::callid_valid, sip_registry::expire, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::ocseq, sip_registry::portno, sip_registry::refresh, regl, secret, sip_registry_destroy(), sip_registry::timeout, and username.
Referenced by reload_config().
04554 { 04555 struct sip_registry *reg; 04556 int portnum = 0; 04557 char username[256] = ""; 04558 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04559 char *porta=NULL; 04560 char *contact=NULL; 04561 04562 if (!value) 04563 return -1; 04564 ast_copy_string(username, value, sizeof(username)); 04565 /* First split around the last '@' then parse the two components. */ 04566 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04567 if (hostname) 04568 *hostname++ = '\0'; 04569 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04570 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04571 return -1; 04572 } 04573 /* split user[:secret[:authuser]] */ 04574 secret = strchr(username, ':'); 04575 if (secret) { 04576 *secret++ = '\0'; 04577 authuser = strchr(secret, ':'); 04578 if (authuser) 04579 *authuser++ = '\0'; 04580 } 04581 /* split host[:port][/contact] */ 04582 contact = strchr(hostname, '/'); 04583 if (contact) 04584 *contact++ = '\0'; 04585 if (ast_strlen_zero(contact)) 04586 contact = "s"; 04587 porta = strchr(hostname, ':'); 04588 if (porta) { 04589 *porta++ = '\0'; 04590 portnum = atoi(porta); 04591 if (portnum == 0) { 04592 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04593 return -1; 04594 } 04595 } 04596 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04597 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04598 return -1; 04599 } 04600 04601 if (ast_string_field_init(reg, 256)) { 04602 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04603 free(reg); 04604 return -1; 04605 } 04606 04607 regobjs++; 04608 ASTOBJ_INIT(reg); 04609 ast_string_field_set(reg, contact, contact); 04610 if (!ast_strlen_zero(username)) 04611 ast_string_field_set(reg, username, username); 04612 if (hostname) 04613 ast_string_field_set(reg, hostname, hostname); 04614 if (authuser) 04615 ast_string_field_set(reg, authuser, authuser); 04616 if (secret) 04617 ast_string_field_set(reg, secret, secret); 04618 reg->expire = -1; 04619 reg->timeout = -1; 04620 reg->refresh = default_expiry; 04621 reg->portno = portnum; 04622 reg->callid_valid = FALSE; 04623 reg->ocseq = INITIAL_CSEQ; 04624 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04625 ASTOBJ_UNREF(reg,sip_registry_destroy); 04626 return 0; 04627 }
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 2965 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, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), sip_do_reload(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
02966 { 02967 /* Really delete */ 02968 if (option_debug > 2) 02969 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 02970 02971 if (reg->call) { 02972 /* Clear registry before destroying to ensure 02973 we don't get reentered trying to grab the registry lock */ 02974 reg->call->registry = NULL; 02975 if (option_debug > 2) 02976 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 02977 sip_destroy(reg->call); 02978 } 02979 if (reg->expire > -1) 02980 ast_sched_del(sched, reg->expire); 02981 if (reg->timeout > -1) 02982 ast_sched_del(sched, reg->timeout); 02983 ast_string_field_free_pools(reg); 02984 regobjs--; 02985 free(reg); 02986 02987 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17501 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().
17502 { 17503 ast_mutex_lock(&sip_reload_lock); 17504 if (sip_reloading) 17505 ast_verbose("Previous SIP reload not yet done\n"); 17506 else { 17507 sip_reloading = TRUE; 17508 if (fd) 17509 sip_reloadreason = CHANNEL_CLI_RELOAD; 17510 else 17511 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17512 } 17513 ast_mutex_unlock(&sip_reload_lock); 17514 restart_monitor(); 17515 17516 return 0; 17517 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 15596 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::ourip, sip_pvt::prefcodec, restart_monitor(), sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
15597 { 15598 int oldformat; 15599 struct sip_pvt *p; 15600 struct ast_channel *tmpc = NULL; 15601 char *ext, *host; 15602 char tmp[256]; 15603 char *dest = data; 15604 15605 oldformat = format; 15606 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15607 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)); 15608 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15609 return NULL; 15610 } 15611 if (option_debug) 15612 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15613 15614 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15615 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15616 *cause = AST_CAUSE_SWITCH_CONGESTION; 15617 return NULL; 15618 } 15619 15620 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15621 15622 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15623 sip_destroy(p); 15624 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15625 *cause = AST_CAUSE_SWITCH_CONGESTION; 15626 return NULL; 15627 } 15628 15629 ast_copy_string(tmp, dest, sizeof(tmp)); 15630 host = strchr(tmp, '@'); 15631 if (host) { 15632 *host++ = '\0'; 15633 ext = tmp; 15634 } else { 15635 ext = strchr(tmp, '/'); 15636 if (ext) 15637 *ext++ = '\0'; 15638 host = tmp; 15639 } 15640 15641 if (create_addr(p, host)) { 15642 *cause = AST_CAUSE_UNREGISTERED; 15643 if (option_debug > 2) 15644 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15645 sip_destroy(p); 15646 return NULL; 15647 } 15648 if (ast_strlen_zero(p->peername) && ext) 15649 ast_string_field_set(p, peername, ext); 15650 /* Recalculate our side, and recalculate Call ID */ 15651 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15652 p->ourip = __ourip; 15653 build_via(p); 15654 build_callid_pvt(p); 15655 15656 /* We have an extension to call, don't use the full contact here */ 15657 /* This to enable dialing registered peers with extension dialling, 15658 like SIP/peername/extension 15659 SIP/peername will still use the full contact */ 15660 if (ext) { 15661 ast_string_field_set(p, username, ext); 15662 ast_string_field_free(p, fullcontact); 15663 } 15664 #if 0 15665 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 15666 #endif 15667 p->prefcodec = oldformat; /* Format for this call */ 15668 ast_mutex_lock(&p->lock); 15669 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 15670 ast_mutex_unlock(&p->lock); 15671 if (!tmpc) 15672 sip_destroy(p); 15673 ast_update_use_count(); 15674 restart_monitor(); 15675 return tmpc; 15676 }
static int sip_reregister | ( | void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7257 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().
07258 { 07259 /* if we are here, we know that we need to reregister. */ 07260 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07261 07262 /* if we couldn't get a reference to the registry object, punt */ 07263 if (!r) 07264 return 0; 07265 07266 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07267 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07268 /* Since registry's are only added/removed by the the monitor thread, this 07269 may be overkill to reference/dereference at all here */ 07270 if (sipdebug) 07271 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07272 07273 r->expire = -1; 07274 __sip_do_register(r); 07275 ASTOBJ_UNREF(r, sip_registry_destroy); 07276 return 0; 07277 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static, read] |
Read RTP from network.
Definition at line 4164 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, ast_frame::frametype, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, ast_frame::subclass, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04165 { 04166 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04167 struct ast_frame *f; 04168 04169 if (!p->rtp) { 04170 /* We have no RTP allocated for this channel */ 04171 return &ast_null_frame; 04172 } 04173 04174 switch(ast->fdno) { 04175 case 0: 04176 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04177 break; 04178 case 1: 04179 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04180 break; 04181 case 2: 04182 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04183 break; 04184 case 3: 04185 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04186 break; 04187 case 5: 04188 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04189 break; 04190 default: 04191 f = &ast_null_frame; 04192 } 04193 /* Don't forward RFC2833 if we're not supposed to */ 04194 if (f && (f->frametype == AST_FRAME_DTMF) && 04195 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04196 return &ast_null_frame; 04197 04198 /* We already hold the channel lock */ 04199 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04200 return f; 04201 04202 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04203 if (!(f->subclass & p->jointcapability)) { 04204 if (option_debug) { 04205 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04206 ast_getformatname(f->subclass), p->owner->name); 04207 } 04208 return &ast_null_frame; 04209 } 04210 if (option_debug) 04211 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04212 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04213 ast_set_read_format(p->owner, p->owner->readformat); 04214 ast_set_write_format(p->owner, p->owner->writeformat); 04215 } 04216 04217 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04218 f = ast_dsp_process(p->owner, p->vad, f); 04219 if (f && f->frametype == AST_FRAME_DTMF) { 04220 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04221 if (option_debug) 04222 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04223 *faxdetect = 1; 04224 } else if (option_debug) { 04225 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04226 } 04227 } 04228 } 04229 04230 return f; 04231 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2076 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_pvt::autokillid, sip_pvt::flags, sip_pvt::method, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02077 { 02078 if (ms < 0) { 02079 if (p->timer_t1 == 0) 02080 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02081 ms = p->timer_t1 * 64; 02082 } 02083 if (sip_debug_test_pvt(p)) 02084 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02085 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02086 append_history(p, "SchedDestroy", "%d ms", ms); 02087 02088 if (p->autokillid > -1) 02089 ast_sched_del(sched, p->autokillid); 02090 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02091 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17428 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
17429 { 17430 int ms; 17431 int regspacing; 17432 if (!regobjs) 17433 return; 17434 regspacing = default_expiry * 1000/regobjs; 17435 if (regspacing > 100) 17436 regspacing = 100; 17437 ms = regspacing; 17438 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17439 ASTOBJ_WRLOCK(iterator); 17440 if (iterator->expire > -1) 17441 ast_sched_del(sched, iterator->expire); 17442 ms += regspacing; 17443 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17444 ASTOBJ_UNLOCK(iterator); 17445 } while (0) 17446 ); 17447 }
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 15153 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by do_monitor(), and handle_request_subscribe().
15154 { 15155 /* Called with peerl lock, but releases it */ 15156 struct sip_pvt *p; 15157 int newmsgs, oldmsgs; 15158 15159 /* Do we have an IP address? If not, skip this peer */ 15160 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 15161 return 0; 15162 15163 /* Check for messages */ 15164 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 15165 15166 peer->lastmsgcheck = time(NULL); 15167 15168 /* Return now if it's the same thing we told them last time */ 15169 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 15170 return 0; 15171 } 15172 15173 15174 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 15175 15176 if (peer->mwipvt) { 15177 /* Base message on subscription */ 15178 p = peer->mwipvt; 15179 } else { 15180 /* Build temporary dialog for this message */ 15181 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 15182 return -1; 15183 if (create_addr_from_peer(p, peer)) { 15184 /* Maybe they're not registered, etc. */ 15185 sip_destroy(p); 15186 return 0; 15187 } 15188 /* Recalculate our side, and recalculate Call ID */ 15189 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15190 p->ourip = __ourip; 15191 build_via(p); 15192 build_callid_pvt(p); 15193 /* Destroy this session after 32 secs */ 15194 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15195 } 15196 /* Send MWI */ 15197 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15198 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15199 return 0; 15200 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3710 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.
03711 { 03712 struct sip_pvt *p = ast->tech_pvt; 03713 int res = 0; 03714 03715 ast_mutex_lock(&p->lock); 03716 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03717 case SIP_DTMF_INBAND: 03718 res = -1; /* Tell Asterisk to generate inband indications */ 03719 break; 03720 case SIP_DTMF_RFC2833: 03721 if (p->rtp) 03722 ast_rtp_senddigit_begin(p->rtp, digit); 03723 break; 03724 default: 03725 break; 03726 } 03727 ast_mutex_unlock(&p->lock); 03728 03729 return res; 03730 }
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 3734 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
03735 { 03736 struct sip_pvt *p = ast->tech_pvt; 03737 int res = 0; 03738 03739 ast_mutex_lock(&p->lock); 03740 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03741 case SIP_DTMF_INFO: 03742 transmit_info_with_digit(p, digit, duration); 03743 break; 03744 case SIP_DTMF_RFC2833: 03745 if (p->rtp) 03746 ast_rtp_senddigit_end(p->rtp, digit); 03747 break; 03748 case SIP_DTMF_INBAND: 03749 res = -1; /* Tell Asterisk to stop inband indications */ 03750 break; 03751 } 03752 ast_mutex_unlock(&p->lock); 03753 03754 return res; 03755 }
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 2319 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().
02320 { 02321 struct sip_pvt *p = ast->tech_pvt; 02322 int debug = sip_debug_test_pvt(p); 02323 02324 if (debug) 02325 ast_verbose("Sending text %s on %s\n", text, ast->name); 02326 if (!p) 02327 return -1; 02328 if (ast_strlen_zero(text)) 02329 return 0; 02330 if (debug) 02331 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02332 transmit_message_with_text(p, text); 02333 return 0; 02334 }
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 17161 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), and sip_pvt::vredirip.
17162 { 17163 struct sip_pvt *p; 17164 int changed = 0; 17165 17166 p = chan->tech_pvt; 17167 if (!p) 17168 return -1; 17169 17170 /* Disable early RTP bridge */ 17171 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 17172 return 0; 17173 17174 ast_mutex_lock(&p->lock); 17175 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 17176 /* If we're destroyed, don't bother */ 17177 ast_mutex_unlock(&p->lock); 17178 return 0; 17179 } 17180 17181 /* if this peer cannot handle reinvites of the media stream to devices 17182 that are known to be behind a NAT, then stop the process now 17183 */ 17184 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 17185 ast_mutex_unlock(&p->lock); 17186 return 0; 17187 } 17188 17189 if (rtp) { 17190 changed |= ast_rtp_get_peer(rtp, &p->redirip); 17191 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 17192 memset(&p->redirip, 0, sizeof(p->redirip)); 17193 changed = 1; 17194 } 17195 if (vrtp) { 17196 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 17197 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 17198 memset(&p->vredirip, 0, sizeof(p->vredirip)); 17199 changed = 1; 17200 } 17201 if (codecs) { 17202 if ((p->redircodecs != codecs)) { 17203 p->redircodecs = codecs; 17204 changed = 1; 17205 } 17206 if ((p->capability & codecs) != p->capability) { 17207 p->jointcapability &= codecs; 17208 p->capability &= codecs; 17209 changed = 1; 17210 } 17211 } 17212 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17213 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 17214 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 17215 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 17216 if (option_debug) 17217 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)); 17218 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 17219 if (option_debug > 2) { 17220 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)); 17221 } 17222 transmit_reinvite_with_sdp(p); 17223 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17224 if (option_debug > 2) { 17225 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)); 17226 } 17227 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17228 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17229 } 17230 } 17231 /* Reset lastrtprx timer */ 17232 p->lastrtprx = p->lastrtptx = time(NULL); 17233 ast_mutex_unlock(&p->lock); 17234 return 0; 17235 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 16988 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), and sip_pvt::udptlredirip.
16989 { 16990 struct sip_pvt *p; 16991 16992 p = chan->tech_pvt; 16993 if (!p) 16994 return -1; 16995 ast_mutex_lock(&p->lock); 16996 if (udptl) 16997 ast_udptl_get_peer(udptl, &p->udptlredirip); 16998 else 16999 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 17000 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 17001 if (!p->pendinginvite) { 17002 if (option_debug > 2) { 17003 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); 17004 } 17005 transmit_reinvite_with_t38_sdp(p); 17006 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 17007 if (option_debug > 2) { 17008 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); 17009 } 17010 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17011 } 17012 } 17013 /* Reset lastrtprx timer */ 17014 p->lastrtprx = p->lastrtptx = time(NULL); 17015 ast_mutex_unlock(&p->lock); 17016 return 0; 17017 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 10748 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, cfsip_options::id, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
10749 { 10750 struct sip_pvt *cur; 10751 size_t len; 10752 int found = 0; 10753 10754 if (argc != 4) 10755 return RESULT_SHOWUSAGE; 10756 len = strlen(argv[3]); 10757 ast_mutex_lock(&iflock); 10758 for (cur = iflist; cur; cur = cur->next) { 10759 if (!strncasecmp(cur->callid, argv[3], len)) { 10760 char formatbuf[BUFSIZ/2]; 10761 ast_cli(fd,"\n"); 10762 if (cur->subscribed != NONE) 10763 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 10764 else 10765 ast_cli(fd, " * SIP Call\n"); 10766 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 10767 ast_cli(fd, " Call-ID: %s\n", cur->callid); 10768 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 10769 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 10770 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 10771 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 10772 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 10773 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 10774 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 10775 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 10776 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 10777 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 10778 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 10779 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)" ); 10780 ast_cli(fd, " Our Tag: %s\n", cur->tag); 10781 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 10782 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 10783 if (!ast_strlen_zero(cur->username)) 10784 ast_cli(fd, " Username: %s\n", cur->username); 10785 if (!ast_strlen_zero(cur->peername)) 10786 ast_cli(fd, " Peername: %s\n", cur->peername); 10787 if (!ast_strlen_zero(cur->uri)) 10788 ast_cli(fd, " Original uri: %s\n", cur->uri); 10789 if (!ast_strlen_zero(cur->cid_num)) 10790 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 10791 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 10792 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 10793 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10794 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 10795 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 10796 ast_cli(fd, " SIP Options: "); 10797 if (cur->sipoptions) { 10798 int x; 10799 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10800 if (cur->sipoptions & sip_options[x].id) 10801 ast_cli(fd, "%s ", sip_options[x].text); 10802 } 10803 } else 10804 ast_cli(fd, "(none)\n"); 10805 ast_cli(fd, "\n\n"); 10806 found++; 10807 } 10808 } 10809 ast_mutex_unlock(&iflock); 10810 if (!found) 10811 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10812 return RESULT_SUCCESS; 10813 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10546 of file chan_sip.c.
References __sip_show_channels().
10547 { 10548 return __sip_show_channels(fd, argc, argv, 0); 10549 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10058 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.
10059 { 10060 struct domain *d; 10061 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10062 10063 if (AST_LIST_EMPTY(&domain_list)) { 10064 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10065 return RESULT_SUCCESS; 10066 } else { 10067 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10068 AST_LIST_LOCK(&domain_list); 10069 AST_LIST_TRAVERSE(&domain_list, d, list) 10070 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10071 domain_mode_to_text(d->mode)); 10072 AST_LIST_UNLOCK(&domain_list); 10073 ast_cli(fd, "\n"); 10074 return RESULT_SUCCESS; 10075 } 10076 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 10816 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sip_pvt::subscribed.
10817 { 10818 struct sip_pvt *cur; 10819 size_t len; 10820 int found = 0; 10821 10822 if (argc != 4) 10823 return RESULT_SHOWUSAGE; 10824 if (!recordhistory) 10825 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 10826 len = strlen(argv[3]); 10827 ast_mutex_lock(&iflock); 10828 for (cur = iflist; cur; cur = cur->next) { 10829 if (!strncasecmp(cur->callid, argv[3], len)) { 10830 struct sip_history *hist; 10831 int x = 0; 10832 10833 ast_cli(fd,"\n"); 10834 if (cur->subscribed != NONE) 10835 ast_cli(fd, " * Subscription\n"); 10836 else 10837 ast_cli(fd, " * SIP Call\n"); 10838 if (cur->history) 10839 AST_LIST_TRAVERSE(cur->history, hist, list) 10840 ast_cli(fd, "%d. %s\n", ++x, hist->event); 10841 if (x == 0) 10842 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 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_inuse | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command to show calls within limits set by call_limit.
Definition at line 9483 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.
09484 { 09485 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09486 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09487 char ilimits[40]; 09488 char iused[40]; 09489 int showall = FALSE; 09490 09491 if (argc < 3) 09492 return RESULT_SHOWUSAGE; 09493 09494 if (argc == 4 && !strcmp(argv[3],"all")) 09495 showall = TRUE; 09496 09497 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09498 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09499 ASTOBJ_RDLOCK(iterator); 09500 if (iterator->call_limit) 09501 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09502 else 09503 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09504 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09505 if (showall || iterator->call_limit) 09506 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09507 ASTOBJ_UNLOCK(iterator); 09508 } while (0) ); 09509 09510 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09511 09512 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09513 ASTOBJ_RDLOCK(iterator); 09514 if (iterator->call_limit) 09515 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09516 else 09517 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09518 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09519 if (showall || iterator->call_limit) 09520 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09521 ASTOBJ_UNLOCK(iterator); 09522 } while (0) ); 09523 09524 return RESULT_SUCCESS; 09525 #undef FORMAT 09526 #undef FORMAT2 09527 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 9804 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
09805 { 09806 char tmp[256]; 09807 if (argc != 3) 09808 return RESULT_SHOWUSAGE; 09809 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 09810 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 09811 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 09812 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 09813 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 09814 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 09815 return RESULT_SUCCESS; 09816 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10110 of file chan_sip.c.
References _sip_show_peer().
10111 { 10112 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10113 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9660 of file chan_sip.c.
References _sip_show_peers().
09661 { 09662 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09663 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10383 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.
10384 { 10385 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10386 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10387 char host[80]; 10388 char tmpdat[256]; 10389 struct tm tm; 10390 10391 10392 if (argc != 3) 10393 return RESULT_SHOWUSAGE; 10394 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10395 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10396 ASTOBJ_RDLOCK(iterator); 10397 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10398 if (iterator->regtime) { 10399 ast_localtime(&iterator->regtime, &tm, NULL); 10400 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10401 } else { 10402 tmpdat[0] = 0; 10403 } 10404 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10405 ASTOBJ_UNLOCK(iterator); 10406 } while(0)); 10407 return RESULT_SUCCESS; 10408 #undef FORMAT 10409 #undef FORMAT2 10410 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10413 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().
10414 { 10415 int realtimepeers; 10416 int realtimeusers; 10417 char codec_buf[BUFSIZ]; 10418 10419 realtimepeers = ast_check_realtime("sippeers"); 10420 realtimeusers = ast_check_realtime("sipusers"); 10421 10422 if (argc != 3) 10423 return RESULT_SHOWUSAGE; 10424 ast_cli(fd, "\n\nGlobal Settings:\n"); 10425 ast_cli(fd, "----------------\n"); 10426 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10427 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10428 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10429 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10430 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10431 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10432 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10433 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10434 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10435 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10436 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10437 ast_cli(fd, " Our auth realm %s\n", global_realm); 10438 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10439 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10440 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10441 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10442 ast_cli(fd, " User Agent: %s\n", global_useragent); 10443 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10444 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10445 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10446 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10447 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10448 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10449 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10450 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10451 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10452 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10453 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10454 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10455 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10456 #endif 10457 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10458 if (!realtimepeers && !realtimeusers) 10459 ast_cli(fd, " SIP realtime: Disabled\n" ); 10460 else 10461 ast_cli(fd, " SIP realtime: Enabled\n" ); 10462 10463 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10464 ast_cli(fd, "---------------------------\n"); 10465 ast_cli(fd, " Codecs: "); 10466 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10467 ast_cli(fd, "%s\n", codec_buf); 10468 ast_cli(fd, " Codec Order: "); 10469 print_codec_to_cli(fd, &default_prefs); 10470 ast_cli(fd, "\n"); 10471 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10472 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10473 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10474 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10475 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10476 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10477 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10478 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10479 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10480 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10481 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10482 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10483 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10484 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10485 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10486 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10487 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10488 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10489 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10490 ast_cli(fd, "\nDefault Settings:\n"); 10491 ast_cli(fd, "-----------------\n"); 10492 ast_cli(fd, " Context: %s\n", default_context); 10493 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10494 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10495 ast_cli(fd, " Qualify: %d\n", default_qualify); 10496 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10497 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" ); 10498 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10499 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10500 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10501 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10502 10503 10504 if (realtimepeers || realtimeusers) { 10505 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10506 ast_cli(fd, "----------------------\n"); 10507 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10508 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10509 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10510 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10511 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10512 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10513 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10514 } 10515 ast_cli(fd, "\n----\n"); 10516 return RESULT_SUCCESS; 10517 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10552 of file chan_sip.c.
References __sip_show_channels().
10553 { 10554 return __sip_show_channels(fd, argc, argv, 1); 10555 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10328 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.
10329 { 10330 char cbuf[256]; 10331 struct sip_user *user; 10332 struct ast_variable *v; 10333 int load_realtime; 10334 10335 if (argc < 4) 10336 return RESULT_SHOWUSAGE; 10337 10338 /* Load from realtime storage? */ 10339 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10340 10341 user = find_user(argv[3], load_realtime); 10342 if (user) { 10343 ast_cli(fd,"\n\n"); 10344 ast_cli(fd, " * Name : %s\n", user->name); 10345 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10346 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10347 ast_cli(fd, " Context : %s\n", user->context); 10348 ast_cli(fd, " Language : %s\n", user->language); 10349 if (!ast_strlen_zero(user->accountcode)) 10350 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10351 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10352 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10353 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10354 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10355 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10356 ast_cli(fd, " Callgroup : "); 10357 print_group(fd, user->callgroup, 0); 10358 ast_cli(fd, " Pickupgroup : "); 10359 print_group(fd, user->pickupgroup, 0); 10360 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10361 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10362 ast_cli(fd, " Codec Order : ("); 10363 print_codec_to_cli(fd, &user->prefs); 10364 ast_cli(fd, ")\n"); 10365 10366 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10367 if (user->chanvars) { 10368 ast_cli(fd, " Variables :\n"); 10369 for (v = user->chanvars ; v ; v = v->next) 10370 ast_cli(fd, " %s = %s\n", v->name, v->value); 10371 } 10372 ast_cli(fd,"\n"); 10373 ASTOBJ_UNREF(user,sip_destroy_user); 10374 } else { 10375 ast_cli(fd,"User %s not found.\n", argv[3]); 10376 ast_cli(fd,"\n"); 10377 } 10378 10379 return RESULT_SUCCESS; 10380 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9583 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_NAT, TRUE, and userl.
09584 { 09585 regex_t regexbuf; 09586 int havepattern = FALSE; 09587 09588 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09589 09590 switch (argc) { 09591 case 5: 09592 if (!strcasecmp(argv[3], "like")) { 09593 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09594 return RESULT_SHOWUSAGE; 09595 havepattern = TRUE; 09596 } else 09597 return RESULT_SHOWUSAGE; 09598 case 3: 09599 break; 09600 default: 09601 return RESULT_SHOWUSAGE; 09602 } 09603 09604 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09605 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09606 ASTOBJ_RDLOCK(iterator); 09607 09608 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09609 ASTOBJ_UNLOCK(iterator); 09610 continue; 09611 } 09612 09613 ast_cli(fd, FORMAT, iterator->name, 09614 iterator->secret, 09615 iterator->accountcode, 09616 iterator->context, 09617 iterator->ha ? "Yes" : "No", 09618 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09619 ASTOBJ_UNLOCK(iterator); 09620 } while (0) 09621 ); 09622 09623 if (havepattern) 09624 regfree(®exbuf); 09625 09626 return RESULT_SUCCESS; 09627 #undef FORMAT 09628 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17348 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(), strcasestr(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
17349 { 17350 char *cdest; 17351 char *extension, *host, *port; 17352 char tmp[80]; 17353 17354 cdest = ast_strdupa(dest); 17355 17356 extension = strsep(&cdest, "@"); 17357 host = strsep(&cdest, ":"); 17358 port = strsep(&cdest, ":"); 17359 if (ast_strlen_zero(extension)) { 17360 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17361 return 0; 17362 } 17363 17364 /* we'll issue the redirect message here */ 17365 if (!host) { 17366 char *localtmp; 17367 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17368 if (ast_strlen_zero(tmp)) { 17369 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17370 return 0; 17371 } 17372 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17373 char lhost[80], lport[80]; 17374 memset(lhost, 0, sizeof(lhost)); 17375 memset(lport, 0, sizeof(lport)); 17376 localtmp++; 17377 /* This is okey because lhost and lport are as big as tmp */ 17378 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17379 if (ast_strlen_zero(lhost)) { 17380 ast_log(LOG_ERROR, "Can't find the host address\n"); 17381 return 0; 17382 } 17383 host = ast_strdupa(lhost); 17384 if (!ast_strlen_zero(lport)) { 17385 port = ast_strdupa(lport); 17386 } 17387 } 17388 } 17389 17390 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17391 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17392 17393 sip_scheddestroy(p, 32000); /* Make sure we stop send this reply. */ 17394 sip_alreadygone(p); 17395 return 0; 17396 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3758 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().
03759 { 03760 struct sip_pvt *p = ast->tech_pvt; 03761 int res; 03762 03763 if (dest == NULL) /* functions below do not take a NULL */ 03764 dest = ""; 03765 ast_mutex_lock(&p->lock); 03766 if (ast->_state == AST_STATE_RING) 03767 res = sip_sipredirect(p, dest); 03768 else 03769 res = transmit_refer(p, dest); 03770 ast_mutex_unlock(&p->lock); 03771 return res; 03772 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3593 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03594 { 03595 struct sip_pvt *p = ast->tech_pvt; 03596 int res = 0; 03597 03598 switch (frame->frametype) { 03599 case AST_FRAME_VOICE: 03600 if (!(frame->subclass & ast->nativeformats)) { 03601 char s1[512], s2[512], s3[512]; 03602 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03603 frame->subclass, 03604 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03605 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03606 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03607 ast->readformat, 03608 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03609 ast->writeformat); 03610 return 0; 03611 } 03612 if (p) { 03613 ast_mutex_lock(&p->lock); 03614 if (p->rtp) { 03615 /* If channel is not up, activate early media session */ 03616 if ((ast->_state != AST_STATE_UP) && 03617 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03618 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03619 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03620 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03621 } 03622 p->lastrtptx = time(NULL); 03623 res = ast_rtp_write(p->rtp, frame); 03624 } 03625 ast_mutex_unlock(&p->lock); 03626 } 03627 break; 03628 case AST_FRAME_VIDEO: 03629 if (p) { 03630 ast_mutex_lock(&p->lock); 03631 if (p->vrtp) { 03632 /* Activate video early media */ 03633 if ((ast->_state != AST_STATE_UP) && 03634 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03635 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03636 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03637 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03638 } 03639 p->lastrtptx = time(NULL); 03640 res = ast_rtp_write(p->vrtp, frame); 03641 } 03642 ast_mutex_unlock(&p->lock); 03643 } 03644 break; 03645 case AST_FRAME_IMAGE: 03646 return 0; 03647 break; 03648 case AST_FRAME_MODEM: 03649 if (p) { 03650 ast_mutex_lock(&p->lock); 03651 /* UDPTL requires two-way communication, so early media is not needed here. 03652 we simply forget the frames if we get modem frames before the bridge is up. 03653 Fax will re-transmit. 03654 */ 03655 if (p->udptl && ast->_state == AST_STATE_UP) 03656 res = ast_udptl_write(p->udptl, frame); 03657 ast_mutex_unlock(&p->lock); 03658 } 03659 break; 03660 default: 03661 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03662 return 0; 03663 } 03664 03665 return res; 03666 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 15052 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), sip_request::data, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), sip_request::headers, sip_request::len, len, sip_request::lines, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), sip_request::method, option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, sip_request::rlPart1, sip_request::rlPart2, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
15053 { 15054 struct sip_request req; 15055 struct sockaddr_in sin = { 0, }; 15056 struct sip_pvt *p; 15057 int res; 15058 socklen_t len = sizeof(sin); 15059 int nounlock; 15060 int recount = 0; 15061 int lockretry; 15062 15063 memset(&req, 0, sizeof(req)); 15064 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 15065 if (res < 0) { 15066 #if !defined(__FreeBSD__) 15067 if (errno == EAGAIN) 15068 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 15069 else 15070 #endif 15071 if (errno != ECONNREFUSED) 15072 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 15073 return 1; 15074 } 15075 if (option_debug && res == sizeof(req.data)) { 15076 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 15077 req.data[sizeof(req.data) - 1] = '\0'; 15078 } else 15079 req.data[res] = '\0'; 15080 req.len = res; 15081 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 15082 ast_set_flag(&req, SIP_PKT_DEBUG); 15083 if (pedanticsipchecking) 15084 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 15085 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15086 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 15087 15088 parse_request(&req); 15089 req.method = find_sip_method(req.rlPart1); 15090 15091 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 15092 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 15093 15094 if (req.headers < 2) /* Must have at least two headers */ 15095 return 1; 15096 15097 /* Process request, with netlock held, and with usual deadlock avoidance */ 15098 for (lockretry = 100; lockretry > 0; lockretry--) { 15099 ast_mutex_lock(&netlock); 15100 15101 /* Find the active SIP dialog or create a new one */ 15102 p = find_call(&req, &sin, req.method); /* returns p locked */ 15103 if (p == NULL) { 15104 if (option_debug) 15105 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 15106 ast_mutex_unlock(&netlock); 15107 return 1; 15108 } 15109 /* Go ahead and lock the owner if it has one -- we may need it */ 15110 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 15111 if (!p->owner || !ast_channel_trylock(p->owner)) 15112 break; /* locking succeeded */ 15113 if (option_debug) 15114 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 15115 ast_mutex_unlock(&p->lock); 15116 ast_mutex_unlock(&netlock); 15117 /* Sleep for a very short amount of time */ 15118 usleep(1); 15119 } 15120 p->recv = sin; 15121 15122 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 15123 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 15124 15125 if (!lockretry) { 15126 if (p->owner) 15127 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 15128 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 15129 if (req.method != SIP_ACK) 15130 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 15131 /* XXX We could add retry-after to make sure they come back */ 15132 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 15133 return 1; 15134 } 15135 nounlock = 0; 15136 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 15137 /* Request failed */ 15138 if (option_debug) 15139 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15140 } 15141 15142 if (p->owner && !nounlock) 15143 ast_channel_unlock(p->owner); 15144 ast_mutex_unlock(&p->lock); 15145 ast_mutex_unlock(&netlock); 15146 if (recount) 15147 ast_update_use_count(); 15148 15149 return 1; 15150 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12327 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().
12328 { 12329 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12330 if (p->rtp) 12331 ast_rtp_stop(p->rtp); 12332 if (p->vrtp) 12333 ast_rtp_stop(p->vrtp); 12334 if (p->udptl) 12335 ast_udptl_stop(p->udptl); 12336 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10520 of file chan_sip.c.
References subscription_types, cfsubscription_types::text, and type.
Referenced by __sip_show_channels(), and sip_show_channel().
10521 { 10522 int i; 10523 10524 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10525 if (subscription_types[i].type == subtype) { 10526 return subscription_types[i].text; 10527 } 10528 } 10529 return subscription_types[0].text; 10530 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6090 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().
06091 { 06092 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06093 06094 if (maxrate & T38FAX_RATE_14400) { 06095 if (option_debug > 1) 06096 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 06097 return 14400; 06098 } else if (maxrate & T38FAX_RATE_12000) { 06099 if (option_debug > 1) 06100 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 06101 return 12000; 06102 } else if (maxrate & T38FAX_RATE_9600) { 06103 if (option_debug > 1) 06104 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 06105 return 9600; 06106 } else if (maxrate & T38FAX_RATE_7200) { 06107 if (option_debug > 1) 06108 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06109 return 7200; 06110 } else if (maxrate & T38FAX_RATE_4800) { 06111 if (option_debug > 1) 06112 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06113 return 4800; 06114 } else if (maxrate & T38FAX_RATE_2400) { 06115 if (option_debug > 1) 06116 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06117 return 2400; 06118 } else { 06119 if (option_debug > 1) 06120 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06121 return 0; 06122 } 06123 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static, read] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 16144 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, sip_peer::flags, sip_peer::prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
16145 { 16146 struct sip_peer *peer; 16147 16148 if (!(peer = ast_calloc(1, sizeof(*peer)))) 16149 return NULL; 16150 16151 apeerobjs++; 16152 ASTOBJ_INIT(peer); 16153 set_peer_defaults(peer); 16154 16155 ast_copy_string(peer->name, name, sizeof(peer->name)); 16156 16157 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 16158 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16159 peer->prefs = default_prefs; 16160 reg_source_db(peer); 16161 16162 return peer; 16163 }
static void temp_pvt_cleanup | ( | void * | data | ) | [static] |
Definition at line 5866 of file chan_sip.c.
References ast_string_field_free_pools, and free.
05867 { 05868 struct sip_pvt *p = data; 05869 05870 ast_string_field_free_pools(p); 05871 05872 free(data); 05873 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | [static] |
Convert transfer mode to text string.
Definition at line 9530 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().
09531 { 09532 if (mode == TRANSFER_OPENFORALL) 09533 return "open"; 09534 else if (mode == TRANSFER_CLOSED) 09535 return "closed"; 09536 return "strict"; 09537 }
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 8375 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().
08376 { 08377 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08378 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08379 }
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 7614 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07615 { 07616 struct sip_request req; 07617 07618 reqprep(&req, p, SIP_INFO, 0, 1); 07619 add_digit(&req, digit, duration); 07620 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07621 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7624 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07625 { 07626 struct sip_request req; 07627 07628 reqprep(&req, p, SIP_INFO, 0, 1); 07629 add_vidupdate(&req); 07630 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07631 }
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 6892 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, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
06893 { 06894 struct sip_request req; 06895 06896 req.method = sipmethod; 06897 if (init) { /* Seems like init always is 2 */ 06898 /* Bump branch even on initial requests */ 06899 p->branch ^= ast_random(); 06900 build_via(p); 06901 if (init > 1) 06902 initreqprep(&req, p, sipmethod); 06903 else 06904 reqprep(&req, p, sipmethod, 0, 1); 06905 } else 06906 reqprep(&req, p, sipmethod, 0, 1); 06907 06908 if (p->options && p->options->auth) 06909 add_header(&req, p->options->authheader, p->options->auth); 06910 append_date(&req); 06911 if (sipmethod == SIP_REFER) { /* Call transfer */ 06912 if (p->refer) { 06913 char buf[BUFSIZ]; 06914 if (!ast_strlen_zero(p->refer->refer_to)) 06915 add_header(&req, "Refer-To", p->refer->refer_to); 06916 if (!ast_strlen_zero(p->refer->referred_by)) { 06917 sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 06918 add_header(&req, "Referred-By", buf); 06919 } 06920 } 06921 } 06922 /* This new INVITE is part of an attended transfer. Make sure that the 06923 other end knows and replace the current call with this new call */ 06924 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 06925 add_header(&req, "Replaces", p->options->replaces); 06926 add_header(&req, "Require", "replaces"); 06927 } 06928 06929 add_header(&req, "Allow", ALLOWED_METHODS); 06930 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06931 if (p->options && p->options->addsipheaders && p->owner) { 06932 struct ast_channel *ast = p->owner; /* The owner channel */ 06933 struct varshead *headp = &ast->varshead; 06934 06935 if (!headp) 06936 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 06937 else { 06938 const struct ast_var_t *current; 06939 AST_LIST_TRAVERSE(headp, current, entries) { 06940 /* SIPADDHEADER: Add SIP header to outgoing call */ 06941 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 06942 char *content, *end; 06943 const char *header = ast_var_value(current); 06944 char *headdup = ast_strdupa(header); 06945 06946 /* Strip of the starting " (if it's there) */ 06947 if (*headdup == '"') 06948 headdup++; 06949 if ((content = strchr(headdup, ':'))) { 06950 *content++ = '\0'; 06951 content = ast_skip_blanks(content); /* Skip white space */ 06952 /* Strip the ending " (if it's there) */ 06953 end = content + strlen(content) -1; 06954 if (*end == '"') 06955 *end = '\0'; 06956 06957 add_header(&req, headdup, content); 06958 if (sipdebug) 06959 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 06960 } 06961 } 06962 } 06963 } 06964 } 06965 if (sdp) { 06966 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 06967 ast_udptl_offered_from_local(p->udptl, 1); 06968 if (option_debug) 06969 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 06970 add_t38_sdp(&req, p); 06971 } else if (p->rtp) 06972 add_sdp(&req, p); 06973 } else { 06974 add_header_contentLength(&req, 0); 06975 } 06976 06977 if (!p->initreq.headers) 06978 initialize_initreq(p, &req); 06979 p->lastinvite = p->ocseq; 06980 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 06981 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7522 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().
07523 { 07524 struct sip_request req; 07525 07526 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07527 add_text(&req, text); 07528 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07529 }
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 7162 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07163 { 07164 struct sip_request req; 07165 char tmp[500]; 07166 char *t = tmp; 07167 size_t maxbytes = sizeof(tmp); 07168 07169 initreqprep(&req, p, SIP_NOTIFY); 07170 add_header(&req, "Event", "message-summary"); 07171 add_header(&req, "Content-Type", default_notifymime); 07172 07173 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07174 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07175 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07176 /* Cisco has a bug in the SIP stack where it can't accept the 07177 (0/0) notification. This can temporarily be disabled in 07178 sip.conf with the "buggymwi" option */ 07179 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)")); 07180 07181 if (p->subscribed) { 07182 if (p->expiry) 07183 add_header(&req, "Subscription-State", "active"); 07184 else /* Expired */ 07185 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07186 } 07187 07188 if (t > tmp + sizeof(tmp)) 07189 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07190 07191 add_header_contentLength(&req, strlen(tmp)); 07192 add_line(&req, tmp); 07193 07194 if (!p->initreq.headers) 07195 initialize_initreq(p, &req); 07196 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07197 }
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 7208 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().
07209 { 07210 struct sip_request req; 07211 char tmp[BUFSIZ/2]; 07212 07213 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07214 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07215 add_header(&req, "Event", tmp); 07216 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07217 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07218 add_header(&req, "Allow", ALLOWED_METHODS); 07219 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07220 07221 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07222 add_header_contentLength(&req, strlen(tmp)); 07223 add_line(&req, tmp); 07224 07225 if (!p->initreq.headers) 07226 initialize_initreq(p, &req); 07227 07228 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07229 }
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 7543 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().
07544 { 07545 struct sip_request req = { 07546 .headers = 0, 07547 }; 07548 char from[256]; 07549 const char *of; 07550 char *c; 07551 char referto[256]; 07552 char *ttag, *ftag; 07553 char *theirtag = ast_strdupa(p->theirtag); 07554 07555 if (option_debug || sipdebug) 07556 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07557 07558 /* Are we transfering an inbound or outbound call ? */ 07559 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07560 of = get_header(&p->initreq, "To"); 07561 ttag = theirtag; 07562 ftag = p->tag; 07563 } else { 07564 of = get_header(&p->initreq, "From"); 07565 ftag = theirtag; 07566 ttag = p->tag; 07567 } 07568 07569 ast_copy_string(from, of, sizeof(from)); 07570 of = get_in_brackets(from); 07571 ast_string_field_set(p, from, of); 07572 if (strncasecmp(of, "sip:", 4)) 07573 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07574 else 07575 of += 4; 07576 /* Get just the username part */ 07577 if ((c = strchr(dest, '@'))) 07578 c = NULL; 07579 else if ((c = strchr(of, '@'))) 07580 *c++ = '\0'; 07581 if (c) 07582 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07583 else 07584 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07585 07586 /* save in case we get 407 challenge */ 07587 sip_refer_allocate(p); 07588 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07589 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07590 p->refer->status = REFER_SENT; /* Set refer status */ 07591 07592 reqprep(&req, p, SIP_REFER, 0, 1); 07593 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07594 07595 add_header(&req, "Refer-To", referto); 07596 add_header(&req, "Allow", ALLOWED_METHODS); 07597 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07598 if (!ast_strlen_zero(p->our_contact)) 07599 add_header(&req, "Referred-By", p->our_contact); 07600 07601 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07602 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07603 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07604 07605 /*! \todo In theory, we should hang around and wait for a reply, before 07606 returning to the dial plan here. Don't know really how that would 07607 affect the transfer() app or the pbx, but, well, to make this 07608 useful we should have a STATUS code on transfer(). 07609 */ 07610 }
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 7331 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_pvt::ourip, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sip_pvt::sa, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07332 { 07333 struct sip_request req; 07334 char from[256]; 07335 char to[256]; 07336 char tmp[80]; 07337 char addr[80]; 07338 struct sip_pvt *p; 07339 07340 /* exit if we are already in process with this registrar ?*/ 07341 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07342 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07343 return 0; 07344 } 07345 07346 if (r->call) { /* We have a registration */ 07347 if (!auth) { 07348 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07349 return 0; 07350 } else { 07351 p = r->call; 07352 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07353 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07354 } 07355 } else { 07356 /* Build callid for registration if we haven't registered before */ 07357 if (!r->callid_valid) { 07358 build_callid_registry(r, __ourip, default_fromdomain); 07359 r->callid_valid = TRUE; 07360 } 07361 /* Allocate SIP packet for registration */ 07362 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07363 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07364 return 0; 07365 } 07366 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07367 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07368 /* Find address to hostname */ 07369 if (create_addr(p, r->hostname)) { 07370 /* we have what we hope is a temporary network error, 07371 * probably DNS. We need to reschedule a registration try */ 07372 sip_destroy(p); 07373 if (r->timeout > -1) { 07374 ast_sched_del(sched, r->timeout); 07375 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07376 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07377 } else { 07378 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07379 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); 07380 } 07381 r->regattempts++; 07382 return 0; 07383 } 07384 /* Copy back Call-ID in case create_addr changed it */ 07385 ast_string_field_set(r, callid, p->callid); 07386 if (r->portno) 07387 p->sa.sin_port = htons(r->portno); 07388 else /* Set registry port to the port set from the peer definition/srv or default */ 07389 r->portno = ntohs(p->sa.sin_port); 07390 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07391 r->call=p; /* Save pointer to SIP packet */ 07392 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07393 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07394 ast_string_field_set(p, peersecret, r->secret); 07395 if (!ast_strlen_zero(r->md5secret)) 07396 ast_string_field_set(p, peermd5secret, r->md5secret); 07397 /* User name in this realm 07398 - if authuser is set, use that, otherwise use username */ 07399 if (!ast_strlen_zero(r->authuser)) { 07400 ast_string_field_set(p, peername, r->authuser); 07401 ast_string_field_set(p, authname, r->authuser); 07402 } else if (!ast_strlen_zero(r->username)) { 07403 ast_string_field_set(p, peername, r->username); 07404 ast_string_field_set(p, authname, r->username); 07405 ast_string_field_set(p, fromuser, r->username); 07406 } 07407 if (!ast_strlen_zero(r->username)) 07408 ast_string_field_set(p, username, r->username); 07409 /* Save extension in packet */ 07410 ast_string_field_set(p, exten, r->contact); 07411 07412 /* 07413 check which address we should use in our contact header 07414 based on whether the remote host is on the external or 07415 internal network so we can register through nat 07416 */ 07417 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07418 p->ourip = bindaddr.sin_addr; 07419 build_contact(p); 07420 } 07421 07422 /* set up a timeout */ 07423 if (auth == NULL) { 07424 if (r->timeout > -1) { 07425 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07426 ast_sched_del(sched, r->timeout); 07427 } 07428 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07429 if (option_debug) 07430 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07431 } 07432 07433 if (strchr(r->username, '@')) { 07434 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07435 if (!ast_strlen_zero(p->theirtag)) 07436 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07437 else 07438 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07439 } else { 07440 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07441 if (!ast_strlen_zero(p->theirtag)) 07442 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07443 else 07444 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07445 } 07446 07447 /* Fromdomain is what we are registering to, regardless of actual 07448 host name from SRV */ 07449 if (!ast_strlen_zero(p->fromdomain)) { 07450 if (r->portno && r->portno != STANDARD_SIP_PORT) 07451 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07452 else 07453 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07454 } else { 07455 if (r->portno && r->portno != STANDARD_SIP_PORT) 07456 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07457 else 07458 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07459 } 07460 ast_string_field_set(p, uri, addr); 07461 07462 p->branch ^= ast_random(); 07463 07464 init_req(&req, sipmethod, addr); 07465 07466 /* Add to CSEQ */ 07467 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07468 p->ocseq = r->ocseq; 07469 07470 build_via(p); 07471 add_header(&req, "Via", p->via); 07472 add_header(&req, "From", from); 07473 add_header(&req, "To", to); 07474 add_header(&req, "Call-ID", p->callid); 07475 add_header(&req, "CSeq", tmp); 07476 if (!ast_strlen_zero(global_useragent)) 07477 add_header(&req, "User-Agent", global_useragent); 07478 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07479 07480 07481 if (auth) /* Add auth header */ 07482 add_header(&req, authheader, auth); 07483 else if (!ast_strlen_zero(r->nonce)) { 07484 char digest[1024]; 07485 07486 /* We have auth data to reuse, build a digest header! */ 07487 if (sipdebug) 07488 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07489 ast_string_field_set(p, realm, r->realm); 07490 ast_string_field_set(p, nonce, r->nonce); 07491 ast_string_field_set(p, domain, r->domain); 07492 ast_string_field_set(p, opaque, r->opaque); 07493 ast_string_field_set(p, qop, r->qop); 07494 r->noncecount++; 07495 p->noncecount = r->noncecount; 07496 07497 memset(digest,0,sizeof(digest)); 07498 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07499 add_header(&req, "Authorization", digest); 07500 else 07501 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07502 07503 } 07504 07505 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07506 add_header(&req, "Expires", tmp); 07507 add_header(&req, "Contact", p->our_contact); 07508 add_header(&req, "Event", "registration"); 07509 add_header_contentLength(&req, 0); 07510 07511 initialize_initreq(p, &req); 07512 if (sip_debug_test_pvt(p)) 07513 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07514 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07515 r->regattempts++; /* Another attempt */ 07516 if (option_debug > 3) 07517 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07518 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07519 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6612 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
06613 { 06614 struct sip_request req; 06615 06616 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06617 06618 add_header(&req, "Allow", ALLOWED_METHODS); 06619 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06620 if (sipdebug) 06621 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06622 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06623 append_history(p, "ReInv", "Re-invite sent"); 06624 add_sdp(&req, p); 06625 /* Use this as the basis */ 06626 initialize_initreq(p, &req); 06627 p->lastinvite = p->ocseq; 06628 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06629 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06630 }
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 6636 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().
06637 { 06638 struct sip_request req; 06639 06640 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06641 06642 add_header(&req, "Allow", ALLOWED_METHODS); 06643 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06644 if (sipdebug) 06645 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06646 ast_udptl_offered_from_local(p->udptl, 1); 06647 add_t38_sdp(&req, p); 06648 /* Use this as the basis */ 06649 initialize_initreq(p, &req); 06650 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06651 p->lastinvite = p->ocseq; 06652 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06653 }
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 7636 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().
07637 { 07638 struct sip_request resp; 07639 07640 if (sipmethod == SIP_ACK) 07641 p->invitestate = INV_CONFIRMED; 07642 07643 reqprep(&resp, p, sipmethod, seqno, newbranch); 07644 add_header_contentLength(&resp, 0); 07645 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07646 }
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 7649 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
07650 { 07651 struct sip_request resp; 07652 07653 reqprep(&resp, p, sipmethod, seqno, newbranch); 07654 if (!ast_strlen_zero(p->realm)) { 07655 char digest[1024]; 07656 07657 memset(digest, 0, sizeof(digest)); 07658 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07659 if (p->options && p->options->auth_type == PROXY_AUTH) 07660 add_header(&resp, "Proxy-Authorization", digest); 07661 else if (p->options && p->options->auth_type == WWW_AUTH) 07662 add_header(&resp, "Authorization", digest); 07663 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07664 add_header(&resp, "Proxy-Authorization", digest); 07665 } else 07666 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07667 } 07668 /* If we are hanging up and know a cause for that, send it in clear text to make 07669 debugging easier. */ 07670 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07671 char buf[10]; 07672 07673 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07674 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07675 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07676 } 07677 07678 add_header_contentLength(&resp, 0); 07679 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07680 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 5926 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
05927 { 05928 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05929 }
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 5945 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().
05946 { 05947 return __transmit_response(p, msg, req, XMIT_CRITICAL); 05948 }
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 5876 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, sip_pvt::branch, build_via(), do_setnat(), sip_pvt::flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), sip_pvt::method, sip_pvt::ocseq, sip_pvt::ourip, sip_pvt::recv, sip_pvt::sa, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, sip_pvt::tag, and XMIT_UNRELIABLE.
Referenced by find_call().
05877 { 05878 struct sip_pvt *p = NULL; 05879 05880 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05881 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05882 return -1; 05883 } 05884 05885 /* if the structure was just allocated, initialize it */ 05886 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 05887 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 05888 if (ast_string_field_init(p, 512)) 05889 return -1; 05890 } 05891 05892 /* Initialize the bare minimum */ 05893 p->method = intended_method; 05894 05895 if (sin) { 05896 p->sa = *sin; 05897 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05898 p->ourip = __ourip; 05899 } else 05900 p->ourip = __ourip; 05901 05902 p->branch = ast_random(); 05903 make_our_tag(p->tag, sizeof(p->tag)); 05904 p->ocseq = INITIAL_CSEQ; 05905 05906 if (useglobal_nat && sin) { 05907 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 05908 p->recv = *sin; 05909 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 05910 } 05911 05912 ast_string_field_set(p, fromdomain, default_fromdomain); 05913 build_via(p); 05914 ast_string_field_set(p, callid, callid); 05915 05916 /* Use this temporary pvt structure to send the message */ 05917 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05918 05919 /* Free the string fields, but not the pool space */ 05920 ast_string_field_free_all(p); 05921 05922 return 0; 05923 }
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 5973 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
05974 { 05975 struct sip_request resp; 05976 respprep(&resp, p, msg, req); 05977 add_header(&resp, "Accept", "application/sdp"); 05978 add_header_contentLength(&resp, 0); 05979 return send_response(p, &resp, reliable, 0); 05980 }
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 5983 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
05984 { 05985 struct sip_request resp; 05986 char tmp[512]; 05987 int seqno = 0; 05988 05989 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05990 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05991 return -1; 05992 } 05993 /* Stale means that they sent us correct authentication, but 05994 based it on an old challenge (nonce) */ 05995 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 05996 respprep(&resp, p, msg, req); 05997 add_header(&resp, header, tmp); 05998 add_header_contentLength(&resp, 0); 05999 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06000 return send_response(p, &resp, reliable, seqno); 06001 }
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 5963 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
05964 { 05965 struct sip_request resp; 05966 respprep(&resp, p, msg, req); 05967 append_date(&resp); 05968 add_header_contentLength(&resp, 0); 05969 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05970 }
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 6541 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06542 { 06543 struct sip_request resp; 06544 int seqno; 06545 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06546 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06547 return -1; 06548 } 06549 respprep(&resp, p, msg, req); 06550 if (p->rtp) { 06551 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06552 if (option_debug) 06553 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06554 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06555 } 06556 try_suggested_sip_codec(p); 06557 add_sdp(&resp, p); 06558 } else 06559 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06560 if (reliable && !p->pendinginvite) 06561 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06562 return send_response(p, &resp, reliable, seqno); 06563 }
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 6501 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06502 { 06503 struct sip_request resp; 06504 int seqno; 06505 06506 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06507 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06508 return -1; 06509 } 06510 respprep(&resp, p, msg, req); 06511 if (p->udptl) { 06512 ast_udptl_offered_from_local(p->udptl, 0); 06513 add_t38_sdp(&resp, p); 06514 } else 06515 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06516 if (retrans && !p->pendinginvite) 06517 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06518 return send_response(p, &resp, retrans, seqno); 06519 }
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 5932 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
05933 { 05934 struct sip_request resp; 05935 respprep(&resp, p, msg, req); 05936 append_date(&resp); 05937 add_header(&resp, "Unsupported", unsupported); 05938 add_header_contentLength(&resp, 0); 05939 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05940 }
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 7200 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().
07201 { 07202 if (!p->initreq.headers) /* Initialize first request before sending */ 07203 initialize_initreq(p, req); 07204 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07205 }
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 6984 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, cfsubscription_types::event, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, cfsubscription_types::mediatype, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
06985 { 06986 char tmp[4000], from[256], to[256]; 06987 char *t = tmp, *c, *mfrom, *mto; 06988 size_t maxbytes = sizeof(tmp); 06989 struct sip_request req; 06990 char hint[AST_MAX_EXTENSION]; 06991 char *statestring = "terminated"; 06992 const struct cfsubscription_types *subscriptiontype; 06993 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 06994 char *pidfstate = "--"; 06995 char *pidfnote= "Ready"; 06996 06997 memset(from, 0, sizeof(from)); 06998 memset(to, 0, sizeof(to)); 06999 memset(tmp, 0, sizeof(tmp)); 07000 07001 switch (state) { 07002 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07003 statestring = (global_notifyringing) ? "early" : "confirmed"; 07004 local_state = NOTIFY_INUSE; 07005 pidfstate = "busy"; 07006 pidfnote = "Ringing"; 07007 break; 07008 case AST_EXTENSION_RINGING: 07009 statestring = "early"; 07010 local_state = NOTIFY_INUSE; 07011 pidfstate = "busy"; 07012 pidfnote = "Ringing"; 07013 break; 07014 case AST_EXTENSION_INUSE: 07015 statestring = "confirmed"; 07016 local_state = NOTIFY_INUSE; 07017 pidfstate = "busy"; 07018 pidfnote = "On the phone"; 07019 break; 07020 case AST_EXTENSION_BUSY: 07021 statestring = "confirmed"; 07022 local_state = NOTIFY_CLOSED; 07023 pidfstate = "busy"; 07024 pidfnote = "On the phone"; 07025 break; 07026 case AST_EXTENSION_UNAVAILABLE: 07027 statestring = "terminated"; 07028 local_state = NOTIFY_CLOSED; 07029 pidfstate = "away"; 07030 pidfnote = "Unavailable"; 07031 break; 07032 case AST_EXTENSION_ONHOLD: 07033 statestring = "confirmed"; 07034 local_state = NOTIFY_INUSE; 07035 pidfstate = "busy"; 07036 pidfnote = "On Hold"; 07037 break; 07038 case AST_EXTENSION_NOT_INUSE: 07039 default: 07040 /* Default setting */ 07041 break; 07042 } 07043 07044 subscriptiontype = find_subscription_type(p->subscribed); 07045 07046 /* Check which device/devices we are watching and if they are registered */ 07047 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07048 char *hint2 = hint, *individual_hint = NULL; 07049 while ((individual_hint = strsep(&hint2, "&"))) { 07050 /* If they are not registered, we will override notification and show no availability */ 07051 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) { 07052 local_state = NOTIFY_CLOSED; 07053 pidfstate = "away"; 07054 pidfnote = "Not online"; 07055 } 07056 } 07057 } 07058 07059 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07060 c = get_in_brackets(from); 07061 if (strncasecmp(c, "sip:", 4)) { 07062 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07063 return -1; 07064 } 07065 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07066 07067 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07068 c = get_in_brackets(to); 07069 if (strncasecmp(c, "sip:", 4)) { 07070 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07071 return -1; 07072 } 07073 mto = strsep(&c, ";"); /* trim ; and beyond */ 07074 07075 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07076 07077 07078 add_header(&req, "Event", subscriptiontype->event); 07079 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07080 switch(state) { 07081 case AST_EXTENSION_DEACTIVATED: 07082 if (timeout) 07083 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07084 else { 07085 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07086 add_header(&req, "Retry-After", "60"); 07087 } 07088 break; 07089 case AST_EXTENSION_REMOVED: 07090 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07091 break; 07092 default: 07093 if (p->expiry) 07094 add_header(&req, "Subscription-State", "active"); 07095 else /* Expired */ 07096 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07097 } 07098 switch (p->subscribed) { 07099 case XPIDF_XML: 07100 case CPIM_PIDF_XML: 07101 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07102 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07103 ast_build_string(&t, &maxbytes, "<presence>\n"); 07104 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07105 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07106 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07107 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07108 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07109 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07110 break; 07111 case PIDF_XML: /* Eyebeam supports this format */ 07112 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07113 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); 07114 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07115 if (pidfstate[0] != '-') 07116 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07117 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07118 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07119 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07120 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07121 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07122 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07123 else 07124 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07125 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07126 break; 07127 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07128 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07129 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); 07130 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07131 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07132 else 07133 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07134 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07135 if (state == AST_EXTENSION_ONHOLD) { 07136 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07137 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07138 "</target>\n</local>\n", mto); 07139 } 07140 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07141 break; 07142 case NONE: 07143 default: 07144 break; 07145 } 07146 07147 if (t > tmp + sizeof(tmp)) 07148 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07149 07150 add_header_contentLength(&req, strlen(tmp)); 07151 add_line(&req, tmp); 07152 07153 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07154 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3544 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().
03545 { 03546 int fmt; 03547 const char *codec; 03548 03549 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03550 if (!codec) 03551 return; 03552 03553 fmt = ast_getformatbyname(codec); 03554 if (fmt) { 03555 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03556 if (p->jointcapability & fmt) { 03557 p->jointcapability &= fmt; 03558 p->capability &= fmt; 03559 } else 03560 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03561 } else 03562 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03563 return; 03564 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 17699 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, clear_realm_authentication(), clear_sip_domains(), iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipsock, TRUE, and userl.
17700 { 17701 struct sip_pvt *p, *pl; 17702 17703 /* First, take us out of the channel type list */ 17704 ast_channel_unregister(&sip_tech); 17705 17706 /* Unregister dial plan functions */ 17707 ast_custom_function_unregister(&sipchaninfo_function); 17708 ast_custom_function_unregister(&sippeer_function); 17709 ast_custom_function_unregister(&sip_header_function); 17710 ast_custom_function_unregister(&checksipdomain_function); 17711 17712 /* Unregister dial plan applications */ 17713 ast_unregister_application(app_dtmfmode); 17714 ast_unregister_application(app_sipaddheader); 17715 17716 /* Unregister CLI commands */ 17717 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 17718 17719 /* Disconnect from the RTP subsystem */ 17720 ast_rtp_proto_unregister(&sip_rtp); 17721 17722 /* Disconnect from UDPTL */ 17723 ast_udptl_proto_unregister(&sip_udptl); 17724 17725 /* Unregister AMI actions */ 17726 ast_manager_unregister("SIPpeers"); 17727 ast_manager_unregister("SIPshowpeer"); 17728 17729 ast_mutex_lock(&iflock); 17730 /* Hangup all interfaces if they have an owner */ 17731 for (p = iflist; p ; p = p->next) { 17732 if (p->owner) 17733 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 17734 } 17735 ast_mutex_unlock(&iflock); 17736 17737 ast_mutex_lock(&monlock); 17738 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 17739 pthread_cancel(monitor_thread); 17740 pthread_kill(monitor_thread, SIGURG); 17741 pthread_join(monitor_thread, NULL); 17742 } 17743 monitor_thread = AST_PTHREADT_STOP; 17744 ast_mutex_unlock(&monlock); 17745 17746 ast_mutex_lock(&iflock); 17747 /* Destroy all the interfaces and free their memory */ 17748 p = iflist; 17749 while (p) { 17750 pl = p; 17751 p = p->next; 17752 __sip_destroy(pl, TRUE); 17753 } 17754 iflist = NULL; 17755 ast_mutex_unlock(&iflock); 17756 17757 /* Free memory for local network address mask */ 17758 ast_free_ha(localaddr); 17759 17760 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17761 ASTOBJ_CONTAINER_DESTROY(&userl); 17762 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 17763 ASTOBJ_CONTAINER_DESTROY(&peerl); 17764 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17765 ASTOBJ_CONTAINER_DESTROY(®l); 17766 17767 clear_realm_authentication(authl); 17768 clear_sip_domains(); 17769 close(sipsock); 17770 sched_context_destroy(sched); 17771 17772 return 0; 17773 }
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 3101 of file chan_sip.c.
References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, and sipdebug.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03102 { 03103 char name[256]; 03104 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03105 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03106 struct sip_user *u = NULL; 03107 struct sip_peer *p = NULL; 03108 03109 if (option_debug > 2) 03110 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03111 03112 /* Test if we need to check call limits, in order to avoid 03113 realtime lookups if we do not need it */ 03114 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03115 return 0; 03116 03117 ast_copy_string(name, fup->username, sizeof(name)); 03118 03119 /* Check the list of users only for incoming calls */ 03120 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03121 inuse = &u->inUse; 03122 call_limit = &u->call_limit; 03123 inringing = NULL; 03124 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03125 inuse = &p->inUse; 03126 call_limit = &p->call_limit; 03127 inringing = &p->inRinging; 03128 ast_copy_string(name, fup->peername, sizeof(name)); 03129 } 03130 if (!p && !u) { 03131 if (option_debug > 1) 03132 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03133 return 0; 03134 } 03135 03136 switch(event) { 03137 /* incoming and outgoing affects the inUse counter */ 03138 case DEC_CALL_LIMIT: 03139 if ( *inuse > 0 ) { 03140 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03141 (*inuse)--; 03142 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03143 } 03144 } else { 03145 *inuse = 0; 03146 } 03147 if (inringing) { 03148 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03149 if (*inringing > 0) 03150 (*inringing)--; 03151 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03152 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03153 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03154 } 03155 } 03156 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03157 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03158 sip_peer_hold(fup, 0); 03159 } 03160 if (option_debug > 1 || sipdebug) { 03161 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03162 } 03163 break; 03164 03165 case INC_CALL_RINGING: 03166 case INC_CALL_LIMIT: 03167 if (*call_limit > 0 ) { 03168 if (*inuse >= *call_limit) { 03169 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); 03170 if (u) 03171 ASTOBJ_UNREF(u, sip_destroy_user); 03172 else 03173 ASTOBJ_UNREF(p, sip_destroy_peer); 03174 return -1; 03175 } 03176 } 03177 if (inringing && (event == INC_CALL_RINGING)) { 03178 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03179 (*inringing)++; 03180 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03181 } 03182 } 03183 /* Continue */ 03184 (*inuse)++; 03185 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03186 if (option_debug > 1 || sipdebug) { 03187 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03188 } 03189 break; 03190 03191 case DEC_CALL_RINGING: 03192 if (inringing) { 03193 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03194 if (*inringing > 0) 03195 (*inringing)--; 03196 else if (!ast_test_flag(&fup->flags[0], SIP_REALTIME) || ast_test_flag(&fup->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03197 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03198 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03199 } 03200 } 03201 break; 03202 03203 default: 03204 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03205 } 03206 if (p) { 03207 ast_device_state_changed("SIP/%s", p->name); 03208 ASTOBJ_UNREF(p, sip_destroy_peer); 03209 } else /* u must be set */ 03210 ASTOBJ_UNREF(u, sip_destroy_user); 03211 return 0; 03212 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2441 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02442 { 02443 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02444 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02445 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02446 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02447 } 02448 }
struct in_addr __ourip [static] |
Definition at line 1193 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 17239 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17241 of file chan_sip.c.
Definition at line 1182 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), 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 1187 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
Definition at line 11538 of file chan_sip.c.
struct ast_cli_entry cli_sip[] [static] |
Definition at line 17535 of file chan_sip.c.
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 17525 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 17530 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 11422 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1196 of file chan_sip.c.
Referenced by sip_debug_test_addr(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 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 17238 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17244 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] |
Definition at line 188 of file chan_sip.c.
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1190 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 1189 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 1188 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1191 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.
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 11439 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 1192 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 10079 of file chan_sip.c.
Referenced by load_module().
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 9630 of file chan_sip.c.
Referenced by load_module().
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 11431 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 11435 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 1198 of file chan_sip.c.
Referenced by complete_sipnotify(), reload_config(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 11371 of file chan_sip.c.
int ourport [static] |
Definition at line 1195 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 11413 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 11395 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 11391 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 11366 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 11399 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 11386 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 11452 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 11408 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 11403 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 11418 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 11456 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 11448 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 11381 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 11376 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
Definition at line 11514 of file chan_sip.c.
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_call(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
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 11444 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 1596 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 1538 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 1564 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 1605 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1186 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), reload_config(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 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 17237 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17242 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.